@@ -324,7 +324,8 @@ class PeerManagerImpl final : public PeerManager
324
324
/* * Send a version message to a peer */
325
325
void PushNodeVersion (CNode& pnode, int64_t nTime);
326
326
327
- /* * Send a ping message every PING_INTERVAL or if requested via RPC. */
327
+ /* * Send a ping message every PING_INTERVAL or if requested via RPC. May
328
+ * mark the peer to be disconnected if a ping has timed out. */
328
329
void MaybeSendPing (CNode& node_to);
329
330
330
331
const CChainParams& m_chainparams;
@@ -4297,6 +4298,17 @@ void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
4297
4298
4298
4299
void PeerManagerImpl::MaybeSendPing (CNode& node_to)
4299
4300
{
4301
+ // Use mockable time for ping timeouts.
4302
+ // This means that setmocktime may cause pings to time out.
4303
+ auto now = GetTime<std::chrono::microseconds>();
4304
+
4305
+ if (m_connman.RunInactivityChecks (node_to) && node_to.nPingNonceSent &&
4306
+ now > node_to.m_ping_start .load () + std::chrono::seconds{TIMEOUT_INTERVAL}) {
4307
+ LogPrint (BCLog::NET, " ping timeout: %fs peer=%d\n " , 0.000001 * count_microseconds (now - node_to.m_ping_start .load ()), node_to.GetId ());
4308
+ node_to.fDisconnect = true ;
4309
+ return ;
4310
+ }
4311
+
4300
4312
const CNetMsgMaker msgMaker (node_to.GetCommonVersion ());
4301
4313
bool pingSend = false ;
4302
4314
@@ -4305,7 +4317,7 @@ void PeerManagerImpl::MaybeSendPing(CNode& node_to)
4305
4317
pingSend = true ;
4306
4318
}
4307
4319
4308
- if (node_to.nPingNonceSent == 0 && node_to.m_ping_start .load () + PING_INTERVAL < GetTime<std::chrono::microseconds>() ) {
4320
+ if (node_to.nPingNonceSent == 0 && now > node_to.m_ping_start .load () + PING_INTERVAL) {
4309
4321
// Ping automatically sent as a latency probe & keepalive.
4310
4322
pingSend = true ;
4311
4323
}
@@ -4316,7 +4328,7 @@ void PeerManagerImpl::MaybeSendPing(CNode& node_to)
4316
4328
GetRandBytes ((unsigned char *)&nonce, sizeof (nonce));
4317
4329
}
4318
4330
node_to.fPingQueued = false ;
4319
- node_to.m_ping_start = GetTime<std::chrono::microseconds>() ;
4331
+ node_to.m_ping_start = now ;
4320
4332
if (node_to.GetCommonVersion () > BIP0031_VERSION) {
4321
4333
node_to.nPingNonceSent = nonce;
4322
4334
m_connman.PushMessage (&node_to, msgMaker.Make (NetMsgType::PING, nonce));
@@ -4368,6 +4380,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
4368
4380
4369
4381
MaybeSendPing (*pto);
4370
4382
4383
+ // MaybeSendPing may have marked peer for disconnection
4384
+ if (pto->fDisconnect ) return true ;
4385
+
4371
4386
{
4372
4387
LOCK (cs_main);
4373
4388
0 commit comments