Merge pull request #2784

f1920e8 Ping automatically every 2 minutes (unconditionally) (Pieter Wuille)
pull/4326/head
Wladimir J. van der Laan 11 years ago
commit 3f39b9d455
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6

@ -4293,8 +4293,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) {
@ -4302,15 +4302,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;
if (pto->nVersion > BIP0031_VERSION) {
// Take timestamp as close as possible before transmitting ping
pto->nPingUsecStart = GetTimeMicros(); pto->nPingUsecStart = GetTimeMicros();
if (pto->nVersion > BIP0031_VERSION) {
pto->nPingNonceSent = nonce;
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");
} }
} }

@ -1024,23 +1024,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;
} }
} }

@ -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;
/** -listen default */ /** -listen default */
@ -219,7 +224,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;
@ -275,10 +279,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)
@ -290,7 +298,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