Changeset View
Changeset View
Standalone View
Standalone View
src/net.cpp
Show First 20 Lines • Show All 580 Lines • ▼ Show 20 Lines | void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap) { | ||||
} | } | ||||
// It is common for nodes with good ping times to suddenly become lagged, | // It is common for nodes with good ping times to suddenly become lagged, | ||||
// due to a new block arriving or other large transfer. Merely reporting | // due to a new block arriving or other large transfer. Merely reporting | ||||
// pingtime might fool the caller into thinking the node was still | // pingtime might fool the caller into thinking the node was still | ||||
// responsive, since pingtime does not update until the ping is complete, | // responsive, since pingtime does not update until the ping is complete, | ||||
// which might take a while. So, if a ping is taking an unusually long time | // which might take a while. So, if a ping is taking an unusually long time | ||||
// in flight, the caller can immediately detect that this is happening. | // in flight, the caller can immediately detect that this is happening. | ||||
int64_t nPingUsecWait = 0; | std::chrono::microseconds ping_wait{0}; | ||||
if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) { | if ((0 != nPingNonceSent) && (0 != m_ping_start.load().count())) { | ||||
nPingUsecWait = GetTimeMicros() - nPingUsecStart; | ping_wait = GetTime<std::chrono::microseconds>() - m_ping_start.load(); | ||||
} | } | ||||
// Raw ping time is in microseconds, but show it to user as whole seconds | // Raw ping time is in microseconds, but show it to user as whole seconds | ||||
// (Bitcoin users should be well used to small numbers with many decimal | // (Bitcoin users should be well used to small numbers with many decimal | ||||
// places by now :) | // places by now :) | ||||
stats.m_ping_usec = nPingUsecTime; | stats.m_ping_usec = nPingUsecTime; | ||||
stats.m_min_ping_usec = nMinPingUsecTime; | stats.m_min_ping_usec = nMinPingUsecTime; | ||||
stats.m_ping_wait_usec = nPingUsecWait; | stats.m_ping_wait_usec = count_microseconds(ping_wait); | ||||
// Leave string empty if addrLocal invalid (not filled in yet) | // Leave string empty if addrLocal invalid (not filled in yet) | ||||
CService addrLocalUnlocked = GetAddrLocal(); | CService addrLocalUnlocked = GetAddrLocal(); | ||||
stats.addrLocal = | stats.addrLocal = | ||||
addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : ""; | addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : ""; | ||||
} | } | ||||
bool CNode::ReceiveMsgBytes(const Config &config, const char *pch, | bool CNode::ReceiveMsgBytes(const Config &config, const char *pch, | ||||
uint32_t nBytes, bool &complete) { | uint32_t nBytes, bool &complete) { | ||||
complete = false; | complete = false; | ||||
int64_t nTimeMicros = GetTimeMicros(); | const auto time = GetTime<std::chrono::microseconds>(); | ||||
LOCK(cs_vRecv); | LOCK(cs_vRecv); | ||||
nLastRecv = nTimeMicros / 1000000; | nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count(); | ||||
nRecvBytes += nBytes; | nRecvBytes += nBytes; | ||||
while (nBytes > 0) { | while (nBytes > 0) { | ||||
// Absorb network data. | // Absorb network data. | ||||
int handled = m_deserializer->Read(config, pch, nBytes); | int handled = m_deserializer->Read(config, pch, nBytes); | ||||
if (handled < 0) { | if (handled < 0) { | ||||
return false; | return false; | ||||
} | } | ||||
pch += handled; | pch += handled; | ||||
nBytes -= handled; | nBytes -= handled; | ||||
if (m_deserializer->Complete()) { | if (m_deserializer->Complete()) { | ||||
// decompose a transport agnostic CNetMessage from the deserializer | // decompose a transport agnostic CNetMessage from the deserializer | ||||
CNetMessage msg = m_deserializer->GetMessage(config, nTimeMicros); | CNetMessage msg = m_deserializer->GetMessage(config, time); | ||||
// Store received bytes per message command to prevent a memory DOS, | // Store received bytes per message command to prevent a memory DOS, | ||||
// only allow valid commands. | // only allow valid commands. | ||||
mapMsgCmdSize::iterator i = | mapMsgCmdSize::iterator i = | ||||
mapRecvBytesPerMsgCmd.find(msg.m_command); | mapRecvBytesPerMsgCmd.find(msg.m_command); | ||||
if (i == mapRecvBytesPerMsgCmd.end()) { | if (i == mapRecvBytesPerMsgCmd.end()) { | ||||
i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); | i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | |||||
const uint256 &V1TransportDeserializer::GetMessageHash() const { | const uint256 &V1TransportDeserializer::GetMessageHash() const { | ||||
assert(Complete()); | assert(Complete()); | ||||
if (data_hash.IsNull()) { | if (data_hash.IsNull()) { | ||||
hasher.Finalize(data_hash.begin()); | hasher.Finalize(data_hash.begin()); | ||||
} | } | ||||
return data_hash; | return data_hash; | ||||
} | } | ||||
CNetMessage V1TransportDeserializer::GetMessage(const Config &config, | CNetMessage | ||||
int64_t time) { | V1TransportDeserializer::GetMessage(const Config &config, | ||||
const std::chrono::microseconds time) { | |||||
// decompose a single CNetMessage from the TransportDeserializer | // decompose a single CNetMessage from the TransportDeserializer | ||||
CNetMessage msg(std::move(vRecv)); | CNetMessage msg(std::move(vRecv)); | ||||
// store state about valid header, netmagic and checksum | // store state about valid header, netmagic and checksum | ||||
msg.m_valid_header = hdr.IsValid(config); | msg.m_valid_header = hdr.IsValid(config); | ||||
// FIXME Split CheckHeaderMagicAndCommand() into CheckHeaderMagic() and | // FIXME Split CheckHeaderMagicAndCommand() into CheckHeaderMagic() and | ||||
// CheckCommand() to prevent the net magic check code duplication. | // CheckCommand() to prevent the net magic check code duplication. | ||||
msg.m_valid_netmagic = | msg.m_valid_netmagic = | ||||
▲ Show 20 Lines • Show All 537 Lines • ▼ Show 20 Lines | if (nTime - pnode->nTimeConnected > m_peer_connect_timeout) { | ||||
pnode->fDisconnect = true; | pnode->fDisconnect = true; | ||||
} else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION | } else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION | ||||
? TIMEOUT_INTERVAL | ? TIMEOUT_INTERVAL | ||||
: 90 * 60)) { | : 90 * 60)) { | ||||
LogPrintf("socket receive timeout: %is\n", | LogPrintf("socket receive timeout: %is\n", | ||||
nTime - pnode->nLastRecv); | nTime - pnode->nLastRecv); | ||||
pnode->fDisconnect = true; | pnode->fDisconnect = true; | ||||
} else if (pnode->nPingNonceSent && | } else if (pnode->nPingNonceSent && | ||||
pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < | pnode->m_ping_start.load() + | ||||
GetTimeMicros()) { | std::chrono::seconds{TIMEOUT_INTERVAL} < | ||||
GetTime<std::chrono::microseconds>()) { | |||||
LogPrintf("ping timeout: %fs\n", | LogPrintf("ping timeout: %fs\n", | ||||
0.000001 * (GetTimeMicros() - pnode->nPingUsecStart)); | 0.000001 * count_microseconds( | ||||
GetTime<std::chrono::microseconds>() - | |||||
pnode->m_ping_start.load())); | |||||
pnode->fDisconnect = true; | pnode->fDisconnect = true; | ||||
} else if (!pnode->fSuccessfullyConnected) { | } else if (!pnode->fSuccessfullyConnected) { | ||||
LogPrint(BCLog::NET, "version handshake timeout from %d\n", | LogPrint(BCLog::NET, "version handshake timeout from %d\n", | ||||
pnode->GetId()); | pnode->GetId()); | ||||
pnode->fDisconnect = true; | pnode->fDisconnect = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,882 Lines • Show Last 20 Lines |