diff --git a/src/net.cpp b/src/net.cpp index abc492e2b..bbd23d292 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -56,7 +56,6 @@ #endif #endif -using namespace std; namespace { const int MAX_OUTBOUND_CONNECTIONS = 8; @@ -78,7 +77,7 @@ bool fDiscover = true; bool fListen = true; uint64_t nLocalServices = NODE_NETWORK; CCriticalSection cs_mapLocalHost; -map mapLocalHost; +std::map mapLocalHost; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; @@ -88,20 +87,17 @@ int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; bool fAddressesInitialized = false; std::string strSubVersion; -vector vNodes; +std::vector vNodes; CCriticalSection cs_vNodes; -map mapRelay; -deque > vRelayExpiration; +std::map mapRelay; +std::deque > vRelayExpiration; CCriticalSection cs_mapRelay; limitedmap mapAlreadyAskedFor(MAX_INV_SZ); -static deque vOneShots; +static std::deque vOneShots; CCriticalSection cs_vOneShots; -set setservAddNodeAddresses; -CCriticalSection cs_setservAddNodeAddresses; - -vector vAddedNodes; +std::vector vAddedNodes; CCriticalSection cs_vAddedNodes; NodeId nLastNodeId = 0; @@ -135,7 +131,7 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer) int nBestReachability = -1; { LOCK(cs_mapLocalHost); - for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) + for (std::map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) { int nScore = (*it).second.nScore; int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); @@ -426,6 +422,26 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) return NULL; } +static void DumpBanlist() +{ + CNode::SweepBanned(); // clean unused entries (if bantime has expired) + + if (!CNode::BannedSetIsDirty()) + return; + + int64_t nStart = GetTimeMillis(); + + CBanDB bandb; + banmap_t banmap; + CNode::SetBannedSetDirty(false); + CNode::GetBanned(banmap); + if (!bandb.Write(banmap)) + CNode::SetBannedSetDirty(true); + + LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", + banmap.size(), GetTimeMillis() - nStart); +} + void CNode::CloseSocketDisconnect() { fDisconnect = true; @@ -443,7 +459,7 @@ void CNode::CloseSocketDisconnect() void CNode::PushVersion() { - int nBestHeight = g_signals.GetHeight().get_value_or(0); + int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0); int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); @@ -467,9 +483,13 @@ bool CNode::setBannedIsDirty; void CNode::ClearBanned() { - LOCK(cs_setBanned); - setBanned.clear(); - setBannedIsDirty = true; + { + LOCK(cs_setBanned); + setBanned.clear(); + setBannedIsDirty = true; + } + DumpBanlist(); //store banlist to disk + uiInterface.BannedListChanged(); } bool CNode::IsBanned(CNetAddr ip) @@ -520,11 +540,25 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; - LOCK(cs_setBanned); - if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) - setBanned[subNet] = banEntry; - - setBannedIsDirty = true; + { + LOCK(cs_setBanned); + if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) { + setBanned[subNet] = banEntry; + setBannedIsDirty = true; + } + else + return; + } + uiInterface.BannedListChanged(); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (subNet.Match((CNetAddr)pnode->addr)) + pnode->fDisconnect = true; + } + } + if(banReason == BanReasonManuallyAdded) + DumpBanlist(); //store banlist to disk immediately if user requested ban } bool CNode::Unban(const CNetAddr &addr) { @@ -533,13 +567,15 @@ bool CNode::Unban(const CNetAddr &addr) { } bool CNode::Unban(const CSubNet &subNet) { - LOCK(cs_setBanned); - if (setBanned.erase(subNet)) { + LOCK(cs_setBanned); + if (!setBanned.erase(subNet)) + return false; setBannedIsDirty = true; - return true; } - return false; + uiInterface.BannedListChanged(); + DumpBanlist(); //store banlist to disk immediately + return true; } void CNode::GetBanned(banmap_t &banMap) @@ -796,53 +832,24 @@ void SocketSendData(CNode *pnode) pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it); } -static list vNodesDisconnected; +static std::list vNodesDisconnected; -class CNodeRef { -public: - CNodeRef(CNode *pnode) : _pnode(pnode) { - LOCK(cs_vNodes); - _pnode->AddRef(); - } - - ~CNodeRef() { - LOCK(cs_vNodes); - _pnode->Release(); - } - - CNode& operator *() const {return *_pnode;}; - CNode* operator ->() const {return _pnode;}; - - CNodeRef& operator =(const CNodeRef& other) - { - if (this != &other) { - LOCK(cs_vNodes); - - _pnode->Release(); - _pnode = other._pnode; - _pnode->AddRef(); - } - return *this; - } - - CNodeRef(const CNodeRef& other): - _pnode(other._pnode) - { - LOCK(cs_vNodes); - _pnode->AddRef(); - } -private: - CNode *_pnode; +struct NodeEvictionCandidate +{ + NodeId id; + int64_t nTimeConnected; + int64_t nMinPingUsecTime; + CAddress addr; }; -static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b) +static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { - return a->nMinPingUsecTime > b->nMinPingUsecTime; + return a.nMinPingUsecTime > b.nMinPingUsecTime; } -static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b) +static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { - return a->nTimeConnected > b->nTimeConnected; + return a.nTimeConnected > b.nTimeConnected; } class CompareNetGroupKeyed @@ -855,14 +862,14 @@ public: GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); } - bool operator()(const CNodeRef &a, const CNodeRef &b) + bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) { std::vector vchGroupA, vchGroupB; CSHA256 hashA, hashB; std::vector vchA(32), vchB(32); - vchGroupA = a->addr.GetGroup(); - vchGroupB = b->addr.GetGroup(); + vchGroupA = a.addr.GetGroup(); + vchGroupB = b.addr.GetGroup(); hashA.Write(begin_ptr(vchGroupA), vchGroupA.size()); hashB.Write(begin_ptr(vchGroupB), vchGroupB.size()); @@ -886,7 +893,7 @@ public: * simultaneously better at all of them than honest peers. */ static bool AttemptToEvictConnection(bool fPreferNewConnection) { - std::vector vEvictionCandidates; + std::vector vEvictionCandidates; { LOCK(cs_vNodes); @@ -897,7 +904,8 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - vEvictionCandidates.push_back(CNodeRef(node)); + NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr}; + vEvictionCandidates.push_back(candidate); } } @@ -932,16 +940,16 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { std::vector naMostConnections; unsigned int nMostConnections = 0; int64_t nMostConnectionsTime = 0; - std::map, std::vector > mapAddrCounts; - BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { - mapAddrCounts[node->addr.GetGroup()].push_back(node); - int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected; - size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size(); + std::map, std::vector > mapAddrCounts; + BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) { + mapAddrCounts[node.addr.GetGroup()].push_back(node); + int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected; + size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size(); if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { nMostConnections = groupsize; nMostConnectionsTime = grouptime; - naMostConnections = node->addr.GetGroup(); + naMostConnections = node.addr.GetGroup(); } } @@ -956,9 +964,15 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { return false; // Disconnect from the network group with the most connections - vEvictionCandidates[0]->fDisconnect = true; - - return true; + NodeId evicted = vEvictionCandidates.front().id; + LOCK(cs_vNodes); + for(std::vector::const_iterator it(vNodes.begin()); it != vNodes.end(); ++it) { + if ((*it)->GetId() == evicted) { + (*it)->fDisconnect = true; + return true; + } + } + return false; } static void AcceptConnection(const ListenSocket& hListenSocket) { @@ -1045,7 +1059,7 @@ void ThreadSocketHandler() { LOCK(cs_vNodes); // Disconnect unused nodes - vector vNodesCopy = vNodes; + std::vector vNodesCopy = vNodes; BOOST_FOREACH(CNode* pnode, vNodesCopy) { if (pnode->fDisconnect || @@ -1069,7 +1083,7 @@ void ThreadSocketHandler() } { // Delete disconnected nodes - list vNodesDisconnectedCopy = vNodesDisconnected; + std::list vNodesDisconnectedCopy = vNodesDisconnected; BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy) { // wait until threads are done using it @@ -1120,7 +1134,7 @@ void ThreadSocketHandler() BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) { FD_SET(hListenSocket.socket, &fdsetRecv); - hSocketMax = max(hSocketMax, hListenSocket.socket); + hSocketMax = std::max(hSocketMax, hListenSocket.socket); have_fds = true; } @@ -1131,7 +1145,7 @@ void ThreadSocketHandler() if (pnode->hSocket == INVALID_SOCKET) continue; FD_SET(pnode->hSocket, &fdsetError); - hSocketMax = max(hSocketMax, pnode->hSocket); + hSocketMax = std::max(hSocketMax, pnode->hSocket); have_fds = true; // Implement the following logic: @@ -1198,7 +1212,7 @@ void ThreadSocketHandler() // // Service each socket // - vector vNodesCopy; + std::vector vNodesCopy; { LOCK(cs_vNodes); vNodesCopy = vNodes; @@ -1355,7 +1369,7 @@ void ThreadMapPort() } } - string strDesc = "Bitcoin " + FormatFullVersion(); + std::string strDesc = "Bitcoin " + FormatFullVersion(); try { while (true) { @@ -1441,7 +1455,7 @@ void ThreadDNSAddressSeed() } } - const vector &vSeeds = Params().DNSSeeds(); + const std::vector &vSeeds = Params().DNSSeeds(); int found = 0; LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); @@ -1450,8 +1464,8 @@ void ThreadDNSAddressSeed() if (HaveNameProxy()) { AddOneShot(seed.host); } else { - vector vIPs; - vector vAdd; + std::vector vIPs; + std::vector vAdd; if (LookupHost(seed.host.c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) @@ -1508,7 +1522,7 @@ void DumpData() void static ProcessOneShot() { - string strDest; + std::string strDest; { LOCK(cs_vOneShots); if (vOneShots.empty()) @@ -1574,7 +1588,7 @@ void ThreadOpenConnections() // 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; - set > setConnected; + std::set > setConnected; { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { @@ -1632,7 +1646,7 @@ void ThreadOpenAddedConnections() if (HaveNameProxy()) { while(true) { - list lAddresses(0); + std::list lAddresses(0); { LOCK(cs_vAddedNodes); BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) @@ -1650,32 +1664,25 @@ void ThreadOpenAddedConnections() for (unsigned int i = 0; true; i++) { - list lAddresses(0); + std::list lAddresses(0); { LOCK(cs_vAddedNodes); BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) lAddresses.push_back(strAddNode); } - list > lservAddressesToAdd(0); + std::list > lservAddressesToAdd(0); BOOST_FOREACH(const std::string& strAddNode, lAddresses) { - vector vservNode(0); + std::vector vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) - { lservAddressesToAdd.push_back(vservNode); - { - LOCK(cs_setservAddNodeAddresses); - BOOST_FOREACH(const CService& serv, vservNode) - setservAddNodeAddresses.insert(serv); - } - } } // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry // (keeping in mind that addnode entries can have many IPs if fNameLookup) { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) - for (list >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) + for (std::list >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) BOOST_FOREACH(const CService& addrNode, *(it)) if (pnode->addr == addrNode) { @@ -1684,7 +1691,7 @@ void ThreadOpenAddedConnections() break; } } - BOOST_FOREACH(vector& vserv, lservAddressesToAdd) + BOOST_FOREACH(std::vector& vserv, lservAddressesToAdd) { CSemaphoreGrant grant(*semOutbound); OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant); @@ -1731,7 +1738,7 @@ void ThreadMessageHandler() while (true) { - vector vNodesCopy; + std::vector vNodesCopy; { LOCK(cs_vNodes); vNodesCopy = vNodes; @@ -1752,7 +1759,7 @@ void ThreadMessageHandler() TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); if (lockRecv) { - if (!g_signals.ProcessMessages(pnode)) + if (!GetNodeSignals().ProcessMessages(pnode)) pnode->CloseSocketDisconnect(); if (pnode->nSendSize < SendBufferSize()) @@ -1770,7 +1777,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode); + GetNodeSignals().SendMessages(pnode); } boost::this_thread::interruption_point(); } @@ -1791,7 +1798,7 @@ void ThreadMessageHandler() -bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted) +bool BindListenPort(const CService &addrBind, std::string& strError, bool fWhitelisted) { strError = ""; int nOne = 1; @@ -1899,7 +1906,7 @@ void static Discover(boost::thread_group& threadGroup) char pszHostName[256] = ""; if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { - vector vaddr; + std::vector vaddr; if (LookupHost(pszHostName, vaddr, 0, true)) { BOOST_FOREACH (const CNetAddr &addr, vaddr) @@ -2300,7 +2307,7 @@ bool CAddrDB::Read(CAddrMan& addr) // Don't try to resize to a negative number if file is small if (fileSize >= sizeof(uint256)) dataSize = fileSize - sizeof(uint256); - vector vchData; + std::vector vchData; vchData.resize(dataSize); uint256 hashIn; @@ -2587,7 +2594,7 @@ bool CBanDB::Read(banmap_t& banSet) // Don't try to resize to a negative number if file is small if (fileSize >= sizeof(uint256)) dataSize = fileSize - sizeof(uint256); - vector vchData; + std::vector vchData; vchData.resize(dataSize); uint256 hashIn; @@ -2627,26 +2634,6 @@ bool CBanDB::Read(banmap_t& banSet) return true; } -void DumpBanlist() -{ - CNode::SweepBanned(); // clean unused entries (if bantime has expired) - - if (!CNode::BannedSetIsDirty()) - return; - - int64_t nStart = GetTimeMillis(); - - CBanDB bandb; - banmap_t banmap; - CNode::SetBannedSetDirty(false); - CNode::GetBanned(banmap); - if (!bandb.Write(banmap)) - CNode::SetBannedSetDirty(true); - - LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", - banmap.size(), GetTimeMillis() - nStart); -} - int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); } diff --git a/src/net.h b/src/net.h index 9ab820ca6..998ee4926 100644 --- a/src/net.h +++ b/src/net.h @@ -83,7 +83,6 @@ CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const CSubNet& subNet); CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); -CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); void MapPort(bool fUseUPnP); unsigned short GetListenPort(); @@ -808,8 +807,6 @@ public: bool Read(banmap_t& banSet); }; -void DumpBanlist(); - /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index d8647d902..18552f073 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -885,15 +885,13 @@ void RPCConsole::banSelectedNode(int bantime) // Get currently selected peer address QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address); // Find possible nodes, ban it and clear the selected node - if (CNode *bannedNode = FindNode(strNode.toStdString())) { + if (FindNode(strNode.toStdString())) { std::string nStr = strNode.toStdString(); std::string addr; int port = 0; SplitHostPort(nStr, port, addr); CNode::Ban(CNetAddr(addr), BanReasonManuallyAdded, bantime); - bannedNode->fDisconnect = true; - DumpBanlist(); clearSelectedNode(); clientModel->getBanTableModel()->refresh(); @@ -912,7 +910,6 @@ void RPCConsole::unbanSelectedNode() if (possibleSubnet.IsValid()) { CNode::Unban(possibleSubnet); - DumpBanlist(); clientModel->getBanTableModel()->refresh(); } } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 320091b9c..e09af8965 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -565,20 +565,12 @@ UniValue setban(const UniValue& params, bool fHelp) absolute = true; isSubnet ? CNode::Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : CNode::Ban(netAddr, BanReasonManuallyAdded, banTime, absolute); - - //disconnect possible nodes - while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr))) - bannedNode->fDisconnect = true; } else if(strCommand == "remove") { if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) )) throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed"); } - - DumpBanlist(); //store banlist to disk - uiInterface.BannedListChanged(); - return NullUniValue; } @@ -624,8 +616,6 @@ UniValue clearbanned(const UniValue& params, bool fHelp) ); CNode::ClearBanned(); - DumpBanlist(); //store banlist to disk - uiInterface.BannedListChanged(); return NullUniValue; }