]> Git Repo - VerusCoin.git/blob - src/net.cpp
Merge pull request #1728 from xanatos/patch-11
[VerusCoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 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 #include "irc.h"
7 #include "db.h"
8 #include "net.h"
9 #include "init.h"
10 #include "strlcpy.h"
11 #include "addrman.h"
12 #include "ui_interface.h"
13
14 #ifdef WIN32
15 #include <string.h>
16 #endif
17
18 #ifdef USE_UPNP
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
23 #endif
24
25 using namespace std;
26 using namespace boost;
27
28 static const int MAX_OUTBOUND_CONNECTIONS = 8;
29
30 void ThreadMessageHandler2(void* parg);
31 void ThreadSocketHandler2(void* parg);
32 void ThreadOpenConnections2(void* parg);
33 void ThreadOpenAddedConnections2(void* parg);
34 #ifdef USE_UPNP
35 void ThreadMapPort2(void* parg);
36 #endif
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
39
40
41 struct LocalServiceInfo {
42     int nScore;
43     int nPort;
44 };
45
46 //
47 // Global state variables
48 //
49 bool fClient = false;
50 bool fDiscover = true;
51 bool fUseUPnP = false;
52 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
53 static CCriticalSection cs_mapLocalHost;
54 static map<CNetAddr, LocalServiceInfo> mapLocalHost;
55 static bool vfReachable[NET_MAX] = {};
56 static bool vfLimited[NET_MAX] = {};
57 static CNode* pnodeLocalHost = NULL;
58 uint64 nLocalHostNonce = 0;
59 array<int, THREAD_MAX> vnThreadsRunning;
60 static std::vector<SOCKET> vhListenSocket;
61 CAddrMan addrman;
62
63 vector<CNode*> vNodes;
64 CCriticalSection cs_vNodes;
65 map<CInv, CDataStream> mapRelay;
66 deque<pair<int64, CInv> > vRelayExpiration;
67 CCriticalSection cs_mapRelay;
68 map<CInv, int64> mapAlreadyAskedFor;
69
70 static deque<string> vOneShots;
71 CCriticalSection cs_vOneShots;
72
73 set<CNetAddr> setservAddNodeAddresses;
74 CCriticalSection cs_setservAddNodeAddresses;
75
76 static CSemaphore *semOutbound = NULL;
77
78 void AddOneShot(string strDest)
79 {
80     LOCK(cs_vOneShots);
81     vOneShots.push_back(strDest);
82 }
83
84 unsigned short GetListenPort()
85 {
86     return (unsigned short)(GetArg("-port", GetDefaultPort()));
87 }
88
89 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
90 {
91     // Filter out duplicate requests
92     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
93         return;
94     pindexLastGetBlocksBegin = pindexBegin;
95     hashLastGetBlocksEnd = hashEnd;
96
97     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
98 }
99
100 // find 'best' local address for a particular peer
101 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
102 {
103     if (fNoListen)
104         return false;
105
106     int nBestScore = -1;
107     int nBestReachability = -1;
108     {
109         LOCK(cs_mapLocalHost);
110         for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
111         {
112             int nScore = (*it).second.nScore;
113             int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
114             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
115             {
116                 addr = CService((*it).first, (*it).second.nPort);
117                 nBestReachability = nReachability;
118                 nBestScore = nScore;
119             }
120         }
121     }
122     return nBestScore >= 0;
123 }
124
125 // get best local address for a particular peer as a CAddress
126 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
127 {
128     CAddress ret(CService("0.0.0.0",0),0);
129     CService addr;
130     if (GetLocal(addr, paddrPeer))
131     {
132         ret = CAddress(addr);
133         ret.nServices = nLocalServices;
134         ret.nTime = GetAdjustedTime();
135     }
136     return ret;
137 }
138
139 bool RecvLine(SOCKET hSocket, string& strLine)
140 {
141     strLine = "";
142     loop
143     {
144         char c;
145         int nBytes = recv(hSocket, &c, 1, 0);
146         if (nBytes > 0)
147         {
148             if (c == '\n')
149                 continue;
150             if (c == '\r')
151                 return true;
152             strLine += c;
153             if (strLine.size() >= 9000)
154                 return true;
155         }
156         else if (nBytes <= 0)
157         {
158             if (fShutdown)
159                 return false;
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                     Sleep(10);
168                     continue;
169                 }
170             }
171             if (!strLine.empty())
172                 return true;
173             if (nBytes == 0)
174             {
175                 // socket closed
176                 printf("socket closed\n");
177                 return false;
178             }
179             else
180             {
181                 // socket error
182                 int nErr = WSAGetLastError();
183                 printf("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     printf("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             loop
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             printf("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 // We now get our external IP from the IRC server first and only use this as a backup
349 bool GetMyExternalIP(CNetAddr& ipRet)
350 {
351     CService addrConnect;
352     const char* pszGet;
353     const char* pszKeyword;
354
355     for (int nLookup = 0; nLookup <= 1; nLookup++)
356     for (int nHost = 1; nHost <= 2; nHost++)
357     {
358         // We should be phasing out our use of sites like these.  If we need
359         // replacements, we should ask for volunteers to put this simple
360         // php file on their web server that prints the client IP:
361         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
362         if (nHost == 1)
363         {
364             addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
365
366             if (nLookup == 1)
367             {
368                 CService addrIP("checkip.dyndns.org", 80, true);
369                 if (addrIP.IsValid())
370                     addrConnect = addrIP;
371             }
372
373             pszGet = "GET / HTTP/1.1\r\n"
374                      "Host: checkip.dyndns.org\r\n"
375                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
376                      "Connection: close\r\n"
377                      "\r\n";
378
379             pszKeyword = "Address:";
380         }
381         else if (nHost == 2)
382         {
383             addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
384
385             if (nLookup == 1)
386             {
387                 CService addrIP("www.showmyip.com", 80, true);
388                 if (addrIP.IsValid())
389                     addrConnect = addrIP;
390             }
391
392             pszGet = "GET /simple/ HTTP/1.1\r\n"
393                      "Host: www.showmyip.com\r\n"
394                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
395                      "Connection: close\r\n"
396                      "\r\n";
397
398             pszKeyword = NULL; // Returns just IP address
399         }
400
401         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
402             return true;
403     }
404
405     return false;
406 }
407
408 void ThreadGetMyExternalIP(void* parg)
409 {
410     // Make this thread recognisable as the external IP detection thread
411     RenameThread("bitcoin-ext-ip");
412
413     CNetAddr addrLocalHost;
414     if (GetMyExternalIP(addrLocalHost))
415     {
416         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
417         AddLocal(addrLocalHost, LOCAL_HTTP);
418     }
419 }
420
421
422
423
424
425 void AddressCurrentlyConnected(const CService& addr)
426 {
427     addrman.Connected(addr);
428 }
429
430
431
432
433
434
435
436 CNode* FindNode(const CNetAddr& ip)
437 {
438     {
439         LOCK(cs_vNodes);
440         BOOST_FOREACH(CNode* pnode, vNodes)
441             if ((CNetAddr)pnode->addr == ip)
442                 return (pnode);
443     }
444     return NULL;
445 }
446
447 CNode* FindNode(std::string addrName)
448 {
449     LOCK(cs_vNodes);
450     BOOST_FOREACH(CNode* pnode, vNodes)
451         if (pnode->addrName == addrName)
452             return (pnode);
453     return NULL;
454 }
455
456 CNode* FindNode(const CService& addr)
457 {
458     {
459         LOCK(cs_vNodes);
460         BOOST_FOREACH(CNode* pnode, vNodes)
461             if ((CService)pnode->addr == addr)
462                 return (pnode);
463     }
464     return NULL;
465 }
466
467 CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout)
468 {
469     if (pszDest == NULL) {
470         if (IsLocal(addrConnect))
471             return NULL;
472
473         // Look for an existing connection
474         CNode* pnode = FindNode((CService)addrConnect);
475         if (pnode)
476         {
477             if (nTimeout != 0)
478                 pnode->AddRef(nTimeout);
479             else
480                 pnode->AddRef();
481             return pnode;
482         }
483     }
484
485
486     /// debug print
487     printf("trying connection %s lastseen=%.1fhrs\n",
488         pszDest ? pszDest : addrConnect.ToString().c_str(),
489         pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
490
491     // Connect
492     SOCKET hSocket;
493     if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
494     {
495         addrman.Attempt(addrConnect);
496
497         /// debug print
498         printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
499
500         // Set to non-blocking
501 #ifdef WIN32
502         u_long nOne = 1;
503         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
504             printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
505 #else
506         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
507             printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
508 #endif
509
510         // Add node
511         CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
512         if (nTimeout != 0)
513             pnode->AddRef(nTimeout);
514         else
515             pnode->AddRef();
516
517         {
518             LOCK(cs_vNodes);
519             vNodes.push_back(pnode);
520         }
521
522         pnode->nTimeConnected = GetTime();
523         return pnode;
524     }
525     else
526     {
527         return NULL;
528     }
529 }
530
531 void CNode::CloseSocketDisconnect()
532 {
533     fDisconnect = true;
534     if (hSocket != INVALID_SOCKET)
535     {
536         printf("disconnecting node %s\n", addrName.c_str());
537         closesocket(hSocket);
538         hSocket = INVALID_SOCKET;
539         vRecv.clear();
540     }
541 }
542
543 void CNode::Cleanup()
544 {
545 }
546
547
548 void CNode::PushVersion()
549 {
550     /// when NTP implemented, change to just nTime = GetAdjustedTime()
551     int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
552     CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
553     CAddress addrMe = GetLocalAddress(&addr);
554     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
555     printf("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());
556     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
557                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
558 }
559
560
561
562
563
564 std::map<CNetAddr, int64> CNode::setBanned;
565 CCriticalSection CNode::cs_setBanned;
566
567 void CNode::ClearBanned()
568 {
569     setBanned.clear();
570 }
571
572 bool CNode::IsBanned(CNetAddr ip)
573 {
574     bool fResult = false;
575     {
576         LOCK(cs_setBanned);
577         std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
578         if (i != setBanned.end())
579         {
580             int64 t = (*i).second;
581             if (GetTime() < t)
582                 fResult = true;
583         }
584     }
585     return fResult;
586 }
587
588 bool CNode::Misbehaving(int howmuch)
589 {
590     if (addr.IsLocal())
591     {
592         printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
593         return false;
594     }
595
596     nMisbehavior += howmuch;
597     if (nMisbehavior >= GetArg("-banscore", 100))
598     {
599         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
600         printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
601         {
602             LOCK(cs_setBanned);
603             if (setBanned[addr] < banTime)
604                 setBanned[addr] = banTime;
605         }
606         CloseSocketDisconnect();
607         return true;
608     } else
609         printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
610     return false;
611 }
612
613 #undef X
614 #define X(name) stats.name = name
615 void CNode::copyStats(CNodeStats &stats)
616 {
617     X(nServices);
618     X(nLastSend);
619     X(nLastRecv);
620     X(nTimeConnected);
621     X(addrName);
622     X(nVersion);
623     X(strSubVer);
624     X(fInbound);
625     X(nReleaseTime);
626     X(nStartingHeight);
627     X(nMisbehavior);
628 }
629 #undef X
630
631
632
633
634
635
636
637
638
639
640 void ThreadSocketHandler(void* parg)
641 {
642     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
643
644     // Make this thread recognisable as the networking thread
645     RenameThread("bitcoin-net");
646
647     try
648     {
649         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
650         ThreadSocketHandler2(parg);
651         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
652     }
653     catch (std::exception& e) {
654         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
655         PrintException(&e, "ThreadSocketHandler()");
656     } catch (...) {
657         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
658         throw; // support pthread_cancel()
659     }
660     printf("ThreadSocketHandler exited\n");
661 }
662
663 void ThreadSocketHandler2(void* parg)
664 {
665     printf("ThreadSocketHandler started\n");
666     list<CNode*> vNodesDisconnected;
667     unsigned int nPrevNodeCount = 0;
668
669     loop
670     {
671         //
672         // Disconnect nodes
673         //
674         {
675             LOCK(cs_vNodes);
676             // Disconnect unused nodes
677             vector<CNode*> vNodesCopy = vNodes;
678             BOOST_FOREACH(CNode* pnode, vNodesCopy)
679             {
680                 if (pnode->fDisconnect ||
681                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
682                 {
683                     // remove from vNodes
684                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
685
686                     // release outbound grant (if any)
687                     pnode->grantOutbound.Release();
688
689                     // close socket and cleanup
690                     pnode->CloseSocketDisconnect();
691                     pnode->Cleanup();
692
693                     // hold in disconnected pool until all refs are released
694                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
695                     if (pnode->fNetworkNode || pnode->fInbound)
696                         pnode->Release();
697                     vNodesDisconnected.push_back(pnode);
698                 }
699             }
700
701             // Delete disconnected nodes
702             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
703             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
704             {
705                 // wait until threads are done using it
706                 if (pnode->GetRefCount() <= 0)
707                 {
708                     bool fDelete = false;
709                     {
710                         TRY_LOCK(pnode->cs_vSend, lockSend);
711                         if (lockSend)
712                         {
713                             TRY_LOCK(pnode->cs_vRecv, lockRecv);
714                             if (lockRecv)
715                             {
716                                 TRY_LOCK(pnode->cs_mapRequests, lockReq);
717                                 if (lockReq)
718                                 {
719                                     TRY_LOCK(pnode->cs_inventory, lockInv);
720                                     if (lockInv)
721                                         fDelete = true;
722                                 }
723                             }
724                         }
725                     }
726                     if (fDelete)
727                     {
728                         vNodesDisconnected.remove(pnode);
729                         delete pnode;
730                     }
731                 }
732             }
733         }
734         if (vNodes.size() != nPrevNodeCount)
735         {
736             nPrevNodeCount = vNodes.size();
737             uiInterface.NotifyNumConnectionsChanged(vNodes.size());
738         }
739
740
741         //
742         // Find which sockets have data to receive
743         //
744         struct timeval timeout;
745         timeout.tv_sec  = 0;
746         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
747
748         fd_set fdsetRecv;
749         fd_set fdsetSend;
750         fd_set fdsetError;
751         FD_ZERO(&fdsetRecv);
752         FD_ZERO(&fdsetSend);
753         FD_ZERO(&fdsetError);
754         SOCKET hSocketMax = 0;
755
756         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
757             FD_SET(hListenSocket, &fdsetRecv);
758             hSocketMax = max(hSocketMax, hListenSocket);
759         }
760         {
761             LOCK(cs_vNodes);
762             BOOST_FOREACH(CNode* pnode, vNodes)
763             {
764                 if (pnode->hSocket == INVALID_SOCKET)
765                     continue;
766                 FD_SET(pnode->hSocket, &fdsetRecv);
767                 FD_SET(pnode->hSocket, &fdsetError);
768                 hSocketMax = max(hSocketMax, pnode->hSocket);
769                 {
770                     TRY_LOCK(pnode->cs_vSend, lockSend);
771                     if (lockSend && !pnode->vSend.empty())
772                         FD_SET(pnode->hSocket, &fdsetSend);
773                 }
774             }
775         }
776
777         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
778         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
779         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
780         if (fShutdown)
781             return;
782         if (nSelect == SOCKET_ERROR)
783         {
784             int nErr = WSAGetLastError();
785             if (hSocketMax != INVALID_SOCKET)
786             {
787                 printf("socket select error %d\n", nErr);
788                 for (unsigned int i = 0; i <= hSocketMax; i++)
789                     FD_SET(i, &fdsetRecv);
790             }
791             FD_ZERO(&fdsetSend);
792             FD_ZERO(&fdsetError);
793             Sleep(timeout.tv_usec/1000);
794         }
795
796
797         //
798         // Accept new connections
799         //
800         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
801         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
802         {
803 #ifdef USE_IPV6
804             struct sockaddr_storage sockaddr;
805 #else
806             struct sockaddr sockaddr;
807 #endif
808             socklen_t len = sizeof(sockaddr);
809             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
810             CAddress addr;
811             int nInbound = 0;
812
813             if (hSocket != INVALID_SOCKET)
814                 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
815                     printf("Warning: Unknown socket family\n");
816
817             {
818                 LOCK(cs_vNodes);
819                 BOOST_FOREACH(CNode* pnode, vNodes)
820                     if (pnode->fInbound)
821                         nInbound++;
822             }
823
824             if (hSocket == INVALID_SOCKET)
825             {
826                 if (WSAGetLastError() != WSAEWOULDBLOCK)
827                     printf("socket error accept failed: %d\n", WSAGetLastError());
828             }
829             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
830             {
831                 {
832                     LOCK(cs_setservAddNodeAddresses);
833                     if (!setservAddNodeAddresses.count(addr))
834                         closesocket(hSocket);
835                 }
836             }
837             else if (CNode::IsBanned(addr))
838             {
839                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
840                 closesocket(hSocket);
841             }
842             else
843             {
844                 printf("accepted connection %s\n", addr.ToString().c_str());
845                 CNode* pnode = new CNode(hSocket, addr, "", true);
846                 pnode->AddRef();
847                 {
848                     LOCK(cs_vNodes);
849                     vNodes.push_back(pnode);
850                 }
851             }
852         }
853
854
855         //
856         // Service each socket
857         //
858         vector<CNode*> vNodesCopy;
859         {
860             LOCK(cs_vNodes);
861             vNodesCopy = vNodes;
862             BOOST_FOREACH(CNode* pnode, vNodesCopy)
863                 pnode->AddRef();
864         }
865         BOOST_FOREACH(CNode* pnode, vNodesCopy)
866         {
867             if (fShutdown)
868                 return;
869
870             //
871             // Receive
872             //
873             if (pnode->hSocket == INVALID_SOCKET)
874                 continue;
875             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
876             {
877                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
878                 if (lockRecv)
879                 {
880                     CDataStream& vRecv = pnode->vRecv;
881                     unsigned int nPos = vRecv.size();
882
883                     if (nPos > ReceiveBufferSize()) {
884                         if (!pnode->fDisconnect)
885                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
886                         pnode->CloseSocketDisconnect();
887                     }
888                     else {
889                         // typical socket buffer is 8K-64K
890                         char pchBuf[0x10000];
891                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
892                         if (nBytes > 0)
893                         {
894                             vRecv.resize(nPos + nBytes);
895                             memcpy(&vRecv[nPos], pchBuf, nBytes);
896                             pnode->nLastRecv = GetTime();
897                         }
898                         else if (nBytes == 0)
899                         {
900                             // socket closed gracefully
901                             if (!pnode->fDisconnect)
902                                 printf("socket closed\n");
903                             pnode->CloseSocketDisconnect();
904                         }
905                         else if (nBytes < 0)
906                         {
907                             // error
908                             int nErr = WSAGetLastError();
909                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
910                             {
911                                 if (!pnode->fDisconnect)
912                                     printf("socket recv error %d\n", nErr);
913                                 pnode->CloseSocketDisconnect();
914                             }
915                         }
916                     }
917                 }
918             }
919
920             //
921             // Send
922             //
923             if (pnode->hSocket == INVALID_SOCKET)
924                 continue;
925             if (FD_ISSET(pnode->hSocket, &fdsetSend))
926             {
927                 TRY_LOCK(pnode->cs_vSend, lockSend);
928                 if (lockSend)
929                 {
930                     CDataStream& vSend = pnode->vSend;
931                     if (!vSend.empty())
932                     {
933                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
934                         if (nBytes > 0)
935                         {
936                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
937                             pnode->nLastSend = GetTime();
938                         }
939                         else if (nBytes < 0)
940                         {
941                             // error
942                             int nErr = WSAGetLastError();
943                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
944                             {
945                                 printf("socket send error %d\n", nErr);
946                                 pnode->CloseSocketDisconnect();
947                             }
948                         }
949                     }
950                 }
951             }
952
953             //
954             // Inactivity checking
955             //
956             if (pnode->vSend.empty())
957                 pnode->nLastSendEmpty = GetTime();
958             if (GetTime() - pnode->nTimeConnected > 60)
959             {
960                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
961                 {
962                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
963                     pnode->fDisconnect = true;
964                 }
965                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
966                 {
967                     printf("socket not sending\n");
968                     pnode->fDisconnect = true;
969                 }
970                 else if (GetTime() - pnode->nLastRecv > 90*60)
971                 {
972                     printf("socket inactivity timeout\n");
973                     pnode->fDisconnect = true;
974                 }
975             }
976         }
977         {
978             LOCK(cs_vNodes);
979             BOOST_FOREACH(CNode* pnode, vNodesCopy)
980                 pnode->Release();
981         }
982
983         Sleep(10);
984     }
985 }
986
987
988
989
990
991
992
993
994
995 #ifdef USE_UPNP
996 void ThreadMapPort(void* parg)
997 {
998     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
999
1000     // Make this thread recognisable as the UPnP thread
1001     RenameThread("bitcoin-UPnP");
1002
1003     try
1004     {
1005         vnThreadsRunning[THREAD_UPNP]++;
1006         ThreadMapPort2(parg);
1007         vnThreadsRunning[THREAD_UPNP]--;
1008     }
1009     catch (std::exception& e) {
1010         vnThreadsRunning[THREAD_UPNP]--;
1011         PrintException(&e, "ThreadMapPort()");
1012     } catch (...) {
1013         vnThreadsRunning[THREAD_UPNP]--;
1014         PrintException(NULL, "ThreadMapPort()");
1015     }
1016     printf("ThreadMapPort exited\n");
1017 }
1018
1019 void ThreadMapPort2(void* parg)
1020 {
1021     printf("ThreadMapPort started\n");
1022
1023     char port[6];
1024     sprintf(port, "%d", GetListenPort());
1025
1026     const char * multicastif = 0;
1027     const char * minissdpdpath = 0;
1028     struct UPNPDev * devlist = 0;
1029     char lanaddr[64];
1030
1031 #ifndef UPNPDISCOVER_SUCCESS
1032     /* miniupnpc 1.5 */
1033     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1034 #else
1035     /* miniupnpc 1.6 */
1036     int error = 0;
1037     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1038 #endif
1039
1040     struct UPNPUrls urls;
1041     struct IGDdatas data;
1042     int r;
1043
1044     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1045     if (r == 1)
1046     {
1047         if (fDiscover) {
1048             char externalIPAddress[40];
1049             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1050             if(r != UPNPCOMMAND_SUCCESS)
1051                 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1052             else
1053             {
1054                 if(externalIPAddress[0])
1055                 {
1056                     printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1057                     AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1058                 }
1059                 else
1060                     printf("UPnP: GetExternalIPAddress failed.\n");
1061             }
1062         }
1063
1064         string strDesc = "Bitcoin " + FormatFullVersion();
1065 #ifndef UPNPDISCOVER_SUCCESS
1066         /* miniupnpc 1.5 */
1067         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1068                             port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1069 #else
1070         /* miniupnpc 1.6 */
1071         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1072                             port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1073 #endif
1074
1075         if(r!=UPNPCOMMAND_SUCCESS)
1076             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1077                 port, port, lanaddr, r, strupnperror(r));
1078         else
1079             printf("UPnP Port Mapping successful.\n");
1080         int i = 1;
1081         loop {
1082             if (fShutdown || !fUseUPnP)
1083             {
1084                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1085                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1086                 freeUPNPDevlist(devlist); devlist = 0;
1087                 FreeUPNPUrls(&urls);
1088                 return;
1089             }
1090             if (i % 600 == 0) // Refresh every 20 minutes
1091             {
1092 #ifndef UPNPDISCOVER_SUCCESS
1093                 /* miniupnpc 1.5 */
1094                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1095                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1096 #else
1097                 /* miniupnpc 1.6 */
1098                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1099                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1100 #endif
1101
1102                 if(r!=UPNPCOMMAND_SUCCESS)
1103                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1104                         port, port, lanaddr, r, strupnperror(r));
1105                 else
1106                     printf("UPnP Port Mapping successful.\n");;
1107             }
1108             Sleep(2000);
1109             i++;
1110         }
1111     } else {
1112         printf("No valid UPnP IGDs found\n");
1113         freeUPNPDevlist(devlist); devlist = 0;
1114         if (r != 0)
1115             FreeUPNPUrls(&urls);
1116         loop {
1117             if (fShutdown || !fUseUPnP)
1118                 return;
1119             Sleep(2000);
1120         }
1121     }
1122 }
1123
1124 void MapPort()
1125 {
1126     if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1127     {
1128         if (!CreateThread(ThreadMapPort, NULL))
1129             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1130     }
1131 }
1132 #else
1133 void MapPort()
1134 {
1135     // Intentionally left blank.
1136 }
1137 #endif
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147 // DNS seeds
1148 // Each pair gives a source name and a seed name.
1149 // The first name is used as information source for addrman.
1150 // The second name should resolve to a list of seed addresses.
1151 static const char *strDNSSeed[][2] = {
1152     {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1153     {"bluematt.me", "dnsseed.bluematt.me"},
1154     {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1155     {"xf2.org", "bitseed.xf2.org"},
1156 };
1157
1158 void ThreadDNSAddressSeed(void* parg)
1159 {
1160     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1161
1162     // Make this thread recognisable as the DNS seeding thread
1163     RenameThread("bitcoin-dnsseed");
1164
1165     try
1166     {
1167         vnThreadsRunning[THREAD_DNSSEED]++;
1168         ThreadDNSAddressSeed2(parg);
1169         vnThreadsRunning[THREAD_DNSSEED]--;
1170     }
1171     catch (std::exception& e) {
1172         vnThreadsRunning[THREAD_DNSSEED]--;
1173         PrintException(&e, "ThreadDNSAddressSeed()");
1174     } catch (...) {
1175         vnThreadsRunning[THREAD_DNSSEED]--;
1176         throw; // support pthread_cancel()
1177     }
1178     printf("ThreadDNSAddressSeed exited\n");
1179 }
1180
1181 void ThreadDNSAddressSeed2(void* parg)
1182 {
1183     printf("ThreadDNSAddressSeed started\n");
1184     int found = 0;
1185
1186     if (!fTestNet)
1187     {
1188         printf("Loading addresses from DNS seeds (could take a while)\n");
1189
1190         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1191             if (GetNameProxy()) {
1192                 AddOneShot(strDNSSeed[seed_idx][1]);
1193             } else {
1194                 vector<CNetAddr> vaddr;
1195                 vector<CAddress> vAdd;
1196                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1197                 {
1198                     BOOST_FOREACH(CNetAddr& ip, vaddr)
1199                     {
1200                         int nOneDay = 24*3600;
1201                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1202                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1203                         vAdd.push_back(addr);
1204                         found++;
1205                     }
1206                 }
1207                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1208             }
1209         }
1210     }
1211
1212     printf("%d addresses found from DNS seeds\n", found);
1213 }
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 unsigned int pnSeed[] =
1227 {
1228     0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1229     0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1230     0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1231     0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1232     0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1233     0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1234     0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1235     0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1236     0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1237     0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1238     0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1239     0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1240     0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1241     0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1242     0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1243     0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1244     0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1245     0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1246     0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1247     0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1248     0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1249     0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1250     0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1251     0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1252     0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1253     0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1254     0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1255     0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1256     0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1257     0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1258     0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1259     0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1260     0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1261     0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1262     0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1263     0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1264     0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1265     0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1266     0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1267     0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1268     0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1269     0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1270     0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1271     0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1272     0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1273     0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1274     0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1275     0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1276     0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1277     0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1278     0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1279     0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1280     0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1281     0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1282     0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1283     0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1284     0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1285     0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1286     0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1287     0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1288     0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1289     0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1290     0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1291     0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1292     0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1293     0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1294     0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1295     0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1296     0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1297     0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1298     0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1299     0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1300     0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1301     0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1302     0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1303     0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1304     0xc461d84a, 0xb2dbe247,
1305 };
1306
1307 void DumpAddresses()
1308 {
1309     int64 nStart = GetTimeMillis();
1310
1311     CAddrDB adb;
1312     adb.Write(addrman);
1313
1314     printf("Flushed %d addresses to peers.dat  %"PRI64d"ms\n",
1315            addrman.size(), GetTimeMillis() - nStart);
1316 }
1317
1318 void ThreadDumpAddress2(void* parg)
1319 {
1320     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1321     while (!fShutdown)
1322     {
1323         DumpAddresses();
1324         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1325         Sleep(100000);
1326         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1327     }
1328     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1329 }
1330
1331 void ThreadDumpAddress(void* parg)
1332 {
1333     IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1334
1335     // Make this thread recognisable as the address dumping thread
1336     RenameThread("bitcoin-adrdump");
1337
1338     try
1339     {
1340         ThreadDumpAddress2(parg);
1341     }
1342     catch (std::exception& e) {
1343         PrintException(&e, "ThreadDumpAddress()");
1344     }
1345     printf("ThreadDumpAddress exited\n");
1346 }
1347
1348 void ThreadOpenConnections(void* parg)
1349 {
1350     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1351
1352     // Make this thread recognisable as the connection opening thread
1353     RenameThread("bitcoin-opencon");
1354
1355     try
1356     {
1357         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1358         ThreadOpenConnections2(parg);
1359         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1360     }
1361     catch (std::exception& e) {
1362         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1363         PrintException(&e, "ThreadOpenConnections()");
1364     } catch (...) {
1365         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1366         PrintException(NULL, "ThreadOpenConnections()");
1367     }
1368     printf("ThreadOpenConnections exited\n");
1369 }
1370
1371 void static ProcessOneShot()
1372 {
1373     string strDest;
1374     {
1375         LOCK(cs_vOneShots);
1376         if (vOneShots.empty())
1377             return;
1378         strDest = vOneShots.front();
1379         vOneShots.pop_front();
1380     }
1381     CAddress addr;
1382     CSemaphoreGrant grant(*semOutbound, true);
1383     if (grant) {
1384         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1385             AddOneShot(strDest);
1386     }
1387 }
1388
1389 void ThreadOpenConnections2(void* parg)
1390 {
1391     printf("ThreadOpenConnections started\n");
1392
1393     // Connect to specific addresses
1394     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1395     {
1396         for (int64 nLoop = 0;; nLoop++)
1397         {
1398             ProcessOneShot();
1399             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1400             {
1401                 CAddress addr;
1402                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1403                 for (int i = 0; i < 10 && i < nLoop; i++)
1404                 {
1405                     Sleep(500);
1406                     if (fShutdown)
1407                         return;
1408                 }
1409             }
1410             Sleep(500);
1411         }
1412     }
1413
1414     // Initiate network connections
1415     int64 nStart = GetTime();
1416     loop
1417     {
1418         ProcessOneShot();
1419
1420         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1421         Sleep(500);
1422         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1423         if (fShutdown)
1424             return;
1425
1426
1427         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1428         CSemaphoreGrant grant(*semOutbound);
1429         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1430         if (fShutdown)
1431             return;
1432
1433         // Add seed nodes if IRC isn't working
1434         if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1435         {
1436             std::vector<CAddress> vAdd;
1437             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1438             {
1439                 // It'll only connect to one or two seed nodes because once it connects,
1440                 // it'll get a pile of addresses with newer timestamps.
1441                 // Seed nodes are given a random 'last seen time' of between one and two
1442                 // weeks ago.
1443                 const int64 nOneWeek = 7*24*60*60;
1444                 struct in_addr ip;
1445                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1446                 CAddress addr(CService(ip, GetDefaultPort()));
1447                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1448                 vAdd.push_back(addr);
1449             }
1450             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1451         }
1452
1453         //
1454         // Choose an address to connect to based on most recently seen
1455         //
1456         CAddress addrConnect;
1457
1458         // Only connect out to one peer per network group (/16 for IPv4).
1459         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1460         int nOutbound = 0;
1461         set<vector<unsigned char> > setConnected;
1462         {
1463             LOCK(cs_vNodes);
1464             BOOST_FOREACH(CNode* pnode, vNodes) {
1465                 if (!pnode->fInbound) {
1466                     setConnected.insert(pnode->addr.GetGroup());
1467                     nOutbound++;
1468                 }
1469             }
1470         }
1471
1472         int64 nANow = GetAdjustedTime();
1473
1474         int nTries = 0;
1475         loop
1476         {
1477             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1478             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1479
1480             // if we selected an invalid address, restart
1481             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1482                 break;
1483
1484             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1485             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1486             // already-connected network ranges, ...) before trying new addrman addresses.
1487             nTries++;
1488             if (nTries > 100)
1489                 break;
1490
1491             if (IsLimited(addr))
1492                 continue;
1493
1494             // only consider very recently tried nodes after 30 failed attempts
1495             if (nANow - addr.nLastTry < 600 && nTries < 30)
1496                 continue;
1497
1498             // do not allow non-default ports, unless after 50 invalid addresses selected already
1499             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1500                 continue;
1501
1502             addrConnect = addr;
1503             break;
1504         }
1505
1506         if (addrConnect.IsValid())
1507             OpenNetworkConnection(addrConnect, &grant);
1508     }
1509 }
1510
1511 void ThreadOpenAddedConnections(void* parg)
1512 {
1513     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1514
1515     // Make this thread recognisable as the connection opening thread
1516     RenameThread("bitcoin-opencon");
1517
1518     try
1519     {
1520         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1521         ThreadOpenAddedConnections2(parg);
1522         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1523     }
1524     catch (std::exception& e) {
1525         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1526         PrintException(&e, "ThreadOpenAddedConnections()");
1527     } catch (...) {
1528         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1529         PrintException(NULL, "ThreadOpenAddedConnections()");
1530     }
1531     printf("ThreadOpenAddedConnections exited\n");
1532 }
1533
1534 void ThreadOpenAddedConnections2(void* parg)
1535 {
1536     printf("ThreadOpenAddedConnections started\n");
1537
1538     if (mapArgs.count("-addnode") == 0)
1539         return;
1540
1541     if (GetNameProxy()) {
1542         while(!fShutdown) {
1543             BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
1544                 CAddress addr;
1545                 CSemaphoreGrant grant(*semOutbound);
1546                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1547                 Sleep(500);
1548             }
1549             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1550             Sleep(120000); // Retry every 2 minutes
1551             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1552         }
1553         return;
1554     }
1555
1556     vector<vector<CService> > vservAddressesToAdd(0);
1557     BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1558     {
1559         vector<CService> vservNode(0);
1560         if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1561         {
1562             vservAddressesToAdd.push_back(vservNode);
1563             {
1564                 LOCK(cs_setservAddNodeAddresses);
1565                 BOOST_FOREACH(CService& serv, vservNode)
1566                     setservAddNodeAddresses.insert(serv);
1567             }
1568         }
1569     }
1570     loop
1571     {
1572         vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1573         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1574         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1575         {
1576             LOCK(cs_vNodes);
1577             BOOST_FOREACH(CNode* pnode, vNodes)
1578                 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1579                     BOOST_FOREACH(CService& addrNode, *(it))
1580                         if (pnode->addr == addrNode)
1581                         {
1582                             it = vservConnectAddresses.erase(it);
1583                             it--;
1584                             break;
1585                         }
1586         }
1587         BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1588         {
1589             CSemaphoreGrant grant(*semOutbound);
1590             OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
1591             Sleep(500);
1592             if (fShutdown)
1593                 return;
1594         }
1595         if (fShutdown)
1596             return;
1597         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1598         Sleep(120000); // Retry every 2 minutes
1599         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1600         if (fShutdown)
1601             return;
1602     }
1603 }
1604
1605 // if successful, this moves the passed grant to the constructed node
1606 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1607 {
1608     //
1609     // Initiate outbound network connection
1610     //
1611     if (fShutdown)
1612         return false;
1613     if (!strDest)
1614         if (IsLocal(addrConnect) ||
1615             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1616             FindNode(addrConnect.ToStringIPPort().c_str()))
1617             return false;
1618     if (strDest && FindNode(strDest))
1619         return false;
1620
1621     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1622     CNode* pnode = ConnectNode(addrConnect, strDest);
1623     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1624     if (fShutdown)
1625         return false;
1626     if (!pnode)
1627         return false;
1628     if (grantOutbound)
1629         grantOutbound->MoveTo(pnode->grantOutbound);
1630     pnode->fNetworkNode = true;
1631     if (fOneShot)
1632         pnode->fOneShot = true;
1633
1634     return true;
1635 }
1636
1637
1638
1639
1640
1641
1642
1643
1644 void ThreadMessageHandler(void* parg)
1645 {
1646     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1647
1648     // Make this thread recognisable as the message handling thread
1649     RenameThread("bitcoin-msghand");
1650
1651     try
1652     {
1653         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1654         ThreadMessageHandler2(parg);
1655         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1656     }
1657     catch (std::exception& e) {
1658         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1659         PrintException(&e, "ThreadMessageHandler()");
1660     } catch (...) {
1661         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1662         PrintException(NULL, "ThreadMessageHandler()");
1663     }
1664     printf("ThreadMessageHandler exited\n");
1665 }
1666
1667 void ThreadMessageHandler2(void* parg)
1668 {
1669     printf("ThreadMessageHandler started\n");
1670     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1671     while (!fShutdown)
1672     {
1673         vector<CNode*> vNodesCopy;
1674         {
1675             LOCK(cs_vNodes);
1676             vNodesCopy = vNodes;
1677             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1678                 pnode->AddRef();
1679         }
1680
1681         // Poll the connected nodes for messages
1682         CNode* pnodeTrickle = NULL;
1683         if (!vNodesCopy.empty())
1684             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1685         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1686         {
1687             // Receive messages
1688             {
1689                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1690                 if (lockRecv)
1691                     ProcessMessages(pnode);
1692             }
1693             if (fShutdown)
1694                 return;
1695
1696             // Send messages
1697             {
1698                 TRY_LOCK(pnode->cs_vSend, lockSend);
1699                 if (lockSend)
1700                     SendMessages(pnode, pnode == pnodeTrickle);
1701             }
1702             if (fShutdown)
1703                 return;
1704         }
1705
1706         {
1707             LOCK(cs_vNodes);
1708             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1709                 pnode->Release();
1710         }
1711
1712         // Wait and allow messages to bunch up.
1713         // Reduce vnThreadsRunning so StopNode has permission to exit while
1714         // we're sleeping, but we must always check fShutdown after doing this.
1715         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1716         Sleep(100);
1717         if (fRequestShutdown)
1718             StartShutdown();
1719         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1720         if (fShutdown)
1721             return;
1722     }
1723 }
1724
1725
1726
1727
1728
1729
1730 bool BindListenPort(const CService &addrBind, string& strError)
1731 {
1732     strError = "";
1733     int nOne = 1;
1734
1735 #ifdef WIN32
1736     // Initialize Windows Sockets
1737     WSADATA wsadata;
1738     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1739     if (ret != NO_ERROR)
1740     {
1741         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1742         printf("%s\n", strError.c_str());
1743         return false;
1744     }
1745 #endif
1746
1747     // Create socket for listening for incoming connections
1748 #ifdef USE_IPV6
1749     struct sockaddr_storage sockaddr;
1750 #else
1751     struct sockaddr sockaddr;
1752 #endif
1753     socklen_t len = sizeof(sockaddr);
1754     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1755     {
1756         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1757         printf("%s\n", strError.c_str());
1758         return false;
1759     }
1760
1761     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1762     if (hListenSocket == INVALID_SOCKET)
1763     {
1764         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1765         printf("%s\n", strError.c_str());
1766         return false;
1767     }
1768
1769 #ifdef SO_NOSIGPIPE
1770     // Different way of disabling SIGPIPE on BSD
1771     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1772 #endif
1773
1774 #ifndef WIN32
1775     // Allow binding if the port is still in TIME_WAIT state after
1776     // the program was closed and restarted.  Not an issue on windows.
1777     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1778 #endif
1779
1780
1781 #ifdef WIN32
1782     // Set to non-blocking, incoming connections will also inherit this
1783     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1784 #else
1785     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1786 #endif
1787     {
1788         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1789         printf("%s\n", strError.c_str());
1790         return false;
1791     }
1792
1793 #ifdef USE_IPV6
1794     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1795     // and enable it by default or not. Try to enable it, if possible.
1796     if (addrBind.IsIPv6()) {
1797 #ifdef IPV6_V6ONLY
1798         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1799 #endif
1800 #ifdef WIN32
1801         int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1802         int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1803         // this call is allowed to fail
1804         setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1805 #endif
1806     }
1807 #endif
1808
1809     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1810     {
1811         int nErr = WSAGetLastError();
1812         if (nErr == WSAEADDRINUSE)
1813             strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
1814         else
1815             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1816         printf("%s\n", strError.c_str());
1817         return false;
1818     }
1819     printf("Bound to %s\n", addrBind.ToString().c_str());
1820
1821     // Listen for incoming connections
1822     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1823     {
1824         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1825         printf("%s\n", strError.c_str());
1826         return false;
1827     }
1828
1829     vhListenSocket.push_back(hListenSocket);
1830
1831     if (addrBind.IsRoutable() && fDiscover)
1832         AddLocal(addrBind, LOCAL_BIND);
1833
1834     return true;
1835 }
1836
1837 void static Discover()
1838 {
1839     if (!fDiscover)
1840         return;
1841
1842 #ifdef WIN32
1843     // Get local host IP
1844     char pszHostName[1000] = "";
1845     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1846     {
1847         vector<CNetAddr> vaddr;
1848         if (LookupHost(pszHostName, vaddr))
1849         {
1850             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1851             {
1852                 AddLocal(addr, LOCAL_IF);
1853             }
1854         }
1855     }
1856 #else
1857     // Get local host ip
1858     struct ifaddrs* myaddrs;
1859     if (getifaddrs(&myaddrs) == 0)
1860     {
1861         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1862         {
1863             if (ifa->ifa_addr == NULL) continue;
1864             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1865             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1866             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1867             if (ifa->ifa_addr->sa_family == AF_INET)
1868             {
1869                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1870                 CNetAddr addr(s4->sin_addr);
1871                 if (AddLocal(addr, LOCAL_IF))
1872                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1873             }
1874 #ifdef USE_IPV6
1875             else if (ifa->ifa_addr->sa_family == AF_INET6)
1876             {
1877                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1878                 CNetAddr addr(s6->sin6_addr);
1879                 if (AddLocal(addr, LOCAL_IF))
1880                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1881             }
1882 #endif
1883         }
1884         freeifaddrs(myaddrs);
1885     }
1886 #endif
1887
1888     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1889     if (!IsLimited(NET_IPV4))
1890         CreateThread(ThreadGetMyExternalIP, NULL);
1891 }
1892
1893 void StartNode(void* parg)
1894 {
1895     // Make this thread recognisable as the startup thread
1896     RenameThread("bitcoin-start");
1897
1898     if (semOutbound == NULL) {
1899         // initialize semaphore
1900         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1901         semOutbound = new CSemaphore(nMaxOutbound);
1902     }
1903
1904     if (pnodeLocalHost == NULL)
1905         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1906
1907     Discover();
1908
1909     //
1910     // Start threads
1911     //
1912
1913     if (!GetBoolArg("-dnsseed", true))
1914         printf("DNS seeding disabled\n");
1915     else
1916         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1917             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1918
1919     // Map ports with UPnP
1920     if (fUseUPnP)
1921         MapPort();
1922
1923     // Get addresses from IRC and advertise ours
1924     if (!CreateThread(ThreadIRCSeed, NULL))
1925         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1926
1927     // Send and receive from sockets, accept connections
1928     if (!CreateThread(ThreadSocketHandler, NULL))
1929         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1930
1931     // Initiate outbound connections from -addnode
1932     if (!CreateThread(ThreadOpenAddedConnections, NULL))
1933         printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1934
1935     // Initiate outbound connections
1936     if (!CreateThread(ThreadOpenConnections, NULL))
1937         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1938
1939     // Process messages
1940     if (!CreateThread(ThreadMessageHandler, NULL))
1941         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1942
1943     // Dump network addresses
1944     if (!CreateThread(ThreadDumpAddress, NULL))
1945         printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1946
1947     // Generate coins in the background
1948     GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1949 }
1950
1951 bool StopNode()
1952 {
1953     printf("StopNode()\n");
1954     fShutdown = true;
1955     nTransactionsUpdated++;
1956     int64 nStart = GetTime();
1957     if (semOutbound)
1958         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1959             semOutbound->post();
1960     do
1961     {
1962         int nThreadsRunning = 0;
1963         for (int n = 0; n < THREAD_MAX; n++)
1964             nThreadsRunning += vnThreadsRunning[n];
1965         if (nThreadsRunning == 0)
1966             break;
1967         if (GetTime() - nStart > 20)
1968             break;
1969         Sleep(20);
1970     } while(true);
1971     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1972     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1973     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1974     if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1975     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1976     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1977 #ifdef USE_UPNP
1978     if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1979 #endif
1980     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1981     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1982     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1983     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
1984         Sleep(20);
1985     Sleep(50);
1986     DumpAddresses();
1987     return true;
1988 }
1989
1990 class CNetCleanup
1991 {
1992 public:
1993     CNetCleanup()
1994     {
1995     }
1996     ~CNetCleanup()
1997     {
1998         // Close sockets
1999         BOOST_FOREACH(CNode* pnode, vNodes)
2000             if (pnode->hSocket != INVALID_SOCKET)
2001                 closesocket(pnode->hSocket);
2002         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
2003             if (hListenSocket != INVALID_SOCKET)
2004                 if (closesocket(hListenSocket) == SOCKET_ERROR)
2005                     printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
2006
2007 #ifdef WIN32
2008         // Shutdown Windows Sockets
2009         WSACleanup();
2010 #endif
2011     }
2012 }
2013 instance_of_cnetcleanup;
This page took 0.135551 seconds and 4 git commands to generate.