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