aboutsummaryrefslogtreecommitdiff
path: root/src/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/net_node.cpp1
-rw-r--r--src/p2p/net_node.h7
-rw-r--r--src/p2p/net_node.inl31
3 files changed, 29 insertions, 10 deletions
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index 8dd551d1e..84cc1581e 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -166,6 +166,7 @@ namespace nodetool
const command_line::arg_descriptor<bool> arg_pad_transactions = {
"pad-transactions", "Pad relayed transactions to help defend against traffic volume analysis", false
};
+ const command_line::arg_descriptor<uint32_t> arg_max_connections_per_ip = {"max-connections-per-ip", "Maximum number of connections allowed from the same IP address", 1};
boost::optional<std::vector<proxy>> get_proxies(boost::program_options::variables_map const& vm)
{
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 9fba5d636..db931122e 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -139,6 +139,7 @@ namespace nodetool
typedef COMMAND_HANDSHAKE_T<typename t_payload_net_handler::payload_type> COMMAND_HANDSHAKE;
typedef COMMAND_TIMED_SYNC_T<typename t_payload_net_handler::payload_type> COMMAND_TIMED_SYNC;
+ static_assert(p2p_connection_context::handshake_command() == COMMAND_HANDSHAKE::ID, "invalid handshake command id");
typedef epee::net_utils::boosted_tcp_server<epee::levin::async_protocol_handler<p2p_connection_context>> net_server;
@@ -257,7 +258,8 @@ namespace nodetool
m_igd(no_igd),
m_offline(false),
is_closing(false),
- m_network_id()
+ m_network_id(),
+ max_connections(1)
{}
virtual ~node_server();
@@ -516,6 +518,8 @@ namespace nodetool
epee::net_utils::ssl_support_t m_ssl_support;
bool m_enable_dns_blocklist;
+
+ uint32_t max_connections;
};
const int64_t default_limit_up = P2P_DEFAULT_LIMIT_RATE_UP; // kB/s
@@ -550,6 +554,7 @@ namespace nodetool
extern const command_line::arg_descriptor<int64_t> arg_limit_rate_down;
extern const command_line::arg_descriptor<int64_t> arg_limit_rate;
extern const command_line::arg_descriptor<bool> arg_pad_transactions;
+ extern const command_line::arg_descriptor<uint32_t> arg_max_connections_per_ip;
}
POP_WARNINGS
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 229dea0b5..407f147f6 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -131,6 +131,7 @@ namespace nodetool
command_line::add_arg(desc, arg_limit_rate_down);
command_line::add_arg(desc, arg_limit_rate);
command_line::add_arg(desc, arg_pad_transactions);
+ command_line::add_arg(desc, arg_max_connections_per_ip);
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
@@ -234,6 +235,7 @@ namespace nodetool
return false;
const time_t now = time(nullptr);
+ bool added = false;
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
time_t limit;
@@ -244,7 +246,10 @@ namespace nodetool
const std::string host_str = addr.host_str();
auto it = m_blocked_hosts.find(host_str);
if (it == m_blocked_hosts.end())
+ {
m_blocked_hosts[host_str] = limit;
+ added = true;
+ }
else if (it->second < limit || !add_only)
it->second = limit;
@@ -275,7 +280,10 @@ namespace nodetool
conns.clear();
}
- MCLOG_CYAN(el::Level::Info, "global", "Host " << host_str << " blocked.");
+ if (added)
+ MCLOG_CYAN(el::Level::Info, "global", "Host " << host_str << " blocked.");
+ else
+ MINFO("Host " << host_str << " block time updated.");
return true;
}
//-----------------------------------------------------------------------------------
@@ -608,6 +616,8 @@ namespace nodetool
return false;
}
+ max_connections = command_line::get_arg(vm, arg_max_connections_per_ip);
+
return true;
}
//-----------------------------------------------------------------------------------
@@ -1217,8 +1227,9 @@ namespace nodetool
if(!handle_remote_peerlist(rsp.local_peerlist_new, context))
{
LOG_WARNING_CC(context, "COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection.");
+ const auto remote_address = context.m_remote_address;
m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id );
- add_host_fail(context.m_remote_address);
+ add_host_fail(remote_address);
}
if(!context.m_is_income)
m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address, context.m_pruning_seed, context.m_rpc_port, context.m_rpc_credits_per_hash);
@@ -1382,7 +1393,7 @@ namespace nodetool
if(just_take_peerlist)
{
zone.m_net_server.get_config_object().close(con->m_connection_id);
- LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED.");
+ MDEBUG(na.str() << "CONNECTION HANDSHAKED OK AND CLOSED.");
return true;
}
@@ -1444,7 +1455,7 @@ namespace nodetool
zone.m_net_server.get_config_object().close(con->m_connection_id);
- LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED.");
+ MDEBUG(na.str() << "CONNECTION HANDSHAKED OK AND CLOSED.");
return true;
}
@@ -2151,6 +2162,7 @@ namespace nodetool
LOG_DEBUG_CC(context, "REMOTE PEERLIST: remote peerlist size=" << peerlist_.size());
LOG_TRACE_CC(context, "REMOTE PEERLIST: " << ENDL << print_peerlist_to_string(peerlist_));
+ CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
return m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.merge_peerlist(peerlist_, [this](const peerlist_entry &pe) {
return !is_addr_recently_failed(pe.adr) && is_remote_host_allowed(pe.adr);
});
@@ -2473,12 +2485,14 @@ namespace nodetool
template<class t_payload_net_handler>
int node_server<t_payload_net_handler>::handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
{
+ // copy since dropping the connection will invalidate the context, and thus the address
+ const auto remote_address = context.m_remote_address;
+
if(arg.node_data.network_id != m_network_id)
{
-
LOG_INFO_CC(context, "WRONG NETWORK AGENT CONNECTED! id=" << arg.node_data.network_id);
drop_connection(context);
- add_host_fail(context.m_remote_address);
+ add_host_fail(remote_address);
return 1;
}
@@ -2486,7 +2500,7 @@ namespace nodetool
{
LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came not from incoming connection");
drop_connection(context);
- add_host_fail(context.m_remote_address);
+ add_host_fail(remote_address);
return 1;
}
@@ -2837,8 +2851,7 @@ namespace nodetool
if (address.get_zone() != epee::net_utils::zone::public_)
return false; // Unable to determine how many connections from host
- const size_t max_connections = 1;
- size_t count = 0;
+ uint32_t count = 0;
m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{