diff --git a/src/init.cpp b/src/init.cpp index fe07ed727..d26d5d73e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -611,14 +611,14 @@ bool AppInit2(int argc, char* argv[]) std::string strError; if (mapArgs.count("-bind")) { BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { - fBound |= Bind(CService(strBind, GetDefaultPort(), false)); + fBound |= Bind(CService(strBind, GetListenPort(), false)); } } else { struct in_addr inaddr_any; inaddr_any.s_addr = INADDR_ANY; - fBound |= Bind(CService(inaddr_any, GetDefaultPort())); + fBound |= Bind(CService(inaddr_any, GetListenPort())); #ifdef USE_IPV6 - fBound |= Bind(CService(in6addr_any, GetDefaultPort())); + fBound |= Bind(CService(in6addr_any, GetListenPort())); #endif } if (!fBound) @@ -628,7 +628,7 @@ bool AppInit2(int argc, char* argv[]) if (mapArgs.count("-externalip")) { BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) - AddLocal(CNetAddr(strAddr, fNameLookup), LOCAL_MANUAL); + AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } if (mapArgs.count("-paytxfee")) diff --git a/src/net.cpp b/src/net.cpp index f12afb78e..951595e68 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; @@ -222,11 +231,9 @@ bool AddLocal(const CService& addr, int nScore) return true; } -bool AddLocal(const CNetAddr& addr, int nScore, int port) +bool AddLocal(const CNetAddr &addr, int nScore) { - if (port == -1) - port = GetListenPort(); - return AddLocal(CService(addr, port), nScore); + return AddLocal(CService(addr, GetListenPort()), nScore); } /** Make a particular network entirely off-limits (no automatic connects to it) */ @@ -249,7 +256,7 @@ bool SeenLocal(const CService& addr) LOCK(cs_mapLocalHost); if (mapLocalHost.count(addr) == 0) return false; - mapLocalHost[addr]++; + mapLocalHost[addr].nScore++; } AdvertizeLocal(); @@ -1887,8 +1894,9 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - for (int i=0; ipost(); + if (semOutbound) + for (int i=0; ipost(); do { int nThreadsRunning = 0; diff --git a/src/net.h b/src/net.h index 8fe8c0047..3755c765d 100644 --- a/src/net.h +++ b/src/net.h @@ -38,6 +38,7 @@ CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const CService& ip); CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0); void MapPort(bool fMapPort); +unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string())); void StartNode(void* parg); bool StopNode(); @@ -58,7 +59,7 @@ enum void SetLimited(enum Network net, bool fLimited = true); bool IsLimited(const CNetAddr& addr); bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); -bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE, int port = -1); +bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); bool SeenLocal(const CService& addr); bool IsLocal(const CService& addr); bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); diff --git a/src/netbase.cpp b/src/netbase.cpp index ebf823e89..f09d981c4 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -464,12 +464,14 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest int port = portDefault; size_t colon = strDest.find_last_of(':'); - char *endp = NULL; - int n = strtol(pszDest + colon + 1, &endp, 10); - if (endp && *endp == 0 && n >= 0) { - strDest = strDest.substr(0, colon); - if (n > 0 && n < 0x10000) - port = n; + if (colon != strDest.npos) { + char *endp = NULL; + int n = strtol(pszDest + colon + 1, &endp, 10); + if (endp && *endp == 0 && n >= 0) { + strDest = strDest.substr(0, colon); + if (n > 0 && n < 0x10000) + port = n; + } } if (strDest[0] == '[' && strDest[strDest.size()-1] == ']') strDest = strDest.substr(1, strDest.size()-2);