]> Git Repo - VerusCoin.git/blob - src/net.cpp
Make CRollingBloomFilter set nTweak for you
[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 void ThreadSocketHandler()
675 {
676     unsigned int nPrevNodeCount = 0;
677     while (true)
678     {
679         //
680         // Disconnect nodes
681         //
682         {
683             LOCK(cs_vNodes);
684             // Disconnect unused nodes
685             vector<CNode*> vNodesCopy = vNodes;
686             BOOST_FOREACH(CNode* pnode, vNodesCopy)
687             {
688                 if (pnode->fDisconnect ||
689                     (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
690                 {
691                     // remove from vNodes
692                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
693
694                     // release outbound grant (if any)
695                     pnode->grantOutbound.Release();
696
697                     // close socket and cleanup
698                     pnode->CloseSocketDisconnect();
699
700                     // hold in disconnected pool until all refs are released
701                     if (pnode->fNetworkNode || pnode->fInbound)
702                         pnode->Release();
703                     vNodesDisconnected.push_back(pnode);
704                 }
705             }
706         }
707         {
708             // Delete disconnected nodes
709             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
710             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
711             {
712                 // wait until threads are done using it
713                 if (pnode->GetRefCount() <= 0)
714                 {
715                     bool fDelete = false;
716                     {
717                         TRY_LOCK(pnode->cs_vSend, lockSend);
718                         if (lockSend)
719                         {
720                             TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
721                             if (lockRecv)
722                             {
723                                 TRY_LOCK(pnode->cs_inventory, lockInv);
724                                 if (lockInv)
725                                     fDelete = true;
726                             }
727                         }
728                     }
729                     if (fDelete)
730                     {
731                         vNodesDisconnected.remove(pnode);
732                         delete pnode;
733                     }
734                 }
735             }
736         }
737         if(vNodes.size() != nPrevNodeCount) {
738             nPrevNodeCount = vNodes.size();
739             uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
740         }
741
742         //
743         // Find which sockets have data to receive
744         //
745         struct timeval timeout;
746         timeout.tv_sec  = 0;
747         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
748
749         fd_set fdsetRecv;
750         fd_set fdsetSend;
751         fd_set fdsetError;
752         FD_ZERO(&fdsetRecv);
753         FD_ZERO(&fdsetSend);
754         FD_ZERO(&fdsetError);
755         SOCKET hSocketMax = 0;
756         bool have_fds = false;
757
758         BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
759             FD_SET(hListenSocket.socket, &fdsetRecv);
760             hSocketMax = max(hSocketMax, hListenSocket.socket);
761             have_fds = true;
762         }
763
764         {
765             LOCK(cs_vNodes);
766             BOOST_FOREACH(CNode* pnode, vNodes)
767             {
768                 if (pnode->hSocket == INVALID_SOCKET)
769                     continue;
770                 FD_SET(pnode->hSocket, &fdsetError);
771                 hSocketMax = max(hSocketMax, pnode->hSocket);
772                 have_fds = true;
773
774                 // Implement the following logic:
775                 // * If there is data to send, select() for sending data. As this only
776                 //   happens when optimistic write failed, we choose to first drain the
777                 //   write buffer in this case before receiving more. This avoids
778                 //   needlessly queueing received data, if the remote peer is not themselves
779                 //   receiving data. This means properly utilizing TCP flow control signalling.
780                 // * Otherwise, if there is no (complete) message in the receive buffer,
781                 //   or there is space left in the buffer, select() for receiving data.
782                 // * (if neither of the above applies, there is certainly one message
783                 //   in the receiver buffer ready to be processed).
784                 // Together, that means that at least one of the following is always possible,
785                 // so we don't deadlock:
786                 // * We send some data.
787                 // * We wait for data to be received (and disconnect after timeout).
788                 // * We process a message in the buffer (message handler thread).
789                 {
790                     TRY_LOCK(pnode->cs_vSend, lockSend);
791                     if (lockSend && !pnode->vSendMsg.empty()) {
792                         FD_SET(pnode->hSocket, &fdsetSend);
793                         continue;
794                     }
795                 }
796                 {
797                     TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
798                     if (lockRecv && (
799                         pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
800                         pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
801                         FD_SET(pnode->hSocket, &fdsetRecv);
802                 }
803             }
804         }
805
806         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
807                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
808         boost::this_thread::interruption_point();
809
810         if (nSelect == SOCKET_ERROR)
811         {
812             if (have_fds)
813             {
814                 int nErr = WSAGetLastError();
815                 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
816                 for (unsigned int i = 0; i <= hSocketMax; i++)
817                     FD_SET(i, &fdsetRecv);
818             }
819             FD_ZERO(&fdsetSend);
820             FD_ZERO(&fdsetError);
821             MilliSleep(timeout.tv_usec/1000);
822         }
823
824         //
825         // Accept new connections
826         //
827         BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket)
828         {
829             if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
830             {
831                 struct sockaddr_storage sockaddr;
832                 socklen_t len = sizeof(sockaddr);
833                 SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
834                 CAddress addr;
835                 int nInbound = 0;
836
837                 if (hSocket != INVALID_SOCKET)
838                     if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
839                         LogPrintf("Warning: Unknown socket family\n");
840
841                 bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
842                 {
843                     LOCK(cs_vNodes);
844                     BOOST_FOREACH(CNode* pnode, vNodes)
845                         if (pnode->fInbound)
846                             nInbound++;
847                 }
848
849                 if (hSocket == INVALID_SOCKET)
850                 {
851                     int nErr = WSAGetLastError();
852                     if (nErr != WSAEWOULDBLOCK)
853                         LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
854                 }
855                 else if (!IsSelectableSocket(hSocket))
856                 {
857                     LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
858                     CloseSocket(hSocket);
859                 }
860                 else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
861                 {
862                     LogPrint("net", "connection from %s dropped (full)\n", addr.ToString());
863                     CloseSocket(hSocket);
864                 }
865                 else if (CNode::IsBanned(addr) && !whitelisted)
866                 {
867                     LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
868                     CloseSocket(hSocket);
869                 }
870                 else
871                 {
872                     CNode* pnode = new CNode(hSocket, addr, "", true);
873                     pnode->AddRef();
874                     pnode->fWhitelisted = whitelisted;
875
876                     {
877                         LOCK(cs_vNodes);
878                         vNodes.push_back(pnode);
879                     }
880                 }
881             }
882         }
883
884         //
885         // Service each socket
886         //
887         vector<CNode*> vNodesCopy;
888         {
889             LOCK(cs_vNodes);
890             vNodesCopy = vNodes;
891             BOOST_FOREACH(CNode* pnode, vNodesCopy)
892                 pnode->AddRef();
893         }
894         BOOST_FOREACH(CNode* pnode, vNodesCopy)
895         {
896             boost::this_thread::interruption_point();
897
898             //
899             // Receive
900             //
901             if (pnode->hSocket == INVALID_SOCKET)
902                 continue;
903             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
904             {
905                 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
906                 if (lockRecv)
907                 {
908                     {
909                         // typical socket buffer is 8K-64K
910                         char pchBuf[0x10000];
911                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
912                         if (nBytes > 0)
913                         {
914                             if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
915                                 pnode->CloseSocketDisconnect();
916                             pnode->nLastRecv = GetTime();
917                             pnode->nRecvBytes += nBytes;
918                             pnode->RecordBytesRecv(nBytes);
919                         }
920                         else if (nBytes == 0)
921                         {
922                             // socket closed gracefully
923                             if (!pnode->fDisconnect)
924                                 LogPrint("net", "socket closed\n");
925                             pnode->CloseSocketDisconnect();
926                         }
927                         else if (nBytes < 0)
928                         {
929                             // error
930                             int nErr = WSAGetLastError();
931                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
932                             {
933                                 if (!pnode->fDisconnect)
934                                     LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
935                                 pnode->CloseSocketDisconnect();
936                             }
937                         }
938                     }
939                 }
940             }
941
942             //
943             // Send
944             //
945             if (pnode->hSocket == INVALID_SOCKET)
946                 continue;
947             if (FD_ISSET(pnode->hSocket, &fdsetSend))
948             {
949                 TRY_LOCK(pnode->cs_vSend, lockSend);
950                 if (lockSend)
951                     SocketSendData(pnode);
952             }
953
954             //
955             // Inactivity checking
956             //
957             int64_t nTime = GetTime();
958             if (nTime - pnode->nTimeConnected > 60)
959             {
960                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
961                 {
962                     LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->id);
963                     pnode->fDisconnect = true;
964                 }
965                 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
966                 {
967                     LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
968                     pnode->fDisconnect = true;
969                 }
970                 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
971                 {
972                     LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
973                     pnode->fDisconnect = true;
974                 }
975                 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
976                 {
977                     LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
978                     pnode->fDisconnect = true;
979                 }
980             }
981         }
982         {
983             LOCK(cs_vNodes);
984             BOOST_FOREACH(CNode* pnode, vNodesCopy)
985                 pnode->Release();
986         }
987     }
988 }
989
990
991
992
993
994
995
996
997
998 #ifdef USE_UPNP
999 void ThreadMapPort()
1000 {
1001     std::string port = strprintf("%u", GetListenPort());
1002     const char * multicastif = 0;
1003     const char * minissdpdpath = 0;
1004     struct UPNPDev * devlist = 0;
1005     char lanaddr[64];
1006
1007 #ifndef UPNPDISCOVER_SUCCESS
1008     /* miniupnpc 1.5 */
1009     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1010 #elif MINIUPNPC_API_VERSION < 14
1011     /* miniupnpc 1.6 */
1012     int error = 0;
1013     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1014 #else
1015     /* miniupnpc 1.9.20150730 */
1016     int error = 0;
1017     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1018 #endif
1019
1020     struct UPNPUrls urls;
1021     struct IGDdatas data;
1022     int r;
1023
1024     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1025     if (r == 1)
1026     {
1027         if (fDiscover) {
1028             char externalIPAddress[40];
1029             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1030             if(r != UPNPCOMMAND_SUCCESS)
1031                 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1032             else
1033             {
1034                 if(externalIPAddress[0])
1035                 {
1036                     LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1037                     AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1038                 }
1039                 else
1040                     LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1041             }
1042         }
1043
1044         string strDesc = "Bitcoin " + FormatFullVersion();
1045
1046         try {
1047             while (true) {
1048 #ifndef UPNPDISCOVER_SUCCESS
1049                 /* miniupnpc 1.5 */
1050                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1051                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1052 #else
1053                 /* miniupnpc 1.6 */
1054                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1055                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1056 #endif
1057
1058                 if(r!=UPNPCOMMAND_SUCCESS)
1059                     LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1060                         port, port, lanaddr, r, strupnperror(r));
1061                 else
1062                     LogPrintf("UPnP Port Mapping successful.\n");;
1063
1064                 MilliSleep(20*60*1000); // Refresh every 20 minutes
1065             }
1066         }
1067         catch (const boost::thread_interrupted&)
1068         {
1069             r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1070             LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
1071             freeUPNPDevlist(devlist); devlist = 0;
1072             FreeUPNPUrls(&urls);
1073             throw;
1074         }
1075     } else {
1076         LogPrintf("No valid UPnP IGDs found\n");
1077         freeUPNPDevlist(devlist); devlist = 0;
1078         if (r != 0)
1079             FreeUPNPUrls(&urls);
1080     }
1081 }
1082
1083 void MapPort(bool fUseUPnP)
1084 {
1085     static boost::thread* upnp_thread = NULL;
1086
1087     if (fUseUPnP)
1088     {
1089         if (upnp_thread) {
1090             upnp_thread->interrupt();
1091             upnp_thread->join();
1092             delete upnp_thread;
1093         }
1094         upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1095     }
1096     else if (upnp_thread) {
1097         upnp_thread->interrupt();
1098         upnp_thread->join();
1099         delete upnp_thread;
1100         upnp_thread = NULL;
1101     }
1102 }
1103
1104 #else
1105 void MapPort(bool)
1106 {
1107     // Intentionally left blank.
1108 }
1109 #endif
1110
1111
1112
1113
1114
1115
1116 void ThreadDNSAddressSeed()
1117 {
1118     // goal: only query DNS seeds if address need is acute
1119     if ((addrman.size() > 0) &&
1120         (!GetBoolArg("-forcednsseed", false))) {
1121         MilliSleep(11 * 1000);
1122
1123         LOCK(cs_vNodes);
1124         if (vNodes.size() >= 2) {
1125             LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1126             return;
1127         }
1128     }
1129
1130     const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1131     int found = 0;
1132
1133     LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1134
1135     BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1136         if (HaveNameProxy()) {
1137             AddOneShot(seed.host);
1138         } else {
1139             vector<CNetAddr> vIPs;
1140             vector<CAddress> vAdd;
1141             if (LookupHost(seed.host.c_str(), vIPs))
1142             {
1143                 BOOST_FOREACH(CNetAddr& ip, vIPs)
1144                 {
1145                     int nOneDay = 24*3600;
1146                     CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1147                     addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1148                     vAdd.push_back(addr);
1149                     found++;
1150                 }
1151             }
1152             addrman.Add(vAdd, CNetAddr(seed.name, true));
1153         }
1154     }
1155
1156     LogPrintf("%d addresses found from DNS seeds\n", found);
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170 void DumpAddresses()
1171 {
1172     int64_t nStart = GetTimeMillis();
1173
1174     CAddrDB adb;
1175     adb.Write(addrman);
1176
1177     LogPrint("net", "Flushed %d addresses to peers.dat  %dms\n",
1178            addrman.size(), GetTimeMillis() - nStart);
1179 }
1180
1181 void static ProcessOneShot()
1182 {
1183     string strDest;
1184     {
1185         LOCK(cs_vOneShots);
1186         if (vOneShots.empty())
1187             return;
1188         strDest = vOneShots.front();
1189         vOneShots.pop_front();
1190     }
1191     CAddress addr;
1192     CSemaphoreGrant grant(*semOutbound, true);
1193     if (grant) {
1194         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1195             AddOneShot(strDest);
1196     }
1197 }
1198
1199 void ThreadOpenConnections()
1200 {
1201     // Connect to specific addresses
1202     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1203     {
1204         for (int64_t nLoop = 0;; nLoop++)
1205         {
1206             ProcessOneShot();
1207             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1208             {
1209                 CAddress addr;
1210                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1211                 for (int i = 0; i < 10 && i < nLoop; i++)
1212                 {
1213                     MilliSleep(500);
1214                 }
1215             }
1216             MilliSleep(500);
1217         }
1218     }
1219
1220     // Initiate network connections
1221     int64_t nStart = GetTime();
1222     while (true)
1223     {
1224         ProcessOneShot();
1225
1226         MilliSleep(500);
1227
1228         CSemaphoreGrant grant(*semOutbound);
1229         boost::this_thread::interruption_point();
1230
1231         // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1232         if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1233             static bool done = false;
1234             if (!done) {
1235                 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1236                 addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1237                 done = true;
1238             }
1239         }
1240
1241         //
1242         // Choose an address to connect to based on most recently seen
1243         //
1244         CAddress addrConnect;
1245
1246         // Only connect out to one peer per network group (/16 for IPv4).
1247         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1248         int nOutbound = 0;
1249         set<vector<unsigned char> > setConnected;
1250         {
1251             LOCK(cs_vNodes);
1252             BOOST_FOREACH(CNode* pnode, vNodes) {
1253                 if (!pnode->fInbound) {
1254                     setConnected.insert(pnode->addr.GetGroup());
1255                     nOutbound++;
1256                 }
1257             }
1258         }
1259
1260         int64_t nANow = GetAdjustedTime();
1261
1262         int nTries = 0;
1263         while (true)
1264         {
1265             CAddrInfo addr = addrman.Select();
1266
1267             // if we selected an invalid address, restart
1268             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1269                 break;
1270
1271             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1272             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1273             // already-connected network ranges, ...) before trying new addrman addresses.
1274             nTries++;
1275             if (nTries > 100)
1276                 break;
1277
1278             if (IsLimited(addr))
1279                 continue;
1280
1281             // only consider very recently tried nodes after 30 failed attempts
1282             if (nANow - addr.nLastTry < 600 && nTries < 30)
1283                 continue;
1284
1285             // do not allow non-default ports, unless after 50 invalid addresses selected already
1286             if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1287                 continue;
1288
1289             addrConnect = addr;
1290             break;
1291         }
1292
1293         if (addrConnect.IsValid())
1294             OpenNetworkConnection(addrConnect, &grant);
1295     }
1296 }
1297
1298 void ThreadOpenAddedConnections()
1299 {
1300     {
1301         LOCK(cs_vAddedNodes);
1302         vAddedNodes = mapMultiArgs["-addnode"];
1303     }
1304
1305     if (HaveNameProxy()) {
1306         while(true) {
1307             list<string> lAddresses(0);
1308             {
1309                 LOCK(cs_vAddedNodes);
1310                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1311                     lAddresses.push_back(strAddNode);
1312             }
1313             BOOST_FOREACH(string& strAddNode, lAddresses) {
1314                 CAddress addr;
1315                 CSemaphoreGrant grant(*semOutbound);
1316                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1317                 MilliSleep(500);
1318             }
1319             MilliSleep(120000); // Retry every 2 minutes
1320         }
1321     }
1322
1323     for (unsigned int i = 0; true; i++)
1324     {
1325         list<string> lAddresses(0);
1326         {
1327             LOCK(cs_vAddedNodes);
1328             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1329                 lAddresses.push_back(strAddNode);
1330         }
1331
1332         list<vector<CService> > lservAddressesToAdd(0);
1333         BOOST_FOREACH(string& strAddNode, lAddresses)
1334         {
1335             vector<CService> vservNode(0);
1336             if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1337             {
1338                 lservAddressesToAdd.push_back(vservNode);
1339                 {
1340                     LOCK(cs_setservAddNodeAddresses);
1341                     BOOST_FOREACH(CService& serv, vservNode)
1342                         setservAddNodeAddresses.insert(serv);
1343                 }
1344             }
1345         }
1346         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1347         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1348         {
1349             LOCK(cs_vNodes);
1350             BOOST_FOREACH(CNode* pnode, vNodes)
1351                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1352                     BOOST_FOREACH(CService& addrNode, *(it))
1353                         if (pnode->addr == addrNode)
1354                         {
1355                             it = lservAddressesToAdd.erase(it);
1356                             it--;
1357                             break;
1358                         }
1359         }
1360         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1361         {
1362             CSemaphoreGrant grant(*semOutbound);
1363             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1364             MilliSleep(500);
1365         }
1366         MilliSleep(120000); // Retry every 2 minutes
1367     }
1368 }
1369
1370 // if successful, this moves the passed grant to the constructed node
1371 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
1372 {
1373     //
1374     // Initiate outbound network connection
1375     //
1376     boost::this_thread::interruption_point();
1377     if (!pszDest) {
1378         if (IsLocal(addrConnect) ||
1379             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1380             FindNode(addrConnect.ToStringIPPort()))
1381             return false;
1382     } else if (FindNode(std::string(pszDest)))
1383         return false;
1384
1385     CNode* pnode = ConnectNode(addrConnect, pszDest);
1386     boost::this_thread::interruption_point();
1387
1388     if (!pnode)
1389         return false;
1390     if (grantOutbound)
1391         grantOutbound->MoveTo(pnode->grantOutbound);
1392     pnode->fNetworkNode = true;
1393     if (fOneShot)
1394         pnode->fOneShot = true;
1395
1396     return true;
1397 }
1398
1399
1400 void ThreadMessageHandler()
1401 {
1402     boost::mutex condition_mutex;
1403     boost::unique_lock<boost::mutex> lock(condition_mutex);
1404
1405     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1406     while (true)
1407     {
1408         vector<CNode*> vNodesCopy;
1409         {
1410             LOCK(cs_vNodes);
1411             vNodesCopy = vNodes;
1412             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1413                 pnode->AddRef();
1414             }
1415         }
1416
1417         // Poll the connected nodes for messages
1418         CNode* pnodeTrickle = NULL;
1419         if (!vNodesCopy.empty())
1420             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1421
1422         bool fSleep = true;
1423
1424         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1425         {
1426             if (pnode->fDisconnect)
1427                 continue;
1428
1429             // Receive messages
1430             {
1431                 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1432                 if (lockRecv)
1433                 {
1434                     if (!g_signals.ProcessMessages(pnode))
1435                         pnode->CloseSocketDisconnect();
1436
1437                     if (pnode->nSendSize < SendBufferSize())
1438                     {
1439                         if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1440                         {
1441                             fSleep = false;
1442                         }
1443                     }
1444                 }
1445             }
1446             boost::this_thread::interruption_point();
1447
1448             // Send messages
1449             {
1450                 TRY_LOCK(pnode->cs_vSend, lockSend);
1451                 if (lockSend)
1452                     g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
1453             }
1454             boost::this_thread::interruption_point();
1455         }
1456
1457         {
1458             LOCK(cs_vNodes);
1459             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1460                 pnode->Release();
1461         }
1462
1463         if (fSleep)
1464             messageHandlerCondition.timed_wait(lock, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1465     }
1466 }
1467
1468
1469
1470
1471
1472
1473 bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted)
1474 {
1475     strError = "";
1476     int nOne = 1;
1477
1478     // Create socket for listening for incoming connections
1479     struct sockaddr_storage sockaddr;
1480     socklen_t len = sizeof(sockaddr);
1481     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1482     {
1483         strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
1484         LogPrintf("%s\n", strError);
1485         return false;
1486     }
1487
1488     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1489     if (hListenSocket == INVALID_SOCKET)
1490     {
1491         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1492         LogPrintf("%s\n", strError);
1493         return false;
1494     }
1495     if (!IsSelectableSocket(hListenSocket))
1496     {
1497         strError = "Error: Couldn't create a listenable socket for incoming connections";
1498         LogPrintf("%s\n", strError);
1499         return false;
1500     }
1501
1502
1503 #ifndef WIN32
1504 #ifdef SO_NOSIGPIPE
1505     // Different way of disabling SIGPIPE on BSD
1506     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1507 #endif
1508     // Allow binding if the port is still in TIME_WAIT state after
1509     // the program was closed and restarted.
1510     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1511 #else
1512     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
1513 #endif
1514
1515     // Set to non-blocking, incoming connections will also inherit this
1516     if (!SetSocketNonBlocking(hListenSocket, true)) {
1517         strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1518         LogPrintf("%s\n", strError);
1519         return false;
1520     }
1521
1522     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1523     // and enable it by default or not. Try to enable it, if possible.
1524     if (addrBind.IsIPv6()) {
1525 #ifdef IPV6_V6ONLY
1526 #ifdef WIN32
1527         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1528 #else
1529         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1530 #endif
1531 #endif
1532 #ifdef WIN32
1533         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1534         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1535 #endif
1536     }
1537
1538     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1539     {
1540         int nErr = WSAGetLastError();
1541         if (nErr == WSAEADDRINUSE)
1542             strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
1543         else
1544             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
1545         LogPrintf("%s\n", strError);
1546         CloseSocket(hListenSocket);
1547         return false;
1548     }
1549     LogPrintf("Bound to %s\n", addrBind.ToString());
1550
1551     // Listen for incoming connections
1552     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1553     {
1554         strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1555         LogPrintf("%s\n", strError);
1556         CloseSocket(hListenSocket);
1557         return false;
1558     }
1559
1560     vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
1561
1562     if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
1563         AddLocal(addrBind, LOCAL_BIND);
1564
1565     return true;
1566 }
1567
1568 void static Discover(boost::thread_group& threadGroup)
1569 {
1570     if (!fDiscover)
1571         return;
1572
1573 #ifdef WIN32
1574     // Get local host IP
1575     char pszHostName[256] = "";
1576     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1577     {
1578         vector<CNetAddr> vaddr;
1579         if (LookupHost(pszHostName, vaddr))
1580         {
1581             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1582             {
1583                 if (AddLocal(addr, LOCAL_IF))
1584                     LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
1585             }
1586         }
1587     }
1588 #else
1589     // Get local host ip
1590     struct ifaddrs* myaddrs;
1591     if (getifaddrs(&myaddrs) == 0)
1592     {
1593         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1594         {
1595             if (ifa->ifa_addr == NULL) continue;
1596             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1597             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1598             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1599             if (ifa->ifa_addr->sa_family == AF_INET)
1600             {
1601                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1602                 CNetAddr addr(s4->sin_addr);
1603                 if (AddLocal(addr, LOCAL_IF))
1604                     LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1605             }
1606             else if (ifa->ifa_addr->sa_family == AF_INET6)
1607             {
1608                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1609                 CNetAddr addr(s6->sin6_addr);
1610                 if (AddLocal(addr, LOCAL_IF))
1611                     LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1612             }
1613         }
1614         freeifaddrs(myaddrs);
1615     }
1616 #endif
1617 }
1618
1619 void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
1620 {
1621     uiInterface.InitMessage(_("Loading addresses..."));
1622     // Load addresses for peers.dat
1623     int64_t nStart = GetTimeMillis();
1624     {
1625         CAddrDB adb;
1626         if (!adb.Read(addrman))
1627             LogPrintf("Invalid or missing peers.dat; recreating\n");
1628     }
1629     LogPrintf("Loaded %i addresses from peers.dat  %dms\n",
1630            addrman.size(), GetTimeMillis() - nStart);
1631     fAddressesInitialized = true;
1632
1633     if (semOutbound == NULL) {
1634         // initialize semaphore
1635         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
1636         semOutbound = new CSemaphore(nMaxOutbound);
1637     }
1638
1639     if (pnodeLocalHost == NULL)
1640         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1641
1642     Discover(threadGroup);
1643
1644     //
1645     // Start threads
1646     //
1647
1648     if (!GetBoolArg("-dnsseed", true))
1649         LogPrintf("DNS seeding disabled\n");
1650     else
1651         threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1652
1653     // Map ports with UPnP
1654     MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
1655
1656     // Send and receive from sockets, accept connections
1657     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1658
1659     // Initiate outbound connections from -addnode
1660     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1661
1662     // Initiate outbound connections
1663     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1664
1665     // Process messages
1666     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1667
1668     // Dump network addresses
1669     scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL);
1670 }
1671
1672 bool StopNode()
1673 {
1674     LogPrintf("StopNode()\n");
1675     MapPort(false);
1676     if (semOutbound)
1677         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1678             semOutbound->post();
1679
1680     if (fAddressesInitialized)
1681     {
1682         DumpAddresses();
1683         fAddressesInitialized = false;
1684     }
1685
1686     return true;
1687 }
1688
1689 class CNetCleanup
1690 {
1691 public:
1692     CNetCleanup() {}
1693
1694     ~CNetCleanup()
1695     {
1696         // Close sockets
1697         BOOST_FOREACH(CNode* pnode, vNodes)
1698             if (pnode->hSocket != INVALID_SOCKET)
1699                 CloseSocket(pnode->hSocket);
1700         BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
1701             if (hListenSocket.socket != INVALID_SOCKET)
1702                 if (!CloseSocket(hListenSocket.socket))
1703                     LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
1704
1705         // clean up some globals (to help leak detection)
1706         BOOST_FOREACH(CNode *pnode, vNodes)
1707             delete pnode;
1708         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1709             delete pnode;
1710         vNodes.clear();
1711         vNodesDisconnected.clear();
1712         vhListenSocket.clear();
1713         delete semOutbound;
1714         semOutbound = NULL;
1715         delete pnodeLocalHost;
1716         pnodeLocalHost = NULL;
1717
1718 #ifdef WIN32
1719         // Shutdown Windows Sockets
1720         WSACleanup();
1721 #endif
1722     }
1723 }
1724 instance_of_cnetcleanup;
1725
1726
1727
1728
1729
1730
1731
1732 void RelayTransaction(const CTransaction& tx)
1733 {
1734     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1735     ss.reserve(10000);
1736     ss << tx;
1737     RelayTransaction(tx, ss);
1738 }
1739
1740 void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
1741 {
1742     CInv inv(MSG_TX, tx.GetHash());
1743     {
1744         LOCK(cs_mapRelay);
1745         // Expire old relay messages
1746         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1747         {
1748             mapRelay.erase(vRelayExpiration.front().second);
1749             vRelayExpiration.pop_front();
1750         }
1751
1752         // Save original serialized message so newer versions are preserved
1753         mapRelay.insert(std::make_pair(inv, ss));
1754         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1755     }
1756     LOCK(cs_vNodes);
1757     BOOST_FOREACH(CNode* pnode, vNodes)
1758     {
1759         if(!pnode->fRelayTxes)
1760             continue;
1761         LOCK(pnode->cs_filter);
1762         if (pnode->pfilter)
1763         {
1764             if (pnode->pfilter->IsRelevantAndUpdate(tx))
1765                 pnode->PushInventory(inv);
1766         } else
1767             pnode->PushInventory(inv);
1768     }
1769 }
1770
1771 void CNode::RecordBytesRecv(uint64_t bytes)
1772 {
1773     LOCK(cs_totalBytesRecv);
1774     nTotalBytesRecv += bytes;
1775 }
1776
1777 void CNode::RecordBytesSent(uint64_t bytes)
1778 {
1779     LOCK(cs_totalBytesSent);
1780     nTotalBytesSent += bytes;
1781 }
1782
1783 uint64_t CNode::GetTotalBytesRecv()
1784 {
1785     LOCK(cs_totalBytesRecv);
1786     return nTotalBytesRecv;
1787 }
1788
1789 uint64_t CNode::GetTotalBytesSent()
1790 {
1791     LOCK(cs_totalBytesSent);
1792     return nTotalBytesSent;
1793 }
1794
1795 void CNode::Fuzz(int nChance)
1796 {
1797     if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
1798     if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
1799
1800     switch (GetRand(3))
1801     {
1802     case 0:
1803         // xor a random byte with a random value:
1804         if (!ssSend.empty()) {
1805             CDataStream::size_type pos = GetRand(ssSend.size());
1806             ssSend[pos] ^= (unsigned char)(GetRand(256));
1807         }
1808         break;
1809     case 1:
1810         // delete a random byte:
1811         if (!ssSend.empty()) {
1812             CDataStream::size_type pos = GetRand(ssSend.size());
1813             ssSend.erase(ssSend.begin()+pos);
1814         }
1815         break;
1816     case 2:
1817         // insert a random byte at a random position
1818         {
1819             CDataStream::size_type pos = GetRand(ssSend.size());
1820             char ch = (char)GetRand(256);
1821             ssSend.insert(ssSend.begin()+pos, ch);
1822         }
1823         break;
1824     }
1825     // Chance of more than one change half the time:
1826     // (more changes exponentially less likely):
1827     Fuzz(2);
1828 }
1829
1830 //
1831 // CAddrDB
1832 //
1833
1834 CAddrDB::CAddrDB()
1835 {
1836     pathAddr = GetDataDir() / "peers.dat";
1837 }
1838
1839 bool CAddrDB::Write(const CAddrMan& addr)
1840 {
1841     // Generate random temporary filename
1842     unsigned short randv = 0;
1843     GetRandBytes((unsigned char*)&randv, sizeof(randv));
1844     std::string tmpfn = strprintf("peers.dat.%04x", randv);
1845
1846     // serialize addresses, checksum data up to that point, then append csum
1847     CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
1848     ssPeers << FLATDATA(Params().MessageStart());
1849     ssPeers << addr;
1850     uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
1851     ssPeers << hash;
1852
1853     // open temp output file, and associate with CAutoFile
1854     boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
1855     FILE *file = fopen(pathTmp.string().c_str(), "wb");
1856     CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
1857     if (fileout.IsNull())
1858         return error("%s: Failed to open file %s", __func__, pathTmp.string());
1859
1860     // Write and commit header, data
1861     try {
1862         fileout << ssPeers;
1863     }
1864     catch (const std::exception& e) {
1865         return error("%s: Serialize or I/O error - %s", __func__, e.what());
1866     }
1867     FileCommit(fileout.Get());
1868     fileout.fclose();
1869
1870     // replace existing peers.dat, if any, with new peers.dat.XXXX
1871     if (!RenameOver(pathTmp, pathAddr))
1872         return error("%s: Rename-into-place failed", __func__);
1873
1874     return true;
1875 }
1876
1877 bool CAddrDB::Read(CAddrMan& addr)
1878 {
1879     // open input file, and associate with CAutoFile
1880     FILE *file = fopen(pathAddr.string().c_str(), "rb");
1881     CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
1882     if (filein.IsNull())
1883         return error("%s: Failed to open file %s", __func__, pathAddr.string());
1884
1885     // use file size to size memory buffer
1886     int fileSize = boost::filesystem::file_size(pathAddr);
1887     int dataSize = fileSize - sizeof(uint256);
1888     // Don't try to resize to a negative number if file is small
1889     if (dataSize < 0)
1890         dataSize = 0;
1891     vector<unsigned char> vchData;
1892     vchData.resize(dataSize);
1893     uint256 hashIn;
1894
1895     // read data and checksum from file
1896     try {
1897         filein.read((char *)&vchData[0], dataSize);
1898         filein >> hashIn;
1899     }
1900     catch (const std::exception& e) {
1901         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1902     }
1903     filein.fclose();
1904
1905     CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
1906
1907     // verify stored checksum matches input data
1908     uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
1909     if (hashIn != hashTmp)
1910         return error("%s: Checksum mismatch, data corrupted", __func__);
1911
1912     unsigned char pchMsgTmp[4];
1913     try {
1914         // de-serialize file header (network specific magic number) and ..
1915         ssPeers >> FLATDATA(pchMsgTmp);
1916
1917         // ... verify the network matches ours
1918         if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
1919             return error("%s: Invalid network magic number", __func__);
1920
1921         // de-serialize address data into one CAddrMan object
1922         ssPeers >> addr;
1923     }
1924     catch (const std::exception& e) {
1925         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1926     }
1927
1928     return true;
1929 }
1930
1931 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
1932 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
1933
1934 CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) :
1935     ssSend(SER_NETWORK, INIT_PROTO_VERSION),
1936     addrKnown(5000, 0.001),
1937     setInventoryKnown(SendBufferSize() / 1000)
1938 {
1939     nServices = 0;
1940     hSocket = hSocketIn;
1941     nRecvVersion = INIT_PROTO_VERSION;
1942     nLastSend = 0;
1943     nLastRecv = 0;
1944     nSendBytes = 0;
1945     nRecvBytes = 0;
1946     nTimeConnected = GetTime();
1947     nTimeOffset = 0;
1948     addr = addrIn;
1949     addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
1950     nVersion = 0;
1951     strSubVer = "";
1952     fWhitelisted = false;
1953     fOneShot = false;
1954     fClient = false; // set by version message
1955     fInbound = fInboundIn;
1956     fNetworkNode = false;
1957     fSuccessfullyConnected = false;
1958     fDisconnect = false;
1959     nRefCount = 0;
1960     nSendSize = 0;
1961     nSendOffset = 0;
1962     hashContinue = uint256();
1963     nStartingHeight = -1;
1964     fGetAddr = false;
1965     fRelayTxes = false;
1966     pfilter = new CBloomFilter();
1967     nPingNonceSent = 0;
1968     nPingUsecStart = 0;
1969     nPingUsecTime = 0;
1970     fPingQueued = false;
1971
1972     {
1973         LOCK(cs_nLastNodeId);
1974         id = nLastNodeId++;
1975     }
1976
1977     if (fLogIPs)
1978         LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
1979     else
1980         LogPrint("net", "Added connection peer=%d\n", id);
1981
1982     // Be shy and don't send version until we hear
1983     if (hSocket != INVALID_SOCKET && !fInbound)
1984         PushVersion();
1985
1986     GetNodeSignals().InitializeNode(GetId(), this);
1987 }
1988
1989 CNode::~CNode()
1990 {
1991     CloseSocket(hSocket);
1992
1993     if (pfilter)
1994         delete pfilter;
1995
1996     GetNodeSignals().FinalizeNode(GetId());
1997 }
1998
1999 void CNode::AskFor(const CInv& inv)
2000 {
2001     if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
2002         return;
2003     // We're using mapAskFor as a priority queue,
2004     // the key is the earliest time the request can be sent
2005     int64_t nRequestTime;
2006     limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
2007     if (it != mapAlreadyAskedFor.end())
2008         nRequestTime = it->second;
2009     else
2010         nRequestTime = 0;
2011     LogPrint("net", "askfor %s  %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id);
2012
2013     // Make sure not to reuse time indexes to keep things in the same order
2014     int64_t nNow = GetTimeMicros() - 1000000;
2015     static int64_t nLastTime;
2016     ++nLastTime;
2017     nNow = std::max(nNow, nLastTime);
2018     nLastTime = nNow;
2019
2020     // Each retry is 2 minutes after the last
2021     nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2022     if (it != mapAlreadyAskedFor.end())
2023         mapAlreadyAskedFor.update(it, nRequestTime);
2024     else
2025         mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2026     mapAskFor.insert(std::make_pair(nRequestTime, inv));
2027 }
2028
2029 void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
2030 {
2031     ENTER_CRITICAL_SECTION(cs_vSend);
2032     assert(ssSend.size() == 0);
2033     ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
2034     LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
2035 }
2036
2037 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
2038 {
2039     ssSend.clear();
2040
2041     LEAVE_CRITICAL_SECTION(cs_vSend);
2042
2043     LogPrint("net", "(aborted)\n");
2044 }
2045
2046 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
2047 {
2048     // The -*messagestest options are intentionally not documented in the help message,
2049     // since they are only used during development to debug the networking code and are
2050     // not intended for end-users.
2051     if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2052     {
2053         LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2054         AbortMessage();
2055         return;
2056     }
2057     if (mapArgs.count("-fuzzmessagestest"))
2058         Fuzz(GetArg("-fuzzmessagestest", 10));
2059
2060     if (ssSend.size() == 0)
2061     {
2062         LEAVE_CRITICAL_SECTION(cs_vSend);
2063         return;
2064     }
2065     // Set the size
2066     unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
2067     WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
2068
2069     // Set the checksum
2070     uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
2071     unsigned int nChecksum = 0;
2072     memcpy(&nChecksum, &hash, sizeof(nChecksum));
2073     assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
2074     memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
2075
2076     LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
2077
2078     std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
2079     ssSend.GetAndClear(*it);
2080     nSendSize += (*it).size();
2081
2082     // If write queue empty, attempt "optimistic write"
2083     if (it == vSendMsg.begin())
2084         SocketSendData(this);
2085
2086     LEAVE_CRITICAL_SECTION(cs_vSend);
2087 }
This page took 0.140801 seconds and 4 git commands to generate.