Browse Source

Ping automatically every 2 minutes (unconditionally)

... instead of after 30 minutes of no sending, for latency measurement
and keep-alive. Also, disconnect if no reply arrives within 20 minutes,
instead of 90 of inactivity (for peers supporting the 'pong' message).
0.10
Pieter Wuille 11 years ago
parent
commit
f1920e8606
  1. 13
      src/main.cpp
  2. 18
      src/net.cpp
  3. 13
      src/net.h

13
src/main.cpp

@ -4296,8 +4296,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
// RPC ping request by user // RPC ping request by user
pingSend = true; pingSend = true;
} }
if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSendMsg.empty()) { if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
// Ping automatically sent as a keepalive // Ping automatically sent as a latency probe & keepalive.
pingSend = true; pingSend = true;
} }
if (pingSend) { if (pingSend) {
@ -4305,15 +4305,14 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
while (nonce == 0) { while (nonce == 0) {
RAND_bytes((unsigned char*)&nonce, sizeof(nonce)); RAND_bytes((unsigned char*)&nonce, sizeof(nonce));
} }
pto->nPingNonceSent = nonce;
pto->fPingQueued = false; pto->fPingQueued = false;
pto->nPingUsecStart = GetTimeMicros();
if (pto->nVersion > BIP0031_VERSION) { if (pto->nVersion > BIP0031_VERSION) {
// Take timestamp as close as possible before transmitting ping pto->nPingNonceSent = nonce;
pto->nPingUsecStart = GetTimeMicros();
pto->PushMessage("ping", nonce); pto->PushMessage("ping", nonce);
} else { } else {
// Peer is too old to support ping command with nonce, pong will never arrive, disable timing // Peer is too old to support ping command with nonce, pong will never arrive.
pto->nPingUsecStart = 0; pto->nPingNonceSent = 0;
pto->PushMessage("ping"); pto->PushMessage("ping");
} }
} }

18
src/net.cpp

@ -1028,23 +1028,27 @@ void ThreadSocketHandler()
// //
// Inactivity checking // Inactivity checking
// //
if (pnode->vSendMsg.empty()) int64_t nTime = GetTime();
pnode->nLastSendEmpty = GetTime(); if (nTime - pnode->nTimeConnected > 60)
if (GetTime() - pnode->nTimeConnected > 60)
{ {
if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
{ {
LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
pnode->fDisconnect = true; pnode->fDisconnect = true;
} }
else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60) else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
{ {
LogPrintf("socket not sending\n"); LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
pnode->fDisconnect = true; pnode->fDisconnect = true;
} }
else if (GetTime() - pnode->nLastRecv > 90*60) else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
{ {
LogPrintf("socket inactivity timeout\n"); LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
pnode->fDisconnect = true;
}
else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
{
LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
pnode->fDisconnect = true; pnode->fDisconnect = true;
} }
} }

13
src/net.h

@ -28,6 +28,7 @@
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <openssl/rand.h> #include <openssl/rand.h>
class CAddrMan; class CAddrMan;
class CBlockIndex; class CBlockIndex;
class CNode; class CNode;
@ -36,6 +37,10 @@ namespace boost {
class thread_group; class thread_group;
} }
/** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
static const int PING_INTERVAL = 2 * 60;
/** Time after which to disconnect, after waiting for a ping response (or inactivity). */
static const int TIMEOUT_INTERVAL = 20 * 60;
/** The maximum number of entries in an 'inv' protocol message */ /** The maximum number of entries in an 'inv' protocol message */
static const unsigned int MAX_INV_SZ = 50000; static const unsigned int MAX_INV_SZ = 50000;
/** -upnp default */ /** -upnp default */
@ -217,7 +222,6 @@ public:
int64_t nLastSend; int64_t nLastSend;
int64_t nLastRecv; int64_t nLastRecv;
int64_t nLastSendEmpty;
int64_t nTimeConnected; int64_t nTimeConnected;
CAddress addr; CAddress addr;
std::string addrName; std::string addrName;
@ -273,10 +277,14 @@ public:
CCriticalSection cs_inventory; CCriticalSection cs_inventory;
std::multimap<int64_t, CInv> mapAskFor; std::multimap<int64_t, CInv> mapAskFor;
// Ping time measurement // Ping time measurement:
// The pong reply we're expecting, or 0 if no pong expected.
uint64_t nPingNonceSent; uint64_t nPingNonceSent;
// Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
int64_t nPingUsecStart; int64_t nPingUsecStart;
// Last measured round-trip time.
int64_t nPingUsecTime; int64_t nPingUsecTime;
// Whether a ping is requested.
bool fPingQueued; bool fPingQueued;
CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000) CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000)
@ -288,7 +296,6 @@ public:
nLastRecv = 0; nLastRecv = 0;
nSendBytes = 0; nSendBytes = 0;
nRecvBytes = 0; nRecvBytes = 0;
nLastSendEmpty = GetTime();
nTimeConnected = GetTime(); nTimeConnected = GetTime();
addr = addrIn; addr = addrIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;

Loading…
Cancel
Save