diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index d19674035d..59f3219068 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -348,7 +348,6 @@ namespace eosio { std::string host; connection_ptr c; tcp::endpoint active_ip; - tcp::resolver::results_type ips; }; using connection_details_index = multi_index_container< @@ -416,9 +415,9 @@ namespace eosio { void add(connection_ptr c); string connect(const string& host, const string& p2p_address); - string resolve_and_connect(const string& host, const string& p2p_address); + string resolve_and_connect(const string& host, const string& p2p_address, const connection_ptr& c = {}); void update_connection_endpoint(connection_ptr c, const tcp::endpoint& endpoint); - void connect(const connection_ptr& c); + void reconnect(const connection_ptr& c); string disconnect(const string& host); void close_all(); @@ -912,7 +911,7 @@ namespace eosio { fc::sha256 conn_node_id; string short_conn_node_id; - string listen_address; // address sent to peer in handshake + const string listen_address; // address sent to peer in handshake string log_p2p_address; string log_remote_endpoint_ip; string log_remote_endpoint_port; @@ -2764,6 +2763,10 @@ namespace eosio { fc_dlog( logger, "Skipping connect due to go_away reason ${r}",("r", reason_str( no_retry ))); return false; } + + if (incoming()) + return false; + if( consecutive_immediate_connection_close > def_max_consecutive_immediate_connection_close || no_retry == benign_other ) { fc::microseconds connector_period = my_impl->connections.get_connector_period(); fc::lock_guard g( conn_mtx ); @@ -2771,9 +2774,10 @@ namespace eosio { return true; // true so doesn't remove from valid connections } } + connection_ptr c = shared_from_this(); strand.post([c]() { - my_impl->connections.connect(c); + my_impl->connections.reconnect(c); }); return true; } @@ -4486,39 +4490,48 @@ namespace eosio { return resolve_and_connect( host, p2p_address ); } - string connections_manager::resolve_and_connect( const string& peer_address, const string& listen_address ) { + string connections_manager::resolve_and_connect( const string& peer_address, const string& listen_address, + const connection_ptr& c ) + { + assert(!c || (c->peer_address() == peer_address && c->listen_address == listen_address)); + string::size_type colon = peer_address.find(':'); if (colon == std::string::npos || colon == 0) { fc_elog( logger, "Invalid peer address. must be \"host:port[:|]\": ${p}", ("p", peer_address) ); return "invalid peer address"; } - std::lock_guard g( connections_mtx ); - if( find_connection_i( peer_address ) ) - return "already connected"; + { + std::lock_guard g(connections_mtx); + if (find_connection_i(peer_address)) + return "already connected"; + } auto [host, port, type] = split_host_port_type(peer_address); auto resolver = std::make_shared( my_impl->thread_pool.get_executor() ); resolver->async_resolve(host, port, - [resolver, host = host, port = port, peer_address = peer_address, listen_address = listen_address, this]( const boost::system::error_code& err, const tcp::resolver::results_type& results ) { - connection_ptr c = std::make_shared( peer_address, listen_address ); - c->set_heartbeat_timeout( heartbeat_timeout ); - std::lock_guard g( connections_mtx ); - auto [it, inserted] = connections.emplace( connection_detail{ - .host = peer_address, - .c = std::move(c), - .ips = results + [this, resolver, c_org{c}, host, port, peer_address, listen_address]( const boost::system::error_code& err, const tcp::resolver::results_type& results ) { + connection_ptr c = c_org ? c_org : std::make_shared( peer_address, listen_address ); + c->strand.post([this, resolver, c, err, results, host, port, peer_address]() { + c->set_heartbeat_timeout( heartbeat_timeout ); + { + std::lock_guard g( connections_mtx ); + connections.emplace( connection_detail{ + .host = peer_address, + .c = c, + }); + } + if( !err ) { + c->connect( results ); + } else { + fc_wlog( logger, "Unable to resolve ${host}:${port} ${error}", + ("host", host)("port", port)( "error", err.message() ) ); + c->set_state(connection::connection_state::closed); + ++(c->consecutive_immediate_connection_close); + } }); - if( !err ) { - it->c->connect( results ); - } else { - fc_wlog( logger, "Unable to resolve ${host}:${port} ${error}", - ("host", host)("port", port)( "error", err.message() ) ); - it->c->set_state(connection::connection_state::closed); - ++(it->c->consecutive_immediate_connection_close); - } } ); return "added connection"; @@ -4536,13 +4549,13 @@ namespace eosio { } } - void connections_manager::connect(const connection_ptr& c) { - std::lock_guard g( connections_mtx ); - const auto& index = connections.get(); - const auto& it = index.find(c); - if( it != index.end() ) { - it->c->connect( it->ips ); + void connections_manager::reconnect(const connection_ptr& c) { + { + std::lock_guard g( connections_mtx ); + auto& index = connections.get(); + index.erase(c); } + resolve_and_connect(c->peer_address(), c->listen_address, c); } // called by API