diff --git a/src/net.cpp b/src/net.cpp index 0e5a89878..53b69d276 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -38,6 +38,10 @@ void ThreadDNSAddressSeed2(void* parg); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); +struct LocalServiceInfo { + int nScore; + int nPort; +}; // // Global state variables @@ -46,7 +50,7 @@ bool fClient = false; static bool fUseUPnP = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); static CCriticalSection cs_mapLocalHost; -static map mapLocalHost; +static map mapLocalHost; static bool vfReachable[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; @@ -98,23 +102,23 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer) if (fUseProxy || mapArgs.count("-connect") || fNoListen) return false; - int nBestCount = -1; + int nBestScore = -1; int nBestReachability = -1; { LOCK(cs_mapLocalHost); - for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) + for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) { - int nCount = (*it).second; + int nScore = (*it).second.nScore; int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); - if (nReachability > nBestReachability || (nReachability == nBestReachability && nCount > nBestCount)) + if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) { - addr = (*it).first; + addr = CService((*it).first, (*it).second.nPort); nBestReachability = nReachability; - nBestCount = nCount; + nBestScore = nScore; } } } - return nBestCount >= 0; + return nBestScore >= 0; } // get best local address for a particular peer as a CAddress @@ -211,7 +215,12 @@ bool AddLocal(const CService& addr, int nScore) { LOCK(cs_mapLocalHost); - mapLocalHost[addr] = std::max(nScore, mapLocalHost[addr]) + (mapLocalHost.count(addr) ? 1 : 0); + bool fAlready = mapLocalHost.count(addr) > 0; + LocalServiceInfo &info = mapLocalHost[addr]; + if (!fAlready || nScore >= info.nScore) { + info.nScore = nScore; + info.nPort = addr.GetPort() + (fAlready ? 1 : 0); + } enum Network net = addr.GetNetwork(); vfReachable[net] = true; if (net == NET_IPV6) vfReachable[NET_IPV4] = true; @@ -249,7 +258,7 @@ bool SeenLocal(const CService& addr) LOCK(cs_mapLocalHost); if (mapLocalHost.count(addr) == 0) return false; - mapLocalHost[addr]++; + mapLocalHost[addr].nScore++; } AdvertizeLocal();