X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fnet.cpp;h=f71169668a979a577e309a6ae58f441f44cad70a;hb=a33d7eb5d68a409e6527f9a25472b3f981118089;hp=7255cab3f70c77010399fb998047db72841d9c15;hpb=cecf7a56ed5a5efd939b21c760c69da616306005;p=novacoin.git diff --git a/src/net.cpp b/src/net.cpp index 7255cab..f711696 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -12,12 +12,7 @@ #include "miner.h" #include "ntp.h" -#ifdef WIN32 -#include -#endif - using namespace std; -using namespace boost; static const int MAX_OUTBOUND_CONNECTIONS = 16; @@ -57,8 +52,8 @@ static CNode* pnodeLocalHost = NULL; static CNode* pnodeSync = NULL; CAddress addrSeenByPeer(CService("0.0.0.0", nPortZero), nLocalServices); uint64_t nLocalHostNonce = 0; -boost::array vnThreadsRunning; -static std::vector vhListenSocket; +array vnThreadsRunning; +static vector vhListenSocket; CAddrMan addrman; vector vNodes; @@ -74,7 +69,7 @@ CCriticalSection cs_vOneShots; set setservAddNodeAddresses; CCriticalSection cs_setservAddNodeAddresses; -vector vAddedNodes; +vector vAddedNodes; CCriticalSection cs_vAddedNodes; static CSemaphore *semOutbound = NULL; @@ -85,9 +80,9 @@ void AddOneShot(string strDest) vOneShots.push_back(strDest); } -unsigned short GetListenPort() +uint16_t GetListenPort() { - return (unsigned short)(GetArg("-port", GetDefaultPort())); + return static_cast(GetArg("-port", GetDefaultPort())); } void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd) @@ -111,7 +106,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 (auto it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) { int nScore = (*it).second.nScore; int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); @@ -196,11 +191,11 @@ bool RecvLine(SOCKET hSocket, string& strLine) void static AdvertizeLocal() { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) { if (pnode->fSuccessfullyConnected) { - CAddress addrLocal = GetLocalAddress(&pnode->addr); + auto addrLocal = GetLocalAddress(&pnode->addr); if (addrLocal.IsRoutable() && (CService)addrLocal != pnode->addrLocal) { pnode->PushAddress(addrLocal); @@ -218,6 +213,44 @@ void SetReachable(enum Network net, bool fFlag) vfReachable[NET_IPV4] = true; } +int GetnScore(const CService& addr) +{ + LOCK(cs_mapLocalHost); + if (mapLocalHost.count(addr) == LOCAL_NONE) + return 0; + return mapLocalHost[addr].nScore; +} + + +// Is our peer's addrLocal potentially useful as an external IP source? +bool IsPeerAddrLocalGood(CNode *pnode) +{ + return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() && + !IsLimited(pnode->addrLocal.GetNetwork()); +} + +// pushes our own address to a peer +void AdvertiseLocal(CNode *pnode) +{ + if (!fNoListen && pnode->fSuccessfullyConnected) + { + auto addrLocal = GetLocalAddress(&pnode->addr); + // If discovery is enabled, sometimes give our peer the address it + // tells us that it sees us as in case it has a better idea of our + // address than we do. + if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() || + GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0)) + { + addrLocal.SetIP(pnode->addrLocal); + } + if (addrLocal.IsRoutable()) + { + printf("AdvertiseLocal: advertising address %s\n", addrLocal.ToString().c_str()); + pnode->PushAddress(addrLocal); + } + } +} + // learn a new local address bool AddLocal(const CService& addr, int nScore) { @@ -308,13 +341,15 @@ extern int GetExternalIPbySTUN(uint64_t rnd, struct sockaddr_in *mapped, const c // We now get our external IP from the IRC server first and only use this as a backup bool GetMyExternalIP(CNetAddr& ipRet) { - struct sockaddr_in mapped; - uint64_t rnd = std::numeric_limits::max(); + struct sockaddr_in mapped = {}; + auto rnd = GetRand(numeric_limits::max()); const char *srv; int rc = GetExternalIPbySTUN(rnd, &mapped, &srv); if(rc >= 0) { ipRet = CNetAddr(mapped.sin_addr); - printf("GetExternalIPbySTUN(%" PRIu64 ") returned %s in attempt %d; Server=%s\n", rnd, ipRet.ToStringIP().c_str(), rc, srv); + if (fDebugNet) { + printf("GetExternalIPbySTUN(%" PRIu64 ") returned %s in attempt %d; Server=%s\n", rnd, ipRet.ToStringIP().c_str(), rc, srv); + } return true; } return false; @@ -333,10 +368,6 @@ void ThreadGetMyExternalIP(void* parg) } } - - - - void AddressCurrentlyConnected(const CService& addr) { addrman.Connected(addr); @@ -353,16 +384,16 @@ CCriticalSection CNode::cs_totalBytesSent; CNode* FindNode(const CNetAddr& ip) { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) if ((CNetAddr)pnode->addr == ip) return (pnode); return NULL; } -CNode* FindNode(std::string addrName) +CNode* FindNode(string addrName) { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) if (pnode->addrName == addrName) return (pnode); return NULL; @@ -371,7 +402,7 @@ CNode* FindNode(std::string addrName) CNode* FindNode(const CService& addr) { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) if ((CService)pnode->addr == addr) return (pnode); return NULL; @@ -441,6 +472,194 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64_t nTimeout) } } +CNode::CNode(SOCKET hSocketIn, CAddress addrIn, string addrNameIn, bool fInboundIn) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) +{ + nServices = 0; + hSocket = hSocketIn; + nLastSend = 0; + nLastRecv = 0; + nSendBytes = 0; + nRecvBytes = 0; + nLastSendEmpty = GetTime(); + nTimeConnected = GetTime(); + nHeaderStart = -1; + nMessageStart = numeric_limits::max(); + addr = addrIn; + addrName = addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn; + nVersion = 0; + strSubVer.clear(); + fOneShot = false; + fClient = false; // set by version message + fInbound = fInboundIn; + fNetworkNode = false; + fSuccessfullyConnected = false; + fDisconnect = false; + nRefCount = 0; + nReleaseTime = 0; + hashContinue = 0; + pindexLastGetBlocksBegin = 0; + hashLastGetBlocksEnd = 0; + nStartingHeight = -1; + nNextLocalAddrSend = 0; + nNextAddrSend = 0; + nNextInvSend = 0; + fStartSync = false; + fGetAddr = false; + nMisbehavior = 0; + hashCheckpointKnown = 0; + setInventoryKnown.max_size((size_t)SendBufferSize() / 1000); + + // Be shy and don't send version until we hear + if (hSocket != INVALID_SOCKET && !fInbound) + PushVersion(); +} + +CNode::~CNode() +{ + if (hSocket != INVALID_SOCKET) + { + CloseSocket(hSocket); + } +} + +int CNode::GetRefCount() +{ + return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); +} + +CNode* CNode::AddRef(int64_t nTimeout) +{ + if (nTimeout != 0) + nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); + else + nRefCount++; + return this; +} + +void CNode::Release() +{ + nRefCount--; +} + +void CNode::AddAddressKnown(const CAddress& addr) +{ + setAddrKnown.insert(addr); +} + +void CNode::PushAddress(const CAddress& addr) +{ + // Known checking here is only to save space from duplicates. + // SendMessages will filter it again for knowns that were added + // after addresses were pushed. + if (addr.IsValid() && !setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); +} + +void CNode::AddInventoryKnown(const CInv& inv) +{ + { + LOCK(cs_inventory); + setInventoryKnown.insert(inv); + } +} + +void CNode::PushInventory(const CInv& inv) +{ + { + LOCK(cs_inventory); + if (!setInventoryKnown.count(inv)) + vInventoryToSend.push_back(inv); + } +} + +void CNode::AskFor(const CInv& inv) +{ + // We're using mapAskFor as a priority queue, + // the key is the earliest time the request can be sent + int64_t& nRequestTime = mapAlreadyAskedFor[inv]; + if (fDebugNet) + printf("askfor %s %" PRId64 " (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str()); + + // Make sure not to reuse time indexes to keep things in the same order + int64_t nNow = (GetTime() - 1) * 1000000; + static int64_t nLastTime; + ++nLastTime; + nNow = max(nNow, nLastTime); + nLastTime = nNow; + + // Each retry is 2 minutes after the last + nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); + mapAskFor.insert({ nRequestTime, inv }); +} + +void CNode::BeginMessage(const char* pszCommand) +{ + ENTER_CRITICAL_SECTION(cs_vSend); + if (nHeaderStart != -1) + AbortMessage(); + nHeaderStart = (int32_t)vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + nMessageStart = (uint32_t)vSend.size(); + if (fDebug) + printf("sending: %s ", pszCommand); +} + +void CNode::AbortMessage() +{ + if (nHeaderStart < 0) + return; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = numeric_limits::max(); + LEAVE_CRITICAL_SECTION(cs_vSend); + + if (fDebug) + printf("(aborted)\n"); +} + +void CNode::EndMessage() +{ + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessages DROPPING SEND MESSAGE\n"); + AbortMessage(); + return; + } + + if (nHeaderStart < 0) + return; + + // Set the size + uint32_t nSize = (uint32_t) vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize)); + + // Set the checksum + auto hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + uint32_t nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum)); + + if (fDebug) { + printf("(%d bytes)\n", nSize); + } + + nHeaderStart = -1; + nMessageStart = numeric_limits::max(); + LEAVE_CRITICAL_SECTION(cs_vSend); +} + +void CNode::EndMessageAbortIfEmpty() +{ + if (nHeaderStart < 0) + return; + int nSize = (int) vSend.size() - nMessageStart; + if (nSize > 0) + EndMessage(); + else + AbortMessage(); +} + void CNode::CloseSocketDisconnect() { fDisconnect = true; @@ -468,7 +687,7 @@ void CNode::Cleanup() void CNode::PushVersion() { - int64_t nTime = GetAdjustedTime(); + auto nTime = GetAdjustedTime(); CAddress addrYou, addrMe; bool fHidden = false; @@ -493,14 +712,14 @@ void CNode::PushVersion() RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str()); PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()), nBestHeight); + nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, vector()), nBestHeight); } -std::map CNode::setBanned; +map CNode::setBanned; CCriticalSection CNode::cs_setBanned; void CNode::ClearBanned() @@ -513,10 +732,10 @@ bool CNode::IsBanned(CNetAddr ip) bool fResult = false; { LOCK(cs_setBanned); - std::map::iterator i = setBanned.find(ip); + auto i = setBanned.find(ip); if (i != setBanned.end()) { - int64_t t = (*i).second; + auto t = (*i).second; if (GetTime() < t) fResult = true; } @@ -535,7 +754,7 @@ bool CNode::Misbehaving(int howmuch) nMisbehavior += howmuch; if (nMisbehavior >= GetArgInt("-banscore", 100)) { - int64_t banTime = GetTime()+GetArg("-bantime", nOneDay); // Default 24-hour ban + auto banTime = GetTime()+GetArg("-bantime", nOneDay); // Default 24-hour ban printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior); { LOCK(cs_setBanned); @@ -589,7 +808,7 @@ void ThreadSocketHandler(void* parg) ThreadSocketHandler2(parg); vnThreadsRunning[THREAD_SOCKETHANDLER]--; } - catch (std::exception& e) { + catch (exception& e) { vnThreadsRunning[THREAD_SOCKETHANDLER]--; PrintException(&e, "ThreadSocketHandler()"); } catch (...) { @@ -614,7 +833,7 @@ void ThreadSocketHandler2(void* parg) LOCK(cs_vNodes); // Disconnect unused nodes vector vNodesCopy = vNodes; - BOOST_FOREACH(CNode* pnode, vNodesCopy) + for(CNode* pnode : vNodesCopy) { if (pnode->fDisconnect || (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) @@ -639,7 +858,7 @@ void ThreadSocketHandler2(void* parg) // Delete disconnected nodes list vNodesDisconnectedCopy = vNodesDisconnected; - BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy) + for(CNode* pnode : vNodesDisconnectedCopy) { // wait until threads are done using it if (pnode->GetRefCount() <= 0) @@ -693,14 +912,14 @@ void ThreadSocketHandler2(void* parg) SOCKET hSocketMax = 0; bool have_fds = false; - BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) { + for(SOCKET hListenSocket : vhListenSocket) { FD_SET(hListenSocket, &fdsetRecv); hSocketMax = max(hSocketMax, hListenSocket); have_fds = true; } { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) { if (pnode->hSocket == INVALID_SOCKET) continue; @@ -740,7 +959,7 @@ void ThreadSocketHandler2(void* parg) // // Accept new connections // - BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + for(SOCKET hListenSocket : vhListenSocket) if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv)) { #ifdef USE_IPV6 @@ -759,7 +978,7 @@ void ThreadSocketHandler2(void* parg) { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) if (pnode->fInbound) nInbound++; } @@ -803,10 +1022,10 @@ void ThreadSocketHandler2(void* parg) { LOCK(cs_vNodes); vNodesCopy = vNodes; - BOOST_FOREACH(CNode* pnode, vNodesCopy) + for(CNode* pnode : vNodesCopy) pnode->AddRef(); } - BOOST_FOREACH(CNode* pnode, vNodesCopy) + for(CNode* pnode : vNodesCopy) { if (fShutdown) return; @@ -931,17 +1150,6 @@ void ThreadSocketHandler2(void* parg) } } -// DNS seeds -// Each pair gives a source name and a seed name. -// The first name is used as information source for addrman. -// The second name should resolve to a list of seed addresses. -static const char *strDNSSeed[][2] = { - {"novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro"}, - {"novacoin.ru", "dnsseed.novacoin.ru"}, - {"novacoin.ru", "testseed.novacoin.ru"}, - {"novaco.in", "dnsseed.novaco.in"}, -}; - void ThreadDNSAddressSeed(void* parg) { // Make this thread recognisable as the DNS seeding thread @@ -953,7 +1161,7 @@ void ThreadDNSAddressSeed(void* parg) ThreadDNSAddressSeed2(parg); vnThreadsRunning[THREAD_DNSSEED]--; } - catch (std::exception& e) { + catch (exception& e) { vnThreadsRunning[THREAD_DNSSEED]--; PrintException(&e, "ThreadDNSAddressSeed()"); } catch (...) { @@ -970,25 +1178,35 @@ void ThreadDNSAddressSeed2(void* parg) if (!fTestNet) { + // DNS seeds + // Each pair gives a source name and a seed name. + // The first name is used as information source for addrman. + // The second name should resolve to a list of seed addresses. + static const vector > vstrDNSSeed = { + { "node.novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro" }, + { "novacoin.ru", "dnsseed.novacoin.ru" }, + { "novacoin.ru", "testseed.novacoin.ru" }, + { "novaco.in", "dnsseed.novaco.in" }, + }; printf("Loading addresses from DNS seeds (could take a while)\n"); - for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { + for (unsigned int seed_idx = 0; seed_idx < vstrDNSSeed.size(); seed_idx++) { if (HaveNameProxy()) { - AddOneShot(strDNSSeed[seed_idx][1]); + AddOneShot(vstrDNSSeed[seed_idx].second); } else { vector vaddr; vector vAdd; - if (LookupHost(strDNSSeed[seed_idx][1], vaddr)) + if (LookupHost(vstrDNSSeed[seed_idx].second, vaddr)) { - BOOST_FOREACH(CNetAddr& ip, vaddr) + for(CNetAddr& ip : vaddr) { - CAddress addr = CAddress(CService(ip, GetDefaultPort())); + auto addr = CAddress(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old vAdd.push_back(addr); found++; } } - addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true)); + addrman.Add(vAdd, CNetAddr(vstrDNSSeed[seed_idx].first, true)); } } } @@ -996,58 +1214,9 @@ void ThreadDNSAddressSeed2(void* parg) printf("%d addresses found from DNS seeds\n", found); } - - - - - - - - - - - -uint32_t pnSeed[] = -{ - 0xa52bf0da, 0x30aa43d8, 0x614488d5, 0x517b6fd5, 0xd4bf62d4, 0xb7d638d4, 0xbc12bcd1, 0xa2501bc6, - 0xfde617c6, 0x3337b1c6, 0x1dcd71c3, 0x2c1544c1, 0xe05f6ac1, 0x852f63c0, 0x3e2363c0, 0x15f563c0, - 0x430d63c0, 0x50d6a9c0, 0xf0a679c0, 0xefdeedbf, 0x7aaee8bc, 0x3a3dbbbc, 0xef218abc, 0x0bef78bc, - 0x8baa3eb2, 0x2bf913b2, 0x24ed9fb2, 0xb42289b2, 0x718a09b0, 0xe9433eb0, 0x559425b0, 0xc97e1fb0, - 0x18e1d4b0, 0x8f6cc1b0, 0xac3838ae, 0x86c0ffad, 0x6b0272a7, 0xa463f8a2, 0x6f17f3a2, 0xb3d6f3a2, - 0x9cd8f997, 0xd513fb94, 0x39e64880, 0x3859dd6f, 0x0b08fe6d, 0xe601fe6d, 0xeb44a26d, 0xfe53186c, - 0x203c2e68, 0x1c542868, 0x0caa8368, 0xb8748368, 0xccca4762, 0xc637555f, 0x638a545f, 0x59b2205f, - 0x52568c5f, 0xba568c5f, 0x8a568c5f, 0x31b0f45e, 0x54a0f45e, 0x37d6f15e, 0xc520175e, 0x7620175e, - 0xc310175e, 0x8e33b45e, 0x7abb5f5d, 0xd3014c5d, 0xa1e1485d, 0x9947645d, 0xfab8ff5c, 0xa979e65b, - 0xa879e65b, 0x9f79e65b, 0x9fa3d25b, 0x112a925b, 0x7b92905b, 0x60647a5b, 0x1e389d5a, 0x851afa59, - 0x0185ef59, 0x26549b59, 0x1c9efe57, 0xc54c1256, 0x1ad51955, 0x19d21955, 0x73c41955, 0x3f74ee55, - 0x633eea55, 0x6883d655, 0xfb72c655, 0x5360a653, 0x17c1ea52, 0xc661c852, 0x1ecdc852, 0x006a9752, - 0xf72d9252, 0x82650551, 0x36f1c851, 0x33f1c851, 0xd5c1864f, 0xb6bf1b4e, 0x96da184e, 0x40d0234d, - 0x9a96ab4c, 0x8fc2a84c, 0xb5dbd048, 0xf4644447, 0x2d51af47, 0xa9625445, 0x83f05243, 0x89672941, - 0x3a8bad3e, 0xf0a05436, 0x6ab7c936, 0x49971d32, 0xadd4482e, 0xcffd212e, 0x6730bc2e, 0x839aa12e, - 0x68d9692e, 0xc7183b25, 0x6c47bb25, 0x2490bb25, 0xad651c1f, 0x048a861f, 0x6937811f, 0x064b2d05, - 0x4d226805, -}; - -const char* pchTorSeed[] = -{ - "seedp4knqnoei57u.onion", - "seedr3hhlepyi7fd.onion", - "seed3uuomkclbiz4.onion", - "seedeh7qck3ouff5.onion", - "5rg3vq4jagckeckf.onion", - "seedt3sraf53ajiy.onion", - "seedg4qyccsg42oq.onion", - "novaqrtoywpg7jly.onion", - "seed3d5wolqbgrcb.onion", - "seed24u5dwph3qw4.onion", - "mj26ulzbs2oskgym.onion", - "eqon4usunavt76m7.onion", - "seedd3aldwpslzl3.onion" -}; - void DumpAddresses() { - int64_t nStart = GetTimeMillis(); + auto nStart = GetTimeMillis(); CAddrDB adb; adb.Write(addrman); @@ -1080,7 +1249,7 @@ void ThreadDumpAddress(void* parg) { ThreadDumpAddress2(parg); } - catch (std::exception& e) { + catch (exception& e) { PrintException(&e, "ThreadDumpAddress()"); } printf("ThreadDumpAddress exited\n"); @@ -1097,7 +1266,7 @@ void ThreadOpenConnections(void* parg) ThreadOpenConnections2(parg); vnThreadsRunning[THREAD_OPENCONNECTIONS]--; } - catch (std::exception& e) { + catch (exception& e) { vnThreadsRunning[THREAD_OPENCONNECTIONS]--; PrintException(&e, "ThreadOpenConnections()"); } catch (...) { @@ -1135,7 +1304,7 @@ void ThreadOpenConnections2(void* parg) for (int64_t nLoop = 0;; nLoop++) { ProcessOneShot(); - BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"]) + for(string strAddr : mapMultiArgs["-connect"]) { CAddress addr; OpenNetworkConnection(addr, NULL, strAddr.c_str()); @@ -1151,7 +1320,7 @@ void ThreadOpenConnections2(void* parg) } // Initiate network connections - int64_t nStart = GetTime(); + auto nStart = GetTime(); for ( ; ; ) { ProcessOneShot(); @@ -1172,15 +1341,44 @@ void ThreadOpenConnections2(void* parg) // Add seed nodes if IRC isn't working if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet) { - std::vector vAdd; - for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) + vector vnSeed = + { + 0x1c542868, 0x3859dd6f, 0x203c2e68, 0xf145a6bc, 0x638a545f, 0x325da346, 0x385da346, 0xfb2b8d5f, + 0x52568c5f, 0xa979e65b, 0x8de6485d, 0x9f79e65b, 0x048a861f, 0x3388b55f, 0x6ff0b45e, 0x17e81f5f, + 0x6c47bb25, 0x1ecdc852, 0x28263db9, 0x47824e5d, 0x36f1c851, 0x2bf913b2, 0x95923cb3, 0x84e63eb2, + 0xefdeedbf, 0x65200092, 0xf36f6805, 0x42692d05, 0x772c1955, 0xb6bf1b4e, 0x7abb5f5d, 0xdb2fa6bc, + 0x90e911bf, 0x82de565f, 0x694416b2, 0x0ab600bc, 0xfcecbe6d, 0x24ed9fb2, 0x1bb618c2, 0xc64765bb, + 0x4e3d62c3, 0xdba24baa, 0x4b7109b0, 0x12a12cc2, 0xfc01864f, 0x0b69e85b, 0x33922c1f, 0xac611bc6, + 0x2a257155, 0x991d5fc0, 0xbfdabcb1, 0x9b73ee55, 0x5bc2b95d, 0xdef0762e, 0x6ab7c936, 0x9c4416b2, + 0xd60d864f, 0x03671f1f, 0x3b5da346, 0xc6f5c851, 0x5411b2d4, 0xe7c25702, 0x63474fb0, 0x7e11c854, + 0x52381d5f, 0x72fdfe59, 0x51599a05, 0xfb12b2d4, 0xaee4f15e, 0xd0e3f15e, 0x2aa2805f, 0xa1caf15e, + 0x34fe425e, 0x46e1f15e, 0xd7c71955, 0xaeeff15e, 0x47c2af55, 0x563d89b2, 0x67980fd9, 0xc9def15e, + 0x9cc51eb9, 0xdaa7aa6b, 0x78e6871f, 0x0d5d2cb2, 0x7aedf15e, 0x9bcaf15e, 0xe5f7f15e, 0x501c1759, + 0xdfbc4980, 0xa7397f2e, 0x31ea1a02, 0x3a27655e, 0xaa86f05c, 0xdcddf15e, 0x64689cb2, 0xd4bf62d4, + 0xf093eab2, 0x98def15e, 0xb6c5f15e, 0x81e8f15e, 0xe5d2fe59, 0xa312786d, 0x4cf9fe59, 0x8a922c1f, + 0x00c7fe59, 0x1ade565f, 0x9e4116b2, 0x2c36983e, 0x68f8f15e, 0x51b7eab2, 0x76c51eb9, 0x9edd4980, + 0x90ef565f, 0x0dd80857, 0xd513fb94, 0xf5bdeab2, 0xa95277b0, 0x2cf2f15e, 0x1897eab2, 0x924416b2, + 0x985c9b59, 0x30aa43d8, 0xf9c6745f, 0xaf862e5f, 0xe0ceeab2, 0xb9b3eab2, 0x6da4eab2, 0xa4fdeab2, + 0x0fa6c125, 0xe38bbd05, 0x5d922c1f, 0x9bd0eab2, 0x73025e02, 0xc4fd794d, 0x8435b35f, 0x2d01bc2e, + 0xaa2a14d4, 0xa22b07cb, 0xebda6f4f, 0xddc6514e, 0xf23feab2, 0xea1e5256, 0x6147b45e, 0x47d21e4f, + 0x67c41c1f, 0x53ec1a02, 0x352e786d, 0x6bec1a02, 0x78fb4abe, 0xd3014c5d, 0x9fbbeab2, 0x1fc51eb9, + 0x720eeab2, 0x2db5eab2, 0xe8baf65c, 0x521b459e, 0x65c4955f, 0x0e7b915f, 0xa8f37e6d, 0x6d0b465f, + 0xfab8ff5c, 0xf7c27e6d, 0x7345a846, 0x4fd1a7d5, 0xdfc97e6d, 0x26c27e6d, 0xa9de36b2, 0xc615344d, + 0x28ceb95d, 0xa52d895e, 0x18c17e6d, 0x13ec1a02, 0x0ba37125, 0x6c3d344d, 0xb3922c1f, 0x506bbeb0, + 0x4d04994e, 0xa1bbe56d, 0xf62c344d, 0x0847d048, 0x4bdc6451, 0xc95b9a05, 0xbcd3a7d5, 0x29b57125, + 0x0c4d2cb2, 0xf2b8eab2, 0xc2d5b95d, 0x0185ef59, 0x30adeab2, 0xcaf0e92e, 0x756c344d, 0xfd9e252e, + 0xbe5ef3bc, 0x4689344d, 0xb223895e, 0xfcebeaad, 0xb7c0e92e, 0x993c1760, 0xe1e171b0, 0xb857e75b, + 0xbf10002e, 0xb55b2cb2, 0xa90e2cb2, 0x13d6f15e, 0xf8be9225, 0x14ddf15e, 0x06e90305, 0x82472cb2, + }; + vector vAdd; + for (unsigned int i = 0; i < vnSeed.size(); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' of between one and two // weeks ago. struct in_addr ip; - memcpy(&ip, &pnSeed[i], sizeof(ip)); + memcpy(&ip, &vnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; vAdd.push_back(addr); @@ -1191,10 +1389,26 @@ void ThreadOpenConnections2(void* parg) // Add Tor nodes if we have connection with onion router if (mapArgs.count("-tor")) { - std::vector vAdd; - for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++) + const vector vstrTorSeed = + { + "seedp4knqnoei57u.onion", + "seedr3hhlepyi7fd.onion", + "seed3uuomkclbiz4.onion", + "seedeh7qck3ouff5.onion", + "5rg3vq4jagckeckf.onion", + "seedt3sraf53ajiy.onion", + "seedg4qyccsg42oq.onion", + "novaqrtoywpg7jly.onion", + "seed3d5wolqbgrcb.onion", + "seed24u5dwph3qw4.onion", + "mj26ulzbs2oskgym.onion", + "eqon4usunavt76m7.onion", + "seedd3aldwpslzl3.onion" + }; + vector vAdd; + for (unsigned int i = 0; i < vstrTorSeed.size(); i++) { - CAddress addr(CService(pchTorSeed[i], GetDefaultPort())); + CAddress addr(CService(vstrTorSeed[i], GetDefaultPort())); addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; vAdd.push_back(addr); } @@ -1212,7 +1426,7 @@ void ThreadOpenConnections2(void* parg) set > setConnected; { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) { + for(CNode* pnode : vNodes) { if (!pnode->fInbound) { setConnected.insert(pnode->addr.GetGroup()); nOutbound++; @@ -1220,13 +1434,13 @@ void ThreadOpenConnections2(void* parg) } } - int64_t nANow = GetAdjustedTime(); + auto nANow = GetAdjustedTime(); int nTries = 0; for ( ; ; ) { // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections) - CAddress addr = addrman.Select(10 + min(nOutbound,8)*10); + auto addr = addrman.Select(10 + min(nOutbound,8)*10); // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) @@ -1270,7 +1484,7 @@ void ThreadOpenAddedConnections(void* parg) ThreadOpenAddedConnections2(parg); vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; } - catch (std::exception& e) { + catch (exception& e) { vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; PrintException(&e, "ThreadOpenAddedConnections()"); } catch (...) { @@ -1294,10 +1508,10 @@ void ThreadOpenAddedConnections2(void* parg) list lAddresses(0); { LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + for(string& strAddNode : vAddedNodes) lAddresses.push_back(strAddNode); } - BOOST_FOREACH(string& strAddNode, lAddresses) { + for(string& strAddNode : lAddresses) { CAddress addr; CSemaphoreGrant grant(*semOutbound); OpenNetworkConnection(addr, &grant, strAddNode.c_str()); @@ -1315,12 +1529,12 @@ void ThreadOpenAddedConnections2(void* parg) list lAddresses(0); { LOCK(cs_vAddedNodes); - BOOST_FOREACH(string& strAddNode, vAddedNodes) + for(string& strAddNode : vAddedNodes) lAddresses.push_back(strAddNode); } list > lservAddressesToAdd(0); - BOOST_FOREACH(string& strAddNode, lAddresses) + for(string& strAddNode : lAddresses) { vector vservNode(0); if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0)) @@ -1328,7 +1542,7 @@ void ThreadOpenAddedConnections2(void* parg) lservAddressesToAdd.push_back(vservNode); { LOCK(cs_setservAddNodeAddresses); - BOOST_FOREACH(CService& serv, vservNode) + for(CService& serv : vservNode) setservAddNodeAddresses.insert(serv); } } @@ -1337,10 +1551,10 @@ void ThreadOpenAddedConnections2(void* parg) // (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(CNode* pnode : vNodes) + for (auto it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++) { - BOOST_FOREACH(CService& addrNode, *(it)) + for(CService& addrNode : *(it)) if (pnode->addr == addrNode) { it = lservAddressesToAdd.erase(it); @@ -1352,7 +1566,7 @@ void ThreadOpenAddedConnections2(void* parg) break; } } - BOOST_FOREACH(vector& vserv, lservAddressesToAdd) + for(vector& vserv : lservAddressesToAdd) { if (vserv.size() == 0) continue; @@ -1415,7 +1629,7 @@ void static StartSync(const vector &vNodes) { int64_t nBestScore = 0; // Iterate over all nodes - BOOST_FOREACH(CNode* pnode, vNodes) { + for(CNode* pnode : vNodes) { // check preconditions for allowing a sync if (!pnode->fClient && !pnode->fOneShot && !pnode->fDisconnect && pnode->fSuccessfullyConnected && @@ -1447,7 +1661,7 @@ void ThreadMessageHandler(void* parg) ThreadMessageHandler2(parg); vnThreadsRunning[THREAD_MESSAGEHANDLER]--; } - catch (std::exception& e) { + catch (exception& e) { vnThreadsRunning[THREAD_MESSAGEHANDLER]--; PrintException(&e, "ThreadMessageHandler()"); } catch (...) { @@ -1468,7 +1682,7 @@ void ThreadMessageHandler2(void* parg) { LOCK(cs_vNodes); vNodesCopy = vNodes; - BOOST_FOREACH(CNode* pnode, vNodesCopy) { + for(CNode* pnode : vNodesCopy) { pnode->AddRef(); if (pnode == pnodeSync) fHaveSyncNode = true; @@ -1479,10 +1693,7 @@ void ThreadMessageHandler2(void* parg) StartSync(vNodesCopy); // Poll the connected nodes for messages - CNode* pnodeTrickle = NULL; - if (!vNodesCopy.empty()) - pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; - BOOST_FOREACH(CNode* pnode, vNodesCopy) + for(CNode* pnode : vNodesCopy) { // Receive messages { @@ -1497,7 +1708,7 @@ void ThreadMessageHandler2(void* parg) { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - SendMessages(pnode, pnode == pnodeTrickle); + SendMessages(pnode); } if (fShutdown) return; @@ -1556,11 +1767,19 @@ bool BindListenPort(const CService &addrBind, string& strError) #ifndef WIN32 #ifdef SO_NOSIGPIPE // Different way of disabling SIGPIPE on BSD - setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); + if (setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)) == SOCKET_ERROR) + { + printf("WARNING: setsockopt failed\n"); + //TODO: work around problem - may be add CloseSocket and return false? + } #endif // Allow binding if the port is still in TIME_WAIT state after // the program was closed and restarted. Not an issue on windows! - setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); + if (setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)) == SOCKET_ERROR) + { + printf("WARNING: setsockopt failed\n"); + //TODO: work around problem - may be add CloseSocket and return false? + } #endif #ifdef WIN32 @@ -1572,6 +1791,7 @@ bool BindListenPort(const CService &addrBind, string& strError) { strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); + CloseSocket(hSocket); return false; } @@ -1581,14 +1801,26 @@ bool BindListenPort(const CService &addrBind, string& strError) if (addrBind.IsIPv6()) { #ifdef IPV6_V6ONLY #ifdef WIN32 - setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int)); + if (setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int)) == SOCKET_ERROR) + { + printf("WARNING: setsockopt failed\n"); + //TODO: work around problem - may be add CloseSocket and return false? + } #else - setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)); + if (setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)) == SOCKET_ERROR) + { + printf("WARNING: setsockopt failed\n"); + //TODO: work around problem - may be add CloseSocket and return false? + } #endif #endif #ifdef WIN32 - int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED; - setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int)); + int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED; + if (setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int)) == SOCKET_ERROR) + { + printf("WARNING: setsockopt failed\n"); + //TODO: work around problem - may be add CloseSocket and return false? + } #endif } #endif @@ -1636,7 +1868,7 @@ void static Discover() vector vaddr; if (LookupHost(pszHostName, vaddr)) { - BOOST_FOREACH (const CNetAddr &addr, vaddr) + for(const auto &addr : vaddr) { AddLocal(addr, LOCAL_IF); } @@ -1749,7 +1981,7 @@ bool StopNode() printf("StopNode()\n"); fShutdown = true; nTransactionsUpdated++; - int64_t nStart = GetTime(); + auto nStart = GetTime(); { LOCK(cs_main); ThreadScriptCheckQuit(); @@ -1795,18 +2027,18 @@ public: ~CNetCleanup() { // Close sockets - BOOST_FOREACH(CNode* pnode, vNodes) + for(CNode* pnode : vNodes) if (pnode->hSocket != INVALID_SOCKET) CloseSocket(pnode->hSocket); - BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + for(SOCKET hListenSocket : vhListenSocket) if (hListenSocket != INVALID_SOCKET) if (!CloseSocket(hListenSocket)) printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError()); // clean up some globals (to help leak detection) - BOOST_FOREACH(CNode *pnode, vNodes) + for(CNode *pnode : vNodes) delete pnode; - BOOST_FOREACH(CNode *pnode, vNodesDisconnected) + for(CNode *pnode : vNodesDisconnected) delete pnode; vNodes.clear(); vNodesDisconnected.clear(); @@ -1823,6 +2055,16 @@ public: } instance_of_cnetcleanup; +inline void RelayInventory(const CInv& inv) +{ + // Put on lists to offer to the other nodes + { + LOCK(cs_vNodes); + for(CNode* pnode : vNodes) + pnode->PushInventory(inv); + } +} + void RelayTransaction(const CTransaction& tx, const uint256& hash) { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -1844,8 +2086,8 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt } // Save original serialized message so newer versions are preserved - mapRelay.insert(std::make_pair(inv, ss)); - vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); + mapRelay.insert({inv, ss}); + vRelayExpiration.push_back({GetTime() + 15 * 60, inv}); } RelayInventory(inv); @@ -1874,3 +2116,6 @@ uint64_t CNode::GetTotalBytesSent() LOCK(cs_totalBytesSent); return nTotalBytesSent; } +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); +}