LCOV - code coverage report
Current view: top level - src - net.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 1327 1680 79.0 %
Date: 2020-09-26 01:30:44 Functions: 136 151 90.1 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2020 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #if defined(HAVE_CONFIG_H)
       7             : #include <config/bitcoin-config.h>
       8             : #endif
       9             : 
      10             : #include <net.h>
      11             : 
      12             : #include <banman.h>
      13             : #include <chainparams.h>
      14             : #include <clientversion.h>
      15             : #include <consensus/consensus.h>
      16             : #include <crypto/sha256.h>
      17             : #include <net_permissions.h>
      18             : #include <netbase.h>
      19             : #include <node/ui_interface.h>
      20             : #include <protocol.h>
      21             : #include <random.h>
      22             : #include <scheduler.h>
      23             : #include <util/strencodings.h>
      24             : #include <util/translation.h>
      25             : 
      26             : #ifdef WIN32
      27             : #include <string.h>
      28             : #else
      29             : #include <fcntl.h>
      30             : #endif
      31             : 
      32             : #ifdef USE_POLL
      33             : #include <poll.h>
      34             : #endif
      35             : 
      36             : #ifdef USE_UPNP
      37             : #include <miniupnpc/miniupnpc.h>
      38             : #include <miniupnpc/upnpcommands.h>
      39             : #include <miniupnpc/upnperrors.h>
      40             : // The minimum supported miniUPnPc API version is set to 10. This keeps compatibility
      41             : // with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages.
      42             : static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed");
      43             : #endif
      44             : 
      45             : #include <cstdint>
      46             : #include <unordered_map>
      47             : 
      48             : #include <math.h>
      49             : 
      50             : // How often to dump addresses to peers.dat
      51             : static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
      52             : 
      53             : /** Number of DNS seeds to query when the number of connections is low. */
      54             : static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
      55             : 
      56             : /** How long to delay before querying DNS seeds
      57             :  *
      58             :  * If we have more than THRESHOLD entries in addrman, then it's likely
      59             :  * that we got those addresses from having previously connected to the P2P
      60             :  * network, and that we'll be able to successfully reconnect to the P2P
      61             :  * network via contacting one of them. So if that's the case, spend a
      62             :  * little longer trying to connect to known peers before querying the
      63             :  * DNS seeds.
      64             :  */
      65             : static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
      66             : static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
      67             : static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000; // "many" vs "few" peers
      68             : 
      69             : // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
      70             : #define FEELER_SLEEP_WINDOW 1
      71             : 
      72             : // MSG_NOSIGNAL is not available on some platforms, if it doesn't exist define it as 0
      73             : #if !defined(MSG_NOSIGNAL)
      74             : #define MSG_NOSIGNAL 0
      75             : #endif
      76             : 
      77             : // MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0
      78             : #if !defined(MSG_DONTWAIT)
      79             : #define MSG_DONTWAIT 0
      80             : #endif
      81             : 
      82             : /** Used to pass flags to the Bind() function */
      83             : enum BindFlags {
      84             :     BF_NONE         = 0,
      85             :     BF_EXPLICIT     = (1U << 0),
      86             :     BF_REPORT_ERROR = (1U << 1),
      87             : };
      88             : 
      89             : // The set of sockets cannot be modified while waiting
      90             : // The sleep time needs to be small to avoid new sockets stalling
      91             : static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
      92             : 
      93         640 : const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
      94             : 
      95             : static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
      96             : static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
      97             : //
      98             : // Global state variables
      99             : //
     100             : bool fDiscover = true;
     101             : bool fListen = true;
     102             : bool g_relay_txes = !DEFAULT_BLOCKSONLY;
     103         640 : RecursiveMutex cs_mapLocalHost;
     104         640 : std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
     105             : static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
     106         640 : std::string strSubVersion;
     107             : 
     108           0 : void CConnman::AddAddrFetch(const std::string& strDest)
     109             : {
     110           0 :     LOCK(m_addr_fetches_mutex);
     111           0 :     m_addr_fetches.push_back(strDest);
     112           0 : }
     113             : 
     114        1318 : uint16_t GetListenPort()
     115             : {
     116        1318 :     return (uint16_t)(gArgs.GetArg("-port", Params().GetDefaultPort()));
     117           0 : }
     118             : 
     119             : // find 'best' local address for a particular peer
     120         816 : bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
     121             : {
     122         816 :     if (!fListen)
     123           0 :         return false;
     124             : 
     125             :     int nBestScore = -1;
     126             :     int nBestReachability = -1;
     127             :     {
     128         816 :         LOCK(cs_mapLocalHost);
     129         817 :         for (const auto& entry : mapLocalHost)
     130             :         {
     131           1 :             int nScore = entry.second.nScore;
     132           1 :             int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
     133           1 :             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
     134             :             {
     135           1 :                 addr = CService(entry.first, entry.second.nPort);
     136             :                 nBestReachability = nReachability;
     137             :                 nBestScore = nScore;
     138           1 :             }
     139           0 :         }
     140         816 :     }
     141         816 :     return nBestScore >= 0;
     142         816 : }
     143             : 
     144             : //! Convert the pnSeed6 array into usable address objects.
     145          63 : static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
     146             : {
     147             :     // It'll only connect to one or two seed nodes because once it connects,
     148             :     // it'll get a pile of addresses with newer timestamps.
     149             :     // Seed nodes are given a random 'last seen time' of between one and two
     150             :     // weeks ago.
     151             :     const int64_t nOneWeek = 7*24*60*60;
     152          63 :     std::vector<CAddress> vSeedsOut;
     153          63 :     vSeedsOut.reserve(vSeedsIn.size());
     154          63 :     FastRandomContext rng;
     155          63 :     for (const auto& seed_in : vSeedsIn) {
     156           0 :         struct in6_addr ip;
     157           0 :         memcpy(&ip, seed_in.addr, sizeof(ip));
     158           0 :         CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE));
     159           0 :         addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
     160           0 :         vSeedsOut.push_back(addr);
     161           0 :     }
     162             :     return vSeedsOut;
     163          63 : }
     164             : 
     165             : // get best local address for a particular peer as a CAddress
     166             : // Otherwise, return the unroutable 0.0.0.0 but filled in with
     167             : // the normal parameters, since the IP may be changed to a useful
     168             : // one by discovery.
     169         816 : CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
     170             : {
     171         816 :     CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices);
     172         816 :     CService addr;
     173         816 :     if (GetLocal(addr, paddrPeer))
     174             :     {
     175           1 :         ret = CAddress(addr, nLocalServices);
     176           1 :     }
     177         816 :     ret.nTime = GetAdjustedTime();
     178             :     return ret;
     179         816 : }
     180             : 
     181           0 : static int GetnScore(const CService& addr)
     182             : {
     183           0 :     LOCK(cs_mapLocalHost);
     184           0 :     if (mapLocalHost.count(addr) == 0) return 0;
     185           0 :     return mapLocalHost[addr].nScore;
     186           0 : }
     187             : 
     188             : // Is our peer's addrLocal potentially useful as an external IP source?
     189         816 : bool IsPeerAddrLocalGood(CNode *pnode)
     190             : {
     191         816 :     CService addrLocal = pnode->GetAddrLocal();
     192         816 :     return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
     193           1 :            IsReachable(addrLocal.GetNetwork());
     194         816 : }
     195             : 
     196             : // pushes our own address to a peer
     197         663 : void AdvertiseLocal(CNode *pnode)
     198             : {
     199         663 :     if (fListen && pnode->fSuccessfullyConnected)
     200             :     {
     201         663 :         CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
     202         663 :         if (gArgs.GetBoolArg("-addrmantest", false)) {
     203             :             // use IPv4 loopback during addrmantest
     204           5 :             addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
     205           5 :         }
     206             :         // If discovery is enabled, sometimes give our peer the address it
     207             :         // tells us that it sees us as in case it has a better idea of our
     208             :         // address than we do.
     209         663 :         FastRandomContext rng;
     210         663 :         if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
     211           0 :              rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0))
     212             :         {
     213           1 :             addrLocal.SetIP(pnode->GetAddrLocal());
     214           1 :         }
     215         663 :         if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
     216             :         {
     217           6 :             LogPrint(BCLog::NET, "AdvertiseLocal: advertising address %s\n", addrLocal.ToString());
     218           6 :             pnode->PushAddress(addrLocal, rng);
     219             :         }
     220         663 :     }
     221         663 : }
     222             : 
     223             : // learn a new local address
     224           1 : bool AddLocal(const CService& addr, int nScore)
     225             : {
     226           1 :     if (!addr.IsRoutable())
     227           0 :         return false;
     228             : 
     229           1 :     if (!fDiscover && nScore < LOCAL_MANUAL)
     230           0 :         return false;
     231             : 
     232           1 :     if (!IsReachable(addr))
     233           0 :         return false;
     234             : 
     235           1 :     LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
     236             : 
     237             :     {
     238           1 :         LOCK(cs_mapLocalHost);
     239           1 :         bool fAlready = mapLocalHost.count(addr) > 0;
     240           1 :         LocalServiceInfo &info = mapLocalHost[addr];
     241           1 :         if (!fAlready || nScore >= info.nScore) {
     242           1 :             info.nScore = nScore + (fAlready ? 1 : 0);
     243           1 :             info.nPort = addr.GetPort();
     244           1 :         }
     245           1 :     }
     246             : 
     247           1 :     return true;
     248           1 : }
     249             : 
     250           0 : bool AddLocal(const CNetAddr &addr, int nScore)
     251             : {
     252           0 :     return AddLocal(CService(addr, GetListenPort()), nScore);
     253           0 : }
     254             : 
     255           1 : void RemoveLocal(const CService& addr)
     256             : {
     257           1 :     LOCK(cs_mapLocalHost);
     258           1 :     LogPrintf("RemoveLocal(%s)\n", addr.ToString());
     259           1 :     mapLocalHost.erase(addr);
     260           1 : }
     261             : 
     262         516 : void SetReachable(enum Network net, bool reachable)
     263             : {
     264         516 :     if (net == NET_UNROUTABLE || net == NET_INTERNAL)
     265             :         return;
     266         514 :     LOCK(cs_mapLocalHost);
     267         514 :     vfLimited[net] = !reachable;
     268         516 : }
     269             : 
     270       10615 : bool IsReachable(enum Network net)
     271             : {
     272       10615 :     LOCK(cs_mapLocalHost);
     273       10615 :     return !vfLimited[net];
     274       10615 : }
     275             : 
     276       10337 : bool IsReachable(const CNetAddr &addr)
     277             : {
     278       10337 :     return IsReachable(addr.GetNetwork());
     279             : }
     280             : 
     281             : /** vote for a local address */
     282           0 : bool SeenLocal(const CService& addr)
     283             : {
     284             :     {
     285           0 :         LOCK(cs_mapLocalHost);
     286           0 :         if (mapLocalHost.count(addr) == 0)
     287           0 :             return false;
     288           0 :         mapLocalHost[addr].nScore++;
     289           0 :     }
     290           0 :     return true;
     291           0 : }
     292             : 
     293             : 
     294             : /** check whether a given address is potentially local */
     295         334 : bool IsLocal(const CService& addr)
     296             : {
     297         334 :     LOCK(cs_mapLocalHost);
     298         334 :     return mapLocalHost.count(addr) > 0;
     299         334 : }
     300             : 
     301           6 : CNode* CConnman::FindNode(const CNetAddr& ip)
     302             : {
     303           6 :     LOCK(cs_vNodes);
     304          22 :     for (CNode* pnode : vNodes) {
     305          16 :       if (static_cast<CNetAddr>(pnode->addr) == ip) {
     306           0 :             return pnode;
     307             :         }
     308          16 :     }
     309           6 :     return nullptr;
     310           6 : }
     311             : 
     312           0 : CNode* CConnman::FindNode(const CSubNet& subNet)
     313             : {
     314           0 :     LOCK(cs_vNodes);
     315           0 :     for (CNode* pnode : vNodes) {
     316           0 :         if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
     317           0 :             return pnode;
     318             :         }
     319           0 :     }
     320           0 :     return nullptr;
     321           0 : }
     322             : 
     323         260 : CNode* CConnman::FindNode(const std::string& addrName)
     324             : {
     325         260 :     LOCK(cs_vNodes);
     326         400 :     for (CNode* pnode : vNodes) {
     327         140 :         if (pnode->GetAddrName() == addrName) {
     328           3 :             return pnode;
     329             :         }
     330         137 :     }
     331         257 :     return nullptr;
     332         260 : }
     333             : 
     334         252 : CNode* CConnman::FindNode(const CService& addr)
     335             : {
     336         252 :     LOCK(cs_vNodes);
     337         377 :     for (CNode* pnode : vNodes) {
     338         125 :         if (static_cast<CService>(pnode->addr) == addr) {
     339           0 :             return pnode;
     340             :         }
     341         125 :     }
     342         252 :     return nullptr;
     343         252 : }
     344             : 
     345         460 : bool CConnman::CheckIncomingNonce(uint64_t nonce)
     346             : {
     347         460 :     LOCK(cs_vNodes);
     348        1473 :     for (const CNode* pnode : vNodes) {
     349        1013 :         if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
     350           0 :             return false;
     351        1013 :     }
     352         460 :     return true;
     353         460 : }
     354             : 
     355             : /** Get the bind address for a socket as CAddress */
     356         713 : static CAddress GetBindAddress(SOCKET sock)
     357             : {
     358         713 :     CAddress addr_bind;
     359         713 :     struct sockaddr_storage sockaddr_bind;
     360         713 :     socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
     361         713 :     if (sock != INVALID_SOCKET) {
     362         713 :         if (!getsockname(sock, (struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
     363         713 :             addr_bind.SetSockAddr((const struct sockaddr*)&sockaddr_bind);
     364             :         } else {
     365           0 :             LogPrint(BCLog::NET, "Warning: getsockname failed\n");
     366             :         }
     367             :     }
     368             :     return addr_bind;
     369         713 : }
     370             : 
     371         256 : CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
     372             : {
     373         256 :     assert(conn_type != ConnectionType::INBOUND);
     374             : 
     375         256 :     if (pszDest == nullptr) {
     376           6 :         if (IsLocal(addrConnect))
     377           0 :             return nullptr;
     378             : 
     379             :         // Look for an existing connection
     380           6 :         CNode* pnode = FindNode(static_cast<CService>(addrConnect));
     381           6 :         if (pnode)
     382             :         {
     383           0 :             LogPrintf("Failed to open new connection, already connected\n");
     384           0 :             return nullptr;
     385             :         }
     386           6 :     }
     387             : 
     388             :     /// debug print
     389         256 :     LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
     390             :         pszDest ? pszDest : addrConnect.ToString(),
     391             :         pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
     392             : 
     393             :     // Resolve
     394         256 :     const int default_port = Params().GetDefaultPort();
     395         256 :     if (pszDest) {
     396         250 :         std::vector<CService> resolved;
     397         250 :         if (Lookup(pszDest, resolved,  default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
     398         246 :             addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
     399         246 :             if (!addrConnect.IsValid()) {
     400           0 :                 LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
     401           0 :                 return nullptr;
     402             :             }
     403             :             // It is possible that we already have a connection to the IP/port pszDest resolved to.
     404             :             // In that case, drop the connection that was just created, and return the existing CNode instead.
     405             :             // Also store the name we used to connect in that CNode, so that future FindNode() calls to that
     406             :             // name catch this early.
     407         246 :             LOCK(cs_vNodes);
     408         246 :             CNode* pnode = FindNode(static_cast<CService>(addrConnect));
     409         246 :             if (pnode)
     410             :             {
     411           0 :                 pnode->MaybeSetAddrName(std::string(pszDest));
     412           0 :                 LogPrintf("Failed to open new connection, already connected\n");
     413           0 :                 return nullptr;
     414             :             }
     415         246 :         }
     416         250 :     }
     417             : 
     418             :     // Connect
     419             :     bool connected = false;
     420         256 :     SOCKET hSocket = INVALID_SOCKET;
     421         256 :     proxyType proxy;
     422         256 :     if (addrConnect.IsValid()) {
     423         252 :         bool proxyConnectionFailed = false;
     424             : 
     425         252 :         if (GetProxy(addrConnect.GetNetwork(), proxy)) {
     426           6 :             hSocket = CreateSocket(proxy.proxy);
     427           6 :             if (hSocket == INVALID_SOCKET) {
     428           0 :                 return nullptr;
     429             :             }
     430           6 :             connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, proxyConnectionFailed);
     431           6 :         } else {
     432             :             // no proxy needed (none set for target network)
     433         246 :             hSocket = CreateSocket(addrConnect);
     434         246 :             if (hSocket == INVALID_SOCKET) {
     435           0 :                 return nullptr;
     436             :             }
     437         246 :             connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, conn_type == ConnectionType::MANUAL);
     438             :         }
     439         252 :         if (!proxyConnectionFailed) {
     440             :             // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
     441             :             // the proxy, mark this as an attempt.
     442         252 :             addrman.Attempt(addrConnect, fCountFailure);
     443             :         }
     444         256 :     } else if (pszDest && GetNameProxy(proxy)) {
     445           3 :         hSocket = CreateSocket(proxy.proxy);
     446         613 :         if (hSocket == INVALID_SOCKET) {
     447         610 :             return nullptr;
     448             :         }
     449           3 :         std::string host;
     450           3 :         int port = default_port;
     451           3 :         SplitHostPort(std::string(pszDest), port, host);
     452           3 :         bool proxyConnectionFailed;
     453           3 :         connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, proxyConnectionFailed);
     454           3 :     }
     455         256 :     if (!connected) {
     456           8 :         CloseSocket(hSocket);
     457           8 :         return nullptr;
     458             :     }
     459             : 
     460             :     // Add node
     461         248 :     NodeId id = GetNewNodeId();
     462         858 :     uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
     463         858 :     CAddress addr_bind = GetBindAddress(hSocket);
     464         248 :     CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type);
     465         248 :     pnode->AddRef();
     466         610 : 
     467         610 :     // We're making a new connection, harvest entropy from the time (and our peer count)
     468         248 :     RandAddEvent((uint32_t)id);
     469             : 
     470             :     return pnode;
     471         512 : }
     472             : 
     473         871 : void CNode::CloseSocketDisconnect()
     474             : {
     475         871 :     fDisconnect = true;
     476        1481 :     LOCK(cs_hSocket);
     477        1481 :     if (hSocket != INVALID_SOCKET)
     478             :     {
     479         713 :         LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
     480         713 :         CloseSocket(hSocket);
     481             :     }
     482         871 : }
     483             : 
     484         466 : void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const {
     485         538 :     for (const auto& subnet : vWhitelistedRange) {
     486          72 :         if (subnet.m_subnet.Match(addr)) NetPermissions::AddFlag(flags, subnet.m_flags);
     487             :     }
     488         466 : }
     489             : 
     490       18752 : std::string CNode::GetAddrName() const {
     491       18752 :     LOCK(cs_addrName);
     492       18752 :     return addrName;
     493       18752 : }
     494             : 
     495           0 : void CNode::MaybeSetAddrName(const std::string& addrNameIn) {
     496           0 :     LOCK(cs_addrName);
     497           0 :     if (addrName.empty()) {
     498           0 :         addrName = addrNameIn;
     499             :     }
     500           0 : }
     501             : 
     502        9452 : CService CNode::GetAddrLocal() const {
     503        9452 :     LOCK(cs_addrLocal);
     504        9452 :     return addrLocal;
     505        9452 : }
     506             : 
     507         699 : void CNode::SetAddrLocal(const CService& addrLocalIn) {
     508         699 :     LOCK(cs_addrLocal);
     509         699 :     if (addrLocal.IsValid()) {
     510           0 :         error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
     511           0 :     } else {
     512         699 :         addrLocal = addrLocalIn;
     513             :     }
     514         699 : }
     515             : 
     516             : #undef X
     517             : #define X(name) stats.name = name
     518        8635 : void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
     519             : {
     520        8635 :     stats.nodeid = this->GetId();
     521        8635 :     X(nServices);
     522        8635 :     X(addr);
     523        8635 :     X(addrBind);
     524        8635 :     stats.m_mapped_as = addr.GetMappedAS(m_asmap);
     525        8635 :     if (m_tx_relay != nullptr) {
     526        8635 :         LOCK(m_tx_relay->cs_filter);
     527        8635 :         stats.fRelayTxes = m_tx_relay->fRelayTxes;
     528        8635 :     } else {
     529           0 :         stats.fRelayTxes = false;
     530             :     }
     531        8635 :     X(nLastSend);
     532        8635 :     X(nLastRecv);
     533        8635 :     X(nLastTXTime);
     534        8635 :     X(nLastBlockTime);
     535        8635 :     X(nTimeConnected);
     536        8635 :     X(nTimeOffset);
     537        8635 :     stats.addrName = GetAddrName();
     538        8635 :     X(nVersion);
     539             :     {
     540        8635 :         LOCK(cs_SubVer);
     541        8635 :         X(cleanSubVer);
     542        8635 :     }
     543        8635 :     stats.fInbound = IsInboundConn();
     544        8635 :     stats.m_manual_connection = IsManualConn();
     545        9245 :     X(nStartingHeight);
     546             :     {
     547        8635 :         LOCK(cs_vSend);
     548        8635 :         X(mapSendBytesPerMsgCmd);
     549        8635 :         X(nSendBytes);
     550        8635 :     }
     551             :     {
     552        8635 :         LOCK(cs_vRecv);
     553        8635 :         X(mapRecvBytesPerMsgCmd);
     554        8635 :         X(nRecvBytes);
     555        8635 :     }
     556        8635 :     X(m_legacyWhitelisted);
     557        8635 :     X(m_permissionFlags);
     558        8635 :     if (m_tx_relay != nullptr) {
     559        8635 :         LOCK(m_tx_relay->cs_feeFilter);
     560        9245 :         stats.minFeeFilter = m_tx_relay->minFeeFilter;
     561        8635 :     } else {
     562           0 :         stats.minFeeFilter = 0;
     563             :     }
     564             : 
     565             :     // It is common for nodes with good ping times to suddenly become lagged,
     566             :     // due to a new block arriving or other large transfer.
     567             :     // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
     568             :     // since pingtime does not update until the ping is complete, which might take a while.
     569             :     // So, if a ping is taking an unusually long time in flight,
     570             :     // the caller can immediately detect that this is happening.
     571             :     std::chrono::microseconds ping_wait{0};
     572        8635 :     if ((0 != nPingNonceSent) && (0 != m_ping_start.load().count())) {
     573         251 :         ping_wait = GetTime<std::chrono::microseconds>() - m_ping_start.load();
     574         251 :     }
     575             : 
     576             :     // 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 :)
     577        8635 :     stats.m_ping_usec = nPingUsecTime;
     578        8635 :     stats.m_min_ping_usec  = nMinPingUsecTime;
     579        8635 :     stats.m_ping_wait_usec = count_microseconds(ping_wait);
     580             : 
     581             :     // Leave string empty if addrLocal invalid (not filled in yet)
     582        8635 :     CService addrLocalUnlocked = GetAddrLocal();
     583        8635 :     stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
     584        8635 : }
     585             : #undef X
     586             : 
     587      104828 : bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete)
     588             : {
     589      104828 :     complete = false;
     590      104828 :     const auto time = GetTime<std::chrono::microseconds>();
     591      104828 :     LOCK(cs_vRecv);
     592      104828 :     nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count();
     593      104828 :     nRecvBytes += nBytes;
     594      298533 :     while (nBytes > 0) {
     595             :         // absorb network data
     596      193706 :         int handled = m_deserializer->Read(pch, nBytes);
     597      193706 :         if (handled < 0) return false;
     598             : 
     599      193705 :         pch += handled;
     600      193705 :         nBytes -= handled;
     601             : 
     602      193705 :         if (m_deserializer->Complete()) {
     603             :             // decompose a transport agnostic CNetMessage from the deserializer
     604       86838 :             CNetMessage msg = m_deserializer->GetMessage(Params().MessageStart(), time);
     605             : 
     606             :             //store received bytes per message command
     607             :             //to prevent a memory DOS, only allow valid commands
     608       86838 :             mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.m_command);
     609       86838 :             if (i == mapRecvBytesPerMsgCmd.end())
     610          83 :                 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
     611       86838 :             assert(i != mapRecvBytesPerMsgCmd.end());
     612       86838 :             i->second += msg.m_raw_message_size;
     613             : 
     614             :             // push the message to the process queue,
     615       86838 :             vRecvMsg.push_back(std::move(msg));
     616             : 
     617       86838 :             complete = true;
     618       86838 :         }
     619      193705 :     }
     620             : 
     621      104827 :     return true;
     622      104828 : }
     623             : 
     624         711 : void CNode::SetSendVersion(int nVersionIn)
     625             : {
     626             :     // Send version may only be changed in the version message, and
     627             :     // only one version message is allowed per session. We can therefore
     628             :     // treat this value as const and even atomic as long as it's only used
     629             :     // once a version message has been successfully processed. Any attempt to
     630             :     // set this twice is an error.
     631         711 :     if (nSendVersion != 0) {
     632           0 :         error("Send version already set for node: %i. Refusing to change from %i to %i", id, nSendVersion, nVersionIn);
     633           0 :     } else {
     634         711 :         nSendVersion = nVersionIn;
     635             :     }
     636         711 : }
     637             : 
     638      707468 : int CNode::GetSendVersion() const
     639             : {
     640             :     // The send version should always be explicitly set to
     641             :     // INIT_PROTO_VERSION rather than using this value until SetSendVersion
     642             :     // has been called.
     643      707468 :     if (nSendVersion == 0) {
     644           0 :         error("Requesting unset send version for node: %i. Using %i", id, INIT_PROTO_VERSION);
     645           0 :         return INIT_PROTO_VERSION;
     646             :     }
     647      707468 :     return nSendVersion;
     648      707468 : }
     649             : 
     650       86840 : int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
     651             : {
     652             :     // copy data to temporary parsing buffer
     653       86840 :     unsigned int nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
     654       86840 :     unsigned int nCopy = std::min(nRemaining, nBytes);
     655             : 
     656       86840 :     memcpy(&hdrbuf[nHdrPos], pch, nCopy);
     657       86840 :     nHdrPos += nCopy;
     658             : 
     659             :     // if header incomplete, exit
     660       86840 :     if (nHdrPos < CMessageHeader::HEADER_SIZE)
     661           1 :         return nCopy;
     662             : 
     663             :     // deserialize to CMessageHeader
     664             :     try {
     665       86839 :         hdrbuf >> hdr;
     666           0 :     }
     667             :     catch (const std::exception&) {
     668             :         return -1;
     669           0 :     }
     670             : 
     671             :     // reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH
     672       86839 :     if (hdr.nMessageSize > MAX_SIZE || hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
     673           1 :         return -1;
     674             :     }
     675             : 
     676             :     // switch state to reading message data
     677       86838 :     in_data = true;
     678             : 
     679       86838 :     return nCopy;
     680       86840 : }
     681             : 
     682      106866 : int V1TransportDeserializer::readData(const char *pch, unsigned int nBytes)
     683             : {
     684      106866 :     unsigned int nRemaining = hdr.nMessageSize - nDataPos;
     685      106866 :     unsigned int nCopy = std::min(nRemaining, nBytes);
     686             : 
     687      106866 :     if (vRecv.size() < nDataPos + nCopy) {
     688             :         // Allocate up to 256 KiB ahead, but never more than the total message size.
     689       89025 :         vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
     690       89025 :     }
     691             : 
     692      106866 :     hasher.Write({(const unsigned char*)pch, nCopy});
     693      106866 :     memcpy(&vRecv[nDataPos], pch, nCopy);
     694      106866 :     nDataPos += nCopy;
     695             : 
     696      106866 :     return nCopy;
     697      106866 : }
     698             : 
     699       86838 : const uint256& V1TransportDeserializer::GetMessageHash() const
     700             : {
     701       86838 :     assert(Complete());
     702       86838 :     if (data_hash.IsNull())
     703       86838 :         hasher.Finalize(data_hash);
     704       86838 :     return data_hash;
     705             : }
     706             : 
     707       86838 : CNetMessage V1TransportDeserializer::GetMessage(const CMessageHeader::MessageStartChars& message_start, const std::chrono::microseconds time)
     708             : {
     709             :     // decompose a single CNetMessage from the TransportDeserializer
     710       86838 :     CNetMessage msg(std::move(vRecv));
     711             : 
     712             :     // store state about valid header, netmagic and checksum
     713       86838 :     msg.m_valid_header = hdr.IsValid(message_start);
     714       86838 :     msg.m_valid_netmagic = (memcmp(hdr.pchMessageStart, message_start, CMessageHeader::MESSAGE_START_SIZE) == 0);
     715       86838 :     uint256 hash = GetMessageHash();
     716             : 
     717             :     // store command string, payload size
     718       86838 :     msg.m_command = hdr.GetCommand();
     719       86838 :     msg.m_message_size = hdr.nMessageSize;
     720       86838 :     msg.m_raw_message_size = hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
     721             : 
     722             :     // We just received a message off the wire, harvest entropy from the time (and the message checksum)
     723       86838 :     RandAddEvent(ReadLE32(hash.begin()));
     724             : 
     725       86838 :     msg.m_valid_checksum = (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) == 0);
     726       86838 :     if (!msg.m_valid_checksum) {
     727           1 :         LogPrint(BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s\n",
     728             :                  SanitizeString(msg.m_command), msg.m_message_size,
     729             :                  HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
     730             :                  HexStr(hdr.pchChecksum));
     731             :     }
     732             : 
     733             :     // store receive time
     734       86838 :     msg.m_time = time;
     735             : 
     736             :     // reset the network deserializer (prepare for the next message)
     737       86838 :     Reset();
     738             :     return msg;
     739       86838 : }
     740             : 
     741       91268 : void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) {
     742             :     // create dbl-sha256 checksum
     743       91268 :     uint256 hash = Hash(msg.data);
     744             : 
     745             :     // create header
     746       91268 :     CMessageHeader hdr(Params().MessageStart(), msg.m_type.c_str(), msg.data.size());
     747       91268 :     memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
     748             : 
     749             :     // serialize header
     750       91268 :     header.reserve(CMessageHeader::HEADER_SIZE);
     751       91268 :     CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, header, 0, hdr};
     752       91268 : }
     753             : 
     754       91153 : size_t CConnman::SocketSendData(CNode *pnode) const EXCLUSIVE_LOCKS_REQUIRED(pnode->cs_vSend)
     755             : {
     756       91153 :     auto it = pnode->vSendMsg.begin();
     757             :     size_t nSentSize = 0;
     758             : 
     759      271319 :     while (it != pnode->vSendMsg.end()) {
     760      180275 :         const auto &data = *it;
     761      180275 :         assert(data.size() > pnode->nSendOffset);
     762             :         int nBytes = 0;
     763             :         {
     764      180275 :             LOCK(pnode->cs_hSocket);
     765      180275 :             if (pnode->hSocket == INVALID_SOCKET)
     766          12 :                 break;
     767      180263 :             nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
     768      180275 :         }
     769      180263 :         if (nBytes > 0) {
     770      180259 :             pnode->nLastSend = GetSystemTimeInSeconds();
     771      180259 :             pnode->nSendBytes += nBytes;
     772      180259 :             pnode->nSendOffset += nBytes;
     773      180259 :             nSentSize += nBytes;
     774      180259 :             if (pnode->nSendOffset == data.size()) {
     775      180166 :                 pnode->nSendOffset = 0;
     776      180166 :                 pnode->nSendSize -= data.size();
     777      180166 :                 pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
     778      180166 :                 it++;
     779             :             } else {
     780             :                 // could not send full message; stop sending more
     781          93 :                 break;
     782             :             }
     783             :         } else {
     784           4 :             if (nBytes < 0) {
     785             :                 // error
     786           4 :                 int nErr = WSAGetLastError();
     787           4 :                 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
     788             :                 {
     789           3 :                     LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
     790           3 :                     pnode->CloseSocketDisconnect();
     791           3 :                 }
     792           4 :             }
     793             :             // couldn't send anything at all
     794           4 :             break;
     795             :         }
     796      180166 :     }
     797             : 
     798       91153 :     if (it == pnode->vSendMsg.end()) {
     799       91044 :         assert(pnode->nSendOffset == 0);
     800       91044 :         assert(pnode->nSendSize == 0);
     801             :     }
     802       91153 :     pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
     803       91153 :     return nSentSize;
     804       91153 : }
     805             : 
     806         388 : struct NodeEvictionCandidate
     807             : {
     808             :     NodeId id;
     809             :     int64_t nTimeConnected;
     810             :     int64_t nMinPingUsecTime;
     811             :     int64_t nLastBlockTime;
     812         729 :     int64_t nLastTXTime;
     813             :     bool fRelevantServices;
     814         729 :     bool fRelayTxes;
     815         729 :     bool fBloomFilter;
     816         729 :     CAddress addr;
     817             :     uint64_t nKeyedNetGroup;
     818             :     bool prefer_evict;
     819             :     bool m_is_local;
     820             : };
     821             : 
     822          67 : static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
     823             : {
     824         796 :     return a.nMinPingUsecTime > b.nMinPingUsecTime;
     825             : }
     826             : 
     827           0 : static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
     828             : {
     829         729 :     return a.nTimeConnected > b.nTimeConnected;
     830         729 : }
     831             : 
     832         729 : static bool CompareLocalHostTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
     833         729 : {
     834           0 :     if (a.m_is_local != b.m_is_local) return b.m_is_local;
     835         729 :     return a.nTimeConnected > b.nTimeConnected;
     836           0 : }
     837             : 
     838          42 : static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
     839          42 :     return a.nKeyedNetGroup < b.nKeyedNetGroup;
     840         729 : }
     841             : 
     842           4 : static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
     843             : {
     844             :     // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
     845           4 :     if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
     846         732 :     if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
     847         732 :     return a.nTimeConnected > b.nTimeConnected;
     848           4 : }
     849             : 
     850          24 : static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
     851             : {
     852         729 :     // 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.
     853         753 :     if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime;
     854         749 :     if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes;
     855         749 :     if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
     856          20 :     return a.nTimeConnected > b.nTimeConnected;
     857          24 : }
     858         729 : 
     859         729 : // Pick out the potential block-relay only peers, and sort them by last block time.
     860           4 : static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
     861         729 : {
     862           4 :     if (a.fRelayTxes != b.fRelayTxes) return a.fRelayTxes;
     863           4 :     if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
     864         732 :     if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
     865         732 :     return a.nTimeConnected > b.nTimeConnected;
     866           4 : }
     867             : 
     868             : //! Sort an array by the specified comparator, then erase the last K elements.
     869             : template<typename T, typename Comparator>
     870           5 : static void EraseLastKElements(std::vector<T> &elements, Comparator comparator, size_t k)
     871             : {
     872           5 :     std::sort(elements.begin(), elements.end(), comparator);
     873           5 :     size_t eraseSize = std::min(k, elements.size());
     874           5 :     elements.erase(elements.end() - eraseSize, elements.end());
     875           5 : }
     876             : 
     877             : /** Try to find a connection to evict when the node is full.
     878             :  *  Extreme care must be taken to avoid opening the node to attacker
     879             :  *   triggered network partitioning.
     880             :  *  The strategy used here is to protect a small number of peers
     881             :  *   for each of several distinct characteristics which are difficult
     882             :  *   to forge.  In order to partition a node the attacker must be
     883             :  *   simultaneously better at all of them than honest peers.
     884             :  */
     885           1 : bool CConnman::AttemptToEvictConnection()
     886             : {
     887           1 :     std::vector<NodeEvictionCandidate> vEvictionCandidates;
     888             :     {
     889           1 :         LOCK(cs_vNodes);
     890             : 
     891          22 :         for (const CNode* node : vNodes) {
     892          21 :             if (node->HasPermission(PF_NOBAN))
     893           0 :                 continue;
     894          21 :             if (!node->IsInboundConn())
     895           0 :                 continue;
     896          21 :             if (node->fDisconnect)
     897           0 :                 continue;
     898             :             bool peer_relay_txes = false;
     899             :             bool peer_filter_not_null = false;
     900          21 :             if (node->m_tx_relay != nullptr) {
     901          21 :                 LOCK(node->m_tx_relay->cs_filter);
     902          21 :                 peer_relay_txes = node->m_tx_relay->fRelayTxes;
     903          21 :                 peer_filter_not_null = node->m_tx_relay->pfilter != nullptr;
     904          21 :             }
     905          63 :             NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
     906          42 :                                                node->nLastBlockTime, node->nLastTXTime,
     907          21 :                                                HasAllDesirableServiceFlags(node->nServices),
     908          63 :                                                peer_relay_txes, peer_filter_not_null, node->addr, node->nKeyedNetGroup,
     909          42 :                                                node->m_prefer_evict, node->addr.IsLocal()};
     910          21 :             vEvictionCandidates.push_back(candidate);
     911          21 :         }
     912           1 :     }
     913             : 
     914             :     // Protect connections with certain characteristics
     915             : 
     916             :     // Deterministically select 4 peers to protect by netgroup.
     917             :     // An attacker cannot predict which netgroups will be protected
     918           1 :     EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
     919             :     // Protect the 8 nodes with the lowest minimum ping time.
     920             :     // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
     921           1 :     EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
     922             :     // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
     923             :     // An attacker cannot manipulate this metric without performing useful work.
     924           1 :     EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
     925             :     // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
     926           1 :     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockRelayOnlyTime);
     927           1 :     size_t erase_size = std::min(size_t(8), vEvictionCandidates.size());
     928           6 :     vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - erase_size, vEvictionCandidates.end(), [](NodeEvictionCandidate const &n) { return !n.fRelayTxes && n.fRelevantServices; }), vEvictionCandidates.end());
     929             : 
     930             :     // Protect 4 nodes that most recently sent us novel blocks.
     931             :     // An attacker cannot manipulate this metric without performing useful work.
     932           1 :     EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
     933         729 : 
     934             :     // Protect the half of the remaining nodes which have been connected the longest.
     935             :     // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
     936             :     // Reserve half of these protected spots for localhost peers, even if
     937         729 :     // they're not longest-uptime overall. This helps protect tor peers, which
     938         729 :     // tend to be otherwise disadvantaged under our eviction criteria.
     939         730 :     size_t initial_size = vEvictionCandidates.size();
     940         730 :     size_t total_protect_size = initial_size / 2;
     941             : 
     942             :     // Pick out up to 1/4 peers that are localhost, sorted by longest uptime.
     943           1 :     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareLocalHostTimeConnected);
     944           1 :     size_t local_erase_size = total_protect_size / 2;
     945           1 :     vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - local_erase_size, vEvictionCandidates.end(), [](NodeEvictionCandidate const &n) { return n.m_is_local; }), vEvictionCandidates.end());
     946             :     // Calculate how many we removed, and update our total number of peers that
     947             :     // we want to protect based on uptime accordingly.
     948           1 :     total_protect_size -= initial_size - vEvictionCandidates.size();
     949           1 :     EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, total_protect_size);
     950             : 
     951           1 :     if (vEvictionCandidates.empty()) return false;
     952             : 
     953             :     // If any remaining peers are preferred for eviction consider only them.
     954             :     // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
     955             :     //  then we probably don't want to evict it no matter what.
     956           2 :     if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
     957           0 :         vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
     958           0 :                                   [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
     959           0 :     }
     960             : 
     961             :     // Identify the network group with the most connections and youngest member.
     962             :     // (vEvictionCandidates is already sorted by reverse connect time)
     963           1 :     uint64_t naMostConnections;
     964             :     unsigned int nMostConnections = 0;
     965             :     int64_t nMostConnectionsTime = 0;
     966           1 :     std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
     967           2 :     for (const NodeEvictionCandidate &node : vEvictionCandidates) {
     968           1 :         std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
     969           1 :         group.push_back(node);
     970           1 :         int64_t grouptime = group[0].nTimeConnected;
     971             : 
     972           1 :         if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
     973           1 :             nMostConnections = group.size();
     974             :             nMostConnectionsTime = grouptime;
     975           1 :             naMostConnections = node.nKeyedNetGroup;
     976           1 :         }
     977             :     }
     978             : 
     979             :     // Reduce to the network group with the most connections
     980           1 :     vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
     981             : 
     982             :     // Disconnect from the network group with the most connections
     983           1 :     NodeId evicted = vEvictionCandidates.front().id;
     984           1 :     LOCK(cs_vNodes);
     985           6 :     for (CNode* pnode : vNodes) {
     986         734 :         if (pnode->GetId() == evicted) {
     987           1 :             pnode->fDisconnect = true;
     988           1 :             return true;
     989             :         }
     990           4 :     }
     991           0 :     return false;
     992         730 : }
     993             : 
     994         466 : void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
     995         466 :     struct sockaddr_storage sockaddr;
     996        1195 :     socklen_t len = sizeof(sockaddr);
     997         466 :     SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
     998        1195 :     CAddress addr;
     999             :     int nInbound = 0;
    1000        1195 :     int nMaxInbound = nMaxConnections - m_max_outbound;
    1001             : 
    1002        1195 :     if (hSocket != INVALID_SOCKET) {
    1003         466 :         if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
    1004         729 :             LogPrintf("Warning: Unknown socket family\n");
    1005             :         }
    1006             :     }
    1007             : 
    1008         466 :     NetPermissionFlags permissionFlags = NetPermissionFlags::PF_NONE;
    1009         466 :     hListenSocket.AddSocketPermissionFlags(permissionFlags);
    1010         466 :     AddWhitelistPermissionFlags(permissionFlags, addr);
    1011             :     bool legacyWhitelisted = false;
    1012         466 :     if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_ISIMPLICIT)) {
    1013           7 :         NetPermissions::ClearFlag(permissionFlags, PF_ISIMPLICIT);
    1014           7 :         if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, PF_FORCERELAY);
    1015           7 :         if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, PF_RELAY);
    1016           7 :         NetPermissions::AddFlag(permissionFlags, PF_MEMPOOL);
    1017           7 :         NetPermissions::AddFlag(permissionFlags, PF_NOBAN);
    1018             :         legacyWhitelisted = true;
    1019           7 :     }
    1020             : 
    1021             :     {
    1022         466 :         LOCK(cs_vNodes);
    1023        1026 :         for (const CNode* pnode : vNodes) {
    1024         560 :             if (pnode->IsInboundConn()) nInbound++;
    1025             :         }
    1026         466 :     }
    1027             : 
    1028         466 :     if (hSocket == INVALID_SOCKET)
    1029             :     {
    1030           0 :         int nErr = WSAGetLastError();
    1031           0 :         if (nErr != WSAEWOULDBLOCK)
    1032           0 :             LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
    1033             :         return;
    1034           0 :     }
    1035             : 
    1036        1195 :     if (!fNetworkActive) {
    1037         729 :         LogPrintf("connection from %s dropped: not accepting new connections\n", addr.ToString());
    1038           0 :         CloseSocket(hSocket);
    1039           0 :         return;
    1040             :     }
    1041             : 
    1042         466 :     if (!IsSelectableSocket(hSocket))
    1043             :     {
    1044           0 :         LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
    1045           0 :         CloseSocket(hSocket);
    1046           0 :         return;
    1047             :     }
    1048             : 
    1049             :     // According to the internet TCP_NODELAY is not carried into accepted sockets
    1050             :     // on all platforms.  Set it again here just to be sure.
    1051         466 :     SetSocketNoDelay(hSocket);
    1052             : 
    1053             :     // Don't accept connections from banned peers.
    1054         466 :     bool banned = m_banman && m_banman->IsBanned(addr);
    1055         466 :     if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && banned)
    1056             :     {
    1057           1 :         LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
    1058           1 :         CloseSocket(hSocket);
    1059           1 :         return;
    1060             :     }
    1061             : 
    1062             :     // Only accept connections from discouraged peers if our inbound slots aren't (almost) full.
    1063         465 :     bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
    1064         465 :     if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && nInbound + 1 >= nMaxInbound && discouraged)
    1065             :     {
    1066           0 :         LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString());
    1067           0 :         CloseSocket(hSocket);
    1068           0 :         return;
    1069             :     }
    1070             : 
    1071         465 :     if (nInbound >= nMaxInbound)
    1072             :     {
    1073           1 :         if (!AttemptToEvictConnection()) {
    1074             :             // No connection to evict, disconnect the new connection
    1075           0 :             LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
    1076           0 :             CloseSocket(hSocket);
    1077           0 :             return;
    1078             :         }
    1079             :     }
    1080             : 
    1081         465 :     NodeId id = GetNewNodeId();
    1082         465 :     uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
    1083         465 :     CAddress addr_bind = GetBindAddress(hSocket);
    1084             : 
    1085         465 :     ServiceFlags nodeServices = nLocalServices;
    1086         465 :     if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
    1087           2 :         nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
    1088           2 :     }
    1089         465 :     CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND);
    1090         465 :     pnode->AddRef();
    1091         465 :     pnode->m_permissionFlags = permissionFlags;
    1092             :     // If this flag is present, the user probably expect that RPC and QT report it as whitelisted (backward compatibility)
    1093         465 :     pnode->m_legacyWhitelisted = legacyWhitelisted;
    1094         465 :     pnode->m_prefer_evict = discouraged;
    1095         465 :     m_msgproc->InitializeNode(pnode);
    1096             : 
    1097         465 :     LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
    1098             : 
    1099             :     {
    1100         465 :         LOCK(cs_vNodes);
    1101         465 :         vNodes.push_back(pnode);
    1102         465 :     }
    1103             : 
    1104             :     // We received a new connection, harvest entropy from the time (and our peer count)
    1105         465 :     RandAddEvent((uint32_t)id);
    1106         931 : }
    1107             : 
    1108      332444 : void CConnman::DisconnectNodes()
    1109             : {
    1110             :     {
    1111      332444 :         LOCK(cs_vNodes);
    1112             : 
    1113      332444 :         if (!fNetworkActive) {
    1114             :             // Disconnect any connected nodes
    1115          95 :             for (CNode* pnode : vNodes) {
    1116           3 :                 if (!pnode->fDisconnect) {
    1117           3 :                     LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
    1118           3 :                     pnode->fDisconnect = true;
    1119           3 :                 }
    1120             :             }
    1121          92 :         }
    1122             : 
    1123             :         // Disconnect unused nodes
    1124      332444 :         std::vector<CNode*> vNodesCopy = vNodes;
    1125      835629 :         for (CNode* pnode : vNodesCopy)
    1126             :         {
    1127      503185 :             if (pnode->fDisconnect)
    1128             :             {
    1129             :                 // remove from vNodes
    1130         299 :                 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
    1131             : 
    1132             :                 // release outbound grant (if any)
    1133         299 :                 pnode->grantOutbound.Release();
    1134             : 
    1135             :                 // close socket and cleanup
    1136         299 :                 pnode->CloseSocketDisconnect();
    1137             : 
    1138             :                 // hold in disconnected pool until all refs are released
    1139         299 :                 pnode->Release();
    1140         299 :                 vNodesDisconnected.push_back(pnode);
    1141             :             }
    1142      503185 :         }
    1143      332444 :     }
    1144             :     {
    1145             :         // Delete disconnected nodes
    1146      332444 :         std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
    1147      332746 :         for (CNode* pnode : vNodesDisconnectedCopy)
    1148             :         {
    1149             :             // wait until threads are done using it
    1150         302 :             if (pnode->GetRefCount() <= 0) {
    1151             :                 bool fDelete = false;
    1152             :                 {
    1153         299 :                     TRY_LOCK(pnode->cs_vSend, lockSend);
    1154         299 :                     if (lockSend) {
    1155             :                         fDelete = true;
    1156         299 :                     }
    1157         299 :                 }
    1158         299 :                 if (fDelete) {
    1159         299 :                     vNodesDisconnected.remove(pnode);
    1160         299 :                     DeleteNode(pnode);
    1161             :                 }
    1162         299 :             }
    1163         302 :         }
    1164      332444 :     }
    1165      332444 : }
    1166             : 
    1167      332444 : void CConnman::NotifyNumConnectionsChanged()
    1168             : {
    1169             :     size_t vNodesSize;
    1170             :     {
    1171      332444 :         LOCK(cs_vNodes);
    1172      332444 :         vNodesSize = vNodes.size();
    1173      332444 :     }
    1174      332444 :     if(vNodesSize != nPrevNodeCount) {
    1175         989 :         nPrevNodeCount = vNodesSize;
    1176         989 :         if(clientInterface)
    1177         989 :             clientInterface->NotifyNumConnectionsChanged(vNodesSize);
    1178             :     }
    1179      332444 : }
    1180             : 
    1181      503184 : void CConnman::InactivityCheck(CNode *pnode)
    1182             : {
    1183      503184 :     int64_t nTime = GetSystemTimeInSeconds();
    1184      503184 :     if (nTime - pnode->nTimeConnected > m_peer_connect_timeout)
    1185             :     {
    1186      188057 :         if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
    1187             :         {
    1188           2 :             LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d from %d\n", m_peer_connect_timeout, pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
    1189           2 :             pnode->fDisconnect = true;
    1190           2 :         }
    1191      188055 :         else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
    1192             :         {
    1193           0 :             LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
    1194           0 :             pnode->fDisconnect = true;
    1195           0 :         }
    1196      188055 :         else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
    1197             :         {
    1198           0 :             LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
    1199           0 :             pnode->fDisconnect = true;
    1200           0 :         }
    1201      188055 :         else if (pnode->nPingNonceSent && pnode->m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL} < GetTime<std::chrono::microseconds>())
    1202             :         {
    1203           1 :             LogPrintf("ping timeout: %fs\n", 0.000001 * count_microseconds(GetTime<std::chrono::microseconds>() - pnode->m_ping_start.load()));
    1204           1 :             pnode->fDisconnect = true;
    1205           1 :         }
    1206      188054 :         else if (!pnode->fSuccessfullyConnected)
    1207             :         {
    1208           1 :             LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId());
    1209           1 :             pnode->fDisconnect = true;
    1210           1 :         }
    1211             :     }
    1212      503184 : }
    1213             : 
    1214      332444 : bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
    1215             : {
    1216      664896 :     for (const ListenSocket& hListenSocket : vhListenSocket) {
    1217      332452 :         recv_set.insert(hListenSocket.socket);
    1218             :     }
    1219             : 
    1220             :     {
    1221      332444 :         LOCK(cs_vNodes);
    1222      835330 :         for (CNode* pnode : vNodes)
    1223             :         {
    1224             :             // Implement the following logic:
    1225             :             // * If there is data to send, select() for sending data. As this only
    1226             :             //   happens when optimistic write failed, we choose to first drain the
    1227             :             //   write buffer in this case before receiving more. This avoids
    1228             :             //   needlessly queueing received data, if the remote peer is not themselves
    1229             :             //   receiving data. This means properly utilizing TCP flow control signalling.
    1230             :             // * Otherwise, if there is space left in the receive buffer, select() for
    1231             :             //   receiving data.
    1232             :             // * Hand off all complete messages to the processor, to be handled without
    1233             :             //   blocking here.
    1234             : 
    1235      502886 :             bool select_recv = !pnode->fPauseRecv;
    1236             :             bool select_send;
    1237             :             {
    1238      502886 :                 LOCK(pnode->cs_vSend);
    1239      502886 :                 select_send = !pnode->vSendMsg.empty();
    1240      502886 :             }
    1241             : 
    1242      502886 :             LOCK(pnode->cs_hSocket);
    1243      502886 :             if (pnode->hSocket == INVALID_SOCKET)
    1244           0 :                 continue;
    1245             : 
    1246      502886 :             error_set.insert(pnode->hSocket);
    1247      502886 :             if (select_send) {
    1248        2828 :                 send_set.insert(pnode->hSocket);
    1249        2828 :                 continue;
    1250             :             }
    1251      500058 :             if (select_recv) {
    1252      496844 :                 recv_set.insert(pnode->hSocket);
    1253      496844 :             }
    1254      502886 :         }
    1255      332444 :     }
    1256             : 
    1257      332444 :     return !recv_set.empty() || !send_set.empty() || !error_set.empty();
    1258           0 : }
    1259             : 
    1260             : #ifdef USE_POLL
    1261             : void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
    1262             : {
    1263             :     std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
    1264             :     if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
    1265             :         interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
    1266             :         return;
    1267             :     }
    1268             : 
    1269             :     std::unordered_map<SOCKET, struct pollfd> pollfds;
    1270             :     for (SOCKET socket_id : recv_select_set) {
    1271             :         pollfds[socket_id].fd = socket_id;
    1272             :         pollfds[socket_id].events |= POLLIN;
    1273             :     }
    1274             : 
    1275             :     for (SOCKET socket_id : send_select_set) {
    1276             :         pollfds[socket_id].fd = socket_id;
    1277             :         pollfds[socket_id].events |= POLLOUT;
    1278             :     }
    1279             : 
    1280             :     for (SOCKET socket_id : error_select_set) {
    1281             :         pollfds[socket_id].fd = socket_id;
    1282             :         // These flags are ignored, but we set them for clarity
    1283             :         pollfds[socket_id].events |= POLLERR|POLLHUP;
    1284             :     }
    1285             : 
    1286             :     std::vector<struct pollfd> vpollfds;
    1287             :     vpollfds.reserve(pollfds.size());
    1288             :     for (auto it : pollfds) {
    1289             :         vpollfds.push_back(std::move(it.second));
    1290             :     }
    1291             : 
    1292             :     if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
    1293             : 
    1294             :     if (interruptNet) return;
    1295             : 
    1296             :     for (struct pollfd pollfd_entry : vpollfds) {
    1297             :         if (pollfd_entry.revents & POLLIN)            recv_set.insert(pollfd_entry.fd);
    1298             :         if (pollfd_entry.revents & POLLOUT)           send_set.insert(pollfd_entry.fd);
    1299             :         if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
    1300             :     }
    1301             : }
    1302             : #else
    1303      332444 : void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
    1304             : {
    1305      332444 :     std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
    1306      332444 :     if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
    1307           0 :         interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
    1308           0 :         return;
    1309             :     }
    1310             : 
    1311             :     //
    1312             :     // Find which sockets have data to receive
    1313             :     //
    1314      332444 :     struct timeval timeout;
    1315      332444 :     timeout.tv_sec  = 0;
    1316      332444 :     timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
    1317             : 
    1318      332444 :     fd_set fdsetRecv;
    1319      332444 :     fd_set fdsetSend;
    1320      332444 :     fd_set fdsetError;
    1321      332444 :     FD_ZERO(&fdsetRecv);
    1322      332444 :     FD_ZERO(&fdsetSend);
    1323      332444 :     FD_ZERO(&fdsetError);
    1324      332444 :     SOCKET hSocketMax = 0;
    1325             : 
    1326     1161740 :     for (SOCKET hSocket : recv_select_set) {
    1327      829296 :         FD_SET(hSocket, &fdsetRecv);
    1328      829296 :         hSocketMax = std::max(hSocketMax, hSocket);
    1329      829296 :     }
    1330             : 
    1331      335272 :     for (SOCKET hSocket : send_select_set) {
    1332        2828 :         FD_SET(hSocket, &fdsetSend);
    1333        2828 :         hSocketMax = std::max(hSocketMax, hSocket);
    1334        2828 :     }
    1335             : 
    1336      835330 :     for (SOCKET hSocket : error_select_set) {
    1337      502886 :         FD_SET(hSocket, &fdsetError);
    1338      502886 :         hSocketMax = std::max(hSocketMax, hSocket);
    1339      502886 :     }
    1340             : 
    1341      332444 :     int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
    1342             : 
    1343      332444 :     if (interruptNet)
    1344         491 :         return;
    1345             : 
    1346      331953 :     if (nSelect == SOCKET_ERROR)
    1347             :     {
    1348           0 :         int nErr = WSAGetLastError();
    1349           0 :         LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
    1350           0 :         for (unsigned int i = 0; i <= hSocketMax; i++)
    1351           0 :             FD_SET(i, &fdsetRecv);
    1352           0 :         FD_ZERO(&fdsetSend);
    1353           0 :         FD_ZERO(&fdsetError);
    1354           0 :         if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
    1355           0 :             return;
    1356           0 :     }
    1357             : 
    1358     1160344 :     for (SOCKET hSocket : recv_select_set) {
    1359      828391 :         if (FD_ISSET(hSocket, &fdsetRecv)) {
    1360      105448 :             recv_set.insert(hSocket);
    1361      105448 :         }
    1362      828391 :     }
    1363             : 
    1364      334781 :     for (SOCKET hSocket : send_select_set) {
    1365        2828 :         if (FD_ISSET(hSocket, &fdsetSend)) {
    1366          94 :             send_set.insert(hSocket);
    1367          94 :         }
    1368        2828 :     }
    1369             : 
    1370      834426 :     for (SOCKET hSocket : error_select_set) {
    1371      502473 :         if (FD_ISSET(hSocket, &fdsetError)) {
    1372           0 :             error_set.insert(hSocket);
    1373           0 :         }
    1374      502473 :     }
    1375      332444 : }
    1376             : #endif
    1377             : 
    1378      332444 : void CConnman::SocketHandler()
    1379             : {
    1380      332444 :     std::set<SOCKET> recv_set, send_set, error_set;
    1381      332444 :     SocketEvents(recv_set, send_set, error_set);
    1382             : 
    1383      332444 :     if (interruptNet) return;
    1384             : 
    1385             :     //
    1386             :     // Accept new connections
    1387             :     //
    1388      663913 :     for (const ListenSocket& hListenSocket : vhListenSocket)
    1389             :     {
    1390      331960 :         if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
    1391             :         {
    1392         466 :             AcceptConnection(hListenSocket);
    1393             :         }
    1394             :     }
    1395             : 
    1396             :     //
    1397             :     // Service each socket
    1398             :     //
    1399      331953 :     std::vector<CNode*> vNodesCopy;
    1400             :     {
    1401      331953 :         LOCK(cs_vNodes);
    1402      331953 :         vNodesCopy = vNodes;
    1403      835139 :         for (CNode* pnode : vNodesCopy)
    1404      503186 :             pnode->AddRef();
    1405      331953 :     }
    1406      835139 :     for (CNode* pnode : vNodesCopy)
    1407             :     {
    1408      503186 :         if (interruptNet)
    1409           0 :             return;
    1410             : 
    1411             :         //
    1412             :         // Receive
    1413             :         //
    1414             :         bool recvSet = false;
    1415             :         bool sendSet = false;
    1416             :         bool errorSet = false;
    1417             :         {
    1418      503186 :             LOCK(pnode->cs_hSocket);
    1419      503186 :             if (pnode->hSocket == INVALID_SOCKET)
    1420           2 :                 continue;
    1421      503184 :             recvSet = recv_set.count(pnode->hSocket) > 0;
    1422      503184 :             sendSet = send_set.count(pnode->hSocket) > 0;
    1423      503184 :             errorSet = error_set.count(pnode->hSocket) > 0;
    1424      503186 :         }
    1425      503184 :         if (recvSet || errorSet)
    1426             :         {
    1427             :             // typical socket buffer is 8K-64K
    1428      104982 :             char pchBuf[0x10000];
    1429             :             int nBytes = 0;
    1430             :             {
    1431      104982 :                 LOCK(pnode->cs_hSocket);
    1432      104982 :                 if (pnode->hSocket == INVALID_SOCKET)
    1433           0 :                     continue;
    1434      104982 :                 nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
    1435      104982 :             }
    1436      104982 :             if (nBytes > 0)
    1437             :             {
    1438      104828 :                 bool notify = false;
    1439      104828 :                 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
    1440           1 :                     pnode->CloseSocketDisconnect();
    1441      104828 :                 RecordBytesRecv(nBytes);
    1442      104828 :                 if (notify) {
    1443             :                     size_t nSizeAdded = 0;
    1444       77821 :                     auto it(pnode->vRecvMsg.begin());
    1445      164659 :                     for (; it != pnode->vRecvMsg.end(); ++it) {
    1446             :                         // vRecvMsg contains only completed CNetMessage
    1447             :                         // the single possible partially deserialized message are held by TransportDeserializer
    1448       86838 :                         nSizeAdded += it->m_raw_message_size;
    1449             :                     }
    1450             :                     {
    1451       77821 :                         LOCK(pnode->cs_vProcessMsg);
    1452       77821 :                         pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
    1453       77821 :                         pnode->nProcessQueueSize += nSizeAdded;
    1454       77821 :                         pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
    1455       77821 :                     }
    1456       77821 :                     WakeMessageHandler();
    1457       77821 :                 }
    1458      104828 :             }
    1459         154 :             else if (nBytes == 0)
    1460             :             {
    1461             :                 // socket closed gracefully
    1462         144 :                 if (!pnode->fDisconnect) {
    1463         144 :                     LogPrint(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
    1464             :                 }
    1465         144 :                 pnode->CloseSocketDisconnect();
    1466             :             }
    1467          10 :             else if (nBytes < 0)
    1468             :             {
    1469             :                 // error
    1470          10 :                 int nErr = WSAGetLastError();
    1471          10 :                 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
    1472             :                 {
    1473          10 :                     if (!pnode->fDisconnect) {
    1474          10 :                         LogPrint(BCLog::NET, "socket recv error for peer=%d: %s\n", pnode->GetId(), NetworkErrorString(nErr));
    1475             :                     }
    1476          10 :                     pnode->CloseSocketDisconnect();
    1477             :                 }
    1478          10 :             }
    1479      104982 :         }
    1480             : 
    1481             :         //
    1482             :         // Send
    1483             :         //
    1484      503184 :         if (sendSet)
    1485             :         {
    1486          94 :             LOCK(pnode->cs_vSend);
    1487          94 :             size_t nBytes = SocketSendData(pnode);
    1488          94 :             if (nBytes) {
    1489          94 :                 RecordBytesSent(nBytes);
    1490             :             }
    1491          94 :         }
    1492             : 
    1493      503184 :         InactivityCheck(pnode);
    1494     1006368 :     }
    1495             :     {
    1496      331953 :         LOCK(cs_vNodes);
    1497      835139 :         for (CNode* pnode : vNodesCopy)
    1498      503186 :             pnode->Release();
    1499      331953 :     }
    1500      332444 : }
    1501             : 
    1502         492 : void CConnman::ThreadSocketHandler()
    1503             : {
    1504      332936 :     while (!interruptNet)
    1505             :     {
    1506      332444 :         DisconnectNodes();
    1507      332444 :         NotifyNumConnectionsChanged();
    1508      332444 :         SocketHandler();
    1509             :     }
    1510         492 : }
    1511             : 
    1512      113144 : void CConnman::WakeMessageHandler()
    1513             : {
    1514             :     {
    1515      113144 :         LOCK(mutexMsgProc);
    1516      113144 :         fMsgProcWake = true;
    1517      113144 :     }
    1518      113144 :     condMsgProc.notify_one();
    1519      113144 : }
    1520             : 
    1521             : 
    1522             : 
    1523             : 
    1524             : 
    1525             : 
    1526             : #ifdef USE_UPNP
    1527         640 : static CThreadInterrupt g_upnp_interrupt;
    1528         640 : static std::thread g_upnp_thread;
    1529           0 : static void ThreadMapPort()
    1530             : {
    1531           0 :     std::string port = strprintf("%u", GetListenPort());
    1532             :     const char * multicastif = nullptr;
    1533             :     const char * minissdpdpath = nullptr;
    1534             :     struct UPNPDev * devlist = nullptr;
    1535           0 :     char lanaddr[64];
    1536             : 
    1537           0 :     int error = 0;
    1538             : #if MINIUPNPC_API_VERSION < 14
    1539             :     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
    1540             : #else
    1541           0 :     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
    1542             : #endif
    1543             : 
    1544           0 :     struct UPNPUrls urls;
    1545           0 :     struct IGDdatas data;
    1546           0 :     int r;
    1547             : 
    1548           0 :     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
    1549           0 :     if (r == 1)
    1550             :     {
    1551           0 :         if (fDiscover) {
    1552           0 :             char externalIPAddress[40];
    1553           0 :             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
    1554           0 :             if (r != UPNPCOMMAND_SUCCESS) {
    1555           0 :                 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
    1556             :             } else {
    1557           0 :                 if (externalIPAddress[0]) {
    1558           0 :                     CNetAddr resolved;
    1559           0 :                     if (LookupHost(externalIPAddress, resolved, false)) {
    1560           0 :                         LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString());
    1561           0 :                         AddLocal(resolved, LOCAL_UPNP);
    1562             :                     }
    1563           0 :                 } else {
    1564           0 :                     LogPrintf("UPnP: GetExternalIPAddress failed.\n");
    1565             :                 }
    1566             :             }
    1567           0 :         }
    1568             : 
    1569           0 :         std::string strDesc = PACKAGE_NAME " " + FormatFullVersion();
    1570             : 
    1571           0 :         do {
    1572           0 :             r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
    1573             : 
    1574           0 :             if (r != UPNPCOMMAND_SUCCESS) {
    1575           0 :                 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
    1576           0 :             } else {
    1577           0 :                 LogPrintf("UPnP Port Mapping successful.\n");
    1578             :             }
    1579           0 :         } while (g_upnp_interrupt.sleep_for(std::chrono::minutes(20)));
    1580             : 
    1581           0 :         r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
    1582           0 :         LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
    1583           0 :         freeUPNPDevlist(devlist); devlist = nullptr;
    1584           0 :         FreeUPNPUrls(&urls);
    1585           0 :     } else {
    1586           0 :         LogPrintf("No valid UPnP IGDs found\n");
    1587           0 :         freeUPNPDevlist(devlist); devlist = nullptr;
    1588           0 :         if (r != 0)
    1589           0 :             FreeUPNPUrls(&urls);
    1590             :     }
    1591           0 : }
    1592             : 
    1593           0 : void StartMapPort()
    1594             : {
    1595           0 :     if (!g_upnp_thread.joinable()) {
    1596           0 :         assert(!g_upnp_interrupt);
    1597           0 :         g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
    1598           0 :     }
    1599           0 : }
    1600             : 
    1601         529 : void InterruptMapPort()
    1602             : {
    1603         529 :     if(g_upnp_thread.joinable()) {
    1604           0 :         g_upnp_interrupt();
    1605           0 :     }
    1606         529 : }
    1607             : 
    1608         529 : void StopMapPort()
    1609             : {
    1610         529 :     if(g_upnp_thread.joinable()) {
    1611           0 :         g_upnp_thread.join();
    1612           0 :         g_upnp_interrupt.reset();
    1613           0 :     }
    1614         529 : }
    1615             : 
    1616             : #else
    1617             : void StartMapPort()
    1618             : {
    1619             :     // Intentionally left blank.
    1620             : }
    1621             : void InterruptMapPort()
    1622             : {
    1623             :     // Intentionally left blank.
    1624             : }
    1625             : void StopMapPort()
    1626             : {
    1627             :     // Intentionally left blank.
    1628             : }
    1629             : #endif
    1630             : 
    1631             : 
    1632             : 
    1633             : 
    1634             : 
    1635             : 
    1636           0 : void CConnman::ThreadDNSAddressSeed()
    1637             : {
    1638           0 :     FastRandomContext rng;
    1639           0 :     std::vector<std::string> seeds = Params().DNSSeeds();
    1640           0 :     Shuffle(seeds.begin(), seeds.end(), rng);
    1641             :     int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
    1642           0 :     int found = 0;
    1643             : 
    1644           0 :     if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
    1645             :         // When -forcednsseed is provided, query all.
    1646           0 :         seeds_right_now = seeds.size();
    1647           0 :     } else if (addrman.size() == 0) {
    1648             :         // If we have no known peers, query all.
    1649             :         // This will occur on the first run, or if peers.dat has been
    1650             :         // deleted.
    1651           0 :         seeds_right_now = seeds.size();
    1652           0 :     }
    1653             : 
    1654             :     // goal: only query DNS seed if address need is acute
    1655             :     // * If we have a reasonable number of peers in addrman, spend
    1656             :     //   some time trying them first. This improves user privacy by
    1657             :     //   creating fewer identifying DNS requests, reduces trust by
    1658             :     //   giving seeds less influence on the network topology, and
    1659             :     //   reduces traffic to the seeds.
    1660             :     // * When querying DNS seeds query a few at once, this ensures
    1661             :     //   that we don't give DNS seeds the ability to eclipse nodes
    1662             :     //   that query them.
    1663             :     // * If we continue having problems, eventually query all the
    1664             :     //   DNS seeds, and if that fails too, also try the fixed seeds.
    1665             :     //   (done in ThreadOpenConnections)
    1666           0 :     const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
    1667             : 
    1668           0 :     for (const std::string& seed : seeds) {
    1669           0 :         if (seeds_right_now == 0) {
    1670           0 :             seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
    1671             : 
    1672           0 :             if (addrman.size() > 0) {
    1673           0 :                 LogPrintf("Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
    1674           0 :                 std::chrono::seconds to_wait = seeds_wait_time;
    1675           0 :                 while (to_wait.count() > 0) {
    1676             :                     // if sleeping for the MANY_PEERS interval, wake up
    1677             :                     // early to see if we have enough peers and can stop
    1678             :                     // this thread entirely freeing up its resources
    1679           0 :                     std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
    1680           0 :                     if (!interruptNet.sleep_for(w)) return;
    1681           0 :                     to_wait -= w;
    1682             : 
    1683             :                     int nRelevant = 0;
    1684             :                     {
    1685           0 :                         LOCK(cs_vNodes);
    1686           0 :                         for (const CNode* pnode : vNodes) {
    1687           0 :                             if (pnode->fSuccessfullyConnected && pnode->IsOutboundOrBlockRelayConn()) ++nRelevant;
    1688             :                         }
    1689           0 :                     }
    1690           0 :                     if (nRelevant >= 2) {
    1691           0 :                         if (found > 0) {
    1692           0 :                             LogPrintf("%d addresses found from DNS seeds\n", found);
    1693           0 :                             LogPrintf("P2P peers available. Finished DNS seeding.\n");
    1694             :                         } else {
    1695           0 :                             LogPrintf("P2P peers available. Skipped DNS seeding.\n");
    1696             :                         }
    1697           0 :                         return;
    1698             :                     }
    1699           0 :                 }
    1700           0 :             }
    1701             :         }
    1702             : 
    1703           0 :         if (interruptNet) return;
    1704             : 
    1705             :         // hold off on querying seeds if P2P network deactivated
    1706           0 :         if (!fNetworkActive) {
    1707           0 :             LogPrintf("Waiting for network to be reactivated before querying DNS seeds.\n");
    1708             :             do {
    1709           0 :                 if (!interruptNet.sleep_for(std::chrono::seconds{1})) return;
    1710           0 :             } while (!fNetworkActive);
    1711             :         }
    1712             : 
    1713           0 :         LogPrintf("Loading addresses from DNS seed %s\n", seed);
    1714           0 :         if (HaveNameProxy()) {
    1715           0 :             AddAddrFetch(seed);
    1716             :         } else {
    1717           0 :             std::vector<CNetAddr> vIPs;
    1718           0 :             std::vector<CAddress> vAdd;
    1719           0 :             ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
    1720           0 :             std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
    1721           0 :             CNetAddr resolveSource;
    1722           0 :             if (!resolveSource.SetInternal(host)) {
    1723           0 :                 continue;
    1724             :             }
    1725             :             unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
    1726           0 :             if (LookupHost(host, vIPs, nMaxIPs, true)) {
    1727           0 :                 for (const CNetAddr& ip : vIPs) {
    1728             :                     int nOneDay = 24*3600;
    1729           0 :                     CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
    1730           0 :                     addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
    1731           0 :                     vAdd.push_back(addr);
    1732           0 :                     found++;
    1733           0 :                 }
    1734           0 :                 addrman.Add(vAdd, resolveSource);
    1735             :             } else {
    1736             :                 // We now avoid directly using results from DNS Seeds which do not support service bit filtering,
    1737             :                 // instead using them as a addrfetch to get nodes with our desired service bits.
    1738           0 :                 AddAddrFetch(seed);
    1739             :             }
    1740           0 :         }
    1741           0 :         --seeds_right_now;
    1742           0 :     }
    1743           0 :     LogPrintf("%d addresses found from DNS seeds\n", found);
    1744           0 : }
    1745             : 
    1746         799 : void CConnman::DumpAddresses()
    1747             : {
    1748         799 :     int64_t nStart = GetTimeMillis();
    1749             : 
    1750         799 :     CAddrDB adb;
    1751         799 :     adb.Write(addrman);
    1752             : 
    1753         799 :     LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat  %dms\n",
    1754             :            addrman.size(), GetTimeMillis() - nStart);
    1755         799 : }
    1756             : 
    1757       25952 : void CConnman::ProcessAddrFetch()
    1758             : {
    1759       25952 :     std::string strDest;
    1760             :     {
    1761       25952 :         LOCK(m_addr_fetches_mutex);
    1762       25952 :         if (m_addr_fetches.empty())
    1763       25952 :             return;
    1764           0 :         strDest = m_addr_fetches.front();
    1765           0 :         m_addr_fetches.pop_front();
    1766       25952 :     }
    1767           0 :     CAddress addr;
    1768           0 :     CSemaphoreGrant grant(*semOutbound, true);
    1769           0 :     if (grant) {
    1770           0 :         OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
    1771             :     }
    1772       25952 : }
    1773             : 
    1774          92 : bool CConnman::GetTryNewOutboundPeer()
    1775             : {
    1776          92 :     return m_try_another_outbound_peer;
    1777             : }
    1778             : 
    1779         613 : void CConnman::SetTryNewOutboundPeer(bool flag)
    1780             : {
    1781         613 :     m_try_another_outbound_peer = flag;
    1782         613 :     LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
    1783         613 : }
    1784             : 
    1785             : // Return the number of peers we have over our outbound connection limit
    1786             : // Exclude peers that are marked for disconnect, or are going to be
    1787             : // disconnected soon (eg one-shots and feelers)
    1788             : // Also exclude peers that haven't finished initial connection handshake yet
    1789             : // (so that we don't decide we're over our desired connection limit, and then
    1790             : // evict some peer that has finished the handshake)
    1791         202 : int CConnman::GetExtraOutboundCount()
    1792             : {
    1793         551 :     int nOutbound = 0;
    1794             :     {
    1795         202 :         LOCK(cs_vNodes);
    1796         551 :         for (const CNode* pnode : vNodes) {
    1797         349 :             if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsOutboundOrBlockRelayConn()) {
    1798          34 :                 ++nOutbound;
    1799          34 :             }
    1800             :         }
    1801         202 :     }
    1802         202 :     return std::max(nOutbound - m_max_outbound_full_relay - m_max_outbound_block_relay, 0);
    1803           0 : }
    1804             : 
    1805         492 : void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
    1806             : {
    1807             :     // Connect to specific addresses
    1808         492 :     if (!connect.empty())
    1809             :     {
    1810           1 :         for (int64_t nLoop = 0;; nLoop++)
    1811             :         {
    1812           1 :             ProcessAddrFetch();
    1813           2 :             for (const std::string& strAddr : connect)
    1814             :             {
    1815           1 :                 CAddress addr(CService(), NODE_NONE);
    1816           1 :                 OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
    1817           1 :                 for (int i = 0; i < 10 && i < nLoop; i++)
    1818             :                 {
    1819           0 :                     if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
    1820           0 :                         return;
    1821             :                 }
    1822           1 :             }
    1823           1 :             if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
    1824           1 :                 return;
    1825             :         }
    1826             :     }
    1827             : 
    1828             :     // Initiate network connections
    1829         491 :     int64_t nStart = GetTime();
    1830             : 
    1831             :     // Minimum time before next feeler connection (in microseconds).
    1832       25954 :     int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
    1833       25954 :     while (!interruptNet)
    1834             :     {
    1835       25951 :         ProcessAddrFetch();
    1836             : 
    1837       25951 :         if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
    1838         488 :             return;
    1839             : 
    1840       25463 :         CSemaphoreGrant grant(*semOutbound);
    1841       25463 :         if (interruptNet)
    1842           0 :             return;
    1843             : 
    1844             :         // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
    1845             :         // Note that we only do this if we started with an empty peers.dat,
    1846             :         // (in which case we will query DNS seeds immediately) *and* the DNS
    1847             :         // seeds have not returned any results.
    1848       25463 :         if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
    1849             :             static bool done = false;
    1850       10582 :             if (!done) {
    1851          63 :                 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
    1852          63 :                 CNetAddr local;
    1853          63 :                 local.SetInternal("fixedseeds");
    1854          63 :                 addrman.Add(convertSeed6(Params().FixedSeeds()), local);
    1855          63 :                 done = true;
    1856          63 :             }
    1857             :         }
    1858             : 
    1859             :         //
    1860             :         // Choose an address to connect to based on most recently seen
    1861             :         //
    1862       25463 :         CAddress addrConnect;
    1863             : 
    1864             :         // Only connect out to one peer per network group (/16 for IPv4).
    1865             :         int nOutboundFullRelay = 0;
    1866             :         int nOutboundBlockRelay = 0;
    1867       25463 :         std::set<std::vector<unsigned char> > setConnected;
    1868             : 
    1869             :         {
    1870       25463 :             LOCK(cs_vNodes);
    1871       62288 :             for (const CNode* pnode : vNodes) {
    1872       36825 :                 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
    1873       36825 :                 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
    1874             : 
    1875             :                 // Netgroups for inbound and manual peers are not excluded because our goal here
    1876             :                 // is to not use multiple of our limited outbound slots on a single netgroup
    1877             :                 // but inbound and manual peers do not use our outbound slots. Inbound peers
    1878             :                 // also have the added issue that they could be attacker controlled and used
    1879             :                 // to prevent us from connecting to particular hosts if we used them here.
    1880       36825 :                 switch (pnode->m_conn_type) {
    1881             :                     case ConnectionType::INBOUND:
    1882             :                     case ConnectionType::MANUAL:
    1883             :                         break;
    1884             :                     case ConnectionType::OUTBOUND_FULL_RELAY:
    1885             :                     case ConnectionType::BLOCK_RELAY:
    1886             :                     case ConnectionType::ADDR_FETCH:
    1887             :                     case ConnectionType::FEELER:
    1888           0 :                         setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
    1889           0 :                 } // no default case, so the compiler can warn about missing cases
    1890             :             }
    1891       25463 :         }
    1892             : 
    1893             :         ConnectionType conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
    1894       25463 :         int64_t nTime = GetTimeMicros();
    1895             :         bool fFeeler = false;
    1896             : 
    1897             :         // Determine what type of connection to open. Opening
    1898             :         // OUTBOUND_FULL_RELAY connections gets the highest priority until we
    1899             :         // meet our full-relay capacity. Then we open BLOCK_RELAY connection
    1900             :         // until we hit our block-relay-only peer limit.
    1901             :         // GetTryNewOutboundPeer() gets set when a stale tip is detected, so we
    1902             :         // try opening an additional OUTBOUND_FULL_RELAY connection. If none of
    1903             :         // these conditions are met, check the nNextFeeler timer to decide if
    1904             :         // we should open a FEELER.
    1905             : 
    1906       25463 :         if (nOutboundFullRelay < m_max_outbound_full_relay) {
    1907             :             // OUTBOUND_FULL_RELAY
    1908           0 :         } else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
    1909             :             conn_type = ConnectionType::BLOCK_RELAY;
    1910           0 :         } else if (GetTryNewOutboundPeer()) {
    1911             :             // OUTBOUND_FULL_RELAY
    1912           0 :         } else if (nTime > nNextFeeler) {
    1913           0 :             nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
    1914             :             conn_type = ConnectionType::FEELER;
    1915             :             fFeeler = true;
    1916             :         } else {
    1917             :             // skip to next iteration of while loop
    1918           0 :             continue;
    1919             :         }
    1920             : 
    1921       25463 :         addrman.ResolveCollisions();
    1922             : 
    1923       25463 :         int64_t nANow = GetAdjustedTime();
    1924       25776 :         int nTries = 0;
    1925       25776 :         while (!interruptNet)
    1926             :         {
    1927       25775 :             CAddrInfo addr = addrman.SelectTriedCollision();
    1928             : 
    1929             :             // SelectTriedCollision returns an invalid address if it is empty.
    1930       25775 :             if (!fFeeler || !addr.IsValid()) {
    1931       25775 :                 addr = addrman.Select(fFeeler);
    1932       25775 :             }
    1933             : 
    1934             :             // Require outbound connections, other than feelers, to be to distinct network groups
    1935       25775 :             if (!fFeeler && setConnected.count(addr.GetGroup(addrman.m_asmap))) {
    1936           0 :                 break;
    1937             :             }
    1938             : 
    1939             :             // if we selected an invalid or local address, restart
    1940       25775 :             if (!addr.IsValid() || IsLocal(addr)) {
    1941       25456 :                 break;
    1942             :             }
    1943             : 
    1944             :             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
    1945             :             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
    1946             :             // already-connected network ranges, ...) before trying new addrman addresses.
    1947         319 :             nTries++;
    1948         319 :             if (nTries > 100)
    1949           0 :                 break;
    1950             : 
    1951         319 :             if (!IsReachable(addr))
    1952           0 :                 continue;
    1953             : 
    1954             :             // only consider very recently tried nodes after 30 failed attempts
    1955         319 :             if (nANow - addr.nLastTry < 600 && nTries < 30)
    1956           0 :                 continue;
    1957             : 
    1958             :             // for non-feelers, require all the services we'll want,
    1959             :             // for feelers, only require they be a full node (only because most
    1960             :             // SPV clients don't have a good address DB available)
    1961         319 :             if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
    1962           0 :                 continue;
    1963         319 :             } else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
    1964           0 :                 continue;
    1965             :             }
    1966             : 
    1967             :             // do not allow non-default ports, unless after 50 invalid addresses selected already
    1968         319 :             if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
    1969         313 :                 continue;
    1970             : 
    1971           6 :             addrConnect = addr;
    1972           6 :             break;
    1973       25775 :         }
    1974             : 
    1975       25463 :         if (addrConnect.IsValid()) {
    1976             : 
    1977           6 :             if (fFeeler) {
    1978             :                 // Add small amount of random noise before connection to avoid synchronization.
    1979           0 :                 int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
    1980           0 :                 if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
    1981           0 :                     return;
    1982           0 :                 LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
    1983           0 :             }
    1984             : 
    1985           6 :             OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
    1986           6 :         }
    1987       50926 :     }
    1988         495 : }
    1989             : 
    1990        6743 : std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
    1991             : {
    1992        6743 :     std::vector<AddedNodeInfo> ret;
    1993             : 
    1994        6743 :     std::list<std::string> lAddresses(0);
    1995             :     {
    1996        6743 :         LOCK(cs_vAddedNodes);
    1997        6743 :         ret.reserve(vAddedNodes.size());
    1998        6743 :         std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
    1999        6743 :     }
    2000             : 
    2001             : 
    2002             :     // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
    2003        6743 :     std::map<CService, bool> mapConnected;
    2004        6743 :     std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
    2005             :     {
    2006        6743 :         LOCK(cs_vNodes);
    2007       15994 :         for (const CNode* pnode : vNodes) {
    2008        9251 :             if (pnode->addr.IsValid()) {
    2009        9251 :                 mapConnected[pnode->addr] = pnode->IsInboundConn();
    2010        9251 :             }
    2011        9251 :             std::string addrName = pnode->GetAddrName();
    2012        9251 :             if (!addrName.empty()) {
    2013        9251 :                 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(), static_cast<const CService&>(pnode->addr));
    2014        9251 :             }
    2015        9251 :         }
    2016        6743 :     }
    2017             : 
    2018        6745 :     for (const std::string& strAddNode : lAddresses) {
    2019           2 :         CService service(LookupNumeric(strAddNode, Params().GetDefaultPort()));
    2020           2 :         AddedNodeInfo addedNode{strAddNode, CService(), false, false};
    2021           2 :         if (service.IsValid()) {
    2022             :             // strAddNode is an IP:port
    2023           1 :             auto it = mapConnected.find(service);
    2024           1 :             if (it != mapConnected.end()) {
    2025           0 :                 addedNode.resolvedAddress = service;
    2026           0 :                 addedNode.fConnected = true;
    2027           0 :                 addedNode.fInbound = it->second;
    2028           0 :             }
    2029           1 :         } else {
    2030             :             // strAddNode is a name
    2031           1 :             auto it = mapConnectedByName.find(strAddNode);
    2032           1 :             if (it != mapConnectedByName.end()) {
    2033           0 :                 addedNode.resolvedAddress = it->second.second;
    2034           0 :                 addedNode.fConnected = true;
    2035           0 :                 addedNode.fInbound = it->second.first;
    2036           0 :             }
    2037           1 :         }
    2038           2 :         ret.emplace_back(std::move(addedNode));
    2039           2 :     }
    2040             : 
    2041             :     return ret;
    2042        6743 : }
    2043             : 
    2044         492 : void CConnman::ThreadOpenAddedConnections()
    2045             : {
    2046         492 :     while (true)
    2047             :     {
    2048        6739 :         CSemaphoreGrant grant(*semAddnode);
    2049        6739 :         std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
    2050       13478 :         bool tried = false;
    2051        6740 :         for (const AddedNodeInfo& info : vInfo) {
    2052           1 :             if (!info.fConnected) {
    2053           1 :                 if (!grant.TryAcquire()) {
    2054             :                     // If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
    2055             :                     // the addednodeinfo state might change.
    2056           0 :                     break;
    2057             :                 }
    2058             :                 tried = true;
    2059           1 :                 CAddress addr(CService(), NODE_NONE);
    2060           1 :                 OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
    2061           1 :                 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
    2062           1 :                     return;
    2063           1 :             }
    2064           0 :         }
    2065             :         // Retry every 60 seconds if a connection was attempted, otherwise two seconds
    2066        6738 :         if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
    2067         491 :             return;
    2068        6739 :     }
    2069         492 : }
    2070             : 
    2071             : // if successful, this moves the passed grant to the constructed node
    2072         258 : void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
    2073             : {
    2074         258 :     assert(conn_type != ConnectionType::INBOUND);
    2075             : 
    2076             :     //
    2077             :     // Initiate outbound network connection
    2078             :     //
    2079         258 :     if (interruptNet) {
    2080             :         return;
    2081             :     }
    2082         258 :     if (!fNetworkActive) {
    2083             :         return;
    2084             :     }
    2085         258 :     if (!pszDest) {
    2086           6 :         bool banned_or_discouraged = m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect));
    2087           6 :         if (IsLocal(addrConnect) || FindNode(static_cast<CNetAddr>(addrConnect)) || banned_or_discouraged || FindNode(addrConnect.ToStringIPPort())) {
    2088           0 :             return;
    2089             :         }
    2090         258 :     } else if (FindNode(std::string(pszDest)))
    2091             :         return;
    2092             : 
    2093         256 :     CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
    2094             : 
    2095         256 :     if (!pnode)
    2096           8 :         return;
    2097         248 :     if (grantOutbound)
    2098           0 :         grantOutbound->MoveTo(pnode->grantOutbound);
    2099             : 
    2100         248 :     m_msgproc->InitializeNode(pnode);
    2101             :     {
    2102         248 :         LOCK(cs_vNodes);
    2103         248 :         vNodes.push_back(pnode);
    2104         248 :     }
    2105         258 : }
    2106             : 
    2107         492 : void CConnman::ThreadMessageHandler()
    2108             : {
    2109      195132 :     while (!flagInterruptMsgProc)
    2110             :     {
    2111      194645 :         std::vector<CNode*> vNodesCopy;
    2112             :         {
    2113      194645 :             LOCK(cs_vNodes);
    2114      194645 :             vNodesCopy = vNodes;
    2115      483994 :             for (CNode* pnode : vNodesCopy) {
    2116      289349 :                 pnode->AddRef();
    2117             :             }
    2118      194645 :         }
    2119             : 
    2120      678632 :         bool fMoreWork = false;
    2121             : 
    2122      483992 :         for (CNode* pnode : vNodesCopy)
    2123             :         {
    2124      289347 :             if (pnode->fDisconnect)
    2125          14 :                 continue;
    2126             : 
    2127             :             // Receive messages
    2128      289333 :             bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
    2129      289333 :             fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
    2130      289333 :             if (flagInterruptMsgProc)
    2131           2 :                 return;
    2132             :             // Send messages
    2133             :             {
    2134      289331 :                 LOCK(pnode->cs_sendProcessing);
    2135      289331 :                 m_msgproc->SendMessages(pnode);
    2136      289331 :             }
    2137             : 
    2138      289331 :             if (flagInterruptMsgProc)
    2139           3 :                 return;
    2140      578656 :         }
    2141             : 
    2142             :         {
    2143      194640 :             LOCK(cs_vNodes);
    2144      483981 :             for (CNode* pnode : vNodesCopy)
    2145      289341 :                 pnode->Release();
    2146      194640 :         }
    2147             : 
    2148      194640 :         WAIT_LOCK(mutexMsgProc, lock);
    2149      194640 :         if (!fMoreWork) {
    2150      463861 :             condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this]() EXCLUSIVE_LOCKS_REQUIRED(mutexMsgProc) { return fMsgProcWake; });
    2151      158273 :         }
    2152      194640 :         fMsgProcWake = false;
    2153      194645 :     }
    2154         492 : }
    2155             : 
    2156         493 : bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions)
    2157             : {
    2158         493 :     int nOne = 1;
    2159             : 
    2160             :     // Create socket for listening for incoming connections
    2161         493 :     struct sockaddr_storage sockaddr;
    2162         493 :     socklen_t len = sizeof(sockaddr);
    2163         493 :     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
    2164             :     {
    2165           0 :         strError = strprintf(Untranslated("Error: Bind address family for %s not supported"), addrBind.ToString());
    2166           0 :         LogPrintf("%s\n", strError.original);
    2167           0 :         return false;
    2168             :     }
    2169             : 
    2170         493 :     SOCKET hListenSocket = CreateSocket(addrBind);
    2171         493 :     if (hListenSocket == INVALID_SOCKET)
    2172             :     {
    2173           0 :         strError = strprintf(Untranslated("Error: Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError()));
    2174           0 :         LogPrintf("%s\n", strError.original);
    2175           0 :         return false;
    2176             :     }
    2177             : 
    2178             :     // Allow binding if the port is still in TIME_WAIT state after
    2179             :     // the program was closed and restarted.
    2180         493 :     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int));
    2181             : 
    2182             :     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
    2183             :     // and enable it by default or not. Try to enable it, if possible.
    2184         493 :     if (addrBind.IsIPv6()) {
    2185             : #ifdef IPV6_V6ONLY
    2186           1 :         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
    2187             : #endif
    2188             : #ifdef WIN32
    2189             :         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
    2190             :         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
    2191             : #endif
    2192           1 :     }
    2193             : 
    2194         493 :     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
    2195             :     {
    2196           0 :         int nErr = WSAGetLastError();
    2197           0 :         if (nErr == WSAEADDRINUSE)
    2198           0 :             strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
    2199             :         else
    2200           0 :             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
    2201           0 :         LogPrintf("%s\n", strError.original);
    2202           0 :         CloseSocket(hListenSocket);
    2203             :         return false;
    2204           0 :     }
    2205         493 :     LogPrintf("Bound to %s\n", addrBind.ToString());
    2206             : 
    2207             :     // Listen for incoming connections
    2208         493 :     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
    2209             :     {
    2210           0 :         strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
    2211           0 :         LogPrintf("%s\n", strError.original);
    2212           0 :         CloseSocket(hListenSocket);
    2213           0 :         return false;
    2214             :     }
    2215             : 
    2216         493 :     vhListenSocket.push_back(ListenSocket(hListenSocket, permissions));
    2217             : 
    2218         493 :     if (addrBind.IsRoutable() && fDiscover && (permissions & PF_NOBAN) == 0)
    2219           0 :         AddLocal(addrBind, LOCAL_BIND);
    2220             : 
    2221         493 :     return true;
    2222         493 : }
    2223             : 
    2224         495 : void Discover()
    2225             : {
    2226         495 :     if (!fDiscover)
    2227             :         return;
    2228             : 
    2229             : #ifdef WIN32
    2230             :     // Get local host IP
    2231             :     char pszHostName[256] = "";
    2232             :     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
    2233             :     {
    2234             :         std::vector<CNetAddr> vaddr;
    2235             :         if (LookupHost(pszHostName, vaddr, 0, true))
    2236             :         {
    2237             :             for (const CNetAddr &addr : vaddr)
    2238             :             {
    2239             :                 if (AddLocal(addr, LOCAL_IF))
    2240             :                     LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
    2241             :             }
    2242             :         }
    2243             :     }
    2244             : #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
    2245             :     // Get local host ip
    2246           0 :     struct ifaddrs* myaddrs;
    2247           0 :     if (getifaddrs(&myaddrs) == 0)
    2248             :     {
    2249           0 :         for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
    2250             :         {
    2251           0 :             if (ifa->ifa_addr == nullptr) continue;
    2252           0 :             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
    2253           0 :             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
    2254           0 :             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
    2255           0 :             if (ifa->ifa_addr->sa_family == AF_INET)
    2256             :             {
    2257           0 :                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
    2258           0 :                 CNetAddr addr(s4->sin_addr);
    2259           0 :                 if (AddLocal(addr, LOCAL_IF))
    2260           0 :                     LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
    2261           0 :             }
    2262           0 :             else if (ifa->ifa_addr->sa_family == AF_INET6)
    2263             :             {
    2264           0 :                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
    2265           0 :                 CNetAddr addr(s6->sin6_addr);
    2266           0 :                 if (AddLocal(addr, LOCAL_IF))
    2267           0 :                     LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
    2268           0 :             }
    2269             :         }
    2270           0 :         freeifaddrs(myaddrs);
    2271           0 :     }
    2272             : #endif
    2273         495 : }
    2274             : 
    2275         615 : void CConnman::SetNetworkActive(bool active)
    2276             : {
    2277         615 :     LogPrintf("%s: %s\n", __func__, active);
    2278             : 
    2279         615 :     if (fNetworkActive == active) {
    2280             :         return;
    2281             :     }
    2282             : 
    2283           8 :     fNetworkActive = active;
    2284             : 
    2285           8 :     uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
    2286         615 : }
    2287             : 
    2288        1219 : CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, bool network_active)
    2289         610 :     : nSeed0(nSeed0In), nSeed1(nSeed1In)
    2290         609 : {
    2291         610 :     SetTryNewOutboundPeer(false);
    2292             : 
    2293         610 :     Options connOptions;
    2294         610 :     Init(connOptions);
    2295         610 :     SetNetworkActive(network_active);
    2296        1219 : }
    2297             : 
    2298         713 : NodeId CConnman::GetNewNodeId()
    2299             : {
    2300         713 :     return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
    2301             : }
    2302             : 
    2303             : 
    2304         493 : bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
    2305         493 :     if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
    2306           0 :         return false;
    2307         493 :     bilingual_str strError;
    2308         493 :     if (!BindListenPort(addr, strError, permissions)) {
    2309           0 :         if ((flags & BF_REPORT_ERROR) && clientInterface) {
    2310           0 :             clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
    2311           0 :         }
    2312           0 :         return false;
    2313             :     }
    2314         493 :     return true;
    2315         493 : }
    2316             : 
    2317         492 : bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds)
    2318             : {
    2319             :     bool fBound = false;
    2320         982 :     for (const auto& addrBind : binds) {
    2321         490 :         fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::PF_NONE);
    2322             :     }
    2323         493 :     for (const auto& addrBind : whiteBinds) {
    2324           1 :         fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
    2325             :     }
    2326         492 :     if (binds.empty() && whiteBinds.empty()) {
    2327           1 :         struct in_addr inaddr_any;
    2328           1 :         inaddr_any.s_addr = INADDR_ANY;
    2329           1 :         struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
    2330           1 :         fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
    2331           1 :         fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
    2332           1 :     }
    2333         492 :     return fBound;
    2334           0 : }
    2335             : 
    2336         492 : bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
    2337             : {
    2338         492 :     Init(connOptions);
    2339             : 
    2340             :     {
    2341         492 :         LOCK(cs_totalBytesRecv);
    2342         492 :         nTotalBytesRecv = 0;
    2343         492 :     }
    2344             :     {
    2345         492 :         LOCK(cs_totalBytesSent);
    2346         492 :         nTotalBytesSent = 0;
    2347         492 :         nMaxOutboundTotalBytesSentInCycle = 0;
    2348         492 :         nMaxOutboundCycleStartTime = 0;
    2349         492 :     }
    2350             : 
    2351         492 :     if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
    2352           0 :         if (clientInterface) {
    2353           0 :             clientInterface->ThreadSafeMessageBox(
    2354           0 :                 _("Failed to listen on any port. Use -listen=0 if you want this."),
    2355           0 :                 "", CClientUIInterface::MSG_ERROR);
    2356           0 :         }
    2357           0 :         return false;
    2358             :     }
    2359             : 
    2360         492 :     for (const auto& strDest : connOptions.vSeedNodes) {
    2361           0 :         AddAddrFetch(strDest);
    2362             :     }
    2363             : 
    2364         492 :     if (clientInterface) {
    2365         492 :         clientInterface->InitMessage(_("Loading P2P addresses...").translated);
    2366         492 :     }
    2367             :     // Load addresses from peers.dat
    2368         492 :     int64_t nStart = GetTimeMillis();
    2369             :     {
    2370         492 :         CAddrDB adb;
    2371         492 :         if (adb.Read(addrman))
    2372         188 :             LogPrintf("Loaded %i addresses from peers.dat  %dms\n", addrman.size(), GetTimeMillis() - nStart);
    2373             :         else {
    2374         304 :             addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
    2375         304 :             LogPrintf("Invalid or missing peers.dat; recreating\n");
    2376         304 :             DumpAddresses();
    2377             :         }
    2378         492 :     }
    2379             : 
    2380         492 :     uiInterface.InitMessage(_("Starting network threads...").translated);
    2381             : 
    2382         492 :     fAddressesInitialized = true;
    2383             : 
    2384         492 :     if (semOutbound == nullptr) {
    2385             :         // initialize semaphore
    2386         492 :         semOutbound = MakeUnique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
    2387         492 :     }
    2388         492 :     if (semAddnode == nullptr) {
    2389             :         // initialize semaphore
    2390         492 :         semAddnode = MakeUnique<CSemaphore>(nMaxAddnode);
    2391         492 :     }
    2392             : 
    2393             :     //
    2394             :     // Start threads
    2395             :     //
    2396         492 :     assert(m_msgproc);
    2397         492 :     InterruptSocks5(false);
    2398         492 :     interruptNet.reset();
    2399         492 :     flagInterruptMsgProc = false;
    2400             : 
    2401             :     {
    2402         492 :         LOCK(mutexMsgProc);
    2403         492 :         fMsgProcWake = false;
    2404         492 :     }
    2405             : 
    2406             :     // Send and receive from sockets, accept connections
    2407         492 :     threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
    2408             : 
    2409         492 :     if (!gArgs.GetBoolArg("-dnsseed", true))
    2410         492 :         LogPrintf("DNS seeding disabled\n");
    2411             :     else
    2412           0 :         threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
    2413             : 
    2414             :     // Initiate manual connections
    2415         492 :     threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
    2416             : 
    2417         492 :     if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
    2418           0 :         if (clientInterface) {
    2419           0 :             clientInterface->ThreadSafeMessageBox(
    2420           0 :                 _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
    2421           0 :                 "", CClientUIInterface::MSG_ERROR);
    2422           0 :         }
    2423           0 :         return false;
    2424             :     }
    2425         492 :     if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty())
    2426         492 :         threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
    2427             : 
    2428             :     // Process messages
    2429         492 :     threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
    2430             : 
    2431             :     // Dump network addresses
    2432         495 :     scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
    2433             : 
    2434         492 :     return true;
    2435         492 : }
    2436             : 
    2437             : class CNetCleanup
    2438             : {
    2439             : public:
    2440        1280 :     CNetCleanup() {}
    2441             : 
    2442        1280 :     ~CNetCleanup()
    2443         640 :     {
    2444             : #ifdef WIN32
    2445             :         // Shutdown Windows Sockets
    2446             :         WSACleanup();
    2447             : #endif
    2448        1280 :     }
    2449             : };
    2450         640 : static CNetCleanup instance_of_cnetcleanup;
    2451             : 
    2452        1117 : void CConnman::Interrupt()
    2453             : {
    2454             :     {
    2455        1117 :         LOCK(mutexMsgProc);
    2456        1117 :         flagInterruptMsgProc = true;
    2457        1117 :     }
    2458        1117 :     condMsgProc.notify_all();
    2459             : 
    2460        1117 :     interruptNet();
    2461        1117 :     InterruptSocks5(true);
    2462             : 
    2463        1117 :     if (semOutbound) {
    2464        5904 :         for (int i=0; i<m_max_outbound; i++) {
    2465        5412 :             semOutbound->post();
    2466             :         }
    2467         492 :     }
    2468             : 
    2469        1117 :     if (semAddnode) {
    2470        4428 :         for (int i=0; i<nMaxAddnode; i++) {
    2471        3936 :             semAddnode->post();
    2472             :         }
    2473         492 :     }
    2474        1117 : }
    2475             : 
    2476        1117 : void CConnman::StopThreads()
    2477             : {
    2478        1117 :     if (threadMessageHandler.joinable())
    2479         492 :         threadMessageHandler.join();
    2480        1117 :     if (threadOpenConnections.joinable())
    2481         492 :         threadOpenConnections.join();
    2482        1117 :     if (threadOpenAddedConnections.joinable())
    2483         492 :         threadOpenAddedConnections.join();
    2484        1117 :     if (threadDNSAddressSeed.joinable())
    2485           0 :         threadDNSAddressSeed.join();
    2486        1117 :     if (threadSocketHandler.joinable())
    2487         492 :         threadSocketHandler.join();
    2488        1117 : }
    2489             : 
    2490        1117 : void CConnman::StopNodes()
    2491             : {
    2492        1117 :     if (fAddressesInitialized) {
    2493         492 :         DumpAddresses();
    2494         492 :         fAddressesInitialized = false;
    2495         492 :     }
    2496             : 
    2497             :     // Close sockets
    2498        1117 :     LOCK(cs_vNodes);
    2499        1531 :     for (CNode* pnode : vNodes)
    2500         414 :         pnode->CloseSocketDisconnect();
    2501        1610 :     for (ListenSocket& hListenSocket : vhListenSocket)
    2502         493 :         if (hListenSocket.socket != INVALID_SOCKET)
    2503         493 :             if (!CloseSocket(hListenSocket.socket))
    2504           0 :                 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
    2505             : 
    2506             :     // clean up some globals (to help leak detection)
    2507        1531 :     for (CNode* pnode : vNodes) {
    2508         414 :         DeleteNode(pnode);
    2509             :     }
    2510        1117 :     for (CNode* pnode : vNodesDisconnected) {
    2511           0 :         DeleteNode(pnode);
    2512           0 :     }
    2513        1117 :     vNodes.clear();
    2514        1117 :     vNodesDisconnected.clear();
    2515        1117 :     vhListenSocket.clear();
    2516        1117 :     semOutbound.reset();
    2517        1117 :     semAddnode.reset();
    2518        1117 : }
    2519             : 
    2520         713 : void CConnman::DeleteNode(CNode* pnode)
    2521             : {
    2522         713 :     assert(pnode);
    2523         713 :     bool fUpdateConnectionTime = false;
    2524         713 :     m_msgproc->FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
    2525         713 :     if (fUpdateConnectionTime) {
    2526         237 :         addrman.Connected(pnode->addr);
    2527         237 :     }
    2528         713 :     delete pnode;
    2529         713 : }
    2530             : 
    2531        1219 : CConnman::~CConnman()
    2532         609 : {
    2533         610 :     Interrupt();
    2534         610 :     Stop();
    2535        1219 : }
    2536             : 
    2537         238 : void CConnman::SetServices(const CService &addr, ServiceFlags nServices)
    2538             : {
    2539         238 :     addrman.SetServices(addr, nServices);
    2540         238 : }
    2541             : 
    2542         238 : void CConnman::MarkAddressGood(const CAddress& addr)
    2543             : {
    2544         238 :     addrman.Good(addr);
    2545         238 : }
    2546             : 
    2547       10014 : bool CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
    2548             : {
    2549       10014 :     return addrman.Add(vAddr, addrFrom, nTimePenalty);
    2550             : }
    2551             : 
    2552         190 : std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct)
    2553             : {
    2554         190 :     std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct);
    2555         190 :     if (m_banman) {
    2556         190 :         addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
    2557       19303 :                         [this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
    2558         190 :                         addresses.end());
    2559         190 :     }
    2560             :     return addresses;
    2561         190 : }
    2562             : 
    2563         244 : std::vector<CAddress> CConnman::GetAddresses(Network requestor_network, size_t max_addresses, size_t max_pct)
    2564             : {
    2565         244 :     const auto current_time = GetTime<std::chrono::microseconds>();
    2566         244 :     if (m_addr_response_caches.find(requestor_network) == m_addr_response_caches.end() ||
    2567          59 :         m_addr_response_caches[requestor_network].m_update_addr_response < current_time) {
    2568         186 :         m_addr_response_caches[requestor_network].m_addrs_response_cache = GetAddresses(max_addresses, max_pct);
    2569         186 :         m_addr_response_caches[requestor_network].m_update_addr_response = current_time + std::chrono::hours(21) + GetRandMillis(std::chrono::hours(6));
    2570         186 :     }
    2571         244 :     return m_addr_response_caches[requestor_network].m_addrs_response_cache;
    2572         244 : }
    2573             : 
    2574           2 : bool CConnman::AddNode(const std::string& strNode)
    2575             : {
    2576           2 :     LOCK(cs_vAddedNodes);
    2577           3 :     for (const std::string& it : vAddedNodes) {
    2578           1 :         if (strNode == it) return false;
    2579           0 :     }
    2580             : 
    2581           1 :     vAddedNodes.push_back(strNode);
    2582           1 :     return true;
    2583           2 : }
    2584             : 
    2585           2 : bool CConnman::RemoveAddedNode(const std::string& strNode)
    2586             : {
    2587           2 :     LOCK(cs_vAddedNodes);
    2588           3 :     for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
    2589           1 :         if (strNode == *it) {
    2590           1 :             vAddedNodes.erase(it);
    2591           1 :             return true;
    2592             :         }
    2593             :     }
    2594           1 :     return false;
    2595           2 : }
    2596             : 
    2597         154 : size_t CConnman::GetNodeCount(NumConnections flags)
    2598             : {
    2599         154 :     LOCK(cs_vNodes);
    2600         154 :     if (flags == CConnman::CONNECTIONS_ALL) // Shortcut if we want total
    2601          66 :         return vNodes.size();
    2602             : 
    2603             :     int nNum = 0;
    2604         174 :     for (const auto& pnode : vNodes) {
    2605          86 :         if (flags & (pnode->IsInboundConn() ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
    2606          43 :             nNum++;
    2607          43 :         }
    2608             :     }
    2609             : 
    2610          88 :     return nNum;
    2611         154 : }
    2612             : 
    2613        4760 : void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
    2614             : {
    2615        4760 :     vstats.clear();
    2616        4760 :     LOCK(cs_vNodes);
    2617        4760 :     vstats.reserve(vNodes.size());
    2618       13395 :     for (CNode* pnode : vNodes) {
    2619        8635 :         vstats.emplace_back();
    2620        8635 :         pnode->copyStats(vstats.back(), addrman.m_asmap);
    2621             :     }
    2622        4760 : }
    2623             : 
    2624           2 : bool CConnman::DisconnectNode(const std::string& strNode)
    2625             : {
    2626           2 :     LOCK(cs_vNodes);
    2627           2 :     if (CNode* pnode = FindNode(strNode)) {
    2628           1 :         pnode->fDisconnect = true;
    2629           1 :         return true;
    2630             :     }
    2631           1 :     return false;
    2632           2 : }
    2633             : 
    2634          17 : bool CConnman::DisconnectNode(const CSubNet& subnet)
    2635             : {
    2636             :     bool disconnected = false;
    2637          17 :     LOCK(cs_vNodes);
    2638          21 :     for (CNode* pnode : vNodes) {
    2639           4 :         if (subnet.Match(pnode->addr)) {
    2640           4 :             pnode->fDisconnect = true;
    2641             :             disconnected = true;
    2642           4 :         }
    2643             :     }
    2644          17 :     return disconnected;
    2645          17 : }
    2646             : 
    2647           8 : bool CConnman::DisconnectNode(const CNetAddr& addr)
    2648             : {
    2649           8 :     return DisconnectNode(CSubNet(addr));
    2650           0 : }
    2651             : 
    2652          25 : bool CConnman::DisconnectNode(NodeId id)
    2653             : {
    2654          25 :     LOCK(cs_vNodes);
    2655          62 :     for(CNode* pnode : vNodes) {
    2656          37 :         if (id == pnode->GetId()) {
    2657          25 :             pnode->fDisconnect = true;
    2658          25 :             return true;
    2659             :         }
    2660          12 :     }
    2661           0 :     return false;
    2662          25 : }
    2663             : 
    2664      104828 : void CConnman::RecordBytesRecv(uint64_t bytes)
    2665             : {
    2666      104828 :     LOCK(cs_totalBytesRecv);
    2667      104828 :     nTotalBytesRecv += bytes;
    2668      104828 : }
    2669             : 
    2670       91140 : void CConnman::RecordBytesSent(uint64_t bytes)
    2671             : {
    2672       91140 :     LOCK(cs_totalBytesSent);
    2673       91140 :     nTotalBytesSent += bytes;
    2674             : 
    2675       91140 :     uint64_t now = GetTime();
    2676       91140 :     if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
    2677             :     {
    2678             :         // timeframe expired, reset cycle
    2679         304 :         nMaxOutboundCycleStartTime = now;
    2680         304 :         nMaxOutboundTotalBytesSentInCycle = 0;
    2681         304 :     }
    2682             : 
    2683             :     // TODO, exclude peers with download permission
    2684       91140 :     nMaxOutboundTotalBytesSentInCycle += bytes;
    2685       91140 : }
    2686             : 
    2687           0 : void CConnman::SetMaxOutboundTarget(uint64_t limit)
    2688             : {
    2689           0 :     LOCK(cs_totalBytesSent);
    2690           0 :     nMaxOutboundLimit = limit;
    2691           0 : }
    2692             : 
    2693           8 : uint64_t CConnman::GetMaxOutboundTarget()
    2694             : {
    2695           8 :     LOCK(cs_totalBytesSent);
    2696           8 :     return nMaxOutboundLimit;
    2697           8 : }
    2698             : 
    2699           8 : uint64_t CConnman::GetMaxOutboundTimeframe()
    2700             : {
    2701           8 :     LOCK(cs_totalBytesSent);
    2702           8 :     return nMaxOutboundTimeframe;
    2703           8 : }
    2704             : 
    2705        1110 : uint64_t CConnman::GetMaxOutboundTimeLeftInCycle()
    2706             : {
    2707        1110 :     LOCK(cs_totalBytesSent);
    2708        1110 :     if (nMaxOutboundLimit == 0)
    2709           8 :         return 0;
    2710             : 
    2711        1102 :     if (nMaxOutboundCycleStartTime == 0)
    2712           0 :         return nMaxOutboundTimeframe;
    2713             : 
    2714        1102 :     uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
    2715        1102 :     uint64_t now = GetTime();
    2716        1102 :     return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();
    2717        1110 : }
    2718             : 
    2719           0 : void CConnman::SetMaxOutboundTimeframe(uint64_t timeframe)
    2720             : {
    2721           0 :     LOCK(cs_totalBytesSent);
    2722           0 :     if (nMaxOutboundTimeframe != timeframe)
    2723             :     {
    2724             :         // reset measure-cycle in case of changing
    2725             :         // the timeframe
    2726           0 :         nMaxOutboundCycleStartTime = GetTime();
    2727           0 :     }
    2728           0 :     nMaxOutboundTimeframe = timeframe;
    2729           0 : }
    2730             : 
    2731       15142 : bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit)
    2732             : {
    2733       15142 :     LOCK(cs_totalBytesSent);
    2734       15142 :     if (nMaxOutboundLimit == 0)
    2735       14040 :         return false;
    2736             : 
    2737        1102 :     if (historicalBlockServingLimit)
    2738             :     {
    2739             :         // keep a large enough buffer to at least relay each block once
    2740        1102 :         uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
    2741        1102 :         uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SERIALIZED_SIZE;
    2742        1102 :         if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
    2743         823 :             return true;
    2744         279 :     }
    2745           0 :     else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
    2746           0 :         return true;
    2747             : 
    2748         279 :     return false;
    2749       15142 : }
    2750             : 
    2751           8 : uint64_t CConnman::GetOutboundTargetBytesLeft()
    2752             : {
    2753           8 :     LOCK(cs_totalBytesSent);
    2754           8 :     if (nMaxOutboundLimit == 0)
    2755           8 :         return 0;
    2756             : 
    2757           0 :     return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
    2758           8 : }
    2759             : 
    2760           8 : uint64_t CConnman::GetTotalBytesRecv()
    2761             : {
    2762           8 :     LOCK(cs_totalBytesRecv);
    2763           8 :     return nTotalBytesRecv;
    2764           8 : }
    2765             : 
    2766           8 : uint64_t CConnman::GetTotalBytesSent()
    2767             : {
    2768           8 :     LOCK(cs_totalBytesSent);
    2769           8 :     return nTotalBytesSent;
    2770           8 : }
    2771             : 
    2772          44 : ServiceFlags CConnman::GetLocalServices() const
    2773             : {
    2774          44 :     return nLocalServices;
    2775             : }
    2776             : 
    2777       39878 : void CConnman::SetBestHeight(int height)
    2778             : {
    2779       39878 :     nBestHeight.store(height, std::memory_order_release);
    2780       39878 : }
    2781             : 
    2782         713 : int CConnman::GetBestHeight() const
    2783             : {
    2784         713 :     return nBestHeight.load(std::memory_order_acquire);
    2785             : }
    2786             : 
    2787       82766 : unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
    2788             : 
    2789        2916 : CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in)
    2790         729 :     : nTimeConnected(GetSystemTimeInSeconds()),
    2791         729 :     addr(addrIn),
    2792         729 :     addrBind(addrBindIn),
    2793         729 :     nKeyedNetGroup(nKeyedNetGroupIn),
    2794             :     // Don't relay addr messages to peers that we connect to as block-relay-only
    2795             :     // peers (to prevent adversaries from inferring these links from addr
    2796             :     // traffic).
    2797         729 :     id(idIn),
    2798         729 :     nLocalHostNonce(nLocalHostNonceIn),
    2799         729 :     m_conn_type(conn_type_in),
    2800         729 :     nLocalServices(nLocalServicesIn),
    2801         729 :     nMyStartingHeight(nMyStartingHeightIn)
    2802         729 : {
    2803         729 :     hSocket = hSocketIn;
    2804         729 :     addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
    2805         729 :     hashContinue = uint256();
    2806         729 :     if (conn_type_in != ConnectionType::BLOCK_RELAY) {
    2807         729 :         m_tx_relay = MakeUnique<TxRelay>();
    2808         729 :     }
    2809             : 
    2810         729 :     if (RelayAddrsWithConn()) {
    2811         729 :         m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
    2812         729 :     }
    2813             : 
    2814       24057 :     for (const std::string &msg : getAllNetMessageTypes())
    2815       23328 :         mapRecvBytesPerMsgCmd[msg] = 0;
    2816         729 :     mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
    2817             : 
    2818         729 :     if (fLogIPs) {
    2819           2 :         LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
    2820             :     } else {
    2821         727 :         LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
    2822             :     }
    2823             : 
    2824         729 :     m_deserializer = MakeUnique<V1TransportDeserializer>(V1TransportDeserializer(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION));
    2825         729 :     m_serializer = MakeUnique<V1TransportSerializer>(V1TransportSerializer());
    2826        1458 : }
    2827             : 
    2828        1458 : CNode::~CNode()
    2829         729 : {
    2830         729 :     CloseSocket(hSocket);
    2831        1458 : }
    2832             : 
    2833      126864 : bool CConnman::NodeFullyConnected(const CNode* pnode)
    2834             : {
    2835      126864 :     return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
    2836             : }
    2837             : 
    2838       91268 : void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
    2839             : {
    2840       91268 :     size_t nMessageSize = msg.data.size();
    2841       91268 :     LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n",  SanitizeString(msg.m_type), nMessageSize, pnode->GetId());
    2842             : 
    2843             :     // make sure we use the appropriate network transport format
    2844       91268 :     std::vector<unsigned char> serializedHeader;
    2845       91268 :     pnode->m_serializer->prepareForTransport(msg, serializedHeader);
    2846       91268 :     size_t nTotalSize = nMessageSize + serializedHeader.size();
    2847             : 
    2848             :     size_t nBytesSent = 0;
    2849             :     {
    2850       91268 :         LOCK(pnode->cs_vSend);
    2851       91268 :         bool optimisticSend(pnode->vSendMsg.empty());
    2852             : 
    2853             :         //log total amount of bytes per message type
    2854       91268 :         pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
    2855       91268 :         pnode->nSendSize += nTotalSize;
    2856             : 
    2857       91268 :         if (pnode->nSendSize > nSendBufferMaxSize)
    2858          37 :             pnode->fPauseSend = true;
    2859       91268 :         pnode->vSendMsg.push_back(std::move(serializedHeader));
    2860       91268 :         if (nMessageSize)
    2861       88934 :             pnode->vSendMsg.push_back(std::move(msg.data));
    2862             : 
    2863             :         // If write queue empty, attempt "optimistic write"
    2864       91268 :         if (optimisticSend == true)
    2865       91059 :             nBytesSent = SocketSendData(pnode);
    2866       91268 :     }
    2867       91268 :     if (nBytesSent)
    2868       91046 :         RecordBytesSent(nBytesSent);
    2869       91268 : }
    2870             : 
    2871         192 : bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
    2872             : {
    2873             :     CNode* found = nullptr;
    2874         192 :     LOCK(cs_vNodes);
    2875         469 :     for (auto&& pnode : vNodes) {
    2876         277 :         if(pnode->GetId() == id) {
    2877         190 :             found = pnode;
    2878         190 :             break;
    2879             :         }
    2880          87 :     }
    2881         192 :     return found != nullptr && NodeFullyConnected(found) && func(found);
    2882         192 : }
    2883             : 
    2884       13350 : int64_t CConnman::PoissonNextSendInbound(int64_t now, int average_interval_seconds)
    2885             : {
    2886       13350 :     if (m_next_send_inv_to_incoming < now) {
    2887             :         // If this function were called from multiple threads simultaneously
    2888             :         // it would possible that both update the next send variable, and return a different result to their caller.
    2889             :         // This is not possible in practice as only the net processing thread invokes this function.
    2890        1584 :         m_next_send_inv_to_incoming = PoissonNextSend(now, average_interval_seconds);
    2891        1584 :     }
    2892       13350 :     return m_next_send_inv_to_incoming;
    2893             : }
    2894             : 
    2895        8500 : int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
    2896             : {
    2897        8500 :     return now + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
    2898             : }
    2899             : 
    2900        1436 : CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
    2901             : {
    2902        1436 :     return CSipHasher(nSeed0, nSeed1).Write(id);
    2903             : }
    2904             : 
    2905         713 : uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const
    2906             : {
    2907         713 :     std::vector<unsigned char> vchNetGroup(ad.GetGroup(addrman.m_asmap));
    2908             : 
    2909         713 :     return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
    2910         713 : }

Generated by: LCOV version 1.15