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