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