Changeset View
Changeset View
Standalone View
Standalone View
src/net.cpp
Show First 20 Lines • Show All 405 Lines • ▼ Show 20 Lines | if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, | ||||
GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE) | GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE) | ||||
.Write(id) | .Write(id) | ||||
.Finalize(); | .Finalize(); | ||||
CAddress addr_bind = GetBindAddress(hSocket); | CAddress addr_bind = GetBindAddress(hSocket); | ||||
CNode *pnode = | CNode *pnode = | ||||
new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, | new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, | ||||
CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, | CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, | ||||
pszDest ? pszDest : "", false); | pszDest ? pszDest : "", false); | ||||
pnode->nServicesExpected = | |||||
ServiceFlags(addrConnect.nServices & nRelevantServices); | |||||
pnode->AddRef(); | pnode->AddRef(); | ||||
return pnode; | return pnode; | ||||
} else if (!proxyConnectionFailed) { | } else if (!proxyConnectionFailed) { | ||||
// If connecting to the node failed, and failure is not caused by a | // If connecting to the node failed, and failure is not caused by a | ||||
// problem connecting to the proxy, mark this as an attempt. | // problem connecting to the proxy, mark this as an attempt. | ||||
addrman.Attempt(addrConnect, fCountFailure); | addrman.Attempt(addrConnect, fCountFailure); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 239 Lines • ▼ Show 20 Lines | void CNode::copyStats(CNodeStats &stats) { | ||||
stats.nTimeOffset = nTimeOffset; | stats.nTimeOffset = nTimeOffset; | ||||
stats.addrName = GetAddrName(); | stats.addrName = GetAddrName(); | ||||
stats.nVersion = nVersion; | stats.nVersion = nVersion; | ||||
{ | { | ||||
LOCK(cs_SubVer); | LOCK(cs_SubVer); | ||||
stats.cleanSubVer = cleanSubVer; | stats.cleanSubVer = cleanSubVer; | ||||
} | } | ||||
stats.fInbound = fInbound; | stats.fInbound = fInbound; | ||||
stats.fAddnode = fAddnode; | stats.m_manual_connection = m_manual_connection; | ||||
stats.nStartingHeight = nStartingHeight; | stats.nStartingHeight = nStartingHeight; | ||||
{ | { | ||||
LOCK(cs_vSend); | LOCK(cs_vSend); | ||||
stats.mapSendBytesPerMsgCmd = mapSendBytesPerMsgCmd; | stats.mapSendBytesPerMsgCmd = mapSendBytesPerMsgCmd; | ||||
stats.nSendBytes = nSendBytes; | stats.nSendBytes = nSendBytes; | ||||
} | } | ||||
{ | { | ||||
LOCK(cs_vRecv); | LOCK(cs_vRecv); | ||||
▲ Show 20 Lines • Show All 319 Lines • ▼ Show 20 Lines | bool CConnman::AttemptToEvictConnection() { | ||||
{ | { | ||||
LOCK(cs_vNodes); | LOCK(cs_vNodes); | ||||
for (CNode *node : vNodes) { | for (CNode *node : vNodes) { | ||||
if (node->fWhitelisted || !node->fInbound || node->fDisconnect) { | if (node->fWhitelisted || !node->fInbound || node->fDisconnect) { | ||||
continue; | continue; | ||||
} | } | ||||
NodeEvictionCandidate candidate = { | NodeEvictionCandidate candidate = { | ||||
node->id, | node->GetId(), | ||||
node->nTimeConnected, | node->nTimeConnected, | ||||
node->nMinPingUsecTime, | node->nMinPingUsecTime, | ||||
node->nLastBlockTime, | node->nLastBlockTime, | ||||
node->nLastTXTime, | node->nLastTXTime, | ||||
(node->nServices & nRelevantServices) == nRelevantServices, | HasAllDesirableServiceFlags(node->nServices), | ||||
node->fRelayTxes, | node->fRelayTxes, | ||||
node->pfilter != nullptr, | node->pfilter != nullptr, | ||||
node->addr, | node->addr, | ||||
node->nKeyedNetGroup}; | node->nKeyedNetGroup}; | ||||
vEvictionCandidates.push_back(candidate); | vEvictionCandidates.push_back(candidate); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 658 Lines • ▼ Show 20 Lines | if ((addrman.size() > 0) && | ||||
(!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { | (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { | ||||
if (!interruptNet.sleep_for(std::chrono::seconds(11))) { | if (!interruptNet.sleep_for(std::chrono::seconds(11))) { | ||||
return; | return; | ||||
} | } | ||||
LOCK(cs_vNodes); | LOCK(cs_vNodes); | ||||
int nRelevant = 0; | int nRelevant = 0; | ||||
for (auto pnode : vNodes) { | for (auto pnode : vNodes) { | ||||
nRelevant += | nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && | ||||
pnode->fSuccessfullyConnected && | !pnode->fOneShot && !pnode->m_manual_connection && | ||||
((pnode->nServices & nRelevantServices) == nRelevantServices); | !pnode->fInbound; | ||||
} | } | ||||
if (nRelevant >= 2) { | if (nRelevant >= 2) { | ||||
LogPrintf("P2P peers available. Skipped DNS seeding.\n"); | LogPrintf("P2P peers available. Skipped DNS seeding.\n"); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
const std::vector<CDNSSeedData> &vSeeds = | const std::vector<CDNSSeedData> &vSeeds = | ||||
config->GetChainParams().DNSSeeds(); | config->GetChainParams().DNSSeeds(); | ||||
int found = 0; | int found = 0; | ||||
LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); | LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); | ||||
for (const CDNSSeedData &seed : vSeeds) { | for (const CDNSSeedData &seed : vSeeds) { | ||||
if (HaveNameProxy()) { | if (HaveNameProxy()) { | ||||
AddOneShot(seed.host); | AddOneShot(seed.host); | ||||
} else { | } else { | ||||
std::vector<CNetAddr> vIPs; | std::vector<CNetAddr> vIPs; | ||||
std::vector<CAddress> vAdd; | std::vector<CAddress> vAdd; | ||||
ServiceFlags requiredServiceBits = nRelevantServices; | ServiceFlags requiredServiceBits = | ||||
GetDesirableServiceFlags(NODE_NONE); | |||||
std::string host = GetDNSHost(seed, &requiredServiceBits); | std::string host = GetDNSHost(seed, &requiredServiceBits); | ||||
CNetAddr resolveSource; | CNetAddr resolveSource; | ||||
if (!resolveSource.SetInternal(host)) { | if (!resolveSource.SetInternal(host)) { | ||||
continue; | continue; | ||||
} | } | ||||
if (LookupHost(host.c_str(), vIPs, 0, true)) { | if (LookupHost(host.c_str(), vIPs, 0, true)) { | ||||
for (const CNetAddr &ip : vIPs) { | for (const CNetAddr &ip : vIPs) { | ||||
int nOneDay = 24 * 3600; | int nOneDay = 24 * 3600; | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
void CConnman::ThreadOpenConnections() { | void CConnman::ThreadOpenConnections() { | ||||
// Connect to specific addresses | // Connect to specific addresses | ||||
if (gArgs.IsArgSet("-connect") && gArgs.GetArgs("-connect").size() > 0) { | if (gArgs.IsArgSet("-connect") && gArgs.GetArgs("-connect").size() > 0) { | ||||
for (int64_t nLoop = 0;; nLoop++) { | for (int64_t nLoop = 0;; nLoop++) { | ||||
ProcessOneShot(); | ProcessOneShot(); | ||||
for (const std::string &strAddr : gArgs.GetArgs("-connect")) { | for (const std::string &strAddr : gArgs.GetArgs("-connect")) { | ||||
CAddress addr(CService(), NODE_NONE); | CAddress addr(CService(), NODE_NONE); | ||||
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str()); | OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), | ||||
false, false, true); | |||||
for (int i = 0; i < 10 && i < nLoop; i++) { | for (int i = 0; i < 10 && i < nLoop; i++) { | ||||
if (!interruptNet.sleep_for( | if (!interruptNet.sleep_for( | ||||
std::chrono::milliseconds(500))) { | std::chrono::milliseconds(500))) { | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) { | if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) { | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | while (!interruptNet) { | ||||
// Only connect out to one peer per network group (/16 for IPv4). Do | // 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 | // this here so we don't have to critsect vNodes inside mapAddresses | ||||
// critsect. | // critsect. | ||||
int nOutbound = 0; | int nOutbound = 0; | ||||
std::set<std::vector<uint8_t>> setConnected; | std::set<std::vector<uint8_t>> setConnected; | ||||
{ | { | ||||
LOCK(cs_vNodes); | LOCK(cs_vNodes); | ||||
for (CNode *pnode : vNodes) { | for (CNode *pnode : vNodes) { | ||||
if (!pnode->fInbound && !pnode->fAddnode) { | if (!pnode->fInbound && !pnode->m_manual_connection) { | ||||
// Netgroups for inbound and addnode peers are not excluded | // Netgroups for inbound and addnode peers are not excluded | ||||
// because our goal here is to not use multiple of our | // because our goal here is to not use multiple of our | ||||
// limited outbound slots on a single netgroup but inbound | // limited outbound slots on a single netgroup but inbound | ||||
// and addnode peers do not use our outbound slots. Inbound | // and addnode peers do not use our outbound slots. Inbound | ||||
// peers also have the added issue that they're attacker | // peers also have the added issue that they're attacker | ||||
// controlled and could be used to prevent us from | // controlled and could be used to prevent us from | ||||
// connecting to particular hosts if we used them here. | // connecting to particular hosts if we used them here. | ||||
setConnected.insert(pnode->addr.GetGroup()); | setConnected.insert(pnode->addr.GetGroup()); | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | while (!interruptNet) { | ||||
if (nTries > 100) { | if (nTries > 100) { | ||||
break; | break; | ||||
} | } | ||||
if (IsLimited(addr)) { | if (IsLimited(addr)) { | ||||
continue; | continue; | ||||
} | } | ||||
// only connect to full nodes | // only consider very recently tried nodes after 30 failed attempts | ||||
if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES) { | if (nANow - addr.nLastTry < 600 && nTries < 30) { | ||||
continue; | continue; | ||||
} | } | ||||
// only consider very recently tried nodes after 30 failed attempts | // for non-feelers, require all the services we'll want, | ||||
if (nANow - addr.nLastTry < 600 && nTries < 30) { | // for feelers, only require they be a full node (only because most | ||||
// SPV clients don't have a good address DB available) | |||||
if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) { | |||||
continue; | continue; | ||||
} | } | ||||
// only consider nodes missing relevant services after 40 failed | if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) { | ||||
// attempts and only if less than half the outbound are up. | |||||
if ((addr.nServices & nRelevantServices) != nRelevantServices && | |||||
(nTries < 40 || nOutbound >= (nMaxOutbound >> 1))) { | |||||
continue; | continue; | ||||
} | } | ||||
// do not allow non-default ports, unless after 50 invalid addresses | // do not allow non-default ports, unless after 50 invalid addresses | ||||
// selected already. | // selected already. | ||||
if (addr.GetPort() != config->GetChainParams().GetDefaultPort() && | if (addr.GetPort() != config->GetChainParams().GetDefaultPort() && | ||||
nTries < 50) { | nTries < 50) { | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | void CConnman::ThreadOpenAddedConnections() { | ||||
} | } | ||||
} | } | ||||
// If successful, this moves the passed grant to the constructed node. | // If successful, this moves the passed grant to the constructed node. | ||||
bool CConnman::OpenNetworkConnection(const CAddress &addrConnect, | bool CConnman::OpenNetworkConnection(const CAddress &addrConnect, | ||||
bool fCountFailure, | bool fCountFailure, | ||||
CSemaphoreGrant *grantOutbound, | CSemaphoreGrant *grantOutbound, | ||||
const char *pszDest, bool fOneShot, | const char *pszDest, bool fOneShot, | ||||
bool fFeeler, bool fAddnode) { | bool fFeeler, bool manual_connection) { | ||||
// | // | ||||
// Initiate outbound network connection | // Initiate outbound network connection | ||||
// | // | ||||
if (interruptNet) { | if (interruptNet) { | ||||
return false; | return false; | ||||
} | } | ||||
if (!fNetworkActive) { | if (!fNetworkActive) { | ||||
return false; | return false; | ||||
Show All 16 Lines | if (grantOutbound) { | ||||
grantOutbound->MoveTo(pnode->grantOutbound); | grantOutbound->MoveTo(pnode->grantOutbound); | ||||
} | } | ||||
if (fOneShot) { | if (fOneShot) { | ||||
pnode->fOneShot = true; | pnode->fOneShot = true; | ||||
} | } | ||||
if (fFeeler) { | if (fFeeler) { | ||||
pnode->fFeeler = true; | pnode->fFeeler = true; | ||||
} | } | ||||
if (fAddnode) { | if (manual_connection) { | ||||
pnode->fAddnode = true; | pnode->m_manual_connection = true; | ||||
} | } | ||||
m_msgproc->InitializeNode(*config, pnode); | m_msgproc->InitializeNode(*config, pnode); | ||||
{ | { | ||||
LOCK(cs_vNodes); | LOCK(cs_vNodes); | ||||
vNodes.push_back(pnode); | vNodes.push_back(pnode); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 756 Lines • ▼ Show 20 Lines | CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, | ||||
bool fInboundIn) | bool fInboundIn) | ||||
: nTimeConnected(GetSystemTimeInSeconds()), addr(addrIn), | : nTimeConnected(GetSystemTimeInSeconds()), addr(addrIn), | ||||
addrBind(addrBindIn), fInbound(fInboundIn), | addrBind(addrBindIn), fInbound(fInboundIn), | ||||
nKeyedNetGroup(nKeyedNetGroupIn), addrKnown(5000, 0.001), | nKeyedNetGroup(nKeyedNetGroupIn), addrKnown(5000, 0.001), | ||||
filterInventoryKnown(50000, 0.000001), id(idIn), | filterInventoryKnown(50000, 0.000001), id(idIn), | ||||
nLocalHostNonce(nLocalHostNonceIn), nLocalServices(nLocalServicesIn), | nLocalHostNonce(nLocalHostNonceIn), nLocalServices(nLocalServicesIn), | ||||
nMyStartingHeight(nMyStartingHeightIn), nSendVersion(0) { | nMyStartingHeight(nMyStartingHeightIn), nSendVersion(0) { | ||||
nServices = NODE_NONE; | nServices = NODE_NONE; | ||||
nServicesExpected = NODE_NONE; | |||||
hSocket = hSocketIn; | hSocket = hSocketIn; | ||||
nRecvVersion = INIT_PROTO_VERSION; | nRecvVersion = INIT_PROTO_VERSION; | ||||
nLastSend = 0; | nLastSend = 0; | ||||
nLastRecv = 0; | nLastRecv = 0; | ||||
nSendBytes = 0; | nSendBytes = 0; | ||||
nRecvBytes = 0; | nRecvBytes = 0; | ||||
nTimeOffset = 0; | nTimeOffset = 0; | ||||
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; | addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; | ||||
nVersion = 0; | nVersion = 0; | ||||
strSubVer = ""; | strSubVer = ""; | ||||
fWhitelisted = false; | fWhitelisted = false; | ||||
fOneShot = false; | fOneShot = false; | ||||
fAddnode = false; | m_manual_connection = false; | ||||
// set by version message | // set by version message | ||||
fClient = false; | fClient = false; | ||||
fFeeler = false; | fFeeler = false; | ||||
fSuccessfullyConnected = false; | fSuccessfullyConnected = false; | ||||
fDisconnect = false; | fDisconnect = false; | ||||
nRefCount = 0; | nRefCount = 0; | ||||
nSendSize = 0; | nSendSize = 0; | ||||
nSendOffset = 0; | nSendOffset = 0; | ||||
▲ Show 20 Lines • Show All 227 Lines • Show Last 20 Lines |