aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp301
1 files changed, 156 insertions, 145 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 587c9e5110..0f9de81d7f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -135,11 +135,10 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn
const int64_t nOneWeek = 7*24*60*60;
std::vector<CAddress> vSeedsOut;
vSeedsOut.reserve(vSeedsIn.size());
- for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
- {
+ for (const auto& seed_in : vSeedsIn) {
struct in6_addr ip;
- memcpy(&ip, i->addr, sizeof(ip));
- CAddress addr(CService(ip, i->port), NODE_NETWORK);
+ memcpy(&ip, seed_in.addr, sizeof(ip));
+ CAddress addr(CService(ip, seed_in.port), NODE_NETWORK);
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
vSeedsOut.push_back(addr);
}
@@ -299,18 +298,22 @@ bool IsReachable(const CNetAddr& addr)
CNode* CConnman::FindNode(const CNetAddr& ip)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if ((CNetAddr)pnode->addr == ip)
- return (pnode);
+ for (CNode* pnode : vNodes) {
+ if ((CNetAddr)pnode->addr == ip) {
+ return pnode;
+ }
+ }
return nullptr;
}
CNode* CConnman::FindNode(const CSubNet& subNet)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if (subNet.Match((CNetAddr)pnode->addr))
- return (pnode);
+ for (CNode* pnode : vNodes) {
+ if (subNet.Match((CNetAddr)pnode->addr)) {
+ return pnode;
+ }
+ }
return nullptr;
}
@@ -319,7 +322,7 @@ CNode* CConnman::FindNode(const std::string& addrName)
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
if (pnode->GetAddrName() == addrName) {
- return (pnode);
+ return pnode;
}
}
return nullptr;
@@ -328,9 +331,11 @@ CNode* CConnman::FindNode(const std::string& addrName)
CNode* CConnman::FindNode(const CService& addr)
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if ((CService)pnode->addr == addr)
- return (pnode);
+ for (CNode* pnode : vNodes) {
+ if ((CService)pnode->addr == addr) {
+ return pnode;
+ }
+ }
return nullptr;
}
@@ -380,19 +385,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pszDest ? pszDest : addrConnect.ToString(),
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
- // Connect
- SOCKET hSocket;
- bool proxyConnectionFailed = false;
- if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
- ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
- {
- if (!IsSelectableSocket(hSocket)) {
- LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
- CloseSocket(hSocket);
- return nullptr;
- }
-
- if (pszDest && addrConnect.IsValid()) {
+ // Resolve
+ const int default_port = Params().GetDefaultPort();
+ if (pszDest) {
+ std::vector<CService> resolved;
+ if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
+ addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
+ if (!addrConnect.IsValid()) {
+ LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s", addrConnect.ToString(), pszDest);
+ return nullptr;
+ }
// It is possible that we already have a connection to the IP/port pszDest resolved to.
// In that case, drop the connection that was just created, and return the existing CNode instead.
// Also store the name we used to connect in that CNode, so that future FindNode() calls to that
@@ -402,27 +404,49 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (pnode)
{
pnode->MaybeSetAddrName(std::string(pszDest));
- CloseSocket(hSocket);
LogPrintf("Failed to open new connection, already connected\n");
return nullptr;
}
}
+ }
- addrman.Attempt(addrConnect, fCountFailure);
+ // Connect
+ bool connected = false;
+ SOCKET hSocket;
+ proxyType proxy;
+ if (addrConnect.IsValid()) {
+ bool proxyConnectionFailed = false;
+
+ if (GetProxy(addrConnect.GetNetwork(), proxy))
+ connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
+ else // no proxy needed (none set for target network)
+ connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
+ if (!proxyConnectionFailed) {
+ // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
+ // the proxy, mark this as an attempt.
+ addrman.Attempt(addrConnect, fCountFailure);
+ }
+ } else if (pszDest && GetNameProxy(proxy)) {
+ std::string host;
+ int port = default_port;
+ SplitHostPort(std::string(pszDest), port, host);
+ connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr);
+ }
+ if (connected) {
+ if (!IsSelectableSocket(hSocket)) {
+ LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
+ CloseSocket(hSocket);
+ return nullptr;
+ }
// Add node
NodeId id = GetNewNodeId();
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
CAddress addr_bind = GetBindAddress(hSocket);
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false);
- pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
pnode->AddRef();
return pnode;
- } else if (!proxyConnectionFailed) {
- // If connecting to the node failed, and failure is not caused by a problem connecting to
- // the proxy, mark this as an attempt.
- addrman.Attempt(addrConnect, fCountFailure);
}
return nullptr;
@@ -474,10 +498,9 @@ void CConnman::ClearBanned()
bool CConnman::IsBanned(CNetAddr ip)
{
LOCK(cs_setBanned);
- for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); it++)
- {
- CSubNet subNet = (*it).first;
- CBanEntry banEntry = (*it).second;
+ for (const auto& it : setBanned) {
+ CSubNet subNet = it.first;
+ CBanEntry banEntry = it.second;
if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil) {
return true;
@@ -661,7 +684,7 @@ void CNode::copyStats(CNodeStats &stats)
X(cleanSubVer);
}
X(fInbound);
- X(fAddnode);
+ X(m_manual_connection);
X(nStartingHeight);
{
LOCK(cs_vSend);
@@ -938,6 +961,16 @@ static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEviction
return a.nTimeConnected > b.nTimeConnected;
}
+
+//! Sort an array by the specified comparator, then erase the last K elements.
+template<typename T, typename Comparator>
+static void EraseLastKElements(std::vector<T> &elements, Comparator comparator, size_t k)
+{
+ std::sort(elements.begin(), elements.end(), comparator);
+ size_t eraseSize = std::min(k, elements.size());
+ elements.erase(elements.end() - eraseSize, elements.end());
+}
+
/** Try to find a connection to evict when the node is full.
* Extreme care must be taken to avoid opening the node to attacker
* triggered network partitioning.
@@ -952,7 +985,7 @@ bool CConnman::AttemptToEvictConnection()
{
LOCK(cs_vNodes);
- for (CNode *node : vNodes) {
+ for (const CNode* node : vNodes) {
if (node->fWhitelisted)
continue;
if (!node->fInbound)
@@ -961,48 +994,29 @@ bool CConnman::AttemptToEvictConnection()
continue;
NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
node->nLastBlockTime, node->nLastTXTime,
- (node->nServices & nRelevantServices) == nRelevantServices,
+ HasAllDesirableServiceFlags(node->nServices),
node->fRelayTxes, node->pfilter != nullptr, node->addr, node->nKeyedNetGroup};
vEvictionCandidates.push_back(candidate);
}
}
- if (vEvictionCandidates.empty()) return false;
-
// Protect connections with certain characteristics
// Deterministically select 4 peers to protect by netgroup.
// An attacker cannot predict which netgroups will be protected
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
- vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
-
- if (vEvictionCandidates.empty()) return false;
-
+ EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
// Protect the 8 nodes with the lowest minimum ping time.
// An attacker cannot manipulate this metric without physically moving nodes closer to the target.
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
- vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
-
- if (vEvictionCandidates.empty()) return false;
-
+ EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
// Protect 4 nodes that most recently sent us transactions.
// An attacker cannot manipulate this metric without performing useful work.
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeTXTime);
- vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
-
- if (vEvictionCandidates.empty()) return false;
-
+ EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
// Protect 4 nodes that most recently sent us blocks.
// An attacker cannot manipulate this metric without performing useful work.
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockTime);
- vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
-
- if (vEvictionCandidates.empty()) return false;
-
+ EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
// Protect the half of the remaining nodes which have been connected the longest.
// This replicates the non-eviction implicit behavior, and precludes attacks that start later.
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
- vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
+ EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, vEvictionCandidates.size() / 2);
if (vEvictionCandidates.empty()) return false;
@@ -1013,12 +1027,12 @@ bool CConnman::AttemptToEvictConnection()
int64_t nMostConnectionsTime = 0;
std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
for (const NodeEvictionCandidate &node : vEvictionCandidates) {
- mapNetGroupNodes[node.nKeyedNetGroup].push_back(node);
- int64_t grouptime = mapNetGroupNodes[node.nKeyedNetGroup][0].nTimeConnected;
- size_t groupsize = mapNetGroupNodes[node.nKeyedNetGroup].size();
+ std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
+ group.push_back(node);
+ int64_t grouptime = group[0].nTimeConnected;
- if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
- nMostConnections = groupsize;
+ if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
+ nMostConnections = group.size();
nMostConnectionsTime = grouptime;
naMostConnections = node.nKeyedNetGroup;
}
@@ -1030,9 +1044,9 @@ bool CConnman::AttemptToEvictConnection()
// Disconnect from the network group with the most connections
NodeId evicted = vEvictionCandidates.front().id;
LOCK(cs_vNodes);
- for(std::vector<CNode*>::const_iterator it(vNodes.begin()); it != vNodes.end(); ++it) {
- if ((*it)->GetId() == evicted) {
- (*it)->fDisconnect = true;
+ for (CNode* pnode : vNodes) {
+ if (pnode->GetId() == evicted) {
+ pnode->fDisconnect = true;
return true;
}
}
@@ -1056,9 +1070,9 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
{
LOCK(cs_vNodes);
- for (CNode* pnode : vNodes)
- if (pnode->fInbound)
- nInbound++;
+ for (const CNode* pnode : vNodes) {
+ if (pnode->fInbound) nInbound++;
+ }
}
if (hSocket == INVALID_SOCKET)
@@ -1520,22 +1534,20 @@ void ThreadMapPort()
void MapPort(bool fUseUPnP)
{
- static boost::thread* upnp_thread = nullptr;
+ static std::unique_ptr<boost::thread> upnp_thread;
if (fUseUPnP)
{
if (upnp_thread) {
upnp_thread->interrupt();
upnp_thread->join();
- delete upnp_thread;
}
- upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
+ upnp_thread.reset(new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
}
else if (upnp_thread) {
upnp_thread->interrupt();
upnp_thread->join();
- delete upnp_thread;
- upnp_thread = nullptr;
+ upnp_thread.reset();
}
}
@@ -1578,7 +1590,7 @@ void CConnman::ThreadDNSAddressSeed()
LOCK(cs_vNodes);
int nRelevant = 0;
for (auto pnode : vNodes) {
- nRelevant += pnode->fSuccessfullyConnected && ((pnode->nServices & nRelevantServices) == nRelevantServices);
+ nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
}
if (nRelevant >= 2) {
LogPrintf("P2P peers available. Skipped DNS seeding.\n");
@@ -1600,7 +1612,7 @@ void CConnman::ThreadDNSAddressSeed()
} else {
std::vector<CNetAddr> vIPs;
std::vector<CAddress> vAdd;
- ServiceFlags requiredServiceBits = nRelevantServices;
+ ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
std::string host = GetDNSHost(seed, &requiredServiceBits);
CNetAddr resolveSource;
if (!resolveSource.SetInternal(host)) {
@@ -1670,6 +1682,37 @@ void CConnman::ProcessOneShot()
}
}
+bool CConnman::GetTryNewOutboundPeer()
+{
+ return m_try_another_outbound_peer;
+}
+
+void CConnman::SetTryNewOutboundPeer(bool flag)
+{
+ m_try_another_outbound_peer = flag;
+ LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
+}
+
+// Return the number of peers we have over our outbound connection limit
+// Exclude peers that are marked for disconnect, or are going to be
+// disconnected soon (eg one-shots and feelers)
+// Also exclude peers that haven't finished initial connection handshake yet
+// (so that we don't decide we're over our desired connection limit, and then
+// evict some peer that has finished the handshake)
+int CConnman::GetExtraOutboundCount()
+{
+ int nOutbound = 0;
+ {
+ LOCK(cs_vNodes);
+ for (CNode* pnode : vNodes) {
+ if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
+ ++nOutbound;
+ }
+ }
+ }
+ return std::max(nOutbound - nMaxOutbound, 0);
+}
+
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
{
// Connect to specific addresses
@@ -1681,7 +1724,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
for (const std::string& strAddr : connect)
{
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++)
{
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
@@ -1729,17 +1772,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
// 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.
int nOutbound = 0;
- int nOutboundRelevant = 0;
std::set<std::vector<unsigned char> > setConnected;
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
- if (!pnode->fInbound && !pnode->fAddnode) {
-
- // Count the peers that have all relevant services
- if (pnode->fSuccessfullyConnected && !pnode->fFeeler && ((pnode->nServices & nRelevantServices) == nRelevantServices)) {
- nOutboundRelevant++;
- }
+ if (!pnode->fInbound && !pnode->m_manual_connection) {
// 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
// but inbound and addnode peers do not use our outbound slots. Inbound peers
@@ -1764,7 +1801,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
// * Only make a feeler connection once every few minutes.
//
bool fFeeler = false;
- if (nOutbound >= nMaxOutbound) {
+
+ if (nOutbound >= nMaxOutbound && !GetTryNewOutboundPeer()) {
int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
if (nTime > nNextFeeler) {
nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
@@ -1794,21 +1832,16 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
if (IsLimited(addr))
continue;
- // only connect to full nodes
- if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
- continue;
-
// only consider very recently tried nodes after 30 failed attempts
if (nANow - addr.nLastTry < 600 && nTries < 30)
continue;
- // only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up.
- ServiceFlags nRequiredServices = nRelevantServices;
- if (nTries >= 40 && nOutbound < (nMaxOutbound >> 1)) {
- nRequiredServices = REQUIRED_SERVICES;
- }
-
- if ((addr.nServices & nRequiredServices) != nRequiredServices) {
+ // for non-feelers, require all the services we'll want,
+ // 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;
+ } else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
continue;
}
@@ -1817,13 +1850,6 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
continue;
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;
}
@@ -1850,8 +1876,7 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
{
LOCK(cs_vAddedNodes);
ret.reserve(vAddedNodes.size());
- for (const std::string& strAddNode : vAddedNodes)
- lAddresses.push_back(strAddNode);
+ std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
}
@@ -1897,11 +1922,6 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
void CConnman::ThreadOpenAddedConnections()
{
- {
- LOCK(cs_vAddedNodes);
- vAddedNodes = gArgs.GetArgs("-addnode");
- }
-
while (true)
{
CSemaphoreGrant grant(*semAddnode);
@@ -1914,11 +1934,9 @@ void CConnman::ThreadOpenAddedConnections()
// the addednodeinfo state might change.
break;
}
- // If strAddedNode is an IP/port, decode it immediately, so
- // OpenNetworkConnection can detect existing connections to that IP/port.
tried = true;
- CService service(LookupNumeric(info.strAddedNode.c_str(), Params().GetDefaultPort()));
- OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false, false, true);
+ CAddress addr(CService(), NODE_NONE);
+ OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
return;
}
@@ -1930,7 +1948,7 @@ void CConnman::ThreadOpenAddedConnections()
}
// if successful, this moves the passed grant to the constructed node
-bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool fAddnode)
+bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection)
{
//
// Initiate outbound network connection
@@ -1959,8 +1977,8 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
pnode->fOneShot = true;
if (fFeeler)
pnode->fFeeler = true;
- if (fAddnode)
- pnode->fAddnode = true;
+ if (manual_connection)
+ pnode->m_manual_connection = true;
m_msgproc->InitializeNode(pnode);
{
@@ -2204,9 +2222,8 @@ CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSe
nLastNodeId = 0;
nSendBufferMaxSize = 0;
nReceiveFloodSize = 0;
- semOutbound = nullptr;
- semAddnode = nullptr;
flagInterruptMsgProc = false;
+ SetTryNewOutboundPeer(false);
Options connOptions;
Init(connOptions);
@@ -2310,11 +2327,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
if (semOutbound == nullptr) {
// initialize semaphore
- semOutbound = new CSemaphore(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
+ semOutbound = MakeUnique<CSemaphore>(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
}
if (semAddnode == nullptr) {
// initialize semaphore
- semAddnode = new CSemaphore(nMaxAddnode);
+ semAddnode = MakeUnique<CSemaphore>(nMaxAddnode);
}
//
@@ -2437,10 +2454,8 @@ void CConnman::Stop()
vNodes.clear();
vNodesDisconnected.clear();
vhListenSocket.clear();
- delete semOutbound;
- semOutbound = nullptr;
- delete semAddnode;
- semAddnode = nullptr;
+ semOutbound.reset();
+ semAddnode.reset();
}
void CConnman::DeleteNode(CNode* pnode)
@@ -2488,9 +2503,8 @@ std::vector<CAddress> CConnman::GetAddresses()
bool CConnman::AddNode(const std::string& strNode)
{
LOCK(cs_vAddedNodes);
- for(std::vector<std::string>::const_iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
- if (strNode == *it)
- return false;
+ for (const std::string& it : vAddedNodes) {
+ if (strNode == it) return false;
}
vAddedNodes.push_back(strNode);
@@ -2516,9 +2530,11 @@ size_t CConnman::GetNodeCount(NumConnections flags)
return vNodes.size();
int nNum = 0;
- for(std::vector<CNode*>::const_iterator it = vNodes.begin(); it != vNodes.end(); ++it)
- if (flags & ((*it)->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
+ for (const auto& pnode : vNodes) {
+ if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
nNum++;
+ }
+ }
return nNum;
}
@@ -2528,8 +2544,7 @@ void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
vstats.clear();
LOCK(cs_vNodes);
vstats.reserve(vNodes.size());
- for(std::vector<CNode*>::iterator it = vNodes.begin(); it != vNodes.end(); ++it) {
- CNode* pnode = *it;
+ for (CNode* pnode : vNodes) {
vstats.emplace_back();
pnode->copyStats(vstats.back());
}
@@ -2696,7 +2711,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
nSendVersion(0)
{
nServices = NODE_NONE;
- nServicesExpected = NODE_NONE;
hSocket = hSocketIn;
nRecvVersion = INIT_PROTO_VERSION;
nLastSend = 0;
@@ -2709,7 +2723,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
strSubVer = "";
fWhitelisted = false;
fOneShot = false;
- fAddnode = false;
+ m_manual_connection = false;
fClient = false; // set by version message
fFeeler = false;
fSuccessfullyConnected = false;
@@ -2727,7 +2741,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
nNextInvSend = 0;
fRelayTxes = false;
fSentAddr = false;
- pfilter = new CBloomFilter();
+ pfilter = MakeUnique<CBloomFilter>();
timeLastMempoolReq = 0;
nLastBlockTime = 0;
nLastTXTime = 0;
@@ -2757,9 +2771,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
CNode::~CNode()
{
CloseSocket(hSocket);
-
- if (pfilter)
- delete pfilter;
}
void CNode::AskFor(const CInv& inv)