changeset 2528:8cf6f12376b1 draft

Merge pull request #1272 from sipa/ipv6fixes A few IPv6 fixes
author Gregory Maxwell <gmaxwell@gmail.com>
date Sat, 12 May 2012 18:55:36 -0700
parents 396e7905991f (current diff) ca8272d195f6 (diff)
children 760eae471e58
files
diffstat 4 files changed, 38 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -611,14 +611,14 @@
         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 @@
     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"))
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -38,6 +38,10 @@
 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 @@
 static bool fUseUPnP = false;
 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
 static CCriticalSection cs_mapLocalHost;
-static map<CService, int> mapLocalHost;
+static map<CNetAddr, LocalServiceInfo> mapLocalHost;
 static bool vfReachable[NET_MAX] = {};
 static bool vfLimited[NET_MAX] = {};
 static CNode* pnodeLocalHost = NULL;
@@ -98,23 +102,23 @@
     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
         return false;
 
-    int nBestCount = -1;
+    int nBestScore = -1;
     int nBestReachability = -1;
     {
         LOCK(cs_mapLocalHost);
-        for (map<CService, int>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
+        for (map<CNetAddr, LocalServiceInfo>::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 @@
 
     {
         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 @@
     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 @@
         LOCK(cs_mapLocalHost);
         if (mapLocalHost.count(addr) == 0)
             return false;
-        mapLocalHost[addr]++;
+        mapLocalHost[addr].nScore++;
     }
 
     AdvertizeLocal();
@@ -1887,8 +1894,9 @@
     fShutdown = true;
     nTransactionsUpdated++;
     int64 nStart = GetTime();
-    for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
-         semOutbound->post();
+    if (semOutbound)
+        for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
+            semOutbound->post();
     do
     {
         int nThreadsRunning = 0;
--- a/src/net.h
+++ b/src/net.h
@@ -38,6 +38,7 @@
 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 @@
 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);
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -464,12 +464,14 @@
     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);