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