Fix ZMQ Notification initialization and shutdown
[bitcoinplatinum.git] / src / net.cpp
blobe18e8d0e29aa30a46b931b223137b5b1ab57465d
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #if defined(HAVE_CONFIG_H)
7 #include "config/bitcoin-config.h"
8 #endif
10 #include "net.h"
12 #include "addrman.h"
13 #include "chainparams.h"
14 #include "clientversion.h"
15 #include "consensus/consensus.h"
16 #include "crypto/common.h"
17 #include "hash.h"
18 #include "primitives/transaction.h"
19 #include "scheduler.h"
20 #include "ui_interface.h"
21 #include "utilstrencodings.h"
23 #ifdef WIN32
24 #include <string.h>
25 #else
26 #include <fcntl.h>
27 #endif
29 #ifdef USE_UPNP
30 #include <miniupnpc/miniupnpc.h>
31 #include <miniupnpc/miniwget.h>
32 #include <miniupnpc/upnpcommands.h>
33 #include <miniupnpc/upnperrors.h>
34 #endif
36 #include <boost/filesystem.hpp>
37 #include <boost/thread.hpp>
39 // Dump addresses to peers.dat every 15 minutes (900s)
40 #define DUMP_ADDRESSES_INTERVAL 900
42 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
43 #define MSG_NOSIGNAL 0
44 #endif
46 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
47 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
48 #ifdef WIN32
49 #ifndef PROTECTION_LEVEL_UNRESTRICTED
50 #define PROTECTION_LEVEL_UNRESTRICTED 10
51 #endif
52 #ifndef IPV6_PROTECTION_LEVEL
53 #define IPV6_PROTECTION_LEVEL 23
54 #endif
55 #endif
57 using namespace std;
59 namespace {
60 const int MAX_OUTBOUND_CONNECTIONS = 8;
62 struct ListenSocket {
63 SOCKET socket;
64 bool whitelisted;
66 ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
71 // Global state variables
73 bool fDiscover = true;
74 bool fListen = true;
75 uint64_t nLocalServices = NODE_NETWORK;
76 CCriticalSection cs_mapLocalHost;
77 map<CNetAddr, LocalServiceInfo> mapLocalHost;
78 static bool vfReachable[NET_MAX] = {};
79 static bool vfLimited[NET_MAX] = {};
80 static CNode* pnodeLocalHost = NULL;
81 uint64_t nLocalHostNonce = 0;
82 static std::vector<ListenSocket> vhListenSocket;
83 CAddrMan addrman;
84 int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
85 bool fAddressesInitialized = false;
86 std::string strSubVersion;
88 vector<CNode*> vNodes;
89 CCriticalSection cs_vNodes;
90 map<CInv, CDataStream> mapRelay;
91 deque<pair<int64_t, CInv> > vRelayExpiration;
92 CCriticalSection cs_mapRelay;
93 limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
95 static deque<string> vOneShots;
96 CCriticalSection cs_vOneShots;
98 set<CNetAddr> setservAddNodeAddresses;
99 CCriticalSection cs_setservAddNodeAddresses;
101 vector<std::string> vAddedNodes;
102 CCriticalSection cs_vAddedNodes;
104 NodeId nLastNodeId = 0;
105 CCriticalSection cs_nLastNodeId;
107 static CSemaphore *semOutbound = NULL;
108 boost::condition_variable messageHandlerCondition;
110 // Signals for message handling
111 static CNodeSignals g_signals;
112 CNodeSignals& GetNodeSignals() { return g_signals; }
114 void AddOneShot(const std::string& strDest)
116 LOCK(cs_vOneShots);
117 vOneShots.push_back(strDest);
120 unsigned short GetListenPort()
122 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
125 // find 'best' local address for a particular peer
126 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
128 if (!fListen)
129 return false;
131 int nBestScore = -1;
132 int nBestReachability = -1;
134 LOCK(cs_mapLocalHost);
135 for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
137 int nScore = (*it).second.nScore;
138 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
139 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
141 addr = CService((*it).first, (*it).second.nPort);
142 nBestReachability = nReachability;
143 nBestScore = nScore;
147 return nBestScore >= 0;
150 //! Convert the pnSeeds6 array into usable address objects.
151 static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
153 // It'll only connect to one or two seed nodes because once it connects,
154 // it'll get a pile of addresses with newer timestamps.
155 // Seed nodes are given a random 'last seen time' of between one and two
156 // weeks ago.
157 const int64_t nOneWeek = 7*24*60*60;
158 std::vector<CAddress> vSeedsOut;
159 vSeedsOut.reserve(vSeedsIn.size());
160 for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
162 struct in6_addr ip;
163 memcpy(&ip, i->addr, sizeof(ip));
164 CAddress addr(CService(ip, i->port));
165 addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
166 vSeedsOut.push_back(addr);
168 return vSeedsOut;
171 // get best local address for a particular peer as a CAddress
172 // Otherwise, return the unroutable 0.0.0.0 but filled in with
173 // the normal parameters, since the IP may be changed to a useful
174 // one by discovery.
175 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
177 CAddress ret(CService("0.0.0.0",GetListenPort()),0);
178 CService addr;
179 if (GetLocal(addr, paddrPeer))
181 ret = CAddress(addr);
183 ret.nServices = nLocalServices;
184 ret.nTime = GetAdjustedTime();
185 return ret;
188 int GetnScore(const CService& addr)
190 LOCK(cs_mapLocalHost);
191 if (mapLocalHost.count(addr) == LOCAL_NONE)
192 return 0;
193 return mapLocalHost[addr].nScore;
196 // Is our peer's addrLocal potentially useful as an external IP source?
197 bool IsPeerAddrLocalGood(CNode *pnode)
199 return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
200 !IsLimited(pnode->addrLocal.GetNetwork());
203 // pushes our own address to a peer
204 void AdvertizeLocal(CNode *pnode)
206 if (fListen && pnode->fSuccessfullyConnected)
208 CAddress addrLocal = GetLocalAddress(&pnode->addr);
209 // If discovery is enabled, sometimes give our peer the address it
210 // tells us that it sees us as in case it has a better idea of our
211 // address than we do.
212 if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
213 GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
215 addrLocal.SetIP(pnode->addrLocal);
217 if (addrLocal.IsRoutable())
219 pnode->PushAddress(addrLocal);
224 void SetReachable(enum Network net, bool fFlag)
226 LOCK(cs_mapLocalHost);
227 vfReachable[net] = fFlag;
228 if (net == NET_IPV6 && fFlag)
229 vfReachable[NET_IPV4] = true;
232 // learn a new local address
233 bool AddLocal(const CService& addr, int nScore)
235 if (!addr.IsRoutable())
236 return false;
238 if (!fDiscover && nScore < LOCAL_MANUAL)
239 return false;
241 if (IsLimited(addr))
242 return false;
244 LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
247 LOCK(cs_mapLocalHost);
248 bool fAlready = mapLocalHost.count(addr) > 0;
249 LocalServiceInfo &info = mapLocalHost[addr];
250 if (!fAlready || nScore >= info.nScore) {
251 info.nScore = nScore + (fAlready ? 1 : 0);
252 info.nPort = addr.GetPort();
254 SetReachable(addr.GetNetwork());
257 return true;
260 bool AddLocal(const CNetAddr &addr, int nScore)
262 return AddLocal(CService(addr, GetListenPort()), nScore);
265 /** Make a particular network entirely off-limits (no automatic connects to it) */
266 void SetLimited(enum Network net, bool fLimited)
268 if (net == NET_UNROUTABLE)
269 return;
270 LOCK(cs_mapLocalHost);
271 vfLimited[net] = fLimited;
274 bool IsLimited(enum Network net)
276 LOCK(cs_mapLocalHost);
277 return vfLimited[net];
280 bool IsLimited(const CNetAddr &addr)
282 return IsLimited(addr.GetNetwork());
285 /** vote for a local address */
286 bool SeenLocal(const CService& addr)
289 LOCK(cs_mapLocalHost);
290 if (mapLocalHost.count(addr) == 0)
291 return false;
292 mapLocalHost[addr].nScore++;
294 return true;
298 /** check whether a given address is potentially local */
299 bool IsLocal(const CService& addr)
301 LOCK(cs_mapLocalHost);
302 return mapLocalHost.count(addr) > 0;
305 /** check whether a given network is one we can probably connect to */
306 bool IsReachable(enum Network net)
308 LOCK(cs_mapLocalHost);
309 return vfReachable[net] && !vfLimited[net];
312 /** check whether a given address is in a network we can probably connect to */
313 bool IsReachable(const CNetAddr& addr)
315 enum Network net = addr.GetNetwork();
316 return IsReachable(net);
319 void AddressCurrentlyConnected(const CService& addr)
321 addrman.Connected(addr);
325 uint64_t CNode::nTotalBytesRecv = 0;
326 uint64_t CNode::nTotalBytesSent = 0;
327 CCriticalSection CNode::cs_totalBytesRecv;
328 CCriticalSection CNode::cs_totalBytesSent;
330 uint64_t CNode::nMaxOutboundLimit = 0;
331 uint64_t CNode::nMaxOutboundTotalBytesSentInCycle = 0;
332 uint64_t CNode::nMaxOutboundTimeframe = 60*60*24; //1 day
333 uint64_t CNode::nMaxOutboundCycleStartTime = 0;
335 CNode* FindNode(const CNetAddr& ip)
337 LOCK(cs_vNodes);
338 BOOST_FOREACH(CNode* pnode, vNodes)
339 if ((CNetAddr)pnode->addr == ip)
340 return (pnode);
341 return NULL;
344 CNode* FindNode(const CSubNet& subNet)
346 LOCK(cs_vNodes);
347 BOOST_FOREACH(CNode* pnode, vNodes)
348 if (subNet.Match((CNetAddr)pnode->addr))
349 return (pnode);
350 return NULL;
353 CNode* FindNode(const std::string& addrName)
355 LOCK(cs_vNodes);
356 BOOST_FOREACH(CNode* pnode, vNodes)
357 if (pnode->addrName == addrName)
358 return (pnode);
359 return NULL;
362 CNode* FindNode(const CService& addr)
364 LOCK(cs_vNodes);
365 BOOST_FOREACH(CNode* pnode, vNodes)
366 if ((CService)pnode->addr == addr)
367 return (pnode);
368 return NULL;
371 CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
373 if (pszDest == NULL) {
374 if (IsLocal(addrConnect))
375 return NULL;
377 // Look for an existing connection
378 CNode* pnode = FindNode((CService)addrConnect);
379 if (pnode)
381 pnode->AddRef();
382 return pnode;
386 /// debug print
387 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
388 pszDest ? pszDest : addrConnect.ToString(),
389 pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
391 // Connect
392 SOCKET hSocket;
393 bool proxyConnectionFailed = false;
394 if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
395 ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
397 if (!IsSelectableSocket(hSocket)) {
398 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
399 CloseSocket(hSocket);
400 return NULL;
403 addrman.Attempt(addrConnect);
405 // Add node
406 CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
407 pnode->AddRef();
410 LOCK(cs_vNodes);
411 vNodes.push_back(pnode);
414 pnode->nTimeConnected = GetTime();
416 return pnode;
417 } else if (!proxyConnectionFailed) {
418 // If connecting to the node failed, and failure is not caused by a problem connecting to
419 // the proxy, mark this as an attempt.
420 addrman.Attempt(addrConnect);
423 return NULL;
426 void CNode::CloseSocketDisconnect()
428 fDisconnect = true;
429 if (hSocket != INVALID_SOCKET)
431 LogPrint("net", "disconnecting peer=%d\n", id);
432 CloseSocket(hSocket);
435 // in case this fails, we'll empty the recv buffer when the CNode is deleted
436 TRY_LOCK(cs_vRecvMsg, lockRecv);
437 if (lockRecv)
438 vRecvMsg.clear();
441 void CNode::PushVersion()
443 int nBestHeight = g_signals.GetHeight().get_value_or(0);
445 int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
446 CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
447 CAddress addrMe = GetLocalAddress(&addr);
448 GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
449 if (fLogIPs)
450 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
451 else
452 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
453 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
454 nLocalHostNonce, strSubVersion, nBestHeight, true);
461 banmap_t CNode::setBanned;
462 CCriticalSection CNode::cs_setBanned;
463 bool CNode::setBannedIsDirty;
465 void CNode::ClearBanned()
467 LOCK(cs_setBanned);
468 setBanned.clear();
469 setBannedIsDirty = true;
472 bool CNode::IsBanned(CNetAddr ip)
474 bool fResult = false;
476 LOCK(cs_setBanned);
477 for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); it++)
479 CSubNet subNet = (*it).first;
480 CBanEntry banEntry = (*it).second;
482 if(subNet.Match(ip) && GetTime() < banEntry.nBanUntil)
483 fResult = true;
486 return fResult;
489 bool CNode::IsBanned(CSubNet subnet)
491 bool fResult = false;
493 LOCK(cs_setBanned);
494 banmap_t::iterator i = setBanned.find(subnet);
495 if (i != setBanned.end())
497 CBanEntry banEntry = (*i).second;
498 if (GetTime() < banEntry.nBanUntil)
499 fResult = true;
502 return fResult;
505 void CNode::Ban(const CNetAddr& addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) {
506 CSubNet subNet(addr);
507 Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
510 void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) {
511 CBanEntry banEntry(GetTime());
512 banEntry.banReason = banReason;
513 if (bantimeoffset <= 0)
515 bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban
516 sinceUnixEpoch = false;
518 banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset;
521 LOCK(cs_setBanned);
522 if (setBanned[subNet].nBanUntil < banEntry.nBanUntil)
523 setBanned[subNet] = banEntry;
525 setBannedIsDirty = true;
528 bool CNode::Unban(const CNetAddr &addr) {
529 CSubNet subNet(addr);
530 return Unban(subNet);
533 bool CNode::Unban(const CSubNet &subNet) {
534 LOCK(cs_setBanned);
535 if (setBanned.erase(subNet))
537 setBannedIsDirty = true;
538 return true;
540 return false;
543 void CNode::GetBanned(banmap_t &banMap)
545 LOCK(cs_setBanned);
546 banMap = setBanned; //create a thread safe copy
549 void CNode::SetBanned(const banmap_t &banMap)
551 LOCK(cs_setBanned);
552 setBanned = banMap;
553 setBannedIsDirty = true;
556 void CNode::SweepBanned()
558 int64_t now = GetTime();
560 LOCK(cs_setBanned);
561 banmap_t::iterator it = setBanned.begin();
562 while(it != setBanned.end())
564 CBanEntry banEntry = (*it).second;
565 if(now > banEntry.nBanUntil)
567 setBanned.erase(it++);
568 setBannedIsDirty = true;
570 else
571 ++it;
575 bool CNode::BannedSetIsDirty()
577 LOCK(cs_setBanned);
578 return setBannedIsDirty;
581 void CNode::SetBannedSetDirty(bool dirty)
583 LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag
584 setBannedIsDirty = dirty;
588 std::vector<CSubNet> CNode::vWhitelistedRange;
589 CCriticalSection CNode::cs_vWhitelistedRange;
591 bool CNode::IsWhitelistedRange(const CNetAddr &addr) {
592 LOCK(cs_vWhitelistedRange);
593 BOOST_FOREACH(const CSubNet& subnet, vWhitelistedRange) {
594 if (subnet.Match(addr))
595 return true;
597 return false;
600 void CNode::AddWhitelistedRange(const CSubNet &subnet) {
601 LOCK(cs_vWhitelistedRange);
602 vWhitelistedRange.push_back(subnet);
605 #undef X
606 #define X(name) stats.name = name
607 void CNode::copyStats(CNodeStats &stats)
609 stats.nodeid = this->GetId();
610 X(nServices);
611 X(nLastSend);
612 X(nLastRecv);
613 X(nTimeConnected);
614 X(nTimeOffset);
615 X(addrName);
616 X(nVersion);
617 X(cleanSubVer);
618 X(fInbound);
619 X(nStartingHeight);
620 X(nSendBytes);
621 X(nRecvBytes);
622 X(fWhitelisted);
624 // It is common for nodes with good ping times to suddenly become lagged,
625 // due to a new block arriving or other large transfer.
626 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
627 // since pingtime does not update until the ping is complete, which might take a while.
628 // So, if a ping is taking an unusually long time in flight,
629 // the caller can immediately detect that this is happening.
630 int64_t nPingUsecWait = 0;
631 if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
632 nPingUsecWait = GetTimeMicros() - nPingUsecStart;
635 // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
636 stats.dPingTime = (((double)nPingUsecTime) / 1e6);
637 stats.dPingMin = (((double)nMinPingUsecTime) / 1e6);
638 stats.dPingWait = (((double)nPingUsecWait) / 1e6);
640 // Leave string empty if addrLocal invalid (not filled in yet)
641 stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
643 #undef X
645 // requires LOCK(cs_vRecvMsg)
646 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
648 while (nBytes > 0) {
650 // get current incomplete message, or create a new one
651 if (vRecvMsg.empty() ||
652 vRecvMsg.back().complete())
653 vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
655 CNetMessage& msg = vRecvMsg.back();
657 // absorb network data
658 int handled;
659 if (!msg.in_data)
660 handled = msg.readHeader(pch, nBytes);
661 else
662 handled = msg.readData(pch, nBytes);
664 if (handled < 0)
665 return false;
667 if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
668 LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
669 return false;
672 pch += handled;
673 nBytes -= handled;
675 if (msg.complete()) {
676 msg.nTime = GetTimeMicros();
677 messageHandlerCondition.notify_one();
681 return true;
684 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
686 // copy data to temporary parsing buffer
687 unsigned int nRemaining = 24 - nHdrPos;
688 unsigned int nCopy = std::min(nRemaining, nBytes);
690 memcpy(&hdrbuf[nHdrPos], pch, nCopy);
691 nHdrPos += nCopy;
693 // if header incomplete, exit
694 if (nHdrPos < 24)
695 return nCopy;
697 // deserialize to CMessageHeader
698 try {
699 hdrbuf >> hdr;
701 catch (const std::exception&) {
702 return -1;
705 // reject messages larger than MAX_SIZE
706 if (hdr.nMessageSize > MAX_SIZE)
707 return -1;
709 // switch state to reading message data
710 in_data = true;
712 return nCopy;
715 int CNetMessage::readData(const char *pch, unsigned int nBytes)
717 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
718 unsigned int nCopy = std::min(nRemaining, nBytes);
720 if (vRecv.size() < nDataPos + nCopy) {
721 // Allocate up to 256 KiB ahead, but never more than the total message size.
722 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
725 memcpy(&vRecv[nDataPos], pch, nCopy);
726 nDataPos += nCopy;
728 return nCopy;
739 // requires LOCK(cs_vSend)
740 void SocketSendData(CNode *pnode)
742 std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
744 while (it != pnode->vSendMsg.end()) {
745 const CSerializeData &data = *it;
746 assert(data.size() > pnode->nSendOffset);
747 int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
748 if (nBytes > 0) {
749 pnode->nLastSend = GetTime();
750 pnode->nSendBytes += nBytes;
751 pnode->nSendOffset += nBytes;
752 pnode->RecordBytesSent(nBytes);
753 if (pnode->nSendOffset == data.size()) {
754 pnode->nSendOffset = 0;
755 pnode->nSendSize -= data.size();
756 it++;
757 } else {
758 // could not send full message; stop sending more
759 break;
761 } else {
762 if (nBytes < 0) {
763 // error
764 int nErr = WSAGetLastError();
765 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
767 LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
768 pnode->CloseSocketDisconnect();
771 // couldn't send anything at all
772 break;
776 if (it == pnode->vSendMsg.end()) {
777 assert(pnode->nSendOffset == 0);
778 assert(pnode->nSendSize == 0);
780 pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
783 static list<CNode*> vNodesDisconnected;
785 class CNodeRef {
786 public:
787 CNodeRef(CNode *pnode) : _pnode(pnode) {
788 LOCK(cs_vNodes);
789 _pnode->AddRef();
792 ~CNodeRef() {
793 LOCK(cs_vNodes);
794 _pnode->Release();
797 CNode& operator *() const {return *_pnode;};
798 CNode* operator ->() const {return _pnode;};
800 CNodeRef& operator =(const CNodeRef& other)
802 if (this != &other) {
803 LOCK(cs_vNodes);
805 _pnode->Release();
806 _pnode = other._pnode;
807 _pnode->AddRef();
809 return *this;
812 CNodeRef(const CNodeRef& other):
813 _pnode(other._pnode)
815 LOCK(cs_vNodes);
816 _pnode->AddRef();
818 private:
819 CNode *_pnode;
822 static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b)
824 return a->nMinPingUsecTime > b->nMinPingUsecTime;
827 static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b)
829 return a->nTimeConnected > b->nTimeConnected;
832 class CompareNetGroupKeyed
834 std::vector<unsigned char> vchSecretKey;
835 public:
836 CompareNetGroupKeyed()
838 vchSecretKey.resize(32, 0);
839 GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
842 bool operator()(const CNodeRef &a, const CNodeRef &b)
844 std::vector<unsigned char> vchGroupA, vchGroupB;
845 CSHA256 hashA, hashB;
846 std::vector<unsigned char> vchA(32), vchB(32);
848 vchGroupA = a->addr.GetGroup();
849 vchGroupB = b->addr.GetGroup();
851 hashA.Write(begin_ptr(vchGroupA), vchGroupA.size());
852 hashB.Write(begin_ptr(vchGroupB), vchGroupB.size());
854 hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
855 hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
857 hashA.Finalize(begin_ptr(vchA));
858 hashB.Finalize(begin_ptr(vchB));
860 return vchA < vchB;
864 static bool AttemptToEvictConnection(bool fPreferNewConnection) {
865 std::vector<CNodeRef> vEvictionCandidates;
867 LOCK(cs_vNodes);
869 BOOST_FOREACH(CNode *node, vNodes) {
870 if (node->fWhitelisted)
871 continue;
872 if (!node->fInbound)
873 continue;
874 if (node->fDisconnect)
875 continue;
876 if (node->addr.IsLocal())
877 continue;
878 vEvictionCandidates.push_back(CNodeRef(node));
882 if (vEvictionCandidates.empty()) return false;
884 // Protect connections with certain characteristics
886 // Deterministically select 4 peers to protect by netgroup.
887 // An attacker cannot predict which netgroups will be protected.
888 static CompareNetGroupKeyed comparerNetGroupKeyed;
889 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed);
890 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
892 if (vEvictionCandidates.empty()) return false;
894 // Protect the 8 nodes with the best ping times.
895 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
896 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
897 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
899 if (vEvictionCandidates.empty()) return false;
901 // Protect the half of the remaining nodes which have been connected the longest.
902 // This replicates the existing implicit behavior.
903 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
904 vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
906 if (vEvictionCandidates.empty()) return false;
908 // Identify the network group with the most connections
909 std::vector<unsigned char> naMostConnections;
910 unsigned int nMostConnections = 0;
911 std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts;
912 BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
913 mapAddrCounts[node->addr.GetGroup()].push_back(node);
915 if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) {
916 nMostConnections = mapAddrCounts[node->addr.GetGroup()].size();
917 naMostConnections = node->addr.GetGroup();
921 // Reduce to the network group with the most connections
922 vEvictionCandidates = mapAddrCounts[naMostConnections];
924 // Do not disconnect peers if there is only 1 connection from their network group
925 if (vEvictionCandidates.size() <= 1)
926 // unless we prefer the new connection (for whitelisted peers)
927 if (!fPreferNewConnection)
928 return false;
930 // Disconnect the most recent connection from the network group with the most connections
931 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
932 vEvictionCandidates[0]->fDisconnect = true;
934 return true;
937 static void AcceptConnection(const ListenSocket& hListenSocket) {
938 struct sockaddr_storage sockaddr;
939 socklen_t len = sizeof(sockaddr);
940 SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
941 CAddress addr;
942 int nInbound = 0;
943 int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS;
945 if (hSocket != INVALID_SOCKET)
946 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
947 LogPrintf("Warning: Unknown socket family\n");
949 bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
951 LOCK(cs_vNodes);
952 BOOST_FOREACH(CNode* pnode, vNodes)
953 if (pnode->fInbound)
954 nInbound++;
957 if (hSocket == INVALID_SOCKET)
959 int nErr = WSAGetLastError();
960 if (nErr != WSAEWOULDBLOCK)
961 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
962 return;
965 if (!IsSelectableSocket(hSocket))
967 LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
968 CloseSocket(hSocket);
969 return;
972 // According to the internet TCP_NODELAY is not carried into accepted sockets
973 // on all platforms. Set it again here just to be sure.
974 int set = 1;
975 #ifdef WIN32
976 setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
977 #else
978 setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int));
979 #endif
981 if (CNode::IsBanned(addr) && !whitelisted)
983 LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
984 CloseSocket(hSocket);
985 return;
988 if (nInbound >= nMaxInbound)
990 if (!AttemptToEvictConnection(whitelisted)) {
991 // No connection to evict, disconnect the new connection
992 LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
993 CloseSocket(hSocket);
994 return;
998 CNode* pnode = new CNode(hSocket, addr, "", true);
999 pnode->AddRef();
1000 pnode->fWhitelisted = whitelisted;
1002 LogPrint("net", "connection from %s accepted\n", addr.ToString());
1005 LOCK(cs_vNodes);
1006 vNodes.push_back(pnode);
1010 void ThreadSocketHandler()
1012 unsigned int nPrevNodeCount = 0;
1013 while (true)
1016 // Disconnect nodes
1019 LOCK(cs_vNodes);
1020 // Disconnect unused nodes
1021 vector<CNode*> vNodesCopy = vNodes;
1022 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1024 if (pnode->fDisconnect ||
1025 (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
1027 // remove from vNodes
1028 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1030 // release outbound grant (if any)
1031 pnode->grantOutbound.Release();
1033 // close socket and cleanup
1034 pnode->CloseSocketDisconnect();
1036 // hold in disconnected pool until all refs are released
1037 if (pnode->fNetworkNode || pnode->fInbound)
1038 pnode->Release();
1039 vNodesDisconnected.push_back(pnode);
1044 // Delete disconnected nodes
1045 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1046 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
1048 // wait until threads are done using it
1049 if (pnode->GetRefCount() <= 0)
1051 bool fDelete = false;
1053 TRY_LOCK(pnode->cs_vSend, lockSend);
1054 if (lockSend)
1056 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1057 if (lockRecv)
1059 TRY_LOCK(pnode->cs_inventory, lockInv);
1060 if (lockInv)
1061 fDelete = true;
1065 if (fDelete)
1067 vNodesDisconnected.remove(pnode);
1068 delete pnode;
1073 if(vNodes.size() != nPrevNodeCount) {
1074 nPrevNodeCount = vNodes.size();
1075 uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
1079 // Find which sockets have data to receive
1081 struct timeval timeout;
1082 timeout.tv_sec = 0;
1083 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
1085 fd_set fdsetRecv;
1086 fd_set fdsetSend;
1087 fd_set fdsetError;
1088 FD_ZERO(&fdsetRecv);
1089 FD_ZERO(&fdsetSend);
1090 FD_ZERO(&fdsetError);
1091 SOCKET hSocketMax = 0;
1092 bool have_fds = false;
1094 BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
1095 FD_SET(hListenSocket.socket, &fdsetRecv);
1096 hSocketMax = max(hSocketMax, hListenSocket.socket);
1097 have_fds = true;
1101 LOCK(cs_vNodes);
1102 BOOST_FOREACH(CNode* pnode, vNodes)
1104 if (pnode->hSocket == INVALID_SOCKET)
1105 continue;
1106 FD_SET(pnode->hSocket, &fdsetError);
1107 hSocketMax = max(hSocketMax, pnode->hSocket);
1108 have_fds = true;
1110 // Implement the following logic:
1111 // * If there is data to send, select() for sending data. As this only
1112 // happens when optimistic write failed, we choose to first drain the
1113 // write buffer in this case before receiving more. This avoids
1114 // needlessly queueing received data, if the remote peer is not themselves
1115 // receiving data. This means properly utilizing TCP flow control signalling.
1116 // * Otherwise, if there is no (complete) message in the receive buffer,
1117 // or there is space left in the buffer, select() for receiving data.
1118 // * (if neither of the above applies, there is certainly one message
1119 // in the receiver buffer ready to be processed).
1120 // Together, that means that at least one of the following is always possible,
1121 // so we don't deadlock:
1122 // * We send some data.
1123 // * We wait for data to be received (and disconnect after timeout).
1124 // * We process a message in the buffer (message handler thread).
1126 TRY_LOCK(pnode->cs_vSend, lockSend);
1127 if (lockSend && !pnode->vSendMsg.empty()) {
1128 FD_SET(pnode->hSocket, &fdsetSend);
1129 continue;
1133 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1134 if (lockRecv && (
1135 pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
1136 pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
1137 FD_SET(pnode->hSocket, &fdsetRecv);
1142 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1143 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1144 boost::this_thread::interruption_point();
1146 if (nSelect == SOCKET_ERROR)
1148 if (have_fds)
1150 int nErr = WSAGetLastError();
1151 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1152 for (unsigned int i = 0; i <= hSocketMax; i++)
1153 FD_SET(i, &fdsetRecv);
1155 FD_ZERO(&fdsetSend);
1156 FD_ZERO(&fdsetError);
1157 MilliSleep(timeout.tv_usec/1000);
1161 // Accept new connections
1163 BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket)
1165 if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
1167 AcceptConnection(hListenSocket);
1172 // Service each socket
1174 vector<CNode*> vNodesCopy;
1176 LOCK(cs_vNodes);
1177 vNodesCopy = vNodes;
1178 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1179 pnode->AddRef();
1181 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1183 boost::this_thread::interruption_point();
1186 // Receive
1188 if (pnode->hSocket == INVALID_SOCKET)
1189 continue;
1190 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
1192 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1193 if (lockRecv)
1196 // typical socket buffer is 8K-64K
1197 char pchBuf[0x10000];
1198 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1199 if (nBytes > 0)
1201 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
1202 pnode->CloseSocketDisconnect();
1203 pnode->nLastRecv = GetTime();
1204 pnode->nRecvBytes += nBytes;
1205 pnode->RecordBytesRecv(nBytes);
1207 else if (nBytes == 0)
1209 // socket closed gracefully
1210 if (!pnode->fDisconnect)
1211 LogPrint("net", "socket closed\n");
1212 pnode->CloseSocketDisconnect();
1214 else if (nBytes < 0)
1216 // error
1217 int nErr = WSAGetLastError();
1218 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1220 if (!pnode->fDisconnect)
1221 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1222 pnode->CloseSocketDisconnect();
1230 // Send
1232 if (pnode->hSocket == INVALID_SOCKET)
1233 continue;
1234 if (FD_ISSET(pnode->hSocket, &fdsetSend))
1236 TRY_LOCK(pnode->cs_vSend, lockSend);
1237 if (lockSend)
1238 SocketSendData(pnode);
1242 // Inactivity checking
1244 int64_t nTime = GetTime();
1245 if (nTime - pnode->nTimeConnected > 60)
1247 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1249 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->id);
1250 pnode->fDisconnect = true;
1252 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1254 LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1255 pnode->fDisconnect = true;
1257 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1259 LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1260 pnode->fDisconnect = true;
1262 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
1264 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1265 pnode->fDisconnect = true;
1270 LOCK(cs_vNodes);
1271 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1272 pnode->Release();
1285 #ifdef USE_UPNP
1286 void ThreadMapPort()
1288 std::string port = strprintf("%u", GetListenPort());
1289 const char * multicastif = 0;
1290 const char * minissdpdpath = 0;
1291 struct UPNPDev * devlist = 0;
1292 char lanaddr[64];
1294 #ifndef UPNPDISCOVER_SUCCESS
1295 /* miniupnpc 1.5 */
1296 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1297 #elif MINIUPNPC_API_VERSION < 14
1298 /* miniupnpc 1.6 */
1299 int error = 0;
1300 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1301 #else
1302 /* miniupnpc 1.9.20150730 */
1303 int error = 0;
1304 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1305 #endif
1307 struct UPNPUrls urls;
1308 struct IGDdatas data;
1309 int r;
1311 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1312 if (r == 1)
1314 if (fDiscover) {
1315 char externalIPAddress[40];
1316 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1317 if(r != UPNPCOMMAND_SUCCESS)
1318 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1319 else
1321 if(externalIPAddress[0])
1323 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1324 AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1326 else
1327 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1331 string strDesc = "Bitcoin " + FormatFullVersion();
1333 try {
1334 while (true) {
1335 #ifndef UPNPDISCOVER_SUCCESS
1336 /* miniupnpc 1.5 */
1337 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1338 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1339 #else
1340 /* miniupnpc 1.6 */
1341 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1342 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1343 #endif
1345 if(r!=UPNPCOMMAND_SUCCESS)
1346 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1347 port, port, lanaddr, r, strupnperror(r));
1348 else
1349 LogPrintf("UPnP Port Mapping successful.\n");;
1351 MilliSleep(20*60*1000); // Refresh every 20 minutes
1354 catch (const boost::thread_interrupted&)
1356 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1357 LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
1358 freeUPNPDevlist(devlist); devlist = 0;
1359 FreeUPNPUrls(&urls);
1360 throw;
1362 } else {
1363 LogPrintf("No valid UPnP IGDs found\n");
1364 freeUPNPDevlist(devlist); devlist = 0;
1365 if (r != 0)
1366 FreeUPNPUrls(&urls);
1370 void MapPort(bool fUseUPnP)
1372 static boost::thread* upnp_thread = NULL;
1374 if (fUseUPnP)
1376 if (upnp_thread) {
1377 upnp_thread->interrupt();
1378 upnp_thread->join();
1379 delete upnp_thread;
1381 upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1383 else if (upnp_thread) {
1384 upnp_thread->interrupt();
1385 upnp_thread->join();
1386 delete upnp_thread;
1387 upnp_thread = NULL;
1391 #else
1392 void MapPort(bool)
1394 // Intentionally left blank.
1396 #endif
1403 void ThreadDNSAddressSeed()
1405 // goal: only query DNS seeds if address need is acute
1406 if ((addrman.size() > 0) &&
1407 (!GetBoolArg("-forcednsseed", false))) {
1408 MilliSleep(11 * 1000);
1410 LOCK(cs_vNodes);
1411 if (vNodes.size() >= 2) {
1412 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1413 return;
1417 const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1418 int found = 0;
1420 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1422 BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1423 if (HaveNameProxy()) {
1424 AddOneShot(seed.host);
1425 } else {
1426 vector<CNetAddr> vIPs;
1427 vector<CAddress> vAdd;
1428 if (LookupHost(seed.host.c_str(), vIPs))
1430 BOOST_FOREACH(const CNetAddr& ip, vIPs)
1432 int nOneDay = 24*3600;
1433 CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1434 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1435 vAdd.push_back(addr);
1436 found++;
1439 addrman.Add(vAdd, CNetAddr(seed.name, true));
1443 LogPrintf("%d addresses found from DNS seeds\n", found);
1457 void DumpAddresses()
1459 int64_t nStart = GetTimeMillis();
1461 CAddrDB adb;
1462 adb.Write(addrman);
1464 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1465 addrman.size(), GetTimeMillis() - nStart);
1468 void DumpData()
1470 DumpAddresses();
1472 if (CNode::BannedSetIsDirty())
1474 DumpBanlist();
1475 CNode::SetBannedSetDirty(false);
1479 void static ProcessOneShot()
1481 string strDest;
1483 LOCK(cs_vOneShots);
1484 if (vOneShots.empty())
1485 return;
1486 strDest = vOneShots.front();
1487 vOneShots.pop_front();
1489 CAddress addr;
1490 CSemaphoreGrant grant(*semOutbound, true);
1491 if (grant) {
1492 if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1493 AddOneShot(strDest);
1497 void ThreadOpenConnections()
1499 // Connect to specific addresses
1500 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1502 for (int64_t nLoop = 0;; nLoop++)
1504 ProcessOneShot();
1505 BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"])
1507 CAddress addr;
1508 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1509 for (int i = 0; i < 10 && i < nLoop; i++)
1511 MilliSleep(500);
1514 MilliSleep(500);
1518 // Initiate network connections
1519 int64_t nStart = GetTime();
1520 while (true)
1522 ProcessOneShot();
1524 MilliSleep(500);
1526 CSemaphoreGrant grant(*semOutbound);
1527 boost::this_thread::interruption_point();
1529 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1530 if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1531 static bool done = false;
1532 if (!done) {
1533 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1534 addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1535 done = true;
1540 // Choose an address to connect to based on most recently seen
1542 CAddress addrConnect;
1544 // Only connect out to one peer per network group (/16 for IPv4).
1545 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1546 int nOutbound = 0;
1547 set<vector<unsigned char> > setConnected;
1549 LOCK(cs_vNodes);
1550 BOOST_FOREACH(CNode* pnode, vNodes) {
1551 if (!pnode->fInbound) {
1552 setConnected.insert(pnode->addr.GetGroup());
1553 nOutbound++;
1558 int64_t nANow = GetAdjustedTime();
1560 int nTries = 0;
1561 while (true)
1563 CAddrInfo addr = addrman.Select();
1565 // if we selected an invalid address, restart
1566 if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1567 break;
1569 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1570 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1571 // already-connected network ranges, ...) before trying new addrman addresses.
1572 nTries++;
1573 if (nTries > 100)
1574 break;
1576 if (IsLimited(addr))
1577 continue;
1579 // only consider very recently tried nodes after 30 failed attempts
1580 if (nANow - addr.nLastTry < 600 && nTries < 30)
1581 continue;
1583 // do not allow non-default ports, unless after 50 invalid addresses selected already
1584 if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1585 continue;
1587 addrConnect = addr;
1588 break;
1591 if (addrConnect.IsValid())
1592 OpenNetworkConnection(addrConnect, &grant);
1596 void ThreadOpenAddedConnections()
1599 LOCK(cs_vAddedNodes);
1600 vAddedNodes = mapMultiArgs["-addnode"];
1603 if (HaveNameProxy()) {
1604 while(true) {
1605 list<string> lAddresses(0);
1607 LOCK(cs_vAddedNodes);
1608 BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
1609 lAddresses.push_back(strAddNode);
1611 BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
1612 CAddress addr;
1613 CSemaphoreGrant grant(*semOutbound);
1614 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1615 MilliSleep(500);
1617 MilliSleep(120000); // Retry every 2 minutes
1621 for (unsigned int i = 0; true; i++)
1623 list<string> lAddresses(0);
1625 LOCK(cs_vAddedNodes);
1626 BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
1627 lAddresses.push_back(strAddNode);
1630 list<vector<CService> > lservAddressesToAdd(0);
1631 BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
1632 vector<CService> vservNode(0);
1633 if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1635 lservAddressesToAdd.push_back(vservNode);
1637 LOCK(cs_setservAddNodeAddresses);
1638 BOOST_FOREACH(const CService& serv, vservNode)
1639 setservAddNodeAddresses.insert(serv);
1643 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1644 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1646 LOCK(cs_vNodes);
1647 BOOST_FOREACH(CNode* pnode, vNodes)
1648 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1649 BOOST_FOREACH(const CService& addrNode, *(it))
1650 if (pnode->addr == addrNode)
1652 it = lservAddressesToAdd.erase(it);
1653 it--;
1654 break;
1657 BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1659 CSemaphoreGrant grant(*semOutbound);
1660 OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1661 MilliSleep(500);
1663 MilliSleep(120000); // Retry every 2 minutes
1667 // if successful, this moves the passed grant to the constructed node
1668 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
1671 // Initiate outbound network connection
1673 boost::this_thread::interruption_point();
1674 if (!pszDest) {
1675 if (IsLocal(addrConnect) ||
1676 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1677 FindNode(addrConnect.ToStringIPPort()))
1678 return false;
1679 } else if (FindNode(std::string(pszDest)))
1680 return false;
1682 CNode* pnode = ConnectNode(addrConnect, pszDest);
1683 boost::this_thread::interruption_point();
1685 if (!pnode)
1686 return false;
1687 if (grantOutbound)
1688 grantOutbound->MoveTo(pnode->grantOutbound);
1689 pnode->fNetworkNode = true;
1690 if (fOneShot)
1691 pnode->fOneShot = true;
1693 return true;
1697 void ThreadMessageHandler()
1699 boost::mutex condition_mutex;
1700 boost::unique_lock<boost::mutex> lock(condition_mutex);
1702 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1703 while (true)
1705 vector<CNode*> vNodesCopy;
1707 LOCK(cs_vNodes);
1708 vNodesCopy = vNodes;
1709 BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1710 pnode->AddRef();
1714 // Poll the connected nodes for messages
1715 CNode* pnodeTrickle = NULL;
1716 if (!vNodesCopy.empty())
1717 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1719 bool fSleep = true;
1721 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1723 if (pnode->fDisconnect)
1724 continue;
1726 // Receive messages
1728 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1729 if (lockRecv)
1731 if (!g_signals.ProcessMessages(pnode))
1732 pnode->CloseSocketDisconnect();
1734 if (pnode->nSendSize < SendBufferSize())
1736 if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1738 fSleep = false;
1743 boost::this_thread::interruption_point();
1745 // Send messages
1747 TRY_LOCK(pnode->cs_vSend, lockSend);
1748 if (lockSend)
1749 g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
1751 boost::this_thread::interruption_point();
1755 LOCK(cs_vNodes);
1756 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1757 pnode->Release();
1760 if (fSleep)
1761 messageHandlerCondition.timed_wait(lock, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1770 bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted)
1772 strError = "";
1773 int nOne = 1;
1775 // Create socket for listening for incoming connections
1776 struct sockaddr_storage sockaddr;
1777 socklen_t len = sizeof(sockaddr);
1778 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1780 strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
1781 LogPrintf("%s\n", strError);
1782 return false;
1785 SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1786 if (hListenSocket == INVALID_SOCKET)
1788 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1789 LogPrintf("%s\n", strError);
1790 return false;
1792 if (!IsSelectableSocket(hListenSocket))
1794 strError = "Error: Couldn't create a listenable socket for incoming connections";
1795 LogPrintf("%s\n", strError);
1796 return false;
1800 #ifndef WIN32
1801 #ifdef SO_NOSIGPIPE
1802 // Different way of disabling SIGPIPE on BSD
1803 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1804 #endif
1805 // Allow binding if the port is still in TIME_WAIT state after
1806 // the program was closed and restarted.
1807 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1808 // Disable Nagle's algorithm
1809 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int));
1810 #else
1811 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
1812 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int));
1813 #endif
1815 // Set to non-blocking, incoming connections will also inherit this
1816 if (!SetSocketNonBlocking(hListenSocket, true)) {
1817 strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1818 LogPrintf("%s\n", strError);
1819 return false;
1822 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1823 // and enable it by default or not. Try to enable it, if possible.
1824 if (addrBind.IsIPv6()) {
1825 #ifdef IPV6_V6ONLY
1826 #ifdef WIN32
1827 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1828 #else
1829 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1830 #endif
1831 #endif
1832 #ifdef WIN32
1833 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1834 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1835 #endif
1838 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1840 int nErr = WSAGetLastError();
1841 if (nErr == WSAEADDRINUSE)
1842 strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
1843 else
1844 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
1845 LogPrintf("%s\n", strError);
1846 CloseSocket(hListenSocket);
1847 return false;
1849 LogPrintf("Bound to %s\n", addrBind.ToString());
1851 // Listen for incoming connections
1852 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1854 strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1855 LogPrintf("%s\n", strError);
1856 CloseSocket(hListenSocket);
1857 return false;
1860 vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
1862 if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
1863 AddLocal(addrBind, LOCAL_BIND);
1865 return true;
1868 void static Discover(boost::thread_group& threadGroup)
1870 if (!fDiscover)
1871 return;
1873 #ifdef WIN32
1874 // Get local host IP
1875 char pszHostName[256] = "";
1876 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1878 vector<CNetAddr> vaddr;
1879 if (LookupHost(pszHostName, vaddr))
1881 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1883 if (AddLocal(addr, LOCAL_IF))
1884 LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
1888 #else
1889 // Get local host ip
1890 struct ifaddrs* myaddrs;
1891 if (getifaddrs(&myaddrs) == 0)
1893 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1895 if (ifa->ifa_addr == NULL) continue;
1896 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1897 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1898 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1899 if (ifa->ifa_addr->sa_family == AF_INET)
1901 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1902 CNetAddr addr(s4->sin_addr);
1903 if (AddLocal(addr, LOCAL_IF))
1904 LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1906 else if (ifa->ifa_addr->sa_family == AF_INET6)
1908 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1909 CNetAddr addr(s6->sin6_addr);
1910 if (AddLocal(addr, LOCAL_IF))
1911 LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1914 freeifaddrs(myaddrs);
1916 #endif
1919 void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
1921 uiInterface.InitMessage(_("Loading addresses..."));
1922 // Load addresses for peers.dat
1923 int64_t nStart = GetTimeMillis();
1925 CAddrDB adb;
1926 if (!adb.Read(addrman))
1927 LogPrintf("Invalid or missing peers.dat; recreating\n");
1930 //try to read stored banlist
1931 CBanDB bandb;
1932 banmap_t banmap;
1933 if (!bandb.Read(banmap))
1934 LogPrintf("Invalid or missing banlist.dat; recreating\n");
1936 CNode::SetBanned(banmap); //thread save setter
1937 CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data
1938 CNode::SweepBanned(); //sweap out unused entries
1940 LogPrintf("Loaded %i addresses from peers.dat %dms\n",
1941 addrman.size(), GetTimeMillis() - nStart);
1942 fAddressesInitialized = true;
1944 if (semOutbound == NULL) {
1945 // initialize semaphore
1946 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
1947 semOutbound = new CSemaphore(nMaxOutbound);
1950 if (pnodeLocalHost == NULL)
1951 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1953 Discover(threadGroup);
1956 // Start threads
1959 if (!GetBoolArg("-dnsseed", true))
1960 LogPrintf("DNS seeding disabled\n");
1961 else
1962 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1964 // Map ports with UPnP
1965 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
1967 // Send and receive from sockets, accept connections
1968 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1970 // Initiate outbound connections from -addnode
1971 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1973 // Initiate outbound connections
1974 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1976 // Process messages
1977 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1979 // Dump network addresses
1980 scheduler.scheduleEvery(&DumpData, DUMP_ADDRESSES_INTERVAL);
1983 bool StopNode()
1985 LogPrintf("StopNode()\n");
1986 MapPort(false);
1987 if (semOutbound)
1988 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1989 semOutbound->post();
1991 if (fAddressesInitialized)
1993 DumpData();
1994 fAddressesInitialized = false;
1997 return true;
2000 class CNetCleanup
2002 public:
2003 CNetCleanup() {}
2005 ~CNetCleanup()
2007 // Close sockets
2008 BOOST_FOREACH(CNode* pnode, vNodes)
2009 if (pnode->hSocket != INVALID_SOCKET)
2010 CloseSocket(pnode->hSocket);
2011 BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
2012 if (hListenSocket.socket != INVALID_SOCKET)
2013 if (!CloseSocket(hListenSocket.socket))
2014 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2016 // clean up some globals (to help leak detection)
2017 BOOST_FOREACH(CNode *pnode, vNodes)
2018 delete pnode;
2019 BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
2020 delete pnode;
2021 vNodes.clear();
2022 vNodesDisconnected.clear();
2023 vhListenSocket.clear();
2024 delete semOutbound;
2025 semOutbound = NULL;
2026 delete pnodeLocalHost;
2027 pnodeLocalHost = NULL;
2029 #ifdef WIN32
2030 // Shutdown Windows Sockets
2031 WSACleanup();
2032 #endif
2035 instance_of_cnetcleanup;
2043 void RelayTransaction(const CTransaction& tx)
2045 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
2046 ss.reserve(10000);
2047 ss << tx;
2048 RelayTransaction(tx, ss);
2051 void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
2053 CInv inv(MSG_TX, tx.GetHash());
2055 LOCK(cs_mapRelay);
2056 // Expire old relay messages
2057 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
2059 mapRelay.erase(vRelayExpiration.front().second);
2060 vRelayExpiration.pop_front();
2063 // Save original serialized message so newer versions are preserved
2064 mapRelay.insert(std::make_pair(inv, ss));
2065 vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
2067 LOCK(cs_vNodes);
2068 BOOST_FOREACH(CNode* pnode, vNodes)
2070 if(!pnode->fRelayTxes)
2071 continue;
2072 LOCK(pnode->cs_filter);
2073 if (pnode->pfilter)
2075 if (pnode->pfilter->IsRelevantAndUpdate(tx))
2076 pnode->PushInventory(inv);
2077 } else
2078 pnode->PushInventory(inv);
2082 void CNode::RecordBytesRecv(uint64_t bytes)
2084 LOCK(cs_totalBytesRecv);
2085 nTotalBytesRecv += bytes;
2088 void CNode::RecordBytesSent(uint64_t bytes)
2090 LOCK(cs_totalBytesSent);
2091 nTotalBytesSent += bytes;
2093 uint64_t now = GetTime();
2094 if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
2096 // timeframe expired, reset cycle
2097 nMaxOutboundCycleStartTime = now;
2098 nMaxOutboundTotalBytesSentInCycle = 0;
2101 // TODO, exclude whitebind peers
2102 nMaxOutboundTotalBytesSentInCycle += bytes;
2105 void CNode::SetMaxOutboundTarget(uint64_t limit)
2107 LOCK(cs_totalBytesSent);
2108 uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE;
2109 nMaxOutboundLimit = limit;
2111 if (limit < recommendedMinimum)
2112 LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\n.", nMaxOutboundLimit, recommendedMinimum);
2115 uint64_t CNode::GetMaxOutboundTarget()
2117 LOCK(cs_totalBytesSent);
2118 return nMaxOutboundLimit;
2121 uint64_t CNode::GetMaxOutboundTimeframe()
2123 LOCK(cs_totalBytesSent);
2124 return nMaxOutboundTimeframe;
2127 uint64_t CNode::GetMaxOutboundTimeLeftInCycle()
2129 LOCK(cs_totalBytesSent);
2130 if (nMaxOutboundLimit == 0)
2131 return 0;
2133 if (nMaxOutboundCycleStartTime == 0)
2134 return nMaxOutboundTimeframe;
2136 uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2137 uint64_t now = GetTime();
2138 return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();
2141 void CNode::SetMaxOutboundTimeframe(uint64_t timeframe)
2143 LOCK(cs_totalBytesSent);
2144 if (nMaxOutboundTimeframe != timeframe)
2146 // reset measure-cycle in case of changing
2147 // the timeframe
2148 nMaxOutboundCycleStartTime = GetTime();
2150 nMaxOutboundTimeframe = timeframe;
2153 bool CNode::OutboundTargetReached(bool historicalBlockServingLimit)
2155 LOCK(cs_totalBytesSent);
2156 if (nMaxOutboundLimit == 0)
2157 return false;
2159 if (historicalBlockServingLimit)
2161 // keep a large enought buffer to at least relay each block once
2162 uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
2163 uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE;
2164 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2165 return true;
2167 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2168 return true;
2170 return false;
2173 uint64_t CNode::GetOutboundTargetBytesLeft()
2175 LOCK(cs_totalBytesSent);
2176 if (nMaxOutboundLimit == 0)
2177 return 0;
2179 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2182 uint64_t CNode::GetTotalBytesRecv()
2184 LOCK(cs_totalBytesRecv);
2185 return nTotalBytesRecv;
2188 uint64_t CNode::GetTotalBytesSent()
2190 LOCK(cs_totalBytesSent);
2191 return nTotalBytesSent;
2194 void CNode::Fuzz(int nChance)
2196 if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
2197 if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
2199 switch (GetRand(3))
2201 case 0:
2202 // xor a random byte with a random value:
2203 if (!ssSend.empty()) {
2204 CDataStream::size_type pos = GetRand(ssSend.size());
2205 ssSend[pos] ^= (unsigned char)(GetRand(256));
2207 break;
2208 case 1:
2209 // delete a random byte:
2210 if (!ssSend.empty()) {
2211 CDataStream::size_type pos = GetRand(ssSend.size());
2212 ssSend.erase(ssSend.begin()+pos);
2214 break;
2215 case 2:
2216 // insert a random byte at a random position
2218 CDataStream::size_type pos = GetRand(ssSend.size());
2219 char ch = (char)GetRand(256);
2220 ssSend.insert(ssSend.begin()+pos, ch);
2222 break;
2224 // Chance of more than one change half the time:
2225 // (more changes exponentially less likely):
2226 Fuzz(2);
2230 // CAddrDB
2233 CAddrDB::CAddrDB()
2235 pathAddr = GetDataDir() / "peers.dat";
2238 bool CAddrDB::Write(const CAddrMan& addr)
2240 // Generate random temporary filename
2241 unsigned short randv = 0;
2242 GetRandBytes((unsigned char*)&randv, sizeof(randv));
2243 std::string tmpfn = strprintf("peers.dat.%04x", randv);
2245 // serialize addresses, checksum data up to that point, then append csum
2246 CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
2247 ssPeers << FLATDATA(Params().MessageStart());
2248 ssPeers << addr;
2249 uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
2250 ssPeers << hash;
2252 // open temp output file, and associate with CAutoFile
2253 boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
2254 FILE *file = fopen(pathTmp.string().c_str(), "wb");
2255 CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
2256 if (fileout.IsNull())
2257 return error("%s: Failed to open file %s", __func__, pathTmp.string());
2259 // Write and commit header, data
2260 try {
2261 fileout << ssPeers;
2263 catch (const std::exception& e) {
2264 return error("%s: Serialize or I/O error - %s", __func__, e.what());
2266 FileCommit(fileout.Get());
2267 fileout.fclose();
2269 // replace existing peers.dat, if any, with new peers.dat.XXXX
2270 if (!RenameOver(pathTmp, pathAddr))
2271 return error("%s: Rename-into-place failed", __func__);
2273 return true;
2276 bool CAddrDB::Read(CAddrMan& addr)
2278 // open input file, and associate with CAutoFile
2279 FILE *file = fopen(pathAddr.string().c_str(), "rb");
2280 CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
2281 if (filein.IsNull())
2282 return error("%s: Failed to open file %s", __func__, pathAddr.string());
2284 // use file size to size memory buffer
2285 uint64_t fileSize = boost::filesystem::file_size(pathAddr);
2286 uint64_t dataSize = 0;
2287 // Don't try to resize to a negative number if file is small
2288 if (fileSize >= sizeof(uint256))
2289 dataSize = fileSize - sizeof(uint256);
2290 vector<unsigned char> vchData;
2291 vchData.resize(dataSize);
2292 uint256 hashIn;
2294 // read data and checksum from file
2295 try {
2296 filein.read((char *)&vchData[0], dataSize);
2297 filein >> hashIn;
2299 catch (const std::exception& e) {
2300 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2302 filein.fclose();
2304 CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
2306 // verify stored checksum matches input data
2307 uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
2308 if (hashIn != hashTmp)
2309 return error("%s: Checksum mismatch, data corrupted", __func__);
2311 unsigned char pchMsgTmp[4];
2312 try {
2313 // de-serialize file header (network specific magic number) and ..
2314 ssPeers >> FLATDATA(pchMsgTmp);
2316 // ... verify the network matches ours
2317 if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2318 return error("%s: Invalid network magic number", __func__);
2320 // de-serialize address data into one CAddrMan object
2321 ssPeers >> addr;
2323 catch (const std::exception& e) {
2324 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2327 return true;
2330 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
2331 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
2333 CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
2334 ssSend(SER_NETWORK, INIT_PROTO_VERSION),
2335 addrKnown(5000, 0.001),
2336 setInventoryKnown(SendBufferSize() / 1000)
2338 nServices = 0;
2339 hSocket = hSocketIn;
2340 nRecvVersion = INIT_PROTO_VERSION;
2341 nLastSend = 0;
2342 nLastRecv = 0;
2343 nSendBytes = 0;
2344 nRecvBytes = 0;
2345 nTimeConnected = GetTime();
2346 nTimeOffset = 0;
2347 addr = addrIn;
2348 addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2349 nVersion = 0;
2350 strSubVer = "";
2351 fWhitelisted = false;
2352 fOneShot = false;
2353 fClient = false; // set by version message
2354 fInbound = fInboundIn;
2355 fNetworkNode = false;
2356 fSuccessfullyConnected = false;
2357 fDisconnect = false;
2358 nRefCount = 0;
2359 nSendSize = 0;
2360 nSendOffset = 0;
2361 hashContinue = uint256();
2362 nStartingHeight = -1;
2363 fGetAddr = false;
2364 fRelayTxes = false;
2365 pfilter = new CBloomFilter();
2366 nPingNonceSent = 0;
2367 nPingUsecStart = 0;
2368 nPingUsecTime = 0;
2369 fPingQueued = false;
2370 nMinPingUsecTime = std::numeric_limits<int64_t>::max();
2373 LOCK(cs_nLastNodeId);
2374 id = nLastNodeId++;
2377 if (fLogIPs)
2378 LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
2379 else
2380 LogPrint("net", "Added connection peer=%d\n", id);
2382 // Be shy and don't send version until we hear
2383 if (hSocket != INVALID_SOCKET && !fInbound)
2384 PushVersion();
2386 GetNodeSignals().InitializeNode(GetId(), this);
2389 CNode::~CNode()
2391 CloseSocket(hSocket);
2393 if (pfilter)
2394 delete pfilter;
2396 GetNodeSignals().FinalizeNode(GetId());
2399 void CNode::AskFor(const CInv& inv)
2401 if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
2402 return;
2403 // We're using mapAskFor as a priority queue,
2404 // the key is the earliest time the request can be sent
2405 int64_t nRequestTime;
2406 limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
2407 if (it != mapAlreadyAskedFor.end())
2408 nRequestTime = it->second;
2409 else
2410 nRequestTime = 0;
2411 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id);
2413 // Make sure not to reuse time indexes to keep things in the same order
2414 int64_t nNow = GetTimeMicros() - 1000000;
2415 static int64_t nLastTime;
2416 ++nLastTime;
2417 nNow = std::max(nNow, nLastTime);
2418 nLastTime = nNow;
2420 // Each retry is 2 minutes after the last
2421 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2422 if (it != mapAlreadyAskedFor.end())
2423 mapAlreadyAskedFor.update(it, nRequestTime);
2424 else
2425 mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2426 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2429 void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
2431 ENTER_CRITICAL_SECTION(cs_vSend);
2432 assert(ssSend.size() == 0);
2433 ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
2434 LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
2437 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
2439 ssSend.clear();
2441 LEAVE_CRITICAL_SECTION(cs_vSend);
2443 LogPrint("net", "(aborted)\n");
2446 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
2448 // The -*messagestest options are intentionally not documented in the help message,
2449 // since they are only used during development to debug the networking code and are
2450 // not intended for end-users.
2451 if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2453 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2454 AbortMessage();
2455 return;
2457 if (mapArgs.count("-fuzzmessagestest"))
2458 Fuzz(GetArg("-fuzzmessagestest", 10));
2460 if (ssSend.size() == 0)
2462 LEAVE_CRITICAL_SECTION(cs_vSend);
2463 return;
2465 // Set the size
2466 unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
2467 WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
2469 // Set the checksum
2470 uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
2471 unsigned int nChecksum = 0;
2472 memcpy(&nChecksum, &hash, sizeof(nChecksum));
2473 assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
2474 memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
2476 LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
2478 std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
2479 ssSend.GetAndClear(*it);
2480 nSendSize += (*it).size();
2482 // If write queue empty, attempt "optimistic write"
2483 if (it == vSendMsg.begin())
2484 SocketSendData(this);
2486 LEAVE_CRITICAL_SECTION(cs_vSend);
2490 // CBanDB
2493 CBanDB::CBanDB()
2495 pathBanlist = GetDataDir() / "banlist.dat";
2498 bool CBanDB::Write(const banmap_t& banSet)
2500 // Generate random temporary filename
2501 unsigned short randv = 0;
2502 GetRandBytes((unsigned char*)&randv, sizeof(randv));
2503 std::string tmpfn = strprintf("banlist.dat.%04x", randv);
2505 // serialize banlist, checksum data up to that point, then append csum
2506 CDataStream ssBanlist(SER_DISK, CLIENT_VERSION);
2507 ssBanlist << FLATDATA(Params().MessageStart());
2508 ssBanlist << banSet;
2509 uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end());
2510 ssBanlist << hash;
2512 // open temp output file, and associate with CAutoFile
2513 boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
2514 FILE *file = fopen(pathTmp.string().c_str(), "wb");
2515 CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
2516 if (fileout.IsNull())
2517 return error("%s: Failed to open file %s", __func__, pathTmp.string());
2519 // Write and commit header, data
2520 try {
2521 fileout << ssBanlist;
2523 catch (const std::exception& e) {
2524 return error("%s: Serialize or I/O error - %s", __func__, e.what());
2526 FileCommit(fileout.Get());
2527 fileout.fclose();
2529 // replace existing banlist.dat, if any, with new banlist.dat.XXXX
2530 if (!RenameOver(pathTmp, pathBanlist))
2531 return error("%s: Rename-into-place failed", __func__);
2533 return true;
2536 bool CBanDB::Read(banmap_t& banSet)
2538 // open input file, and associate with CAutoFile
2539 FILE *file = fopen(pathBanlist.string().c_str(), "rb");
2540 CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
2541 if (filein.IsNull())
2542 return error("%s: Failed to open file %s", __func__, pathBanlist.string());
2544 // use file size to size memory buffer
2545 uint64_t fileSize = boost::filesystem::file_size(pathBanlist);
2546 uint64_t dataSize = 0;
2547 // Don't try to resize to a negative number if file is small
2548 if (fileSize >= sizeof(uint256))
2549 dataSize = fileSize - sizeof(uint256);
2550 vector<unsigned char> vchData;
2551 vchData.resize(dataSize);
2552 uint256 hashIn;
2554 // read data and checksum from file
2555 try {
2556 filein.read((char *)&vchData[0], dataSize);
2557 filein >> hashIn;
2559 catch (const std::exception& e) {
2560 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2562 filein.fclose();
2564 CDataStream ssBanlist(vchData, SER_DISK, CLIENT_VERSION);
2566 // verify stored checksum matches input data
2567 uint256 hashTmp = Hash(ssBanlist.begin(), ssBanlist.end());
2568 if (hashIn != hashTmp)
2569 return error("%s: Checksum mismatch, data corrupted", __func__);
2571 unsigned char pchMsgTmp[4];
2572 try {
2573 // de-serialize file header (network specific magic number) and ..
2574 ssBanlist >> FLATDATA(pchMsgTmp);
2576 // ... verify the network matches ours
2577 if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2578 return error("%s: Invalid network magic number", __func__);
2580 // de-serialize address data into one CAddrMan object
2581 ssBanlist >> banSet;
2583 catch (const std::exception& e) {
2584 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2587 return true;
2590 void DumpBanlist()
2592 int64_t nStart = GetTimeMillis();
2594 CNode::SweepBanned(); //clean unused entries (if bantime has expired)
2596 CBanDB bandb;
2597 banmap_t banmap;
2598 CNode::GetBanned(banmap);
2599 bandb.Write(banmap);
2601 LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
2602 banmap.size(), GetTimeMillis() - nStart);