aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Newbery <john@johnnewbery.com>2020-06-21 18:15:56 -0400
committerJohn Newbery <john@johnnewbery.com>2021-02-15 16:02:43 +0000
commitdd2646d12c172cb8899669af717c590483a17404 (patch)
tree61d8e6619a2f8e56fe88d7097b2dec1776f5bf93
parent0b43b81f69ff13dbc1e893a80950f186690b4f62 (diff)
downloadbitcoin-dd2646d12c172cb8899669af717c590483a17404.tar.xz
[net processing] Move ping timeout logic to net processing
Ping messages are an application-level mechanism. Move timeout logic from net to net processing.
-rw-r--r--src/net.cpp8
-rw-r--r--src/net_processing.cpp21
2 files changed, 18 insertions, 11 deletions
diff --git a/src/net.cpp b/src/net.cpp
index a02b66bd74..f8a417ddd1 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1247,14 +1247,6 @@ bool CConnman::InactivityCheck(const CNode& node) const
return true;
}
- if (node.nPingNonceSent && node.m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL} < GetTime<std::chrono::microseconds>()) {
- // We use mockable time for ping timeouts. This means that setmocktime
- // may cause pings to time out for peers that have been connected for
- // longer than m_peer_connect_timeout.
- LogPrint(BCLog::NET, "ping timeout: %fs peer=%d\n", 0.000001 * count_microseconds(GetTime<std::chrono::microseconds>() - node.m_ping_start.load()), node.GetId());
- return true;
- }
-
if (!node.fSuccessfullyConnected) {
LogPrint(BCLog::NET, "version handshake timeout peer=%d\n", node.GetId());
return true;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 94d9be6a9b..ac3e6d0343 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -324,7 +324,8 @@ private:
/** Send a version message to a peer */
void PushNodeVersion(CNode& pnode, int64_t nTime);
- /** Send a ping message every PING_INTERVAL or if requested via RPC. */
+ /** Send a ping message every PING_INTERVAL or if requested via RPC. May
+ * mark the peer to be disconnected if a ping has timed out. */
void MaybeSendPing(CNode& node_to);
const CChainParams& m_chainparams;
@@ -4297,6 +4298,17 @@ void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
void PeerManagerImpl::MaybeSendPing(CNode& node_to)
{
+ // Use mockable time for ping timeouts.
+ // This means that setmocktime may cause pings to time out.
+ auto now = GetTime<std::chrono::microseconds>();
+
+ if (m_connman.RunInactivityChecks(node_to) && node_to.nPingNonceSent &&
+ now > node_to.m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL}) {
+ LogPrint(BCLog::NET, "ping timeout: %fs peer=%d\n", 0.000001 * count_microseconds(now - node_to.m_ping_start.load()), node_to.GetId());
+ node_to.fDisconnect = true;
+ return;
+ }
+
const CNetMsgMaker msgMaker(node_to.GetCommonVersion());
bool pingSend = false;
@@ -4305,7 +4317,7 @@ void PeerManagerImpl::MaybeSendPing(CNode& node_to)
pingSend = true;
}
- if (node_to.nPingNonceSent == 0 && node_to.m_ping_start.load() + PING_INTERVAL < GetTime<std::chrono::microseconds>()) {
+ if (node_to.nPingNonceSent == 0 && now > node_to.m_ping_start.load() + PING_INTERVAL) {
// Ping automatically sent as a latency probe & keepalive.
pingSend = true;
}
@@ -4316,7 +4328,7 @@ void PeerManagerImpl::MaybeSendPing(CNode& node_to)
GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
}
node_to.fPingQueued = false;
- node_to.m_ping_start = GetTime<std::chrono::microseconds>();
+ node_to.m_ping_start = now;
if (node_to.GetCommonVersion() > BIP0031_VERSION) {
node_to.nPingNonceSent = nonce;
m_connman.PushMessage(&node_to, msgMaker.Make(NetMsgType::PING, nonce));
@@ -4368,6 +4380,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
MaybeSendPing(*pto);
+ // MaybeSendPing may have marked peer for disconnection
+ if (pto->fDisconnect) return true;
+
{
LOCK(cs_main);