From 614b928b94d0af44f738e86c10953f9e0b8b09a3 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Thu, 4 Feb 2021 09:37:04 -0600 Subject: [PATCH] use p2p address for duplicate connection resolution --- plugins/net_plugin/net_plugin.cpp | 35 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 302a46748b6..81a6ad7c90b 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -422,8 +422,9 @@ namespace eosio { constexpr uint16_t proto_block_id_notify = 2; // reserved. feature was removed. next net_version should be 3 constexpr uint16_t proto_pruned_types = 3; // supports new signed_block & packed_transaction types constexpr uint16_t heartbeat_interval = 4; // supports configurable heartbeat interval + constexpr uint16_t dup_goaway_resolution = 5; // support peer address based duplicate connection resolution - constexpr uint16_t net_version = heartbeat_interval; + constexpr uint16_t net_version = dup_goaway_resolution; /** * Index by start_block_num @@ -2841,18 +2842,26 @@ namespace eosio { if(check.get() == this) continue; if(check->connected() && check->peer_name() == msg.p2p_address) { - // It's possible that both peers could arrive here at relatively the same time, so - // we need to avoid the case where they would both tell a different connection to go away. - // Using the sum of the initial handshake times of the two connections, we will - // arbitrarily (but consistently between the two peers) keep one of them. - std::unique_lock g_check_conn( check->conn_mtx ); - auto check_time = check->last_handshake_sent.time + check->last_handshake_recv.time; - g_check_conn.unlock(); - g_conn.lock(); - auto c_time = last_handshake_sent.time; - g_conn.unlock(); - if (msg.time + c_time <= check_time) - continue; + if (net_version < dup_goaway_resolution || msg.network_version < dup_goaway_resolution) { + // It's possible that both peers could arrive here at relatively the same time, so + // we need to avoid the case where they would both tell a different connection to go away. + // Using the sum of the initial handshake times of the two connections, we will + // arbitrarily (but consistently between the two peers) keep one of them. + + std::unique_lock g_check_conn( check->conn_mtx ); + auto check_time = check->last_handshake_sent.time + check->last_handshake_recv.time; + g_check_conn.unlock(); + g_conn.lock(); + auto c_time = last_handshake_sent.time; + g_conn.unlock(); + if (msg.time + c_time <= check_time) + continue; + } + else if (my_impl->p2p_address < msg.p2p_address) { + // only the connection from lower p2p_address to higher p2p_address will be considered as a duplicate, + // so there is no chance for both connections to be closed + continue; + } g_cnts.unlock(); fc_dlog( logger, "sending go_away duplicate to ${ep}", ("ep",msg.p2p_address) );