net: only enforce the services required to connect

also once half of all outgoing nodes have our preferred flags, require only
minimal flags from the rest.
This commit is contained in:
Cory Fields 2017-05-24 17:00:27 -04:00
parent 217b416c72
commit b6fbfc2282

View file

@ -1721,11 +1721,17 @@ void CConnman::ThreadOpenConnections()
// Only connect out to one peer per network group (/16 for IPv4). // Only connect out to one peer per network group (/16 for IPv4).
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect. // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
int nOutbound = 0; int nOutbound = 0;
int nOutboundRelevant = 0;
std::set<std::vector<unsigned char> > setConnected; std::set<std::vector<unsigned char> > setConnected;
{ {
LOCK(cs_vNodes); LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) { BOOST_FOREACH(CNode* pnode, vNodes) {
if (!pnode->fInbound && !pnode->fAddnode) { if (!pnode->fInbound && !pnode->fAddnode) {
// Count the peers that have all relevant services
if (pnode->fSuccessfullyConnected && !pnode->fFeeler && ((pnode->nServices & nRelevantServices) == nRelevantServices)) {
nOutboundRelevant++;
}
// Netgroups for inbound and addnode peers are not excluded because our goal here // Netgroups for inbound and addnode peers are not excluded because our goal here
// is to not use multiple of our limited outbound slots on a single netgroup // is to not use multiple of our limited outbound slots on a single netgroup
// but inbound and addnode peers do not use our outbound slots. Inbound peers // but inbound and addnode peers do not use our outbound slots. Inbound peers
@ -1789,14 +1795,27 @@ void CConnman::ThreadOpenConnections()
continue; continue;
// only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up. // only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up.
if ((addr.nServices & nRelevantServices) != nRelevantServices && (nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) ServiceFlags nRequiredServices = nRelevantServices;
if (nTries >= 40 && nOutbound < (nMaxOutbound >> 1)) {
nRequiredServices = REQUIRED_SERVICES;
}
if ((addr.nServices & nRequiredServices) != nRequiredServices) {
continue; continue;
}
// do not allow non-default ports, unless after 50 invalid addresses selected already // do not allow non-default ports, unless after 50 invalid addresses selected already
if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
continue; continue;
addrConnect = addr; addrConnect = addr;
// regardless of the services assumed to be available, only require the minimum if half or more outbound have relevant services
if (nOutboundRelevant >= (nMaxOutbound >> 1)) {
addrConnect.nServices = REQUIRED_SERVICES;
} else {
addrConnect.nServices = nRequiredServices;
}
break; break;
} }