interim checkin of the rebased code
This commit is contained in:
@@ -169,7 +169,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};
|
||||
const command_line::arg_descriptor<uint32_t> arg_max_connections_per_ip = {"max-connections-per-ip", "Maximum number of p2p connections allowed from the same IP address", 1};
|
||||
|
||||
boost::optional<std::vector<proxy>> get_proxies(boost::program_options::variables_map const& vm)
|
||||
{
|
||||
@@ -327,7 +327,7 @@ namespace nodetool
|
||||
}
|
||||
|
||||
boost::optional<boost::asio::ip::tcp::socket>
|
||||
socks_connect_internal(const std::atomic<bool>& stop_signal, boost::asio::io_service& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote)
|
||||
socks_connect_internal(const std::atomic<bool>& stop_signal, boost::asio::io_context& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote)
|
||||
{
|
||||
using socket_type = net::socks::client::stream_type::socket;
|
||||
using client_result = std::pair<boost::system::error_code, socket_type>;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/optional/optional_fwd.hpp>
|
||||
@@ -103,7 +103,7 @@ namespace nodetool
|
||||
|
||||
// hides boost::future and chrono stuff from mondo template file
|
||||
boost::optional<boost::asio::ip::tcp::socket>
|
||||
socks_connect_internal(const std::atomic<bool>& stop_signal, boost::asio::io_service& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote);
|
||||
socks_connect_internal(const std::atomic<bool>& stop_signal, boost::asio::io_context& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote);
|
||||
|
||||
|
||||
template<class base_type>
|
||||
@@ -124,7 +124,8 @@ namespace nodetool
|
||||
template<class t_payload_net_handler>
|
||||
class node_server: public epee::levin::levin_commands_handler<p2p_connection_context_t<typename t_payload_net_handler::connection_context> >,
|
||||
public i_p2p_endpoint<typename t_payload_net_handler::connection_context>,
|
||||
public epee::net_utils::i_connection_filter
|
||||
public epee::net_utils::i_connection_filter,
|
||||
public epee::net_utils::i_connection_limit
|
||||
{
|
||||
struct by_conn_id{};
|
||||
struct by_peer_id{};
|
||||
@@ -179,7 +180,7 @@ namespace nodetool
|
||||
set_config_defaults();
|
||||
}
|
||||
|
||||
network_zone(boost::asio::io_service& public_service)
|
||||
network_zone(boost::asio::io_context& public_service)
|
||||
: m_connect(nullptr),
|
||||
m_net_server(public_service, epee::net_utils::e_connection_type_P2P),
|
||||
m_seed_nodes(),
|
||||
@@ -349,7 +350,10 @@ namespace nodetool
|
||||
virtual bool add_host_fail(const epee::net_utils::network_address &address, unsigned int score = 1);
|
||||
//----------------- i_connection_filter --------------------------------------------------------
|
||||
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t = NULL);
|
||||
//----------------- i_connection_limit ---------------------------------------------------------
|
||||
virtual bool is_host_limit(const epee::net_utils::network_address &address);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
bool parse_peer_from_string(epee::net_utils::network_address& pe, const std::string& node_addr, uint16_t default_port = 0);
|
||||
bool handle_command_line(
|
||||
const boost::program_options::variables_map& vm
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace nodetool
|
||||
template<class t_payload_net_handler>
|
||||
node_server<t_payload_net_handler>::~node_server()
|
||||
{
|
||||
// tcp server uses io_service in destructor, and every zone uses
|
||||
// tcp server uses io_context in destructor, and every zone uses
|
||||
// io_service from public zone.
|
||||
for (auto current = m_network_zones.begin(); current != m_network_zones.end(); /* below */)
|
||||
{
|
||||
@@ -226,6 +226,26 @@ namespace nodetool
|
||||
// not found in hosts or subnets, allowed
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_host_limit(const epee::net_utils::network_address &address)
|
||||
{
|
||||
const network_zone& zone = m_network_zones.at(address.get_zone());
|
||||
if (zone.m_current_number_of_in_peers >= zone.m_config.m_net_config.max_in_connection_count) // in peers limit
|
||||
{
|
||||
MWARNING("Exceeded max incoming connections, so dropping this one.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(has_too_many_connections(address))
|
||||
{
|
||||
MWARNING("CONNECTION FROM " << address.host_str() << " REFUSED, too many connections from the same address");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::block_host(epee::net_utils::network_address addr, time_t seconds, bool add_only)
|
||||
@@ -456,7 +476,7 @@ namespace nodetool
|
||||
m_use_ipv6 = command_line::get_arg(vm, arg_p2p_use_ipv6);
|
||||
m_require_ipv4 = !command_line::get_arg(vm, arg_p2p_ignore_ipv4);
|
||||
public_zone.m_notifier = cryptonote::levin::notify{
|
||||
public_zone.m_net_server.get_io_service(), public_zone.m_net_server.get_config_shared(), nullptr, epee::net_utils::zone::public_, pad_txs, m_payload_handler.get_core()
|
||||
public_zone.m_net_server.get_io_context(), public_zone.m_net_server.get_config_shared(), nullptr, epee::net_utils::zone::public_, pad_txs, m_payload_handler.get_core()
|
||||
};
|
||||
|
||||
if (command_line::has_arg(vm, arg_p2p_add_peer))
|
||||
@@ -531,6 +551,16 @@ namespace nodetool
|
||||
std::istringstream iss(banned_ips);
|
||||
for (std::string line; std::getline(iss, line); )
|
||||
{
|
||||
// ignore comments after '#' character
|
||||
const size_t pound_idx = line.find('#');
|
||||
if (pound_idx != std::string::npos)
|
||||
line.resize(pound_idx);
|
||||
|
||||
// trim whitespace and ignore empty lines
|
||||
boost::trim(line);
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
auto subnet = net::get_ipv4_subnet_address(line);
|
||||
if (subnet)
|
||||
{
|
||||
@@ -609,7 +639,7 @@ namespace nodetool
|
||||
}
|
||||
|
||||
zone.m_notifier = cryptonote::levin::notify{
|
||||
zone.m_net_server.get_io_service(), zone.m_net_server.get_config_shared(), std::move(this_noise), proxy.zone, pad_txs, m_payload_handler.get_core()
|
||||
zone.m_net_server.get_io_context(), zone.m_net_server.get_config_shared(), std::move(this_noise), proxy.zone, pad_txs, m_payload_handler.get_core()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -671,20 +701,18 @@ namespace nodetool
|
||||
net::get_network_address_host_and_port(addr, host, port);
|
||||
MINFO("Resolving node address: host=" << host << ", port=" << port);
|
||||
|
||||
io_service io_srv;
|
||||
ip::tcp::resolver resolver(io_srv);
|
||||
ip::tcp::resolver::query query(host, port, boost::asio::ip::tcp::resolver::query::canonical_name);
|
||||
boost::system::error_code ec;
|
||||
ip::tcp::resolver::iterator i = resolver.resolve(query, ec);
|
||||
CHECK_AND_ASSERT_MES(!ec, false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
|
||||
io_context io_srv;
|
||||
ip::tcp::resolver resolver(io_srv);
|
||||
const auto results = resolver.resolve(host, port, boost::asio::ip::tcp::resolver::canonical_name, ec);
|
||||
CHECK_AND_ASSERT_MES(!ec && !results.empty(), false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
|
||||
|
||||
ip::tcp::resolver::iterator iend;
|
||||
for (; i != iend; ++i)
|
||||
for (const auto& result : results)
|
||||
{
|
||||
ip::tcp::endpoint endpoint = *i;
|
||||
const auto& endpoint = result.endpoint();
|
||||
if (endpoint.address().is_v4())
|
||||
{
|
||||
epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong()), endpoint.port()}};
|
||||
epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_uint()), endpoint.port()}};
|
||||
seed_nodes.push_back(na);
|
||||
MINFO("Added node: " << na.str());
|
||||
}
|
||||
@@ -887,7 +915,7 @@ namespace nodetool
|
||||
return zone_->second;
|
||||
|
||||
network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_];
|
||||
return m_network_zones.emplace_hint(zone_, std::piecewise_construct, std::make_tuple(zone), std::tie(public_zone.m_net_server.get_io_service()))->second;
|
||||
return m_network_zones.emplace_hint(zone_, std::piecewise_construct, std::make_tuple(zone), std::tie(public_zone.m_net_server.get_io_context()))->second;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
@@ -964,6 +992,7 @@ namespace nodetool
|
||||
std::string ipv6_addr = "";
|
||||
std::string ipv6_port = "";
|
||||
zone.second.m_net_server.set_connection_filter(this);
|
||||
zone.second.m_net_server.set_connection_limit(this);
|
||||
MINFO("Binding (IPv4) on " << zone.second.m_bind_ip << ":" << zone.second.m_port);
|
||||
if (!zone.second.m_bind_ipv6_address.empty() && m_use_ipv6)
|
||||
{
|
||||
@@ -2292,11 +2321,12 @@ namespace nodetool
|
||||
if (enet::zone::tor < network->first)
|
||||
break; // unknown network
|
||||
|
||||
if (network->second.m_connect)
|
||||
const auto status = network->second.m_notifier.get_status();
|
||||
if (network->second.m_connect && status.has_outgoing)
|
||||
return send(*network);
|
||||
}
|
||||
|
||||
// configuration should not allow this scenario
|
||||
MWARNING("Unable to send " << txs.size() << " transaction(s): anonymity networks had no outgoing connections");
|
||||
return enet::zone::invalid;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
@@ -2475,6 +2505,20 @@ namespace nodetool
|
||||
std::vector<peerlist_entry> local_peerlist_new;
|
||||
zone.m_peerlist.get_peerlist_head(local_peerlist_new, true, max_peerlist_size);
|
||||
|
||||
/* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
|
||||
do not know the address of the connecting peer. This is relayed to them,
|
||||
iff the node has setup an inbound hidden service.
|
||||
|
||||
\note Insert into `local_peerlist_new` so that it is only sent once like
|
||||
the other peers. */
|
||||
if(outgoing_to_same_zone)
|
||||
{
|
||||
local_peerlist_new.insert(
|
||||
local_peerlist_new.begin() + crypto::rand_range(std::size_t(0), local_peerlist_new.size()),
|
||||
peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, 0}
|
||||
);
|
||||
}
|
||||
|
||||
//only include out peers we did not already send
|
||||
rsp.local_peerlist_new.reserve(local_peerlist_new.size());
|
||||
for (auto &pe: local_peerlist_new)
|
||||
@@ -2485,17 +2529,6 @@ namespace nodetool
|
||||
}
|
||||
m_payload_handler.get_payload_sync_data(rsp.payload_data);
|
||||
|
||||
/* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
|
||||
do not know the address of the connecting peer. This is relayed to them,
|
||||
iff the node has setup an inbound hidden service. The other peer will have
|
||||
to use the random peer_id value to link the two. My initial thought is that
|
||||
the inbound peer should leave the other side marked as `<unknown tor host>`,
|
||||
etc., because someone could give faulty addresses over Tor/I2P to get the
|
||||
real peer with that identity banned/blacklisted. */
|
||||
|
||||
if(outgoing_to_same_zone)
|
||||
rsp.local_peerlist_new.push_back(peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, std::time(nullptr)});
|
||||
|
||||
LOG_DEBUG_CC(context, "COMMAND_TIMED_SYNC");
|
||||
return 1;
|
||||
}
|
||||
@@ -2539,13 +2572,6 @@ namespace nodetool
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (zone.m_current_number_of_in_peers >= zone.m_config.m_net_config.max_in_connection_count) // in peers limit
|
||||
{
|
||||
LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but already have max incoming connections, so dropping this one.");
|
||||
drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!m_payload_handler.process_payload_sync_data(arg.payload_data, context, true))
|
||||
{
|
||||
LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but process_payload_sync_data returned false, dropping connection.");
|
||||
@@ -2555,13 +2581,6 @@ namespace nodetool
|
||||
|
||||
zone.m_notifier.on_handshake_complete(context.m_connection_id, context.m_is_income);
|
||||
|
||||
if(has_too_many_connections(context.m_remote_address))
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << context.m_remote_address.host_str() << " REFUSED, too many connections from the same address");
|
||||
drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//associate peer_id with this connection
|
||||
context.peer_id = arg.node_data.peer_id;
|
||||
context.m_in_timedsync = false;
|
||||
@@ -2881,15 +2900,16 @@ namespace nodetool
|
||||
if (cntxt.m_is_income && cntxt.m_remote_address.is_same_host(address)) {
|
||||
count++;
|
||||
|
||||
if (count > max_connections) {
|
||||
// the only call location happens BEFORE foreach_connection list is updated
|
||||
if (count >= max_connections) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return count > max_connections;
|
||||
// the only call location happens BEFORE foreach_connection list is updated
|
||||
return count >= max_connections;
|
||||
}
|
||||
|
||||
template<class t_payload_net_handler>
|
||||
@@ -3100,7 +3120,7 @@ namespace nodetool
|
||||
boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>>
|
||||
node_server<t_payload_net_handler>::socks_connect(network_zone& zone, const epee::net_utils::network_address& remote, epee::net_utils::ssl_support_t ssl_support)
|
||||
{
|
||||
auto result = socks_connect_internal(zone.m_net_server.get_stop_signal(), zone.m_net_server.get_io_service(), zone.m_proxy_address, remote);
|
||||
auto result = socks_connect_internal(zone.m_net_server.get_stop_signal(), zone.m_net_server.get_io_context(), zone.m_proxy_address, remote);
|
||||
if (result) // if no error
|
||||
{
|
||||
p2p_connection_context context{};
|
||||
|
||||
Reference in New Issue
Block a user