]> Git Repo - VerusCoin.git/blob - src/net.cpp
Auto merge of #1599 - daira:1597.fix-other-potential-race-conditions, r=daira
[VerusCoin.git] / src / net.cpp
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.
5
6 #if defined(HAVE_CONFIG_H)
7 #include "config/bitcoin-config.h"
8 #endif
9
10 #include "net.h"
11
12 #include "addrman.h"
13 #include "chainparams.h"
14 #include "clientversion.h"
15 #include "primitives/transaction.h"
16 #include "scheduler.h"
17 #include "ui_interface.h"
18 #include "crypto/common.h"
19
20 #ifdef WIN32
21 #include <string.h>
22 #else
23 #include <fcntl.h>
24 #endif
25
26 #ifdef USE_UPNP
27 #include <miniupnpc/miniupnpc.h>
28 #include <miniupnpc/miniwget.h>
29 #include <miniupnpc/upnpcommands.h>
30 #include <miniupnpc/upnperrors.h>
31 #endif
32
33 #include <boost/filesystem.hpp>
34 #include <boost/thread.hpp>
35
36 // Dump addresses to peers.dat every 15 minutes (900s)
37 #define DUMP_ADDRESSES_INTERVAL 900
38
39 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
40 #define MSG_NOSIGNAL 0
41 #endif
42
43 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
44 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
45 #ifdef WIN32
46 #ifndef PROTECTION_LEVEL_UNRESTRICTED
47 #define PROTECTION_LEVEL_UNRESTRICTED 10
48 #endif
49 #ifndef IPV6_PROTECTION_LEVEL
50 #define IPV6_PROTECTION_LEVEL 23
51 #endif
52 #endif
53
54 using namespace std;
55
56 namespace {
57     const int MAX_OUTBOUND_CONNECTIONS = 8;
58
59     struct ListenSocket {
60         SOCKET socket;
61         bool whitelisted;
62
63         ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
64     };
65 }
66
67 //
68 // Global state variables
69 //
70 bool fDiscover = true;
71 bool fListen = true;
72 uint64_t nLocalServices = NODE_NETWORK;
73 CCriticalSection cs_mapLocalHost;
74 map<CNetAddr, LocalServiceInfo> mapLocalHost;
75 static bool vfReachable[NET_MAX] = {};
76 static bool vfLimited[NET_MAX] = {};
77 static CNode* pnodeLocalHost = NULL;
78 uint64_t nLocalHostNonce = 0;
79 static std::vector<ListenSocket> vhListenSocket;
80 CAddrMan addrman;
81 int nMaxConnections = 125;
82 bool fAddressesInitialized = false;
83
84 vector<CNode*> vNodes;
85 CCriticalSection cs_vNodes;
86 map<CInv, CDataStream> mapRelay;
87 deque<pair<int64_t, CInv> > vRelayExpiration;
88 CCriticalSection cs_mapRelay;
89 limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
90
91 static deque<string> vOneShots;
92 CCriticalSection cs_vOneShots;
93
94 set<CNetAddr> setservAddNodeAddresses;
95 CCriticalSection cs_setservAddNodeAddresses;
96
97 vector<std::string> vAddedNodes;
98 CCriticalSection cs_vAddedNodes;
99
100 NodeId nLastNodeId = 0;
101 CCriticalSection cs_nLastNodeId;
102
103 static CSemaphore *semOutbound = NULL;
104 boost::condition_variable messageHandlerCondition;
105
106 // Signals for message handling
107 static CNodeSignals g_signals;
108 CNodeSignals& GetNodeSignals() { return g_signals; }
109
110 void AddOneShot(string strDest)
111 {
112     LOCK(cs_vOneShots);
113     vOneShots.push_back(strDest);
114 }
115
116 unsigned short GetListenPort()
117 {
118     return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
119 }
120
121 // find 'best' local address for a particular peer
122 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
123 {
124     if (!fListen)
125         return false;
126
127     int nBestScore = -1;
128     int nBestReachability = -1;
129     {
130         LOCK(cs_mapLocalHost);
131         for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
132         {
133             int nScore = (*it).second.nScore;
134             int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
135             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
136             {
137                 addr = CService((*it).first, (*it).second.nPort);
138                 nBestReachability = nReachability;
139                 nBestScore = nScore;
140             }
141         }
142     }
143     return nBestScore >= 0;
144 }
145
146 //! Convert the pnSeeds6 array into usable address objects.
147 static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
148 {
149     // It'll only connect to one or two seed nodes because once it connects,
150     // it'll get a pile of addresses with newer timestamps.
151     // Seed nodes are given a random 'last seen time' of between one and two
152     // weeks ago.
153     const int64_t nOneWeek = 7*24*60*60;
154     std::vector<CAddress> vSeedsOut;
155     vSeedsOut.reserve(vSeedsIn.size());
156     for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
157     {
158         struct in6_addr ip;
159         memcpy(&ip, i->addr, sizeof(ip));
160         CAddress addr(CService(ip, i->port));
161         addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
162         vSeedsOut.push_back(addr);
163     }
164     return vSeedsOut;
165 }
166
167 // get best local address for a particular peer as a CAddress
168 // Otherwise, return the unroutable 0.0.0.0 but filled in with
169 // the normal parameters, since the IP may be changed to a useful
170 // one by discovery.
171 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
172 {
173     CAddress ret(CService("0.0.0.0",GetListenPort()),0);
174     CService addr;
175     if (GetLocal(addr, paddrPeer))
176     {
177         ret = CAddress(addr);
178     }
179     ret.nServices = nLocalServices;
180     ret.nTime = GetAdjustedTime();
181     return ret;
182 }
183
184 int GetnScore(const CService& addr)
185 {
186     LOCK(cs_mapLocalHost);
187     if (mapLocalHost.count(addr) == LOCAL_NONE)
188         return 0;
189     return mapLocalHost[addr].nScore;
190 }
191
192 // Is our peer's addrLocal potentially useful as an external IP source?
193 bool IsPeerAddrLocalGood(CNode *pnode)
194 {
195     return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
196            !IsLimited(pnode->addrLocal.GetNetwork());
197 }
198
199 // pushes our own address to a peer
200 void AdvertizeLocal(CNode *pnode)
201 {
202     if (fListen && pnode->fSuccessfullyConnected)
203     {
204         CAddress addrLocal = GetLocalAddress(&pnode->addr);
205         // If discovery is enabled, sometimes give our peer the address it
206         // tells us that it sees us as in case it has a better idea of our
207         // address than we do.
208         if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
209              GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
210         {
211             addrLocal.SetIP(pnode->addrLocal);
212         }
213         if (addrLocal.IsRoutable())
214         {
215             pnode->PushAddress(addrLocal);
216         }
217     }
218 }
219
220 void SetReachable(enum Network net, bool fFlag)
221 {
222     LOCK(cs_mapLocalHost);
223     vfReachable[net] = fFlag;
224     if (net == NET_IPV6 && fFlag)
225         vfReachable[NET_IPV4] = true;
226 }
227
228 // learn a new local address
229 bool AddLocal(const CService& addr, int nScore)
230 {
231     if (!addr.IsRoutable())
232         return false;
233
234     if (!fDiscover && nScore < LOCAL_MANUAL)
235         return false;
236
237     if (IsLimited(addr))
238         return false;
239
240     LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
241
242     {
243         LOCK(cs_mapLocalHost);
244         bool fAlready = mapLocalHost.count(addr) > 0;
245         LocalServiceInfo &info = mapLocalHost[addr];
246         if (!fAlready || nScore >= info.nScore) {
247             info.nScore = nScore + (fAlready ? 1 : 0);
248             info.nPort = addr.GetPort();
249         }
250         SetReachable(addr.GetNetwork());
251     }
252
253     return true;
254 }
255
256 bool AddLocal(const CNetAddr &addr, int nScore)
257 {
258     return AddLocal(CService(addr, GetListenPort()), nScore);
259 }
260
261 /** Make a particular network entirely off-limits (no automatic connects to it) */
262 void SetLimited(enum Network net, bool fLimited)
263 {
264     if (net == NET_UNROUTABLE)
265         return;
266     LOCK(cs_mapLocalHost);
267     vfLimited[net] = fLimited;
268 }
269
270 bool IsLimited(enum Network net)
271 {
272     LOCK(cs_mapLocalHost);
273     return vfLimited[net];
274 }
275
276 bool IsLimited(const CNetAddr &addr)
277 {
278     return IsLimited(addr.GetNetwork());
279 }
280
281 /** vote for a local address */
282 bool SeenLocal(const CService& addr)
283 {
284     {
285         LOCK(cs_mapLocalHost);
286         if (mapLocalHost.count(addr) == 0)
287             return false;
288         mapLocalHost[addr].nScore++;
289     }
290     return true;
291 }
292
293
294 /** check whether a given address is potentially local */
295 bool IsLocal(const CService& addr)
296 {
297     LOCK(cs_mapLocalHost);
298     return mapLocalHost.count(addr) > 0;
299 }
300
301 /** check whether a given network is one we can probably connect to */
302 bool IsReachable(enum Network net)
303 {
304     LOCK(cs_mapLocalHost);
305     return vfReachable[net] && !vfLimited[net];
306 }
307
308 /** check whether a given address is in a network we can probably connect to */
309 bool IsReachable(const CNetAddr& addr)
310 {
311     enum Network net = addr.GetNetwork();
312     return IsReachable(net);
313 }
314
315 void AddressCurrentlyConnected(const CService& addr)
316 {
317     addrman.Connected(addr);
318 }
319
320
321 uint64_t CNode::nTotalBytesRecv = 0;
322 uint64_t CNode::nTotalBytesSent = 0;
323 CCriticalSection CNode::cs_totalBytesRecv;
324 CCriticalSection CNode::cs_totalBytesSent;
325
326 CNode* FindNode(const CNetAddr& ip)
327 {
328     LOCK(cs_vNodes);
329     BOOST_FOREACH(CNode* pnode, vNodes)
330         if ((CNetAddr)pnode->addr == ip)
331             return (pnode);
332     return NULL;
333 }
334
335 CNode* FindNode(const std::string& addrName)
336 {
337     LOCK(cs_vNodes);
338     BOOST_FOREACH(CNode* pnode, vNodes)
339         if (pnode->addrName == addrName)
340             return (pnode);
341     return NULL;
342 }
343
344 CNode* FindNode(const CService& addr)
345 {
346     LOCK(cs_vNodes);
347     BOOST_FOREACH(CNode* pnode, vNodes)
348         if ((CService)pnode->addr == addr)
349             return (pnode);
350     return NULL;
351 }
352
353 CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
354 {
355     if (pszDest == NULL) {
356         if (IsLocal(addrConnect))
357             return NULL;
358
359         // Look for an existing connection
360         CNode* pnode = FindNode((CService)addrConnect);
361         if (pnode)
362         {
363             pnode->AddRef();
364             return pnode;
365         }
366     }
367
368     /// debug print
369     LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
370         pszDest ? pszDest : addrConnect.ToString(),
371         pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
372
373     // Connect
374     SOCKET hSocket;
375     bool proxyConnectionFailed = false;
376     if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
377                   ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
378     {
379         if (!IsSelectableSocket(hSocket)) {
380             LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
381             CloseSocket(hSocket);
382             return NULL;
383         }
384
385         addrman.Attempt(addrConnect);
386
387         // Add node
388         CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
389         pnode->AddRef();
390
391         {
392             LOCK(cs_vNodes);
393             vNodes.push_back(pnode);
394         }
395
396         pnode->nTimeConnected = GetTime();
397
398         return pnode;
399     } else if (!proxyConnectionFailed) {
400         // If connecting to the node failed, and failure is not caused by a problem connecting to
401         // the proxy, mark this as an attempt.
402         addrman.Attempt(addrConnect);
403     }
404
405     return NULL;
406 }
407
408 void CNode::CloseSocketDisconnect()
409 {
410     fDisconnect = true;
411     if (hSocket != INVALID_SOCKET)
412     {
413         LogPrint("net", "disconnecting peer=%d\n", id);
414         CloseSocket(hSocket);
415     }
416
417     // in case this fails, we'll empty the recv buffer when the CNode is deleted
418     TRY_LOCK(cs_vRecvMsg, lockRecv);
419     if (lockRecv)
420         vRecvMsg.clear();
421 }
422
423 void CNode::PushVersion()
424 {
425     int nBestHeight = g_signals.GetHeight().get_value_or(0);
426
427     int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
428     CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
429     CAddress addrMe = GetLocalAddress(&addr);
430     GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
431     if (fLogIPs)
432         LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
433     else
434         LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
435     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
436                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
437 }
438
439
440
441
442
443 std::map<CNetAddr, int64_t> CNode::setBanned;
444 CCriticalSection CNode::cs_setBanned;
445
446 void CNode::ClearBanned()
447 {
448     setBanned.clear();
449 }
450
451 bool CNode::IsBanned(CNetAddr ip)
452 {
453     bool fResult = false;
454     {
455         LOCK(cs_setBanned);
456         std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
457         if (i != setBanned.end())
458         {
459             int64_t t = (*i).second;
460             if (GetTime() < t)
461                 fResult = true;
462         }
463     }
464     return fResult;
465 }
466
467 bool CNode::Ban(const CNetAddr &addr) {
468     int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
469     {
470         LOCK(cs_setBanned);
471         if (setBanned[addr] < banTime)
472             setBanned[addr] = banTime;
473     }
474     return true;
475 }
476
477
478 std::vector<CSubNet> CNode::vWhitelistedRange;
479 CCriticalSection CNode::cs_vWhitelistedRange;
480
481 bool CNode::IsWhitelistedRange(const CNetAddr &addr) {
482     LOCK(cs_vWhitelistedRange);
483     BOOST_FOREACH(const CSubNet& subnet, vWhitelistedRange) {
484         if (subnet.Match(addr))
485             return true;
486     }
487     return false;
488 }
489
490 void CNode::AddWhitelistedRange(const CSubNet &subnet) {
491     LOCK(cs_vWhitelistedRange);
492     vWhitelistedRange.push_back(subnet);
493 }
494
495 #undef X
496 #define X(name) stats.name = name
497 void CNode::copyStats(CNodeStats &stats)
498 {
499     stats.nodeid = this->GetId();
500     X(nServices);
501     X(nLastSend);
502     X(nLastRecv);
503     X(nTimeConnected);
504     X(nTimeOffset);
505     X(addrName);
506     X(nVersion);
507     X(cleanSubVer);
508     X(fInbound);
509     X(nStartingHeight);
510     X(nSendBytes);
511     X(nRecvBytes);
512     X(fWhitelisted);
513
514     // It is common for nodes with good ping times to suddenly become lagged,
515     // due to a new block arriving or other large transfer.
516     // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
517     // since pingtime does not update until the ping is complete, which might take a while.
518     // So, if a ping is taking an unusually long time in flight,
519     // the caller can immediately detect that this is happening.
520     int64_t nPingUsecWait = 0;
521     if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
522         nPingUsecWait = GetTimeMicros() - nPingUsecStart;
523     }
524
525     // 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 :)
526     stats.dPingTime = (((double)nPingUsecTime) / 1e6);
527     stats.dPingWait = (((double)nPingUsecWait) / 1e6);
528
529     // Leave string empty if addrLocal invalid (not filled in yet)
530     stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
531 }
532 #undef X
533
534 // requires LOCK(cs_vRecvMsg)
535 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
536 {
537     while (nBytes > 0) {
538
539         // get current incomplete message, or create a new one
540         if (vRecvMsg.empty() ||
541             vRecvMsg.back().complete())
542             vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
543
544         CNetMessage& msg = vRecvMsg.back();
545
546         // absorb network data
547         int handled;
548         if (!msg.in_data)
549             handled = msg.readHeader(pch, nBytes);
550         else
551             handled = msg.readData(pch, nBytes);
552
553         if (handled < 0)
554                 return false;
555
556         if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
557             LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
558             return false;
559         }
560
561         pch += handled;
562         nBytes -= handled;
563
564         if (msg.complete()) {
565             msg.nTime = GetTimeMicros();
566             messageHandlerCondition.notify_one();
567         }
568     }
569
570     return true;
571 }
572
573 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
574 {
575     // copy data to temporary parsing buffer
576     unsigned int nRemaining = 24 - nHdrPos;
577     unsigned int nCopy = std::min(nRemaining, nBytes);
578
579     memcpy(&hdrbuf[nHdrPos], pch, nCopy);
580     nHdrPos += nCopy;
581
582     // if header incomplete, exit
583     if (nHdrPos < 24)
584         return nCopy;
585
586     // deserialize to CMessageHeader
587     try {
588         hdrbuf >> hdr;
589     }
590     catch (const std::exception&) {
591         return -1;
592     }
593
594     // reject messages larger than MAX_SIZE
595     if (hdr.nMessageSize > MAX_SIZE)
596             return -1;
597
598     // switch state to reading message data
599     in_data = true;
600
601     return nCopy;
602 }
603
604 int CNetMessage::readData(const char *pch, unsigned int nBytes)
605 {
606     unsigned int nRemaining = hdr.nMessageSize - nDataPos;
607     unsigned int nCopy = std::min(nRemaining, nBytes);
608
609     if (vRecv.size() < nDataPos + nCopy) {
610         // Allocate up to 256 KiB ahead, but never more than the total message size.
611         vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
612     }
613
614     memcpy(&vRecv[nDataPos], pch, nCopy);
615     nDataPos += nCopy;
616
617     return nCopy;
618 }
619
620
621
622
623
624
625
626
627
628 // requires LOCK(cs_vSend)
629 void SocketSendData(CNode *pnode)
630 {
631     std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
632
633     while (it != pnode->vSendMsg.end()) {
634         const CSerializeData &data = *it;
635         assert(data.size() > pnode->nSendOffset);
636         int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
637         if (nBytes > 0) {
638             pnode->nLastSend = GetTime();
639             pnode->nSendBytes += nBytes;
640             pnode->nSendOffset += nBytes;
641             pnode->RecordBytesSent(nBytes);
642             if (pnode->nSendOffset == data.size()) {
643                 pnode->nSendOffset = 0;
644                 pnode->nSendSize -= data.size();
645                 it++;
646             } else {
647                 // could not send full message; stop sending more
648                 break;
649             }
650         } else {
651             if (nBytes < 0) {
652                 // error
653                 int nErr = WSAGetLastError();
654                 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
655                 {
656                     LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
657                     pnode->CloseSocketDisconnect();
658                 }
659             }
660             // couldn't send anything at all
661             break;
662         }
663     }
664
665     if (it == pnode->vSendMsg.end()) {
666         assert(pnode->nSendOffset == 0);
667         assert(pnode->nSendSize == 0);
668     }
669     pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
670 }
671
672 static list<CNode*> vNodesDisconnected;
673
674 class CNodeRef {
675 public:
676     CNodeRef(CNode *pnode) : _pnode(pnode) {
677         LOCK(cs_vNodes);
678         _pnode->AddRef();
679     }
680
681     ~CNodeRef() {
682         LOCK(cs_vNodes);
683         _pnode->Release();
684     }
685
686     CNode& operator *() const {return *_pnode;};
687     CNode* operator ->() const {return _pnode;};
688
689     CNodeRef& operator =(const CNodeRef& other)
690     {
691         if (this != &other) {
692             LOCK(cs_vNodes);
693
694             _pnode->Release();
695             _pnode = other._pnode;
696             _pnode->AddRef();
697         }
698         return *this;
699     }
700
701     CNodeRef(const CNodeRef& other):
702         _pnode(other._pnode)
703     {
704         LOCK(cs_vNodes);
705         _pnode->AddRef();
706     }
707 private:
708     CNode *_pnode;
709 };
710
711 static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b)
712 {
713     return a->nMinPingUsecTime > b->nMinPingUsecTime;
714 }
715
716 static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b)
717 {
718     return a->nTimeConnected > b->nTimeConnected;
719 }
720
721 class CompareNetGroupKeyed
722 {
723     std::vector<unsigned char> vchSecretKey;
724 public:
725     CompareNetGroupKeyed()
726     {
727         vchSecretKey.resize(32, 0);
728         GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
729     }
730
731     bool operator()(const CNodeRef &a, const CNodeRef &b)
732     {
733         std::vector<unsigned char> vchGroupA, vchGroupB;
734         CSHA256 hashA, hashB;
735         std::vector<unsigned char> vchA(32), vchB(32);
736
737         vchGroupA = a->addr.GetGroup();
738         vchGroupB = b->addr.GetGroup();
739
740         hashA.Write(begin_ptr(vchGroupA), vchGroupA.size());
741         hashB.Write(begin_ptr(vchGroupB), vchGroupB.size());
742
743         hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
744         hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
745
746         hashA.Finalize(begin_ptr(vchA));
747         hashB.Finalize(begin_ptr(vchB));
748
749         return vchA < vchB;
750     }
751 };
752
753 static bool AttemptToEvictConnection(bool fPreferNewConnection) {
754     std::vector<CNodeRef> vEvictionCandidates;
755     {
756         LOCK(cs_vNodes);
757
758         BOOST_FOREACH(CNode *node, vNodes) {
759             if (node->fWhitelisted)
760                 continue;
761             if (!node->fInbound)
762                 continue;
763             if (node->fDisconnect)
764                 continue;
765             if (node->addr.IsLocal())
766                 continue;
767             vEvictionCandidates.push_back(CNodeRef(node));
768         }
769     }
770
771     if (vEvictionCandidates.empty()) return false;
772
773     // Protect connections with certain characteristics
774
775     // Deterministically select 4 peers to protect by netgroup.
776     // An attacker cannot predict which netgroups will be protected.
777     static CompareNetGroupKeyed comparerNetGroupKeyed;
778     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed);
779     vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
780
781     if (vEvictionCandidates.empty()) return false;
782
783     // Protect the 8 nodes with the best ping times.
784     // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
785     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
786     vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
787
788     if (vEvictionCandidates.empty()) return false;
789
790     // Protect the half of the remaining nodes which have been connected the longest.
791     // This replicates the existing implicit behavior.
792     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
793     vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
794
795     if (vEvictionCandidates.empty()) return false;
796
797     // Identify the network group with the most connections
798     std::vector<unsigned char> naMostConnections;
799     unsigned int nMostConnections = 0;
800     std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts;
801     BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
802         mapAddrCounts[node->addr.GetGroup()].push_back(node);
803
804         if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) {
805             nMostConnections = mapAddrCounts[node->addr.GetGroup()].size();
806             naMostConnections = node->addr.GetGroup();
807         }
808     }
809
810     // Reduce to the network group with the most connections
811     vEvictionCandidates = mapAddrCounts[naMostConnections];
812
813     // Do not disconnect peers if there is only 1 connection from their network group
814     if (vEvictionCandidates.size() <= 1)
815         // unless we prefer the new connection (for whitelisted peers)
816         if (!fPreferNewConnection)
817             return false;
818
819     // Disconnect the most recent connection from the network group with the most connections
820     std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
821     vEvictionCandidates[0]->fDisconnect = true;
822
823     return true;
824 }
825
826 static void AcceptConnection(const ListenSocket& hListenSocket) {
827     struct sockaddr_storage sockaddr;
828     socklen_t len = sizeof(sockaddr);
829     SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
830     CAddress addr;
831     int nInbound = 0;
832     int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS;
833
834     if (hSocket != INVALID_SOCKET)
835         if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
836             LogPrintf("Warning: Unknown socket family\n");
837
838     bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
839     {
840         LOCK(cs_vNodes);
841         BOOST_FOREACH(CNode* pnode, vNodes)
842             if (pnode->fInbound)
843                 nInbound++;
844     }
845
846     if (hSocket == INVALID_SOCKET)
847     {
848         int nErr = WSAGetLastError();
849         if (nErr != WSAEWOULDBLOCK)
850             LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
851         return;
852     }
853
854     if (!IsSelectableSocket(hSocket))
855     {
856         LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
857         CloseSocket(hSocket);
858         return;
859     }
860
861     if (CNode::IsBanned(addr) && !whitelisted)
862     {
863         LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
864         CloseSocket(hSocket);
865         return;
866     }
867
868     if (nInbound >= nMaxInbound)
869     {
870         if (!AttemptToEvictConnection(whitelisted)) {
871             // No connection to evict, disconnect the new connection
872             LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
873             CloseSocket(hSocket);
874             return;
875         }
876     }
877
878     // According to the internet TCP_NODELAY is not carried into accepted sockets
879     // on all platforms.  Set it again here just to be sure.
880     int set = 1;
881 #ifdef WIN32
882     setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
883 #else
884     setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int));
885 #endif
886
887     CNode* pnode = new CNode(hSocket, addr, "", true);
888     pnode->AddRef();
889     pnode->fWhitelisted = whitelisted;
890
891     LogPrint("net", "connection from %s accepted\n", addr.ToString());
892
893     {
894         LOCK(cs_vNodes);
895         vNodes.push_back(pnode);
896     }
897 }
898
899 void ThreadSocketHandler()
900 {
901     unsigned int nPrevNodeCount = 0;
902     while (true)
903     {
904         //
905         // Disconnect nodes
906         //
907         {
908             LOCK(cs_vNodes);
909             // Disconnect unused nodes
910             vector<CNode*> vNodesCopy = vNodes;
911             BOOST_FOREACH(CNode* pnode, vNodesCopy)
912             {
913                 if (pnode->fDisconnect ||
914                     (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
915                 {
916                     // remove from vNodes
917                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
918
919                     // release outbound grant (if any)
920                     pnode->grantOutbound.Release();
921
922                     // close socket and cleanup
923                     pnode->CloseSocketDisconnect();
924
925                     // hold in disconnected pool until all refs are released
926                     if (pnode->fNetworkNode || pnode->fInbound)
927                         pnode->Release();
928                     vNodesDisconnected.push_back(pnode);
929                 }
930             }
931         }
932         {
933             // Delete disconnected nodes
934             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
935             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
936             {
937                 // wait until threads are done using it
938                 if (pnode->GetRefCount() <= 0)
939                 {
940                     bool fDelete = false;
941                     {
942                         TRY_LOCK(pnode->cs_vSend, lockSend);
943                         if (lockSend)
944                         {
945                             TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
946                             if (lockRecv)
947                             {
948                                 TRY_LOCK(pnode->cs_inventory, lockInv);
949                                 if (lockInv)
950                                     fDelete = true;
951                             }
952                         }
953                     }
954                     if (fDelete)
955                     {
956                         vNodesDisconnected.remove(pnode);
957                         delete pnode;
958                     }
959                 }
960             }
961         }
962         if(vNodes.size() != nPrevNodeCount) {
963             nPrevNodeCount = vNodes.size();
964             uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
965         }
966
967         //
968         // Find which sockets have data to receive
969         //
970         struct timeval timeout;
971         timeout.tv_sec  = 0;
972         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
973
974         fd_set fdsetRecv;
975         fd_set fdsetSend;
976         fd_set fdsetError;
977         FD_ZERO(&fdsetRecv);
978         FD_ZERO(&fdsetSend);
979         FD_ZERO(&fdsetError);
980         SOCKET hSocketMax = 0;
981         bool have_fds = false;
982
983         BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
984             FD_SET(hListenSocket.socket, &fdsetRecv);
985             hSocketMax = max(hSocketMax, hListenSocket.socket);
986             have_fds = true;
987         }
988
989         {
990             LOCK(cs_vNodes);
991             BOOST_FOREACH(CNode* pnode, vNodes)
992             {
993                 if (pnode->hSocket == INVALID_SOCKET)
994                     continue;
995                 FD_SET(pnode->hSocket, &fdsetError);
996                 hSocketMax = max(hSocketMax, pnode->hSocket);
997                 have_fds = true;
998
999                 // Implement the following logic:
1000                 // * If there is data to send, select() for sending data. As this only
1001                 //   happens when optimistic write failed, we choose to first drain the
1002                 //   write buffer in this case before receiving more. This avoids
1003                 //   needlessly queueing received data, if the remote peer is not themselves
1004                 //   receiving data. This means properly utilizing TCP flow control signalling.
1005                 // * Otherwise, if there is no (complete) message in the receive buffer,
1006                 //   or there is space left in the buffer, select() for receiving data.
1007                 // * (if neither of the above applies, there is certainly one message
1008                 //   in the receiver buffer ready to be processed).
1009                 // Together, that means that at least one of the following is always possible,
1010                 // so we don't deadlock:
1011                 // * We send some data.
1012                 // * We wait for data to be received (and disconnect after timeout).
1013                 // * We process a message in the buffer (message handler thread).
1014                 {
1015                     TRY_LOCK(pnode->cs_vSend, lockSend);
1016                     if (lockSend && !pnode->vSendMsg.empty()) {
1017                         FD_SET(pnode->hSocket, &fdsetSend);
1018                         continue;
1019                     }
1020                 }
1021                 {
1022                     TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1023                     if (lockRecv && (
1024                         pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
1025                         pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
1026                         FD_SET(pnode->hSocket, &fdsetRecv);
1027                 }
1028             }
1029         }
1030
1031         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1032                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1033         boost::this_thread::interruption_point();
1034
1035         if (nSelect == SOCKET_ERROR)
1036         {
1037             if (have_fds)
1038             {
1039                 int nErr = WSAGetLastError();
1040                 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1041                 for (unsigned int i = 0; i <= hSocketMax; i++)
1042                     FD_SET(i, &fdsetRecv);
1043             }
1044             FD_ZERO(&fdsetSend);
1045             FD_ZERO(&fdsetError);
1046             MilliSleep(timeout.tv_usec/1000);
1047         }
1048
1049         //
1050         // Accept new connections
1051         //
1052         BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket)
1053         {
1054             if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
1055             {
1056                 AcceptConnection(hListenSocket);
1057             }
1058         }
1059
1060         //
1061         // Service each socket
1062         //
1063         vector<CNode*> vNodesCopy;
1064         {
1065             LOCK(cs_vNodes);
1066             vNodesCopy = vNodes;
1067             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1068                 pnode->AddRef();
1069         }
1070         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1071         {
1072             boost::this_thread::interruption_point();
1073
1074             //
1075             // Receive
1076             //
1077             if (pnode->hSocket == INVALID_SOCKET)
1078                 continue;
1079             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
1080             {
1081                 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1082                 if (lockRecv)
1083                 {
1084                     {
1085                         // typical socket buffer is 8K-64K
1086                         char pchBuf[0x10000];
1087                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1088                         if (nBytes > 0)
1089                         {
1090                             if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
1091                                 pnode->CloseSocketDisconnect();
1092                             pnode->nLastRecv = GetTime();
1093                             pnode->nRecvBytes += nBytes;
1094                             pnode->RecordBytesRecv(nBytes);
1095                         }
1096                         else if (nBytes == 0)
1097                         {
1098                             // socket closed gracefully
1099                             if (!pnode->fDisconnect)
1100                                 LogPrint("net", "socket closed\n");
1101                             pnode->CloseSocketDisconnect();
1102                         }
1103                         else if (nBytes < 0)
1104                         {
1105                             // error
1106                             int nErr = WSAGetLastError();
1107                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1108                             {
1109                                 if (!pnode->fDisconnect)
1110                                     LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1111                                 pnode->CloseSocketDisconnect();
1112                             }
1113                         }
1114                     }
1115                 }
1116             }
1117
1118             //
1119             // Send
1120             //
1121             if (pnode->hSocket == INVALID_SOCKET)
1122                 continue;
1123             if (FD_ISSET(pnode->hSocket, &fdsetSend))
1124             {
1125                 TRY_LOCK(pnode->cs_vSend, lockSend);
1126                 if (lockSend)
1127                     SocketSendData(pnode);
1128             }
1129
1130             //
1131             // Inactivity checking
1132             //
1133             int64_t nTime = GetTime();
1134             if (nTime - pnode->nTimeConnected > 60)
1135             {
1136                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1137                 {
1138                     LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->id);
1139                     pnode->fDisconnect = true;
1140                 }
1141                 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1142                 {
1143                     LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1144                     pnode->fDisconnect = true;
1145                 }
1146                 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1147                 {
1148                     LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1149                     pnode->fDisconnect = true;
1150                 }
1151                 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
1152                 {
1153                     LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1154                     pnode->fDisconnect = true;
1155                 }
1156             }
1157         }
1158         {
1159             LOCK(cs_vNodes);
1160             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1161                 pnode->Release();
1162         }
1163     }
1164 }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174 #ifdef USE_UPNP
1175 void ThreadMapPort()
1176 {
1177     std::string port = strprintf("%u", GetListenPort());
1178     const char * multicastif = 0;
1179     const char * minissdpdpath = 0;
1180     struct UPNPDev * devlist = 0;
1181     char lanaddr[64];
1182
1183 #ifndef UPNPDISCOVER_SUCCESS
1184     /* miniupnpc 1.5 */
1185     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1186 #elif MINIUPNPC_API_VERSION < 14
1187     /* miniupnpc 1.6 */
1188     int error = 0;
1189     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1190 #else
1191     /* miniupnpc 1.9.20150730 */
1192     int error = 0;
1193     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1194 #endif
1195
1196     struct UPNPUrls urls;
1197     struct IGDdatas data;
1198     int r;
1199
1200     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1201     if (r == 1)
1202     {
1203         if (fDiscover) {
1204             char externalIPAddress[40];
1205             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1206             if(r != UPNPCOMMAND_SUCCESS)
1207                 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1208             else
1209             {
1210                 if(externalIPAddress[0])
1211                 {
1212                     LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1213                     AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1214                 }
1215                 else
1216                     LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1217             }
1218         }
1219
1220         string strDesc = "Bitcoin " + FormatFullVersion();
1221
1222         try {
1223             while (true) {
1224 #ifndef UPNPDISCOVER_SUCCESS
1225                 /* miniupnpc 1.5 */
1226                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1227                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1228 #else
1229                 /* miniupnpc 1.6 */
1230                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1231                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1232 #endif
1233
1234                 if(r!=UPNPCOMMAND_SUCCESS)
1235                     LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1236                         port, port, lanaddr, r, strupnperror(r));
1237                 else
1238                     LogPrintf("UPnP Port Mapping successful.\n");;
1239
1240                 MilliSleep(20*60*1000); // Refresh every 20 minutes
1241             }
1242         }
1243         catch (const boost::thread_interrupted&)
1244         {
1245             r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1246             LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
1247             freeUPNPDevlist(devlist); devlist = 0;
1248             FreeUPNPUrls(&urls);
1249             throw;
1250         }
1251     } else {
1252         LogPrintf("No valid UPnP IGDs found\n");
1253         freeUPNPDevlist(devlist); devlist = 0;
1254         if (r != 0)
1255             FreeUPNPUrls(&urls);
1256     }
1257 }
1258
1259 void MapPort(bool fUseUPnP)
1260 {
1261     static boost::thread* upnp_thread = NULL;
1262
1263     if (fUseUPnP)
1264     {
1265         if (upnp_thread) {
1266             upnp_thread->interrupt();
1267             upnp_thread->join();
1268             delete upnp_thread;
1269         }
1270         upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1271     }
1272     else if (upnp_thread) {
1273         upnp_thread->interrupt();
1274         upnp_thread->join();
1275         delete upnp_thread;
1276         upnp_thread = NULL;
1277     }
1278 }
1279
1280 #else
1281 void MapPort(bool)
1282 {
1283     // Intentionally left blank.
1284 }
1285 #endif
1286
1287
1288
1289
1290
1291
1292 void ThreadDNSAddressSeed()
1293 {
1294     // goal: only query DNS seeds if address need is acute
1295     if ((addrman.size() > 0) &&
1296         (!GetBoolArg("-forcednsseed", false))) {
1297         MilliSleep(11 * 1000);
1298
1299         LOCK(cs_vNodes);
1300         if (vNodes.size() >= 2) {
1301             LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1302             return;
1303         }
1304     }
1305
1306     const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1307     int found = 0;
1308
1309     LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1310
1311     BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1312         if (HaveNameProxy()) {
1313             AddOneShot(seed.host);
1314         } else {
1315             vector<CNetAddr> vIPs;
1316             vector<CAddress> vAdd;
1317             if (LookupHost(seed.host.c_str(), vIPs))
1318             {
1319                 BOOST_FOREACH(CNetAddr& ip, vIPs)
1320                 {
1321                     int nOneDay = 24*3600;
1322                     CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1323                     addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1324                     vAdd.push_back(addr);
1325                     found++;
1326                 }
1327             }
1328             addrman.Add(vAdd, CNetAddr(seed.name, true));
1329         }
1330     }
1331
1332     LogPrintf("%d addresses found from DNS seeds\n", found);
1333 }
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346 void DumpAddresses()
1347 {
1348     int64_t nStart = GetTimeMillis();
1349
1350     CAddrDB adb;
1351     adb.Write(addrman);
1352
1353     LogPrint("net", "Flushed %d addresses to peers.dat  %dms\n",
1354            addrman.size(), GetTimeMillis() - nStart);
1355 }
1356
1357 void static ProcessOneShot()
1358 {
1359     string strDest;
1360     {
1361         LOCK(cs_vOneShots);
1362         if (vOneShots.empty())
1363             return;
1364         strDest = vOneShots.front();
1365         vOneShots.pop_front();
1366     }
1367     CAddress addr;
1368     CSemaphoreGrant grant(*semOutbound, true);
1369     if (grant) {
1370         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1371             AddOneShot(strDest);
1372     }
1373 }
1374
1375 void ThreadOpenConnections()
1376 {
1377     // Connect to specific addresses
1378     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1379     {
1380         for (int64_t nLoop = 0;; nLoop++)
1381         {
1382             ProcessOneShot();
1383             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1384             {
1385                 CAddress addr;
1386                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1387                 for (int i = 0; i < 10 && i < nLoop; i++)
1388                 {
1389                     MilliSleep(500);
1390                 }
1391             }
1392             MilliSleep(500);
1393         }
1394     }
1395
1396     // Initiate network connections
1397     int64_t nStart = GetTime();
1398     while (true)
1399     {
1400         ProcessOneShot();
1401
1402         MilliSleep(500);
1403
1404         CSemaphoreGrant grant(*semOutbound);
1405         boost::this_thread::interruption_point();
1406
1407         // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1408         if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1409             static bool done = false;
1410             if (!done) {
1411                 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1412                 addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1413                 done = true;
1414             }
1415         }
1416
1417         //
1418         // Choose an address to connect to based on most recently seen
1419         //
1420         CAddress addrConnect;
1421
1422         // Only connect out to one peer per network group (/16 for IPv4).
1423         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1424         int nOutbound = 0;
1425         set<vector<unsigned char> > setConnected;
1426         {
1427             LOCK(cs_vNodes);
1428             BOOST_FOREACH(CNode* pnode, vNodes) {
1429                 if (!pnode->fInbound) {
1430                     setConnected.insert(pnode->addr.GetGroup());
1431                     nOutbound++;
1432                 }
1433             }
1434         }
1435
1436         int64_t nANow = GetAdjustedTime();
1437
1438         int nTries = 0;
1439         while (true)
1440         {
1441             CAddrInfo addr = addrman.Select();
1442
1443             // if we selected an invalid address, restart
1444             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1445                 break;
1446
1447             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1448             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1449             // already-connected network ranges, ...) before trying new addrman addresses.
1450             nTries++;
1451             if (nTries > 100)
1452                 break;
1453
1454             if (IsLimited(addr))
1455                 continue;
1456
1457             // only consider very recently tried nodes after 30 failed attempts
1458             if (nANow - addr.nLastTry < 600 && nTries < 30)
1459                 continue;
1460
1461             // do not allow non-default ports, unless after 50 invalid addresses selected already
1462             if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1463                 continue;
1464
1465             addrConnect = addr;
1466             break;
1467         }
1468
1469         if (addrConnect.IsValid())
1470             OpenNetworkConnection(addrConnect, &grant);
1471     }
1472 }
1473
1474 void ThreadOpenAddedConnections()
1475 {
1476     {
1477         LOCK(cs_vAddedNodes);
1478         vAddedNodes = mapMultiArgs["-addnode"];
1479     }
1480
1481     if (HaveNameProxy()) {
1482         while(true) {
1483             list<string> lAddresses(0);
1484             {
1485                 LOCK(cs_vAddedNodes);
1486                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1487                     lAddresses.push_back(strAddNode);
1488             }
1489             BOOST_FOREACH(string& strAddNode, lAddresses) {
1490                 CAddress addr;
1491                 CSemaphoreGrant grant(*semOutbound);
1492                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1493                 MilliSleep(500);
1494             }
1495             MilliSleep(120000); // Retry every 2 minutes
1496         }
1497     }
1498
1499     for (unsigned int i = 0; true; i++)
1500     {
1501         list<string> lAddresses(0);
1502         {
1503             LOCK(cs_vAddedNodes);
1504             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1505                 lAddresses.push_back(strAddNode);
1506         }
1507
1508         list<vector<CService> > lservAddressesToAdd(0);
1509         BOOST_FOREACH(string& strAddNode, lAddresses)
1510         {
1511             vector<CService> vservNode(0);
1512             if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1513             {
1514                 lservAddressesToAdd.push_back(vservNode);
1515                 {
1516                     LOCK(cs_setservAddNodeAddresses);
1517                     BOOST_FOREACH(CService& serv, vservNode)
1518                         setservAddNodeAddresses.insert(serv);
1519                 }
1520             }
1521         }
1522         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1523         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1524         {
1525             LOCK(cs_vNodes);
1526             BOOST_FOREACH(CNode* pnode, vNodes)
1527                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1528                     BOOST_FOREACH(CService& addrNode, *(it))
1529                         if (pnode->addr == addrNode)
1530                         {
1531                             it = lservAddressesToAdd.erase(it);
1532                             it--;
1533                             break;
1534                         }
1535         }
1536         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1537         {
1538             CSemaphoreGrant grant(*semOutbound);
1539             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1540             MilliSleep(500);
1541         }
1542         MilliSleep(120000); // Retry every 2 minutes
1543     }
1544 }
1545
1546 // if successful, this moves the passed grant to the constructed node
1547 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
1548 {
1549     //
1550     // Initiate outbound network connection
1551     //
1552     boost::this_thread::interruption_point();
1553     if (!pszDest) {
1554         if (IsLocal(addrConnect) ||
1555             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1556             FindNode(addrConnect.ToStringIPPort()))
1557             return false;
1558     } else if (FindNode(std::string(pszDest)))
1559         return false;
1560
1561     CNode* pnode = ConnectNode(addrConnect, pszDest);
1562     boost::this_thread::interruption_point();
1563
1564     if (!pnode)
1565         return false;
1566     if (grantOutbound)
1567         grantOutbound->MoveTo(pnode->grantOutbound);
1568     pnode->fNetworkNode = true;
1569     if (fOneShot)
1570         pnode->fOneShot = true;
1571
1572     return true;
1573 }
1574
1575
1576 void ThreadMessageHandler()
1577 {
1578     boost::mutex condition_mutex;
1579     boost::unique_lock<boost::mutex> lock(condition_mutex);
1580
1581     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1582     while (true)
1583     {
1584         vector<CNode*> vNodesCopy;
1585         {
1586             LOCK(cs_vNodes);
1587             vNodesCopy = vNodes;
1588             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1589                 pnode->AddRef();
1590             }
1591         }
1592
1593         // Poll the connected nodes for messages
1594         CNode* pnodeTrickle = NULL;
1595         if (!vNodesCopy.empty())
1596             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1597
1598         bool fSleep = true;
1599
1600         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1601         {
1602             if (pnode->fDisconnect)
1603                 continue;
1604
1605             // Receive messages
1606             {
1607                 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1608                 if (lockRecv)
1609                 {
1610                     if (!g_signals.ProcessMessages(pnode))
1611                         pnode->CloseSocketDisconnect();
1612
1613                     if (pnode->nSendSize < SendBufferSize())
1614                     {
1615                         if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1616                         {
1617                             fSleep = false;
1618                         }
1619                     }
1620                 }
1621             }
1622             boost::this_thread::interruption_point();
1623
1624             // Send messages
1625             {
1626                 TRY_LOCK(pnode->cs_vSend, lockSend);
1627                 if (lockSend)
1628                     g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
1629             }
1630             boost::this_thread::interruption_point();
1631         }
1632
1633         {
1634             LOCK(cs_vNodes);
1635             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1636                 pnode->Release();
1637         }
1638
1639         if (fSleep)
1640             messageHandlerCondition.timed_wait(lock, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1641     }
1642 }
1643
1644
1645
1646
1647
1648
1649 bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted)
1650 {
1651     strError = "";
1652     int nOne = 1;
1653
1654     // Create socket for listening for incoming connections
1655     struct sockaddr_storage sockaddr;
1656     socklen_t len = sizeof(sockaddr);
1657     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1658     {
1659         strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
1660         LogPrintf("%s\n", strError);
1661         return false;
1662     }
1663
1664     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1665     if (hListenSocket == INVALID_SOCKET)
1666     {
1667         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1668         LogPrintf("%s\n", strError);
1669         return false;
1670     }
1671     if (!IsSelectableSocket(hListenSocket))
1672     {
1673         strError = "Error: Couldn't create a listenable socket for incoming connections";
1674         LogPrintf("%s\n", strError);
1675         return false;
1676     }
1677
1678
1679 #ifndef WIN32
1680 #ifdef SO_NOSIGPIPE
1681     // Different way of disabling SIGPIPE on BSD
1682     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1683 #endif
1684     // Allow binding if the port is still in TIME_WAIT state after
1685     // the program was closed and restarted.
1686     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1687     // Disable Nagle's algorithm
1688     setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int));
1689 #else
1690     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
1691     setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int));
1692 #endif
1693
1694     // Set to non-blocking, incoming connections will also inherit this
1695     if (!SetSocketNonBlocking(hListenSocket, true)) {
1696         strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1697         LogPrintf("%s\n", strError);
1698         return false;
1699     }
1700
1701     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1702     // and enable it by default or not. Try to enable it, if possible.
1703     if (addrBind.IsIPv6()) {
1704 #ifdef IPV6_V6ONLY
1705 #ifdef WIN32
1706         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1707 #else
1708         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1709 #endif
1710 #endif
1711 #ifdef WIN32
1712         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1713         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1714 #endif
1715     }
1716
1717     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1718     {
1719         int nErr = WSAGetLastError();
1720         if (nErr == WSAEADDRINUSE)
1721             strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
1722         else
1723             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
1724         LogPrintf("%s\n", strError);
1725         CloseSocket(hListenSocket);
1726         return false;
1727     }
1728     LogPrintf("Bound to %s\n", addrBind.ToString());
1729
1730     // Listen for incoming connections
1731     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1732     {
1733         strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1734         LogPrintf("%s\n", strError);
1735         CloseSocket(hListenSocket);
1736         return false;
1737     }
1738
1739     vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
1740
1741     if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
1742         AddLocal(addrBind, LOCAL_BIND);
1743
1744     return true;
1745 }
1746
1747 void static Discover(boost::thread_group& threadGroup)
1748 {
1749     if (!fDiscover)
1750         return;
1751
1752 #ifdef WIN32
1753     // Get local host IP
1754     char pszHostName[256] = "";
1755     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1756     {
1757         vector<CNetAddr> vaddr;
1758         if (LookupHost(pszHostName, vaddr))
1759         {
1760             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1761             {
1762                 if (AddLocal(addr, LOCAL_IF))
1763                     LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
1764             }
1765         }
1766     }
1767 #else
1768     // Get local host ip
1769     struct ifaddrs* myaddrs;
1770     if (getifaddrs(&myaddrs) == 0)
1771     {
1772         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1773         {
1774             if (ifa->ifa_addr == NULL) continue;
1775             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1776             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1777             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1778             if (ifa->ifa_addr->sa_family == AF_INET)
1779             {
1780                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1781                 CNetAddr addr(s4->sin_addr);
1782                 if (AddLocal(addr, LOCAL_IF))
1783                     LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1784             }
1785             else if (ifa->ifa_addr->sa_family == AF_INET6)
1786             {
1787                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1788                 CNetAddr addr(s6->sin6_addr);
1789                 if (AddLocal(addr, LOCAL_IF))
1790                     LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1791             }
1792         }
1793         freeifaddrs(myaddrs);
1794     }
1795 #endif
1796 }
1797
1798 void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
1799 {
1800     uiInterface.InitMessage(_("Loading addresses..."));
1801     // Load addresses for peers.dat
1802     int64_t nStart = GetTimeMillis();
1803     {
1804         CAddrDB adb;
1805         if (!adb.Read(addrman))
1806             LogPrintf("Invalid or missing peers.dat; recreating\n");
1807     }
1808     LogPrintf("Loaded %i addresses from peers.dat  %dms\n",
1809            addrman.size(), GetTimeMillis() - nStart);
1810     fAddressesInitialized = true;
1811
1812     if (semOutbound == NULL) {
1813         // initialize semaphore
1814         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
1815         semOutbound = new CSemaphore(nMaxOutbound);
1816     }
1817
1818     if (pnodeLocalHost == NULL)
1819         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1820
1821     Discover(threadGroup);
1822
1823     //
1824     // Start threads
1825     //
1826
1827     if (!GetBoolArg("-dnsseed", true))
1828         LogPrintf("DNS seeding disabled\n");
1829     else
1830         threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1831
1832     // Map ports with UPnP
1833     MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
1834
1835     // Send and receive from sockets, accept connections
1836     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1837
1838     // Initiate outbound connections from -addnode
1839     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1840
1841     // Initiate outbound connections
1842     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1843
1844     // Process messages
1845     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1846
1847     // Dump network addresses
1848     scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL);
1849 }
1850
1851 bool StopNode()
1852 {
1853     LogPrintf("StopNode()\n");
1854     MapPort(false);
1855     if (semOutbound)
1856         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1857             semOutbound->post();
1858
1859     if (fAddressesInitialized)
1860     {
1861         DumpAddresses();
1862         fAddressesInitialized = false;
1863     }
1864
1865     return true;
1866 }
1867
1868 class CNetCleanup
1869 {
1870 public:
1871     CNetCleanup() {}
1872
1873     ~CNetCleanup()
1874     {
1875         // Close sockets
1876         BOOST_FOREACH(CNode* pnode, vNodes)
1877             if (pnode->hSocket != INVALID_SOCKET)
1878                 CloseSocket(pnode->hSocket);
1879         BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
1880             if (hListenSocket.socket != INVALID_SOCKET)
1881                 if (!CloseSocket(hListenSocket.socket))
1882                     LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
1883
1884         // clean up some globals (to help leak detection)
1885         BOOST_FOREACH(CNode *pnode, vNodes)
1886             delete pnode;
1887         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1888             delete pnode;
1889         vNodes.clear();
1890         vNodesDisconnected.clear();
1891         vhListenSocket.clear();
1892         delete semOutbound;
1893         semOutbound = NULL;
1894         delete pnodeLocalHost;
1895         pnodeLocalHost = NULL;
1896
1897 #ifdef WIN32
1898         // Shutdown Windows Sockets
1899         WSACleanup();
1900 #endif
1901     }
1902 }
1903 instance_of_cnetcleanup;
1904
1905
1906
1907
1908
1909
1910
1911 void RelayTransaction(const CTransaction& tx)
1912 {
1913     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1914     ss.reserve(10000);
1915     ss << tx;
1916     RelayTransaction(tx, ss);
1917 }
1918
1919 void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
1920 {
1921     CInv inv(MSG_TX, tx.GetHash());
1922     {
1923         LOCK(cs_mapRelay);
1924         // Expire old relay messages
1925         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1926         {
1927             mapRelay.erase(vRelayExpiration.front().second);
1928             vRelayExpiration.pop_front();
1929         }
1930
1931         // Save original serialized message so newer versions are preserved
1932         mapRelay.insert(std::make_pair(inv, ss));
1933         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1934     }
1935     LOCK(cs_vNodes);
1936     BOOST_FOREACH(CNode* pnode, vNodes)
1937     {
1938         if(!pnode->fRelayTxes)
1939             continue;
1940         LOCK(pnode->cs_filter);
1941         if (pnode->pfilter)
1942         {
1943             if (pnode->pfilter->IsRelevantAndUpdate(tx))
1944                 pnode->PushInventory(inv);
1945         } else
1946             pnode->PushInventory(inv);
1947     }
1948 }
1949
1950 void CNode::RecordBytesRecv(uint64_t bytes)
1951 {
1952     LOCK(cs_totalBytesRecv);
1953     nTotalBytesRecv += bytes;
1954 }
1955
1956 void CNode::RecordBytesSent(uint64_t bytes)
1957 {
1958     LOCK(cs_totalBytesSent);
1959     nTotalBytesSent += bytes;
1960 }
1961
1962 uint64_t CNode::GetTotalBytesRecv()
1963 {
1964     LOCK(cs_totalBytesRecv);
1965     return nTotalBytesRecv;
1966 }
1967
1968 uint64_t CNode::GetTotalBytesSent()
1969 {
1970     LOCK(cs_totalBytesSent);
1971     return nTotalBytesSent;
1972 }
1973
1974 void CNode::Fuzz(int nChance)
1975 {
1976     if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
1977     if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
1978
1979     switch (GetRand(3))
1980     {
1981     case 0:
1982         // xor a random byte with a random value:
1983         if (!ssSend.empty()) {
1984             CDataStream::size_type pos = GetRand(ssSend.size());
1985             ssSend[pos] ^= (unsigned char)(GetRand(256));
1986         }
1987         break;
1988     case 1:
1989         // delete a random byte:
1990         if (!ssSend.empty()) {
1991             CDataStream::size_type pos = GetRand(ssSend.size());
1992             ssSend.erase(ssSend.begin()+pos);
1993         }
1994         break;
1995     case 2:
1996         // insert a random byte at a random position
1997         {
1998             CDataStream::size_type pos = GetRand(ssSend.size());
1999             char ch = (char)GetRand(256);
2000             ssSend.insert(ssSend.begin()+pos, ch);
2001         }
2002         break;
2003     }
2004     // Chance of more than one change half the time:
2005     // (more changes exponentially less likely):
2006     Fuzz(2);
2007 }
2008
2009 //
2010 // CAddrDB
2011 //
2012
2013 CAddrDB::CAddrDB()
2014 {
2015     pathAddr = GetDataDir() / "peers.dat";
2016 }
2017
2018 bool CAddrDB::Write(const CAddrMan& addr)
2019 {
2020     // Generate random temporary filename
2021     unsigned short randv = 0;
2022     GetRandBytes((unsigned char*)&randv, sizeof(randv));
2023     std::string tmpfn = strprintf("peers.dat.%04x", randv);
2024
2025     // serialize addresses, checksum data up to that point, then append csum
2026     CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
2027     ssPeers << FLATDATA(Params().MessageStart());
2028     ssPeers << addr;
2029     uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
2030     ssPeers << hash;
2031
2032     // open temp output file, and associate with CAutoFile
2033     boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
2034     FILE *file = fopen(pathTmp.string().c_str(), "wb");
2035     CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
2036     if (fileout.IsNull())
2037         return error("%s: Failed to open file %s", __func__, pathTmp.string());
2038
2039     // Write and commit header, data
2040     try {
2041         fileout << ssPeers;
2042     }
2043     catch (const std::exception& e) {
2044         return error("%s: Serialize or I/O error - %s", __func__, e.what());
2045     }
2046     FileCommit(fileout.Get());
2047     fileout.fclose();
2048
2049     // replace existing peers.dat, if any, with new peers.dat.XXXX
2050     if (!RenameOver(pathTmp, pathAddr))
2051         return error("%s: Rename-into-place failed", __func__);
2052
2053     return true;
2054 }
2055
2056 bool CAddrDB::Read(CAddrMan& addr)
2057 {
2058     // open input file, and associate with CAutoFile
2059     FILE *file = fopen(pathAddr.string().c_str(), "rb");
2060     CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
2061     if (filein.IsNull())
2062         return error("%s: Failed to open file %s", __func__, pathAddr.string());
2063
2064     // use file size to size memory buffer
2065     int fileSize = boost::filesystem::file_size(pathAddr);
2066     int dataSize = fileSize - sizeof(uint256);
2067     // Don't try to resize to a negative number if file is small
2068     if (dataSize < 0)
2069         dataSize = 0;
2070     vector<unsigned char> vchData;
2071     vchData.resize(dataSize);
2072     uint256 hashIn;
2073
2074     // read data and checksum from file
2075     try {
2076         filein.read((char *)&vchData[0], dataSize);
2077         filein >> hashIn;
2078     }
2079     catch (const std::exception& e) {
2080         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2081     }
2082     filein.fclose();
2083
2084     CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
2085
2086     // verify stored checksum matches input data
2087     uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
2088     if (hashIn != hashTmp)
2089         return error("%s: Checksum mismatch, data corrupted", __func__);
2090
2091     unsigned char pchMsgTmp[4];
2092     try {
2093         // de-serialize file header (network specific magic number) and ..
2094         ssPeers >> FLATDATA(pchMsgTmp);
2095
2096         // ... verify the network matches ours
2097         if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2098             return error("%s: Invalid network magic number", __func__);
2099
2100         // de-serialize address data into one CAddrMan object
2101         ssPeers >> addr;
2102     }
2103     catch (const std::exception& e) {
2104         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2105     }
2106
2107     return true;
2108 }
2109
2110 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
2111 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
2112
2113 CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) :
2114     ssSend(SER_NETWORK, INIT_PROTO_VERSION),
2115     addrKnown(5000, 0.001),
2116     setInventoryKnown(SendBufferSize() / 1000)
2117 {
2118     nServices = 0;
2119     hSocket = hSocketIn;
2120     nRecvVersion = INIT_PROTO_VERSION;
2121     nLastSend = 0;
2122     nLastRecv = 0;
2123     nSendBytes = 0;
2124     nRecvBytes = 0;
2125     nTimeConnected = GetTime();
2126     nTimeOffset = 0;
2127     addr = addrIn;
2128     addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2129     nVersion = 0;
2130     strSubVer = "";
2131     fWhitelisted = false;
2132     fOneShot = false;
2133     fClient = false; // set by version message
2134     fInbound = fInboundIn;
2135     fNetworkNode = false;
2136     fSuccessfullyConnected = false;
2137     fDisconnect = false;
2138     nRefCount = 0;
2139     nSendSize = 0;
2140     nSendOffset = 0;
2141     hashContinue = uint256();
2142     nStartingHeight = -1;
2143     fGetAddr = false;
2144     fRelayTxes = false;
2145     fSentAddr = false;
2146     pfilter = new CBloomFilter();
2147     nPingNonceSent = 0;
2148     nPingUsecStart = 0;
2149     nPingUsecTime = 0;
2150     fPingQueued = false;
2151     nMinPingUsecTime = std::numeric_limits<int64_t>::max();
2152
2153     {
2154         LOCK(cs_nLastNodeId);
2155         id = nLastNodeId++;
2156     }
2157
2158     if (fLogIPs)
2159         LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
2160     else
2161         LogPrint("net", "Added connection peer=%d\n", id);
2162
2163     // Be shy and don't send version until we hear
2164     if (hSocket != INVALID_SOCKET && !fInbound)
2165         PushVersion();
2166
2167     GetNodeSignals().InitializeNode(GetId(), this);
2168 }
2169
2170 CNode::~CNode()
2171 {
2172     CloseSocket(hSocket);
2173
2174     if (pfilter)
2175         delete pfilter;
2176
2177     GetNodeSignals().FinalizeNode(GetId());
2178 }
2179
2180 void CNode::AskFor(const CInv& inv)
2181 {
2182     if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
2183         return;
2184     // a peer may not have multiple non-responded queue positions for a single inv item
2185     if (!setAskFor.insert(inv.hash).second)
2186         return;
2187
2188     // We're using mapAskFor as a priority queue,
2189     // the key is the earliest time the request can be sent
2190     int64_t nRequestTime;
2191     limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
2192     if (it != mapAlreadyAskedFor.end())
2193         nRequestTime = it->second;
2194     else
2195         nRequestTime = 0;
2196     LogPrint("net", "askfor %s  %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id);
2197
2198     // Make sure not to reuse time indexes to keep things in the same order
2199     int64_t nNow = GetTimeMicros() - 1000000;
2200     static int64_t nLastTime;
2201     ++nLastTime;
2202     nNow = std::max(nNow, nLastTime);
2203     nLastTime = nNow;
2204
2205     // Each retry is 2 minutes after the last
2206     nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2207     if (it != mapAlreadyAskedFor.end())
2208         mapAlreadyAskedFor.update(it, nRequestTime);
2209     else
2210         mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2211     mapAskFor.insert(std::make_pair(nRequestTime, inv));
2212 }
2213
2214 void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
2215 {
2216     ENTER_CRITICAL_SECTION(cs_vSend);
2217     assert(ssSend.size() == 0);
2218     ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
2219     LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
2220 }
2221
2222 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
2223 {
2224     ssSend.clear();
2225
2226     LEAVE_CRITICAL_SECTION(cs_vSend);
2227
2228     LogPrint("net", "(aborted)\n");
2229 }
2230
2231 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
2232 {
2233     // The -*messagestest options are intentionally not documented in the help message,
2234     // since they are only used during development to debug the networking code and are
2235     // not intended for end-users.
2236     if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2237     {
2238         LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2239         AbortMessage();
2240         return;
2241     }
2242     if (mapArgs.count("-fuzzmessagestest"))
2243         Fuzz(GetArg("-fuzzmessagestest", 10));
2244
2245     if (ssSend.size() == 0)
2246     {
2247         LEAVE_CRITICAL_SECTION(cs_vSend);
2248         return;
2249     }
2250     // Set the size
2251     unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
2252     WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
2253
2254     // Set the checksum
2255     uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
2256     unsigned int nChecksum = 0;
2257     memcpy(&nChecksum, &hash, sizeof(nChecksum));
2258     assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
2259     memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
2260
2261     LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
2262
2263     std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
2264     ssSend.GetAndClear(*it);
2265     nSendSize += (*it).size();
2266
2267     // If write queue empty, attempt "optimistic write"
2268     if (it == vSendMsg.begin())
2269         SocketSendData(this);
2270
2271     LEAVE_CRITICAL_SECTION(cs_vSend);
2272 }
This page took 0.147163 seconds and 4 git commands to generate.