diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -417,7 +417,9 @@ template bool operator()(I first, I last) const { while (first != last) { - if (!(*first)) return false; + if (!(*first)) { + return false; + } ++first; } return true; @@ -550,7 +552,10 @@ } bool complete() const { - if (!in_data) return false; + if (!in_data) { + return false; + } + return (hdr.nMessageSize == nDataPos); } @@ -769,10 +774,8 @@ } void AddInventoryKnown(const CInv &inv) { - { - LOCK(cs_inventory); - filterInventoryKnown.insert(inv.hash); - } + LOCK(cs_inventory); + filterInventoryKnown.insert(inv.hash); } void PushInventory(const CInv &inv) { @@ -804,8 +807,10 @@ void MaybeSetAddrName(const std::string &addrNameIn); }; -/** Return a timestamp in the future (in microseconds) for exponentially - * distributed events. */ +/** + * Return a timestamp in the future (in microseconds) for exponentially + * distributed events. + */ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); std::string getSubVersionEB(uint64_t MaxBlockSize); diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -154,7 +154,9 @@ int GetnScore(const CService &addr) { LOCK(cs_mapLocalHost); - if (mapLocalHost.count(addr) == LOCAL_NONE) return 0; + if (mapLocalHost.count(addr) == LOCAL_NONE) { + return 0; + } return mapLocalHost[addr].nScore; } @@ -189,11 +191,17 @@ // Learn a new local address. bool AddLocal(const CService &addr, int nScore) { - if (!addr.IsRoutable()) return false; + if (!addr.IsRoutable()) { + return false; + } - if (!fDiscover && nScore < LOCAL_MANUAL) return false; + if (!fDiscover && nScore < LOCAL_MANUAL) { + return false; + } - if (IsLimited(addr)) return false; + if (IsLimited(addr)) { + return false; + } LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore); @@ -224,7 +232,9 @@ /** Make a particular network entirely off-limits (no automatic connects to it) */ void SetLimited(enum Network net, bool fLimited) { - if (net == NET_UNROUTABLE) return; + if (net == NET_UNROUTABLE) { + return; + } LOCK(cs_mapLocalHost); vfLimited[net] = fLimited; } @@ -240,11 +250,11 @@ /** vote for a local address */ bool SeenLocal(const CService &addr) { - { - LOCK(cs_mapLocalHost); - if (mapLocalHost.count(addr) == 0) return false; - mapLocalHost[addr].nScore++; + LOCK(cs_mapLocalHost); + if (mapLocalHost.count(addr) == 0) { + return false; } + mapLocalHost[addr].nScore++; return true; } @@ -268,15 +278,21 @@ CNode *CConnman::FindNode(const CNetAddr &ip) { LOCK(cs_vNodes); - for (CNode *pnode : vNodes) - if ((CNetAddr)pnode->addr == ip) return (pnode); + for (CNode *pnode : vNodes) { + if ((CNetAddr)pnode->addr == ip) { + return pnode; + } + } return nullptr; } CNode *CConnman::FindNode(const CSubNet &subNet) { LOCK(cs_vNodes); - for (CNode *pnode : vNodes) - if (subNet.Match((CNetAddr)pnode->addr)) return (pnode); + for (CNode *pnode : vNodes) { + if (subNet.Match((CNetAddr)pnode->addr)) { + return pnode; + } + } return nullptr; } @@ -284,7 +300,7 @@ LOCK(cs_vNodes); for (CNode *pnode : vNodes) { if (pnode->GetAddrName() == addrName) { - return (pnode); + return pnode; } } return nullptr; @@ -292,8 +308,11 @@ CNode *CConnman::FindNode(const CService &addr) { LOCK(cs_vNodes); - for (CNode *pnode : vNodes) - if ((CService)pnode->addr == addr) return (pnode); + for (CNode *pnode : vNodes) { + if ((CService)pnode->addr == addr) { + return pnode; + } + } return nullptr; } @@ -310,7 +329,9 @@ CNode *CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure) { if (pszDest == nullptr) { - if (IsLocal(addrConnect)) return nullptr; + if (IsLocal(addrConnect)) { + return nullptr; + } // Look for an existing connection CNode *pnode = FindNode((CService)addrConnect); @@ -387,7 +408,9 @@ // Clean unused entries (if bantime has expired) SweepBanned(); - if (!BannedSetIsDirty()) return; + if (!BannedSetIsDirty()) { + return; + } int64_t nStart = GetTimeMillis(); @@ -395,7 +418,9 @@ banmap_t banmap; SetBannedSetDirty(false); GetBanned(banmap); - if (!bandb.Write(banmap)) SetBannedSetDirty(true); + if (!bandb.Write(banmap)) { + SetBannedSetDirty(true); + } LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); @@ -416,37 +441,43 @@ setBanned.clear(); setBannedIsDirty = true; } + // Store banlist to disk. DumpBanlist(); - if (clientInterface) clientInterface->BannedListChanged(); + if (clientInterface) { + clientInterface->BannedListChanged(); + } } bool CConnman::IsBanned(CNetAddr ip) { + LOCK(cs_setBanned); + bool fResult = false; - { - LOCK(cs_setBanned); - for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); - it++) { - CSubNet subNet = (*it).first; - CBanEntry banEntry = (*it).second; + for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); + it++) { + CSubNet subNet = (*it).first; + CBanEntry banEntry = (*it).second; - if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) - fResult = true; + if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) { + fResult = true; } } + return fResult; } bool CConnman::IsBanned(CSubNet subnet) { + LOCK(cs_setBanned); + bool fResult = false; - { - LOCK(cs_setBanned); - banmap_t::iterator i = setBanned.find(subnet); - if (i != setBanned.end()) { - CBanEntry banEntry = (*i).second; - if (GetTime() < banEntry.nBanUntil) fResult = true; + banmap_t::iterator i = setBanned.find(subnet); + if (i != setBanned.end()) { + CBanEntry banEntry = (*i).second; + if (GetTime() < banEntry.nBanUntil) { + fResult = true; } } + return fResult; } @@ -471,16 +502,24 @@ if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) { setBanned[subNet] = banEntry; setBannedIsDirty = true; - } else + } else { return; + } + } + + if (clientInterface) { + clientInterface->BannedListChanged(); } - if (clientInterface) clientInterface->BannedListChanged(); + { LOCK(cs_vNodes); for (CNode *pnode : vNodes) { - if (subNet.Match((CNetAddr)pnode->addr)) pnode->fDisconnect = true; + if (subNet.Match((CNetAddr)pnode->addr)) { + pnode->fDisconnect = true; + } } } + if (banReason == BanReasonManuallyAdded) { // Store banlist to disk immediately if user requested ban. DumpBanlist(); @@ -495,10 +534,16 @@ bool CConnman::Unban(const CSubNet &subNet) { { LOCK(cs_setBanned); - if (!setBanned.erase(subNet)) return false; + if (!setBanned.erase(subNet)) { + return false; + } setBannedIsDirty = true; } - if (clientInterface) clientInterface->BannedListChanged(); + + if (clientInterface) { + clientInterface->BannedListChanged(); + } + // Store banlist to disk immediately. DumpBanlist(); return true; @@ -530,8 +575,9 @@ LogPrint("net", "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString()); - } else + } else { ++it; + } } } @@ -541,14 +587,17 @@ } void CConnman::SetBannedSetDirty(bool dirty) { - LOCK(cs_setBanned); // reuse setBanned lock for the isDirty flag + // Reuse setBanned lock for the isDirty flag. + LOCK(cs_setBanned); setBannedIsDirty = dirty; } bool CConnman::IsWhitelistedRange(const CNetAddr &addr) { LOCK(cs_vWhitelistedRange); for (const CSubNet &subnet : vWhitelistedRange) { - if (subnet.Match(addr)) return true; + if (subnet.Match(addr)) { + return true; + } } return false; } @@ -635,9 +684,9 @@ // 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 // places by now :) - stats.dPingTime = (((double)nPingUsecTime) / 1e6); - stats.dMinPing = (((double)nMinPingUsecTime) / 1e6); - stats.dPingWait = (((double)nPingUsecWait) / 1e6); + stats.dPingTime = ((double(nPingUsecTime)) / 1e6); + stats.dMinPing = ((double(nMinPingUsecTime)) / 1e6); + stats.dPingWait = ((double(nPingUsecWait)) / 1e6); // Leave string empty if addrLocal invalid (not filled in yet) CService addrLocalUnlocked = GetAddrLocal(); @@ -655,20 +704,24 @@ nRecvBytes += nBytes; while (nBytes > 0) { // get current incomplete message, or create a new one - if (vRecvMsg.empty() || vRecvMsg.back().complete()) + if (vRecvMsg.empty() || vRecvMsg.back().complete()) { vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION)); + } CNetMessage &msg = vRecvMsg.back(); // absorb network data int handled; - if (!msg.in_data) + if (!msg.in_data) { handled = msg.readHeader(pch, nBytes); - else + } else { handled = msg.readData(pch, nBytes); + } - if (handled < 0) return false; + if (handled < 0) { + return false; + } if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { LogPrint("net", "Oversized message from peer=%i, disconnecting\n", @@ -680,13 +733,14 @@ nBytes -= handled; if (msg.complete()) { - // Store received bytes per message command to prevent a memory DOS, // only allow valid commands. mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand); - if (i == mapRecvBytesPerMsgCmd.end()) + if (i == mapRecvBytesPerMsgCmd.end()) { i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); + } + assert(i != mapRecvBytesPerMsgCmd.end()); i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE; @@ -733,7 +787,9 @@ nHdrPos += nCopy; // if header incomplete, exit - if (nHdrPos < 24) return nCopy; + if (nHdrPos < 24) { + return nCopy; + } // deserialize to CMessageHeader try { @@ -743,7 +799,9 @@ } // reject messages larger than MAX_SIZE - if (hdr.nMessageSize > MAX_SIZE) return -1; + if (hdr.nMessageSize > MAX_SIZE) { + return -1; + } // switch state to reading message data in_data = true; @@ -770,7 +828,9 @@ const uint256 &CNetMessage::GetMessageHash() const { assert(complete()); - if (data_hash.IsNull()) hasher.Finalize(data_hash.begin()); + if (data_hash.IsNull()) { + hasher.Finalize(data_hash.begin()); + } return data_hash; } @@ -786,7 +846,10 @@ { LOCK(pnode->cs_hSocket); - if (pnode->hSocket == INVALID_SOCKET) break; + if (pnode->hSocket == INVALID_SOCKET) { + break; + } + nBytes = send( pnode->hSocket, reinterpret_cast(data.data()) + pnode->nSendOffset, @@ -869,9 +932,14 @@ const NodeEvictionCandidate &b) { // There is a fall-through here because it is common for a node to have many // peers which have not yet relayed a block. - if (a.nLastBlockTime != b.nLastBlockTime) + if (a.nLastBlockTime != b.nLastBlockTime) { return a.nLastBlockTime < b.nLastBlockTime; - if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices; + } + + if (a.fRelevantServices != b.fRelevantServices) { + return b.fRelevantServices; + } + return a.nTimeConnected > b.nTimeConnected; } @@ -879,9 +947,18 @@ const NodeEvictionCandidate &b) { // There is a fall-through here because it is common for a node to have more // than a few peers that have not yet relayed txn. - if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime; - if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes; - if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter; + if (a.nLastTXTime != b.nLastTXTime) { + return a.nLastTXTime < b.nLastTXTime; + } + + if (a.fRelayTxes != b.fRelayTxes) { + return b.fRelayTxes; + } + + if (a.fBloomFilter != b.fBloomFilter) { + return a.fBloomFilter; + } + return a.nTimeConnected > b.nTimeConnected; } @@ -899,9 +976,9 @@ LOCK(cs_vNodes); for (CNode *node : vNodes) { - if (node->fWhitelisted) continue; - if (!node->fInbound) continue; - if (node->fDisconnect) continue; + if (node->fWhitelisted || !node->fInbound || node->fDisconnect) { + continue; + } NodeEvictionCandidate candidate = { node->id, node->nTimeConnected, @@ -917,7 +994,9 @@ } } - if (vEvictionCandidates.empty()) return false; + if (vEvictionCandidates.empty()) { + return false; + } // Protect connections with certain characteristics @@ -930,7 +1009,9 @@ std::min(4, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); - if (vEvictionCandidates.empty()) return false; + if (vEvictionCandidates.empty()) { + return false; + } // Protect the 8 nodes with the lowest minimum ping time. An attacker cannot // manipulate this metric without physically moving nodes closer to the @@ -942,7 +1023,9 @@ std::min(8, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); - if (vEvictionCandidates.empty()) return false; + if (vEvictionCandidates.empty()) { + return false; + } // Protect 4 nodes that most recently sent us transactions. An attacker // cannot manipulate this metric without performing useful work. @@ -953,7 +1036,9 @@ std::min(4, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); - if (vEvictionCandidates.empty()) return false; + if (vEvictionCandidates.empty()) { + return false; + } // Protect 4 nodes that most recently sent us blocks. An attacker cannot // manipulate this metric without performing useful work. @@ -964,7 +1049,9 @@ std::min(4, static_cast(vEvictionCandidates.size())), vEvictionCandidates.end()); - if (vEvictionCandidates.empty()) return false; + if (vEvictionCandidates.empty()) { + return false; + } // Protect the half of the remaining nodes which have been connected the // longest. This replicates the non-eviction implicit behavior, and @@ -976,7 +1063,9 @@ static_cast(vEvictionCandidates.size() / 2), vEvictionCandidates.end()); - if (vEvictionCandidates.empty()) return false; + if (vEvictionCandidates.empty()) { + return false; + } // Identify the network group with the most connections and youngest member. // (vEvictionCandidates is already sorted by reverse connect time) @@ -1024,22 +1113,28 @@ int nInbound = 0; int nMaxInbound = nMaxConnections - (nMaxOutbound + nMaxFeeler); - if (hSocket != INVALID_SOCKET) - if (!addr.SetSockAddr((const struct sockaddr *)&sockaddr)) + if (hSocket != INVALID_SOCKET) { + if (!addr.SetSockAddr((const struct sockaddr *)&sockaddr)) { LogPrintf("Warning: Unknown socket family\n"); + } + } bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr); { LOCK(cs_vNodes); - for (CNode *pnode : vNodes) - if (pnode->fInbound) nInbound++; + for (CNode *pnode : vNodes) { + if (pnode->fInbound) { + nInbound++; + } + } } if (hSocket == INVALID_SOCKET) { int nErr = WSAGetLastError(); - if (nErr != WSAEWOULDBLOCK) + if (nErr != WSAEWOULDBLOCK) { LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); + } return; } @@ -1162,8 +1257,9 @@ } if (vNodesSize != nPrevNodeCount) { nPrevNodeCount = vNodesSize; - if (clientInterface) + if (clientInterface) { clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount); + } } // @@ -1171,7 +1267,8 @@ // struct timeval timeout; timeout.tv_sec = 0; - timeout.tv_usec = 50000; // frequency to poll pnode->vSend + // Frequency to poll pnode->vSend + timeout.tv_usec = 50000; fd_set fdsetRecv; fd_set fdsetSend; @@ -1211,7 +1308,9 @@ } LOCK(pnode->cs_hSocket); - if (pnode->hSocket == INVALID_SOCKET) continue; + if (pnode->hSocket == INVALID_SOCKET) { + continue; + } FD_SET(pnode->hSocket, &fdsetError); hSocketMax = std::max(hSocketMax, pnode->hSocket); @@ -1229,20 +1328,24 @@ int nSelect = select(have_fds ? hSocketMax + 1 : 0, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); - if (interruptNet) return; + if (interruptNet) { + return; + } if (nSelect == SOCKET_ERROR) { if (have_fds) { int nErr = WSAGetLastError(); LogPrintf("socket select error %s\n", NetworkErrorString(nErr)); - for (unsigned int i = 0; i <= hSocketMax; i++) + for (unsigned int i = 0; i <= hSocketMax; i++) { FD_SET(i, &fdsetRecv); + } } FD_ZERO(&fdsetSend); FD_ZERO(&fdsetError); if (!interruptNet.sleep_for( - std::chrono::milliseconds(timeout.tv_usec / 1000))) + std::chrono::milliseconds(timeout.tv_usec / 1000))) { return; + } } // @@ -1262,11 +1365,14 @@ { LOCK(cs_vNodes); vNodesCopy = vNodes; - for (CNode *pnode : vNodesCopy) + for (CNode *pnode : vNodesCopy) { pnode->AddRef(); + } } for (CNode *pnode : vNodesCopy) { - if (interruptNet) return; + if (interruptNet) { + return; + } // // Receive @@ -1276,65 +1382,68 @@ bool errorSet = false; { LOCK(pnode->cs_hSocket); - if (pnode->hSocket == INVALID_SOCKET) continue; + if (pnode->hSocket == INVALID_SOCKET) { + continue; + } recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv); sendSet = FD_ISSET(pnode->hSocket, &fdsetSend); errorSet = FD_ISSET(pnode->hSocket, &fdsetError); } if (recvSet || errorSet) { + // typical socket buffer is 8K-64K + char pchBuf[0x10000]; + int nBytes = 0; { - { - // typical socket buffer is 8K-64K - char pchBuf[0x10000]; - int nBytes = 0; + LOCK(pnode->cs_hSocket); + if (pnode->hSocket == INVALID_SOCKET) { + continue; + } + nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), + MSG_DONTWAIT); + } + if (nBytes > 0) { + bool notify = false; + if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify)) { + pnode->CloseSocketDisconnect(); + } + RecordBytesRecv(nBytes); + if (notify) { + size_t nSizeAdded = 0; + auto it(pnode->vRecvMsg.begin()); + for (; it != pnode->vRecvMsg.end(); ++it) { + if (!it->complete()) { + break; + } + nSizeAdded += + it->vRecv.size() + CMessageHeader::HEADER_SIZE; + } { - LOCK(pnode->cs_hSocket); - if (pnode->hSocket == INVALID_SOCKET) continue; - nBytes = recv(pnode->hSocket, pchBuf, - sizeof(pchBuf), MSG_DONTWAIT); + LOCK(pnode->cs_vProcessMsg); + pnode->vProcessMsg.splice( + pnode->vProcessMsg.end(), pnode->vRecvMsg, + pnode->vRecvMsg.begin(), it); + pnode->nProcessQueueSize += nSizeAdded; + pnode->fPauseRecv = + pnode->nProcessQueueSize > nReceiveFloodSize; } - if (nBytes > 0) { - bool notify = false; - if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify)) - pnode->CloseSocketDisconnect(); - RecordBytesRecv(nBytes); - if (notify) { - size_t nSizeAdded = 0; - auto it(pnode->vRecvMsg.begin()); - for (; it != pnode->vRecvMsg.end(); ++it) { - if (!it->complete()) break; - nSizeAdded += it->vRecv.size() + - CMessageHeader::HEADER_SIZE; - } - { - LOCK(pnode->cs_vProcessMsg); - pnode->vProcessMsg.splice( - pnode->vProcessMsg.end(), - pnode->vRecvMsg, - pnode->vRecvMsg.begin(), it); - pnode->nProcessQueueSize += nSizeAdded; - pnode->fPauseRecv = - pnode->nProcessQueueSize > - nReceiveFloodSize; - } - WakeMessageHandler(); - } - } else if (nBytes == 0) { - // socket closed gracefully - if (!pnode->fDisconnect) - LogPrint("net", "socket closed\n"); - pnode->CloseSocketDisconnect(); - } else if (nBytes < 0) { - // error - int nErr = WSAGetLastError(); - if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && - nErr != WSAEINTR && nErr != WSAEINPROGRESS) { - if (!pnode->fDisconnect) - LogPrintf("socket recv error %s\n", - NetworkErrorString(nErr)); - pnode->CloseSocketDisconnect(); - } + WakeMessageHandler(); + } + } else if (nBytes == 0) { + // socket closed gracefully + if (!pnode->fDisconnect) { + LogPrint("net", "socket closed\n"); + } + pnode->CloseSocketDisconnect(); + } else if (nBytes < 0) { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && + nErr != WSAEINTR && nErr != WSAEINPROGRESS) { + if (!pnode->fDisconnect) { + LogPrintf("socket recv error %s\n", + NetworkErrorString(nErr)); } + pnode->CloseSocketDisconnect(); } } } @@ -1432,9 +1541,9 @@ char externalIPAddress[40]; r = UPNP_GetExternalIPAddress( urls.controlURL, data.first.servicetype, externalIPAddress); - if (r != UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) { LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); - else { + } else { if (externalIPAddress[0]) { CNetAddr resolved; if (LookupHost(externalIPAddress, resolved, false)) { @@ -1442,8 +1551,9 @@ resolved.ToString().c_str()); AddLocal(resolved, LOCAL_UPNP); } - } else + } else { LogPrintf("UPnP: GetExternalIPAddress failed.\n"); + } } } @@ -1487,7 +1597,9 @@ LogPrintf("No valid UPnP IGDs found\n"); freeUPNPDevlist(devlist); devlist = 0; - if (r != 0) FreeUPNPUrls(&urls); + if (r != 0) { + FreeUPNPUrls(&urls); + } } } @@ -1538,7 +1650,9 @@ // less influence on the network topology, and reduces traffic to the seeds. if ((addrman.size() > 0) && (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { - if (!interruptNet.sleep_for(std::chrono::seconds(11))) return; + if (!interruptNet.sleep_for(std::chrono::seconds(11))) { + return; + } LOCK(cs_vNodes); int nRelevant = 0; @@ -1613,15 +1727,19 @@ std::string strDest; { LOCK(cs_vOneShots); - if (vOneShots.empty()) return; + if (vOneShots.empty()) { + return; + } strDest = vOneShots.front(); vOneShots.pop_front(); } CAddress addr; CSemaphoreGrant grant(*semOutbound, true); if (grant) { - if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true)) + if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), + true)) { AddOneShot(strDest); + } } } @@ -1635,11 +1753,15 @@ CAddress addr(CService(), NODE_NONE); OpenNetworkConnection(addr, false, nullptr, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { - if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) + if (!interruptNet.sleep_for( + std::chrono::milliseconds(500))) { return; + } } } - if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) return; + if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) { + return; + } } } @@ -1652,10 +1774,14 @@ while (!interruptNet) { ProcessOneShot(); - if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) return; + if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) { + return; + } CSemaphoreGrant grant(*semOutbound); - if (interruptNet) return; + if (interruptNet) { + return; + } // Add seed nodes if DNS seeds are all down (an infrastructure attack?). if (addrman.size() == 0 && (GetTime() - nStart > 60)) { @@ -1728,8 +1854,9 @@ // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || - IsLocal(addr)) + IsLocal(addr)) { break; + } // If we didn't find an appropriate destination after trying 100 // addresses fetched from addrman, stop this loop, and let the outer @@ -1737,27 +1864,36 @@ // already-connected network ranges, ...) before trying new addrman // addresses. nTries++; - if (nTries > 100) break; + if (nTries > 100) { + break; + } - if (IsLimited(addr)) continue; + if (IsLimited(addr)) { + continue; + } // only connect to full nodes - if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) + if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) { continue; + } // only consider very recently tried nodes after 30 failed attempts - if (nANow - addr.nLastTry < 600 && nTries < 30) continue; + if (nANow - addr.nLastTry < 600 && nTries < 30) { + continue; + } // only consider nodes missing relevant services after 40 failed // attempts and only if less than half the outbound are up. if ((addr.nServices & nRelevantServices) != nRelevantServices && - (nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) + (nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) { continue; + } // do not allow non-default ports, unless after 50 invalid addresses // selected already. - if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) + if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) { continue; + } addrConnect = addr; break; @@ -1770,8 +1906,9 @@ // synchronization. int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000); if (!interruptNet.sleep_for( - std::chrono::milliseconds(randsleep))) + std::chrono::milliseconds(randsleep))) { return; + } LogPrint("net", "Making feeler connection to %s\n", addrConnect.ToString()); } @@ -1791,8 +1928,9 @@ { LOCK(cs_vAddedNodes); ret.reserve(vAddedNodes.size()); - for (const std::string &strAddNode : vAddedNodes) + for (const std::string &strAddNode : vAddedNodes) { lAddresses.push_back(strAddNode); + } } // Build a map of all already connected addresses (by IP:port and by name) @@ -1846,8 +1984,9 @@ void CConnman::ThreadOpenAddedConnections() { { LOCK(cs_vAddedNodes); - if (mapMultiArgs.count("-addnode")) + if (mapMultiArgs.count("-addnode")) { vAddedNodes = mapMultiArgs.at("-addnode"); + } } while (true) { @@ -1871,14 +2010,16 @@ OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false, false, true); - if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) + if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) { return; + } } } // Retry every 60 seconds if a connection was attempted, otherwise two // seconds. - if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2))) + if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2))) { return; + } } } @@ -1899,18 +2040,30 @@ } if (!pszDest) { if (IsLocal(addrConnect) || FindNode((CNetAddr)addrConnect) || - IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) + IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) { return false; - } else if (FindNode(std::string(pszDest))) + } + } else if (FindNode(std::string(pszDest))) { return false; + } CNode *pnode = ConnectNode(addrConnect, pszDest, fCountFailure); - if (!pnode) return false; - if (grantOutbound) grantOutbound->MoveTo(pnode->grantOutbound); - if (fOneShot) pnode->fOneShot = true; - if (fFeeler) pnode->fFeeler = true; - if (fAddnode) pnode->fAddnode = true; + if (!pnode) { + return false; + } + if (grantOutbound) { + grantOutbound->MoveTo(pnode->grantOutbound); + } + if (fOneShot) { + pnode->fOneShot = true; + } + if (fFeeler) { + pnode->fFeeler = true; + } + if (fAddnode) { + pnode->fAddnode = true; + } // FIXME: Pass the config down rather than use GetConfig() GetNodeSignals().InitializeNode(GetConfig(), pnode, *this); @@ -1936,14 +2089,18 @@ bool fMoreWork = false; for (CNode *pnode : vNodesCopy) { - if (pnode->fDisconnect) continue; + if (pnode->fDisconnect) { + continue; + } // Receive messages // FIXME: Pass the config down here. bool fMoreNodeWork = GetNodeSignals().ProcessMessages( GetConfig(), pnode, *this, flagInterruptMsgProc); fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend); - if (flagInterruptMsgProc) return; + if (flagInterruptMsgProc) { + return; + } // Send messages { @@ -1951,7 +2108,9 @@ GetNodeSignals().SendMessages(GetConfig(), pnode, *this, flagInterruptMsgProc); } - if (flagInterruptMsgProc) return; + if (flagInterruptMsgProc) { + return; + } } { @@ -2081,14 +2240,17 @@ vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted)); - if (addrBind.IsRoutable() && fDiscover && !fWhitelisted) + if (addrBind.IsRoutable() && fDiscover && !fWhitelisted) { AddLocal(addrBind, LOCAL_BIND); + } return true; } void Discover(boost::thread_group &threadGroup) { - if (!fDiscover) return; + if (!fDiscover) { + return; + } #ifdef WIN32 // Get local host IP @@ -2097,9 +2259,10 @@ std::vector vaddr; if (LookupHost(pszHostName, vaddr, 0, true)) { for (const CNetAddr &addr : vaddr) { - if (AddLocal(addr, LOCAL_IF)) + if (AddLocal(addr, LOCAL_IF)) { LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString()); + } } } } @@ -2109,23 +2272,26 @@ if (getifaddrs(&myaddrs) == 0) { for (struct ifaddrs *ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == nullptr) continue; - if ((ifa->ifa_flags & IFF_UP) == 0) continue; - if (strcmp(ifa->ifa_name, "lo") == 0) continue; - if (strcmp(ifa->ifa_name, "lo0") == 0) continue; + if (ifa->ifa_addr == nullptr || (ifa->ifa_flags & IFF_UP) == 0 || + strcmp(ifa->ifa_name, "lo") == 0 || + strcmp(ifa->ifa_name, "lo0") == 0) { + continue; + } if (ifa->ifa_addr->sa_family == AF_INET) { struct sockaddr_in *s4 = (struct sockaddr_in *)(ifa->ifa_addr); CNetAddr addr(s4->sin_addr); - if (AddLocal(addr, LOCAL_IF)) + if (AddLocal(addr, LOCAL_IF)) { LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString()); + } } else if (ifa->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)(ifa->ifa_addr); CNetAddr addr(s6->sin6_addr); - if (AddLocal(addr, LOCAL_IF)) + if (AddLocal(addr, LOCAL_IF)) { LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString()); + } } } freeifaddrs(myaddrs); @@ -2198,8 +2364,9 @@ SetBestHeight(connOptions.nBestHeight); clientInterface = connOptions.uiInterface; - if (clientInterface) + if (clientInterface) { clientInterface->InitMessage(_("Loading addresses...")); + } // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); { @@ -2214,7 +2381,9 @@ DumpAddresses(); } } - if (clientInterface) clientInterface->InitMessage(_("Loading banlist...")); + if (clientInterface) { + clientInterface->InitMessage(_("Loading banlist...")); + } // Load addresses from banlist.dat nStart = GetTimeMillis(); CBanDB bandb; @@ -2268,13 +2437,14 @@ &TraceThread>, "net", std::function(std::bind(&CConnman::ThreadSocketHandler, this))); - if (!GetBoolArg("-dnsseed", true)) + if (!GetBoolArg("-dnsseed", true)) { LogPrintf("DNS seeding disabled\n"); - else + } else { threadDNSAddressSeed = std::thread(&TraceThread>, "dnsseed", std::function( std::bind(&CConnman::ThreadDNSAddressSeed, this))); + } // Initiate outbound connections from -addnode threadOpenAddedConnections = @@ -2285,11 +2455,12 @@ // Initiate outbound connections unless connect=0 if (!mapMultiArgs.count("-connect") || mapMultiArgs.at("-connect").size() != 1 || - mapMultiArgs.at("-connect")[0] != "0") + mapMultiArgs.at("-connect")[0] != "0") { threadOpenConnections = std::thread(&TraceThread>, "opencon", std::function( std::bind(&CConnman::ThreadOpenConnections, this))); + } // Process messages threadMessageHandler = @@ -2340,12 +2511,21 @@ } void CConnman::Stop() { - if (threadMessageHandler.joinable()) threadMessageHandler.join(); - if (threadOpenConnections.joinable()) threadOpenConnections.join(); - if (threadOpenAddedConnections.joinable()) + if (threadMessageHandler.joinable()) { + threadMessageHandler.join(); + } + if (threadOpenConnections.joinable()) { + threadOpenConnections.join(); + } + if (threadOpenAddedConnections.joinable()) { threadOpenAddedConnections.join(); - if (threadDNSAddressSeed.joinable()) threadDNSAddressSeed.join(); - if (threadSocketHandler.joinable()) threadSocketHandler.join(); + } + if (threadDNSAddressSeed.joinable()) { + threadDNSAddressSeed.join(); + } + if (threadSocketHandler.joinable()) { + threadSocketHandler.join(); + } if (fAddressesInitialized) { DumpData(); @@ -2357,10 +2537,12 @@ pnode->CloseSocketDisconnect(); } for (ListenSocket &hListenSocket : vhListenSocket) { - if (hListenSocket.socket != INVALID_SOCKET) - if (!CloseSocket(hListenSocket.socket)) + if (hListenSocket.socket != INVALID_SOCKET) { + if (!CloseSocket(hListenSocket.socket)) { LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError())); + } + } } // clean up some globals (to help leak detection) @@ -2383,7 +2565,9 @@ assert(pnode); bool fUpdateConnectionTime = false; GetNodeSignals().FinalizeNode(pnode->GetId(), fUpdateConnectionTime); - if (fUpdateConnectionTime) addrman.Connected(pnode->addr); + if (fUpdateConnectionTime) { + addrman.Connected(pnode->addr); + } delete pnode; } @@ -2422,7 +2606,9 @@ LOCK(cs_vAddedNodes); for (std::vector::const_iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) { - if (strNode == *it) return false; + if (strNode == *it) { + return false; + } } vAddedNodes.push_back(strNode); @@ -2444,13 +2630,17 @@ size_t CConnman::GetNodeCount(NumConnections flags) { LOCK(cs_vNodes); // Shortcut if we want total - if (flags == CConnman::CONNECTIONS_ALL) return vNodes.size(); + if (flags == CConnman::CONNECTIONS_ALL) { + return vNodes.size(); + } int nNum = 0; for (std::vector::const_iterator it = vNodes.begin(); - it != vNodes.end(); ++it) - if (flags & ((*it)->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) + it != vNodes.end(); ++it) { + if (flags & ((*it)->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) { nNum++; + } + } return nNum; } @@ -2523,9 +2713,13 @@ uint64_t CConnman::GetMaxOutboundTimeLeftInCycle() { LOCK(cs_totalBytesSent); - if (nMaxOutboundLimit == 0) return 0; + if (nMaxOutboundLimit == 0) { + return 0; + } - if (nMaxOutboundCycleStartTime == 0) return nMaxOutboundTimeframe; + if (nMaxOutboundCycleStartTime == 0) { + return nMaxOutboundTimeframe; + } uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe; uint64_t now = GetTime(); @@ -2543,24 +2737,30 @@ bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit) { LOCK(cs_totalBytesSent); - if (nMaxOutboundLimit == 0) return false; + if (nMaxOutboundLimit == 0) { + return false; + } if (historicalBlockServingLimit) { // keep a large enough buffer to at least relay each block once. uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle(); uint64_t buffer = timeLeftInCycle / 600 * ONE_MEGABYTE; if (buffer >= nMaxOutboundLimit || - nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) + nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) { return true; - } else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) + } + } else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) { return true; + } return false; } uint64_t CConnman::GetOutboundTargetBytesLeft() { LOCK(cs_totalBytesSent); - if (nMaxOutboundLimit == 0) return 0; + if (nMaxOutboundLimit == 0) { + return 0; + } return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 @@ -2620,7 +2820,8 @@ fWhitelisted = false; fOneShot = false; fAddnode = false; - fClient = false; // set by version message + // set by version message + fClient = false; fFeeler = false; fSuccessfullyConnected = false; fDisconnect = false; @@ -2658,16 +2859,19 @@ } mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; - if (fLogIPs) + if (fLogIPs) { LogPrint("net", "Added connection to %s peer=%d\n", addrName, id); - else + } else { LogPrint("net", "Added connection peer=%d\n", id); + } } CNode::~CNode() { CloseSocket(hSocket); - if (pfilter) delete pfilter; + if (pfilter) { + delete pfilter; + } } void CNode::AskFor(const CInv &inv) { @@ -2678,7 +2882,9 @@ // a peer may not have multiple non-responded queue positions for a single // inv item. - if (!setAskFor.insert(inv.hash).second) return; + if (!setAskFor.insert(inv.hash).second) { + return; + } // We're using mapAskFor as a priority queue, the key is the earliest time // the request can be sent. @@ -2703,10 +2909,11 @@ // Each retry is 2 minutes after the last nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow); - if (it != mapAlreadyAskedFor.end()) + if (it != mapAlreadyAskedFor.end()) { mapAlreadyAskedFor.update(it, nRequestTime); - else + } else { mapAlreadyAskedFor.insert(std::make_pair(inv.hash, nRequestTime)); + } mapAskFor.insert(std::make_pair(nRequestTime, inv)); } @@ -2738,14 +2945,22 @@ pnode->mapSendBytesPerMsgCmd[msg.command] += nTotalSize; pnode->nSendSize += nTotalSize; - if (pnode->nSendSize > nSendBufferMaxSize) pnode->fPauseSend = true; + if (pnode->nSendSize > nSendBufferMaxSize) { + pnode->fPauseSend = true; + } pnode->vSendMsg.push_back(std::move(serializedHeader)); - if (nMessageSize) pnode->vSendMsg.push_back(std::move(msg.data)); + if (nMessageSize) { + pnode->vSendMsg.push_back(std::move(msg.data)); + } // If write queue empty, attempt "optimistic write" - if (optimisticSend == true) nBytesSent = SocketSendData(pnode); + if (optimisticSend == true) { + nBytesSent = SocketSendData(pnode); + } + } + if (nBytesSent) { + RecordBytesSent(nBytesSent); } - if (nBytesSent) RecordBytesSent(nBytesSent); } bool CConnman::ForNode(NodeId id, std::function func) { @@ -2761,10 +2976,10 @@ } int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { - return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * - -0.0000000000000035527136788 /* -1/2^48 */) * - average_interval_seconds * -1000000.0 + - 0.5); + return nNow + int64_t(log1p(GetRand(1ULL << 48) * + -0.0000000000000035527136788 /* -1/2^48 */) * + average_interval_seconds * -1000000.0 + + 0.5); } CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const { @@ -2778,6 +2993,7 @@ .Write(&vchNetGroup[0], vchNetGroup.size()) .Finalize(); } + /** * This function convert MaxBlockSize from byte to * MB with a decimal precision one digit rounded down @@ -2800,7 +3016,9 @@ ebMBs << (MaxBlockSize / (ONE_MEGABYTE / 10)); std::string eb = ebMBs.str(); eb.insert(eb.size() - 1, ".", 1); - if (eb.substr(0, 1) == ".") eb = "0" + eb; + if (eb.substr(0, 1) == ".") { + eb = "0" + eb; + } return eb; } @@ -2813,11 +3031,12 @@ // sanitize comments per BIP-0014, format user agent and check total size if (mapMultiArgs.count("-uacomment")) { for (const std::string &cmt : mapMultiArgs.at("-uacomment")) { - if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) + if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) { LogPrintf( "User Agent comment (%s) contains unsafe characters. " "We are going to use a sanitize version of the comment.\n", cmt); + } uacomments.push_back(cmt); } } @@ -2833,5 +3052,6 @@ subversion.append(")/"); LogPrintf("Current network string has been set to: %s\n", subversion); } + return subversion; }