Merge pull request #1272 from sipa/ipv6fixes

A few IPv6 fixes
This commit is contained in:
Gregory Maxwell 2012-05-12 18:55:36 -07:00
commit 6f7d45a323
4 changed files with 38 additions and 27 deletions

View file

@ -611,14 +611,14 @@ bool AppInit2(int argc, char* argv[])
std::string strError; std::string strError;
if (mapArgs.count("-bind")) { if (mapArgs.count("-bind")) {
BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
fBound |= Bind(CService(strBind, GetDefaultPort(), false)); fBound |= Bind(CService(strBind, GetListenPort(), false));
} }
} else { } else {
struct in_addr inaddr_any; struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY; inaddr_any.s_addr = INADDR_ANY;
fBound |= Bind(CService(inaddr_any, GetDefaultPort())); fBound |= Bind(CService(inaddr_any, GetListenPort()));
#ifdef USE_IPV6 #ifdef USE_IPV6
fBound |= Bind(CService(in6addr_any, GetDefaultPort())); fBound |= Bind(CService(in6addr_any, GetListenPort()));
#endif #endif
} }
if (!fBound) if (!fBound)
@ -628,7 +628,7 @@ bool AppInit2(int argc, char* argv[])
if (mapArgs.count("-externalip")) if (mapArgs.count("-externalip"))
{ {
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"])
AddLocal(CNetAddr(strAddr, fNameLookup), LOCAL_MANUAL); AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
} }
if (mapArgs.count("-paytxfee")) if (mapArgs.count("-paytxfee"))

View file

@ -38,6 +38,10 @@ void ThreadDNSAddressSeed2(void* parg);
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
struct LocalServiceInfo {
int nScore;
int nPort;
};
// //
// Global state variables // Global state variables
@ -46,7 +50,7 @@ bool fClient = false;
static bool fUseUPnP = false; static bool fUseUPnP = false;
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
static CCriticalSection cs_mapLocalHost; static CCriticalSection cs_mapLocalHost;
static map<CService, int> mapLocalHost; static map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {}; static bool vfReachable[NET_MAX] = {};
static bool vfLimited[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL; static CNode* pnodeLocalHost = NULL;
@ -98,23 +102,23 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
if (fUseProxy || mapArgs.count("-connect") || fNoListen) if (fUseProxy || mapArgs.count("-connect") || fNoListen)
return false; return false;
int nBestCount = -1; int nBestScore = -1;
int nBestReachability = -1; int nBestReachability = -1;
{ {
LOCK(cs_mapLocalHost); 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); 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; nBestReachability = nReachability;
nBestCount = nCount; nBestScore = nScore;
} }
} }
} }
return nBestCount >= 0; return nBestScore >= 0;
} }
// get best local address for a particular peer as a CAddress // 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); 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(); enum Network net = addr.GetNetwork();
vfReachable[net] = true; vfReachable[net] = true;
if (net == NET_IPV6) vfReachable[NET_IPV4] = true; if (net == NET_IPV6) vfReachable[NET_IPV4] = true;
@ -222,11 +231,9 @@ bool AddLocal(const CService& addr, int nScore)
return true; return true;
} }
bool AddLocal(const CNetAddr& addr, int nScore, int port) bool AddLocal(const CNetAddr &addr, int nScore)
{ {
if (port == -1) return AddLocal(CService(addr, GetListenPort()), nScore);
port = GetListenPort();
return AddLocal(CService(addr, port), nScore);
} }
/** Make a particular network entirely off-limits (no automatic connects to it) */ /** Make a particular network entirely off-limits (no automatic connects to it) */
@ -249,7 +256,7 @@ bool SeenLocal(const CService& addr)
LOCK(cs_mapLocalHost); LOCK(cs_mapLocalHost);
if (mapLocalHost.count(addr) == 0) if (mapLocalHost.count(addr) == 0)
return false; return false;
mapLocalHost[addr]++; mapLocalHost[addr].nScore++;
} }
AdvertizeLocal(); AdvertizeLocal();
@ -1887,8 +1894,9 @@ bool StopNode()
fShutdown = true; fShutdown = true;
nTransactionsUpdated++; nTransactionsUpdated++;
int64 nStart = GetTime(); int64 nStart = GetTime();
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++) if (semOutbound)
semOutbound->post(); for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
semOutbound->post();
do do
{ {
int nThreadsRunning = 0; int nThreadsRunning = 0;

View file

@ -38,6 +38,7 @@ CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CService& ip); CNode* FindNode(const CService& ip);
CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0); CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
void MapPort(bool fMapPort); void MapPort(bool fMapPort);
unsigned short GetListenPort();
bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string())); bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
void StartNode(void* parg); void StartNode(void* parg);
bool StopNode(); bool StopNode();
@ -58,7 +59,7 @@ enum
void SetLimited(enum Network net, bool fLimited = true); void SetLimited(enum Network net, bool fLimited = true);
bool IsLimited(const CNetAddr& addr); bool IsLimited(const CNetAddr& addr);
bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); 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 SeenLocal(const CService& addr);
bool IsLocal(const CService& addr); bool IsLocal(const CService& addr);
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);

View file

@ -464,12 +464,14 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
int port = portDefault; int port = portDefault;
size_t colon = strDest.find_last_of(':'); size_t colon = strDest.find_last_of(':');
char *endp = NULL; if (colon != strDest.npos) {
int n = strtol(pszDest + colon + 1, &endp, 10); char *endp = NULL;
if (endp && *endp == 0 && n >= 0) { int n = strtol(pszDest + colon + 1, &endp, 10);
strDest = strDest.substr(0, colon); if (endp && *endp == 0 && n >= 0) {
if (n > 0 && n < 0x10000) strDest = strDest.substr(0, colon);
port = n; if (n > 0 && n < 0x10000)
port = n;
}
} }
if (strDest[0] == '[' && strDest[strDest.size()-1] == ']') if (strDest[0] == '[' && strDest[strDest.size()-1] == ']')
strDest = strDest.substr(1, strDest.size()-2); strDest = strDest.substr(1, strDest.size()-2);