Keep local service information per address

Keep local service information per CNetAddr instead of per CService,
but move the port into the information kept on it.
This commit is contained in:
Pieter Wuille 2012-05-13 00:41:24 +02:00
parent 89b5616d10
commit 139d2f7c29

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);
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<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 @@ 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<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 @@ 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();