Merge branch 'spentpertxout' of https://github.com/sipa/bitcoin
[novacoin.git] / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "headers.h"
6
7 static const int MAX_OUTBOUND_CONNECTIONS = 8;
8
9 void ThreadMessageHandler2(void* parg);
10 void ThreadSocketHandler2(void* parg);
11 void ThreadOpenConnections2(void* parg);
12 bool OpenNetworkConnection(const CAddress& addrConnect);
13
14
15
16
17
18 //
19 // Global state variables
20 //
21 bool fClient = false;
22 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
23 CAddress addrLocalHost(0, 0, nLocalServices);
24 CNode* pnodeLocalHost = NULL;
25 uint64 nLocalHostNonce = 0;
26 array<int, 10> vnThreadsRunning;
27 SOCKET hListenSocket = INVALID_SOCKET;
28
29 vector<CNode*> vNodes;
30 CCriticalSection cs_vNodes;
31 map<vector<unsigned char>, CAddress> mapAddresses;
32 CCriticalSection cs_mapAddresses;
33 map<CInv, CDataStream> mapRelay;
34 deque<pair<int64, CInv> > vRelayExpiration;
35 CCriticalSection cs_mapRelay;
36 map<CInv, int64> mapAlreadyAskedFor;
37
38 // Settings
39 int fUseProxy = false;
40 CAddress addrProxy("127.0.0.1:9050");
41
42
43
44
45
46 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
47 {
48     // Filter out duplicate requests
49     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
50         return;
51     pindexLastGetBlocksBegin = pindexBegin;
52     hashLastGetBlocksEnd = hashEnd;
53
54     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
55 }
56
57
58
59
60
61 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
62 {
63     hSocketRet = INVALID_SOCKET;
64
65     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
66     if (hSocket == INVALID_SOCKET)
67         return false;
68 #ifdef BSD
69     int set = 1;
70     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
71 #endif
72
73     bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
74     bool fProxy = (fUseProxy && fRoutable);
75     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
76
77     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
78     {
79         closesocket(hSocket);
80         return false;
81     }
82
83     if (fProxy)
84     {
85         printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str());
86         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
87         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
88         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
89         char* pszSocks4 = pszSocks4IP;
90         int nSize = sizeof(pszSocks4IP);
91
92         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
93         if (ret != nSize)
94         {
95             closesocket(hSocket);
96             return error("Error sending to proxy");
97         }
98         char pchRet[8];
99         if (recv(hSocket, pchRet, 8, 0) != 8)
100         {
101             closesocket(hSocket);
102             return error("Error reading proxy response");
103         }
104         if (pchRet[1] != 0x5a)
105         {
106             closesocket(hSocket);
107             if (pchRet[1] != 0x5b)
108                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
109             return false;
110         }
111         printf("proxy connected %s\n", addrConnect.ToStringLog().c_str());
112     }
113
114     hSocketRet = hSocket;
115     return true;
116 }
117
118
119
120 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
121 {
122     SOCKET hSocket;
123     if (!ConnectSocket(addrConnect, hSocket))
124         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
125
126     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
127
128     string strLine;
129     while (RecvLine(hSocket, strLine))
130     {
131         if (strLine.empty()) // HTTP response is separated from headers by blank line
132         {
133             loop
134             {
135                 if (!RecvLine(hSocket, strLine))
136                 {
137                     closesocket(hSocket);
138                     return false;
139                 }
140                 if (pszKeyword == NULL)
141                     break;
142                 if (strLine.find(pszKeyword) != -1)
143                 {
144                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
145                     break;
146                 }
147             }
148             closesocket(hSocket);
149             if (strLine.find("<") != -1)
150                 strLine = strLine.substr(0, strLine.find("<"));
151             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
152             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
153                 strLine.resize(strLine.size()-1);
154             CAddress addr(strLine.c_str());
155             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
156             if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
157                 return false;
158             ipRet = addr.ip;
159             return true;
160         }
161     }
162     closesocket(hSocket);
163     return error("GetMyExternalIP() : connection closed");
164 }
165
166 // We now get our external IP from the IRC server first and only use this as a backup
167 bool GetMyExternalIP(unsigned int& ipRet)
168 {
169     CAddress addrConnect;
170     const char* pszGet;
171     const char* pszKeyword;
172
173     if (fUseProxy)
174         return false;
175
176     for (int nLookup = 0; nLookup <= 1; nLookup++)
177     for (int nHost = 1; nHost <= 2; nHost++)
178     {
179         // We should be phasing out our use of sites like these.  If we need
180         // replacements, we should ask for volunteers to put this simple
181         // php file on their webserver that prints the client IP:
182         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
183         if (nHost == 1)
184         {
185             addrConnect = CAddress("91.198.22.70:80"); // checkip.dyndns.org
186
187             if (nLookup == 1)
188             {
189                 struct hostent* phostent = gethostbyname("checkip.dyndns.org");
190                 if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
191                     addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
192             }
193
194             pszGet = "GET / HTTP/1.1\r\n"
195                      "Host: checkip.dyndns.org\r\n"
196                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
197                      "Connection: close\r\n"
198                      "\r\n";
199
200             pszKeyword = "Address:";
201         }
202         else if (nHost == 2)
203         {
204             addrConnect = CAddress("74.208.43.192:80"); // www.showmyip.com
205
206             if (nLookup == 1)
207             {
208                 struct hostent* phostent = gethostbyname("www.showmyip.com");
209                 if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
210                     addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
211             }
212
213             pszGet = "GET /simple/ HTTP/1.1\r\n"
214                      "Host: www.showmyip.com\r\n"
215                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
216                      "Connection: close\r\n"
217                      "\r\n";
218
219             pszKeyword = NULL; // Returns just IP address
220         }
221
222         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
223             return true;
224     }
225
226     return false;
227 }
228
229 void ThreadGetMyExternalIP(void* parg)
230 {
231     // Wait for IRC to get it first
232     if (!GetBoolArg("-noirc"))
233     {
234         for (int i = 0; i < 2 * 60; i++)
235         {
236             Sleep(1000);
237             if (fGotExternalIP || fShutdown)
238                 return;
239         }
240     }
241
242     // Fallback in case IRC fails to get it
243     if (GetMyExternalIP(addrLocalHost.ip))
244     {
245         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
246         if (addrLocalHost.IsRoutable())
247         {
248             // If we already connected to a few before we had our IP, go back and addr them.
249             // setAddrKnown automatically filters any duplicate sends.
250             CAddress addr(addrLocalHost);
251             addr.nTime = GetAdjustedTime();
252             CRITICAL_BLOCK(cs_vNodes)
253                 foreach(CNode* pnode, vNodes)
254                     pnode->PushAddress(addr);
255         }
256     }
257 }
258
259
260
261
262
263 bool AddAddress(CAddress addr, int64 nTimePenalty)
264 {
265     if (!addr.IsRoutable())
266         return false;
267     if (addr.ip == addrLocalHost.ip)
268         return false;
269     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
270     CRITICAL_BLOCK(cs_mapAddresses)
271     {
272         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
273         if (it == mapAddresses.end())
274         {
275             // New address
276             printf("AddAddress(%s)\n", addr.ToStringLog().c_str());
277             mapAddresses.insert(make_pair(addr.GetKey(), addr));
278             CAddrDB().WriteAddress(addr);
279             return true;
280         }
281         else
282         {
283             bool fUpdated = false;
284             CAddress& addrFound = (*it).second;
285             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
286             {
287                 // Services have been added
288                 addrFound.nServices |= addr.nServices;
289                 fUpdated = true;
290             }
291             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
292             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
293             if (addrFound.nTime < addr.nTime - nUpdateInterval)
294             {
295                 // Periodically update most recently seen time
296                 addrFound.nTime = addr.nTime;
297                 fUpdated = true;
298             }
299             if (fUpdated)
300                 CAddrDB().WriteAddress(addrFound);
301         }
302     }
303     return false;
304 }
305
306 void AddressCurrentlyConnected(const CAddress& addr)
307 {
308     CRITICAL_BLOCK(cs_mapAddresses)
309     {
310         // Only if it's been published already
311         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
312         if (it != mapAddresses.end())
313         {
314             CAddress& addrFound = (*it).second;
315             int64 nUpdateInterval = 20 * 60;
316             if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
317             {
318                 // Periodically update most recently seen time
319                 addrFound.nTime = GetAdjustedTime();
320                 CAddrDB addrdb;
321                 addrdb.WriteAddress(addrFound);
322             }
323         }
324     }
325 }
326
327
328
329
330
331 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
332 {
333     // If the dialog might get closed before the reply comes back,
334     // call this in the destructor so it doesn't get called after it's deleted.
335     CRITICAL_BLOCK(cs_vNodes)
336     {
337         foreach(CNode* pnode, vNodes)
338         {
339             CRITICAL_BLOCK(pnode->cs_mapRequests)
340             {
341                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
342                 {
343                     CRequestTracker& tracker = (*mi).second;
344                     if (tracker.fn == fn && tracker.param1 == param1)
345                         pnode->mapRequests.erase(mi++);
346                     else
347                         mi++;
348                 }
349             }
350         }
351     }
352 }
353
354
355
356
357
358
359
360 //
361 // Subscription methods for the broadcast and subscription system.
362 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
363 //
364 // The subscription system uses a meet-in-the-middle strategy.
365 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
366 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
367 //
368
369 bool AnySubscribed(unsigned int nChannel)
370 {
371     if (pnodeLocalHost->IsSubscribed(nChannel))
372         return true;
373     CRITICAL_BLOCK(cs_vNodes)
374         foreach(CNode* pnode, vNodes)
375             if (pnode->IsSubscribed(nChannel))
376                 return true;
377     return false;
378 }
379
380 bool CNode::IsSubscribed(unsigned int nChannel)
381 {
382     if (nChannel >= vfSubscribe.size())
383         return false;
384     return vfSubscribe[nChannel];
385 }
386
387 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
388 {
389     if (nChannel >= vfSubscribe.size())
390         return;
391
392     if (!AnySubscribed(nChannel))
393     {
394         // Relay subscribe
395         CRITICAL_BLOCK(cs_vNodes)
396             foreach(CNode* pnode, vNodes)
397                 if (pnode != this)
398                     pnode->PushMessage("subscribe", nChannel, nHops);
399     }
400
401     vfSubscribe[nChannel] = true;
402 }
403
404 void CNode::CancelSubscribe(unsigned int nChannel)
405 {
406     if (nChannel >= vfSubscribe.size())
407         return;
408
409     // Prevent from relaying cancel if wasn't subscribed
410     if (!vfSubscribe[nChannel])
411         return;
412     vfSubscribe[nChannel] = false;
413
414     if (!AnySubscribed(nChannel))
415     {
416         // Relay subscription cancel
417         CRITICAL_BLOCK(cs_vNodes)
418             foreach(CNode* pnode, vNodes)
419                 if (pnode != this)
420                     pnode->PushMessage("sub-cancel", nChannel);
421     }
422 }
423
424
425
426
427
428
429
430
431
432 CNode* FindNode(unsigned int ip)
433 {
434     CRITICAL_BLOCK(cs_vNodes)
435     {
436         foreach(CNode* pnode, vNodes)
437             if (pnode->addr.ip == ip)
438                 return (pnode);
439     }
440     return NULL;
441 }
442
443 CNode* FindNode(CAddress addr)
444 {
445     CRITICAL_BLOCK(cs_vNodes)
446     {
447         foreach(CNode* pnode, vNodes)
448             if (pnode->addr == addr)
449                 return (pnode);
450     }
451     return NULL;
452 }
453
454 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
455 {
456     if (addrConnect.ip == addrLocalHost.ip)
457         return NULL;
458
459     // Look for an existing connection
460     CNode* pnode = FindNode(addrConnect.ip);
461     if (pnode)
462     {
463         if (nTimeout != 0)
464             pnode->AddRef(nTimeout);
465         else
466             pnode->AddRef();
467         return pnode;
468     }
469
470     /// debug print
471     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
472         addrConnect.ToStringLog().c_str(),
473         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
474         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
475
476     CRITICAL_BLOCK(cs_mapAddresses)
477         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
478
479     // Connect
480     SOCKET hSocket;
481     if (ConnectSocket(addrConnect, hSocket))
482     {
483         /// debug print
484         printf("connected %s\n", addrConnect.ToStringLog().c_str());
485
486         // Set to nonblocking
487 #ifdef __WXMSW__
488         u_long nOne = 1;
489         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
490             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
491 #else
492         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
493             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
494 #endif
495
496         // Add node
497         CNode* pnode = new CNode(hSocket, addrConnect, false);
498         if (nTimeout != 0)
499             pnode->AddRef(nTimeout);
500         else
501             pnode->AddRef();
502         CRITICAL_BLOCK(cs_vNodes)
503             vNodes.push_back(pnode);
504
505         pnode->nTimeConnected = GetTime();
506         return pnode;
507     }
508     else
509     {
510         return NULL;
511     }
512 }
513
514 void CNode::CloseSocketDisconnect()
515 {
516     fDisconnect = true;
517     if (hSocket != INVALID_SOCKET)
518     {
519         if (fDebug)
520             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
521         printf("disconnecting node %s\n", addr.ToStringLog().c_str());
522         closesocket(hSocket);
523         hSocket = INVALID_SOCKET;
524     }
525 }
526
527 void CNode::Cleanup()
528 {
529     // All of a nodes broadcasts and subscriptions are automatically torn down
530     // when it goes down, so a node has to stay up to keep its broadcast going.
531
532     // Cancel subscriptions
533     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
534         if (vfSubscribe[nChannel])
535             CancelSubscribe(nChannel);
536 }
537
538
539
540
541
542
543
544
545
546
547
548
549
550 void ThreadSocketHandler(void* parg)
551 {
552     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
553     try
554     {
555         vnThreadsRunning[0]++;
556         ThreadSocketHandler2(parg);
557         vnThreadsRunning[0]--;
558     }
559     catch (std::exception& e) {
560         vnThreadsRunning[0]--;
561         PrintException(&e, "ThreadSocketHandler()");
562     } catch (...) {
563         vnThreadsRunning[0]--;
564         throw; // support pthread_cancel()
565     }
566     printf("ThreadSocketHandler exiting\n");
567 }
568
569 void ThreadSocketHandler2(void* parg)
570 {
571     printf("ThreadSocketHandler started\n");
572     list<CNode*> vNodesDisconnected;
573     int nPrevNodeCount = 0;
574
575     loop
576     {
577         //
578         // Disconnect nodes
579         //
580         CRITICAL_BLOCK(cs_vNodes)
581         {
582             // Disconnect unused nodes
583             vector<CNode*> vNodesCopy = vNodes;
584             foreach(CNode* pnode, vNodesCopy)
585             {
586                 if (pnode->fDisconnect ||
587                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
588                 {
589                     // remove from vNodes
590                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
591
592                     // close socket and cleanup
593                     pnode->CloseSocketDisconnect();
594                     pnode->Cleanup();
595
596                     // hold in disconnected pool until all refs are released
597                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
598                     if (pnode->fNetworkNode || pnode->fInbound)
599                         pnode->Release();
600                     vNodesDisconnected.push_back(pnode);
601                 }
602             }
603
604             // Delete disconnected nodes
605             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
606             foreach(CNode* pnode, vNodesDisconnectedCopy)
607             {
608                 // wait until threads are done using it
609                 if (pnode->GetRefCount() <= 0)
610                 {
611                     bool fDelete = false;
612                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
613                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
614                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
615                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
616                         fDelete = true;
617                     if (fDelete)
618                     {
619                         vNodesDisconnected.remove(pnode);
620                         delete pnode;
621                     }
622                 }
623             }
624         }
625         if (vNodes.size() != nPrevNodeCount)
626         {
627             nPrevNodeCount = vNodes.size();
628             MainFrameRepaint();
629         }
630
631
632         //
633         // Find which sockets have data to receive
634         //
635         struct timeval timeout;
636         timeout.tv_sec  = 0;
637         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
638
639         fd_set fdsetRecv;
640         fd_set fdsetSend;
641         fd_set fdsetError;
642         FD_ZERO(&fdsetRecv);
643         FD_ZERO(&fdsetSend);
644         FD_ZERO(&fdsetError);
645         SOCKET hSocketMax = 0;
646
647         if(hListenSocket != INVALID_SOCKET)
648             FD_SET(hListenSocket, &fdsetRecv);
649         hSocketMax = max(hSocketMax, hListenSocket);
650         CRITICAL_BLOCK(cs_vNodes)
651         {
652             foreach(CNode* pnode, vNodes)
653             {
654                 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
655                     continue;
656                 FD_SET(pnode->hSocket, &fdsetRecv);
657                 FD_SET(pnode->hSocket, &fdsetError);
658                 hSocketMax = max(hSocketMax, pnode->hSocket);
659                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
660                     if (!pnode->vSend.empty())
661                         FD_SET(pnode->hSocket, &fdsetSend);
662             }
663         }
664
665         vnThreadsRunning[0]--;
666         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
667         vnThreadsRunning[0]++;
668         if (fShutdown)
669             return;
670         if (nSelect == SOCKET_ERROR)
671         {
672             int nErr = WSAGetLastError();
673             printf("socket select error %d\n", nErr);
674             for (int i = 0; i <= hSocketMax; i++)
675                 FD_SET(i, &fdsetRecv);
676             FD_ZERO(&fdsetSend);
677             FD_ZERO(&fdsetError);
678             Sleep(timeout.tv_usec/1000);
679         }
680
681
682         //
683         // Accept new connections
684         //
685         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
686         {
687             struct sockaddr_in sockaddr;
688             socklen_t len = sizeof(sockaddr);
689             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
690             CAddress addr(sockaddr);
691             int nInbound = 0;
692
693             CRITICAL_BLOCK(cs_vNodes)
694                 foreach(CNode* pnode, vNodes)
695                 if (pnode->fInbound)
696                     nInbound++;
697             if (hSocket == INVALID_SOCKET)
698             {
699                 if (WSAGetLastError() != WSAEWOULDBLOCK)
700                     printf("socket error accept failed: %d\n", WSAGetLastError());
701             }
702             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
703             {
704                 closesocket(hSocket);
705             }
706             else
707             {
708                 printf("accepted connection %s\n", addr.ToStringLog().c_str());
709                 CNode* pnode = new CNode(hSocket, addr, true);
710                 pnode->AddRef();
711                 CRITICAL_BLOCK(cs_vNodes)
712                     vNodes.push_back(pnode);
713             }
714         }
715
716
717         //
718         // Service each socket
719         //
720         vector<CNode*> vNodesCopy;
721         CRITICAL_BLOCK(cs_vNodes)
722         {
723             vNodesCopy = vNodes;
724             foreach(CNode* pnode, vNodesCopy)
725                 pnode->AddRef();
726         }
727         foreach(CNode* pnode, vNodesCopy)
728         {
729             if (fShutdown)
730                 return;
731
732             //
733             // Receive
734             //
735             if (pnode->hSocket == INVALID_SOCKET)
736                 continue;
737             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
738             {
739                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
740                 {
741                     CDataStream& vRecv = pnode->vRecv;
742                     unsigned int nPos = vRecv.size();
743
744                     if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
745                         if (!pnode->fDisconnect)
746                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
747                         pnode->CloseSocketDisconnect();
748                     }
749                     else {
750                         // typical socket buffer is 8K-64K
751                         char pchBuf[0x10000];
752                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
753                         if (nBytes > 0)
754                         {
755                             vRecv.resize(nPos + nBytes);
756                             memcpy(&vRecv[nPos], pchBuf, nBytes);
757                             pnode->nLastRecv = GetTime();
758                         }
759                         else if (nBytes == 0)
760                         {
761                             // socket closed gracefully
762                             if (!pnode->fDisconnect)
763                                 printf("socket closed\n");
764                             pnode->CloseSocketDisconnect();
765                         }
766                         else if (nBytes < 0)
767                         {
768                             // error
769                             int nErr = WSAGetLastError();
770                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
771                             {
772                                 if (!pnode->fDisconnect)
773                                     printf("socket recv error %d\n", nErr);
774                                 pnode->CloseSocketDisconnect();
775                             }
776                         }
777                     }
778                 }
779             }
780
781             //
782             // Send
783             //
784             if (pnode->hSocket == INVALID_SOCKET)
785                 continue;
786             if (FD_ISSET(pnode->hSocket, &fdsetSend))
787             {
788                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
789                 {
790                     CDataStream& vSend = pnode->vSend;
791                     if (!vSend.empty())
792                     {
793                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
794                         if (nBytes > 0)
795                         {
796                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
797                             pnode->nLastSend = GetTime();
798                         }
799                         else if (nBytes < 0)
800                         {
801                             // error
802                             int nErr = WSAGetLastError();
803                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
804                             {
805                                 printf("socket send error %d\n", nErr);
806                                 pnode->CloseSocketDisconnect();
807                             }
808                         }
809                         if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
810                             if (!pnode->fDisconnect)
811                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
812                             pnode->CloseSocketDisconnect();
813                         }
814                     }
815                 }
816             }
817
818             //
819             // Inactivity checking
820             //
821             if (pnode->vSend.empty())
822                 pnode->nLastSendEmpty = GetTime();
823             if (GetTime() - pnode->nTimeConnected > 60)
824             {
825                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
826                 {
827                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
828                     pnode->fDisconnect = true;
829                 }
830                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
831                 {
832                     printf("socket not sending\n");
833                     pnode->fDisconnect = true;
834                 }
835                 else if (GetTime() - pnode->nLastRecv > 90*60)
836                 {
837                     printf("socket inactivity timeout\n");
838                     pnode->fDisconnect = true;
839                 }
840             }
841         }
842         CRITICAL_BLOCK(cs_vNodes)
843         {
844             foreach(CNode* pnode, vNodesCopy)
845                 pnode->Release();
846         }
847
848         Sleep(10);
849     }
850 }
851
852
853
854
855
856
857
858
859
860 static const char *strDNSSeed[] = {
861     "bitseed.xf2.org",
862     "bitseed.bitcoin.org.uk",
863 };
864
865 void DNSAddressSeed()
866 {
867     int found = 0;
868
869     printf("Loading addresses from DNS seeds (could take a while)\n");
870
871     for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
872         struct hostent* phostent = gethostbyname(strDNSSeed[seed_idx]);
873         if (!phostent)
874             continue;
875
876         for (int host = 0; phostent->h_addr_list[host] != NULL; host++) {
877             CAddress addr(*(unsigned int*)phostent->h_addr_list[host],
878                           GetDefaultPort(), NODE_NETWORK);
879             addr.nTime = 0;
880             if (addr.IsValid() && addr.GetByte(3) != 127) {
881                 AddAddress(addr);
882                 found++;
883             }
884         }
885     }
886
887     printf("%d addresses found from DNS seeds\n", found);
888 }
889
890
891
892 unsigned int pnSeed[] =
893 {
894     0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
895     0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
896     0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
897     0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
898     0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
899     0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
900     0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
901     0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
902     0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
903     0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
904     0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
905     0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
906     0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
907     0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
908     0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
909     0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
910     0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
911     0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
912     0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
913     0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
914     0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
915     0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
916     0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
917     0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
918     0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
919     0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
920     0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
921     0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
922     0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
923     0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
924     0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
925     0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
926     0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
927     0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
928     0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
929     0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
930     0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
931     0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
932     0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
933     0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
934 };
935
936
937
938 void ThreadOpenConnections(void* parg)
939 {
940     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
941     try
942     {
943         vnThreadsRunning[1]++;
944         ThreadOpenConnections2(parg);
945         vnThreadsRunning[1]--;
946     }
947     catch (std::exception& e) {
948         vnThreadsRunning[1]--;
949         PrintException(&e, "ThreadOpenConnections()");
950     } catch (...) {
951         vnThreadsRunning[1]--;
952         PrintException(NULL, "ThreadOpenConnections()");
953     }
954     printf("ThreadOpenConnections exiting\n");
955 }
956
957 void ThreadOpenConnections2(void* parg)
958 {
959     printf("ThreadOpenConnections started\n");
960
961     // Connect to specific addresses
962     if (mapArgs.count("-connect"))
963     {
964         for (int64 nLoop = 0;; nLoop++)
965         {
966             foreach(string strAddr, mapMultiArgs["-connect"])
967             {
968                 CAddress addr(strAddr, NODE_NETWORK);
969                 if (addr.IsValid())
970                     OpenNetworkConnection(addr);
971                 for (int i = 0; i < 10 && i < nLoop; i++)
972                 {
973                     Sleep(500);
974                     if (fShutdown)
975                         return;
976                 }
977             }
978         }
979     }
980
981     // Connect to manually added nodes first
982     if (mapArgs.count("-addnode"))
983     {
984         foreach(string strAddr, mapMultiArgs["-addnode"])
985         {
986             CAddress addr(strAddr, NODE_NETWORK);
987             if (addr.IsValid())
988             {
989                 OpenNetworkConnection(addr);
990                 Sleep(500);
991                 if (fShutdown)
992                     return;
993             }
994         }
995     }
996
997     // Initiate network connections
998     int64 nStart = GetTime();
999     loop
1000     {
1001         // Limit outbound connections
1002         vnThreadsRunning[1]--;
1003         Sleep(500);
1004         loop
1005         {
1006             int nOutbound = 0;
1007             CRITICAL_BLOCK(cs_vNodes)
1008                 foreach(CNode* pnode, vNodes)
1009                     if (!pnode->fInbound)
1010                         nOutbound++;
1011             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1012             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1013             if (nOutbound < nMaxOutboundConnections)
1014                 break;
1015             Sleep(2000);
1016             if (fShutdown)
1017                 return;
1018         }
1019         vnThreadsRunning[1]++;
1020         if (fShutdown)
1021             return;
1022
1023         CRITICAL_BLOCK(cs_mapAddresses)
1024         {
1025             // Add seed nodes if IRC isn't working
1026             static bool fSeedUsed;
1027             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1028             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1029             {
1030                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1031                 {
1032                     // It'll only connect to one or two seed nodes because once it connects,
1033                     // it'll get a pile of addresses with newer timestamps.
1034                     CAddress addr;
1035                     addr.ip = pnSeed[i];
1036                     addr.nTime = 0;
1037                     AddAddress(addr);
1038                 }
1039                 fSeedUsed = true;
1040             }
1041
1042             if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1043             {
1044                 // Disconnect seed nodes
1045                 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1046                 static int64 nSeedDisconnected;
1047                 if (nSeedDisconnected == 0)
1048                 {
1049                     nSeedDisconnected = GetTime();
1050                     CRITICAL_BLOCK(cs_vNodes)
1051                         foreach(CNode* pnode, vNodes)
1052                             if (setSeed.count(pnode->addr.ip))
1053                                 pnode->fDisconnect = true;
1054                 }
1055
1056                 // Keep setting timestamps to 0 so they won't reconnect
1057                 if (GetTime() - nSeedDisconnected < 60 * 60)
1058                 {
1059                     foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1060                     {
1061                         if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1062                         {
1063                             item.second.nTime = 0;
1064                             CAddrDB().WriteAddress(item.second);
1065                         }
1066                     }
1067                 }
1068             }
1069         }
1070
1071
1072         //
1073         // Choose an address to connect to based on most recently seen
1074         //
1075         CAddress addrConnect;
1076         int64 nBest = INT64_MIN;
1077
1078         // Only connect to one address per a.b.?.? range.
1079         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1080         set<unsigned int> setConnected;
1081         CRITICAL_BLOCK(cs_vNodes)
1082             foreach(CNode* pnode, vNodes)
1083                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1084
1085         CRITICAL_BLOCK(cs_mapAddresses)
1086         {
1087             foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1088             {
1089                 const CAddress& addr = item.second;
1090                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1091                     continue;
1092                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1093                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1094
1095                 // Randomize the order in a deterministic way, putting the standard port first
1096                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1097                 if (addr.port != GetDefaultPort())
1098                     nRandomizer += 2 * 60 * 60;
1099
1100                 // Last seen  Base retry frequency
1101                 //   <1 hour   10 min
1102                 //    1 hour    1 hour
1103                 //    4 hours   2 hours
1104                 //   24 hours   5 hours
1105                 //   48 hours   7 hours
1106                 //    7 days   13 hours
1107                 //   30 days   27 hours
1108                 //   90 days   46 hours
1109                 //  365 days   93 hours
1110                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1111
1112                 // Fast reconnect for one hour after last seen
1113                 if (nSinceLastSeen < 60 * 60)
1114                     nDelay = 10 * 60;
1115
1116                 // Limit retry frequency
1117                 if (nSinceLastTry < nDelay)
1118                     continue;
1119
1120                 // If we have IRC, we'll be notified when they first come online,
1121                 // and again every 24 hours by the refresh broadcast.
1122                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1123                     continue;
1124
1125                 // Only try the old stuff if we don't have enough connections
1126                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1127                     continue;
1128
1129                 // If multiple addresses are ready, prioritize by time since
1130                 // last seen and time since last tried.
1131                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1132                 if (nScore > nBest)
1133                 {
1134                     nBest = nScore;
1135                     addrConnect = addr;
1136                 }
1137             }
1138         }
1139
1140         if (addrConnect.IsValid())
1141             OpenNetworkConnection(addrConnect);
1142     }
1143 }
1144
1145 bool OpenNetworkConnection(const CAddress& addrConnect)
1146 {
1147     //
1148     // Initiate outbound network connection
1149     //
1150     if (fShutdown)
1151         return false;
1152     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1153         return false;
1154
1155     vnThreadsRunning[1]--;
1156     CNode* pnode = ConnectNode(addrConnect);
1157     vnThreadsRunning[1]++;
1158     if (fShutdown)
1159         return false;
1160     if (!pnode)
1161         return false;
1162     pnode->fNetworkNode = true;
1163
1164     return true;
1165 }
1166
1167
1168
1169
1170
1171
1172
1173
1174 void ThreadMessageHandler(void* parg)
1175 {
1176     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1177     try
1178     {
1179         vnThreadsRunning[2]++;
1180         ThreadMessageHandler2(parg);
1181         vnThreadsRunning[2]--;
1182     }
1183     catch (std::exception& e) {
1184         vnThreadsRunning[2]--;
1185         PrintException(&e, "ThreadMessageHandler()");
1186     } catch (...) {
1187         vnThreadsRunning[2]--;
1188         PrintException(NULL, "ThreadMessageHandler()");
1189     }
1190     printf("ThreadMessageHandler exiting\n");
1191 }
1192
1193 void ThreadMessageHandler2(void* parg)
1194 {
1195     printf("ThreadMessageHandler started\n");
1196     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1197     while (!fShutdown)
1198     {
1199         vector<CNode*> vNodesCopy;
1200         CRITICAL_BLOCK(cs_vNodes)
1201         {
1202             vNodesCopy = vNodes;
1203             foreach(CNode* pnode, vNodesCopy)
1204                 pnode->AddRef();
1205         }
1206
1207         // Poll the connected nodes for messages
1208         CNode* pnodeTrickle = NULL;
1209         if (!vNodesCopy.empty())
1210             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1211         foreach(CNode* pnode, vNodesCopy)
1212         {
1213             // Receive messages
1214             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1215                 ProcessMessages(pnode);
1216             if (fShutdown)
1217                 return;
1218
1219             // Send messages
1220             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1221                 SendMessages(pnode, pnode == pnodeTrickle);
1222             if (fShutdown)
1223                 return;
1224         }
1225
1226         CRITICAL_BLOCK(cs_vNodes)
1227         {
1228             foreach(CNode* pnode, vNodesCopy)
1229                 pnode->Release();
1230         }
1231
1232         // Wait and allow messages to bunch up.
1233         // Reduce vnThreadsRunning so StopNode has permission to exit while
1234         // we're sleeping, but we must always check fShutdown after doing this.
1235         vnThreadsRunning[2]--;
1236         Sleep(100);
1237         if (fRequestShutdown)
1238             Shutdown(NULL);
1239         vnThreadsRunning[2]++;
1240         if (fShutdown)
1241             return;
1242     }
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 bool BindListenPort(string& strError)
1254 {
1255     strError = "";
1256     int nOne = 1;
1257     addrLocalHost.port = GetDefaultPort();
1258
1259 #ifdef __WXMSW__
1260     // Initialize Windows Sockets
1261     WSADATA wsadata;
1262     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1263     if (ret != NO_ERROR)
1264     {
1265         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1266         printf("%s\n", strError.c_str());
1267         return false;
1268     }
1269 #endif
1270
1271     // Create socket for listening for incoming connections
1272     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1273     if (hListenSocket == INVALID_SOCKET)
1274     {
1275         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1276         printf("%s\n", strError.c_str());
1277         return false;
1278     }
1279
1280 #ifdef BSD
1281     // Different way of disabling SIGPIPE on BSD
1282     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1283 #endif
1284
1285 #ifndef __WXMSW__
1286     // Allow binding if the port is still in TIME_WAIT state after
1287     // the program was closed and restarted.  Not an issue on windows.
1288     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1289 #endif
1290
1291 #ifdef __WXMSW__
1292     // Set to nonblocking, incoming connections will also inherit this
1293     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1294 #else
1295     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1296 #endif
1297     {
1298         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1299         printf("%s\n", strError.c_str());
1300         return false;
1301     }
1302
1303     // The sockaddr_in structure specifies the address family,
1304     // IP address, and port for the socket that is being bound
1305     struct sockaddr_in sockaddr;
1306     memset(&sockaddr, 0, sizeof(sockaddr));
1307     sockaddr.sin_family = AF_INET;
1308     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1309     sockaddr.sin_port = GetDefaultPort();
1310     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1311     {
1312         int nErr = WSAGetLastError();
1313         if (nErr == WSAEADDRINUSE)
1314             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1315         else
1316             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1317         printf("%s\n", strError.c_str());
1318         return false;
1319     }
1320     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1321
1322     // Listen for incoming connections
1323     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1324     {
1325         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1326         printf("%s\n", strError.c_str());
1327         return false;
1328     }
1329
1330     return true;
1331 }
1332
1333 void StartNode(void* parg)
1334 {
1335     if (pnodeLocalHost == NULL)
1336         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
1337
1338 #ifdef __WXMSW__
1339     // Get local host ip
1340     char pszHostName[1000] = "";
1341     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1342     {
1343         struct hostent* phostent = gethostbyname(pszHostName);
1344         if (phostent)
1345         {
1346             // Take the first IP that isn't loopback 127.x.x.x
1347             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1348                 printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
1349             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1350             {
1351                 CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
1352                 if (addr.IsValid() && addr.GetByte(3) != 127)
1353                 {
1354                     addrLocalHost = addr;
1355                     break;
1356                 }
1357             }
1358         }
1359     }
1360 #else
1361     // Get local host ip
1362     struct ifaddrs* myaddrs;
1363     if (getifaddrs(&myaddrs) == 0)
1364     {
1365         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1366         {
1367             if (ifa->ifa_addr == NULL) continue;
1368             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1369             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1370             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1371             char pszIP[100];
1372             if (ifa->ifa_addr->sa_family == AF_INET)
1373             {
1374                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1375                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1376                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1377
1378                 // Take the first IP that isn't loopback 127.x.x.x
1379                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
1380                 if (addr.IsValid() && addr.GetByte(3) != 127)
1381                 {
1382                     addrLocalHost = addr;
1383                     break;
1384                 }
1385             }
1386             else if (ifa->ifa_addr->sa_family == AF_INET6)
1387             {
1388                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1389                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1390                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1391             }
1392         }
1393         freeifaddrs(myaddrs);
1394     }
1395 #endif
1396     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1397
1398     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1399     {
1400         // Proxies can't take incoming connections
1401         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1402         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1403     }
1404     else
1405     {
1406         CreateThread(ThreadGetMyExternalIP, NULL);
1407     }
1408
1409     //
1410     // Start threads
1411     //
1412
1413     // Get addresses from IRC and advertise ours
1414     if (!CreateThread(ThreadIRCSeed, NULL))
1415         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1416
1417     // Send and receive from sockets, accept connections
1418     pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1419
1420     // Initiate outbound connections
1421     if (!CreateThread(ThreadOpenConnections, NULL))
1422         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1423
1424     // Process messages
1425     if (!CreateThread(ThreadMessageHandler, NULL))
1426         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1427
1428     // Generate coins in the background
1429     GenerateBitcoins(fGenerateBitcoins);
1430 }
1431
1432 bool StopNode()
1433 {
1434     printf("StopNode()\n");
1435     fShutdown = true;
1436     nTransactionsUpdated++;
1437     int64 nStart = GetTime();
1438     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0)
1439     {
1440         if (GetTime() - nStart > 20)
1441             break;
1442         Sleep(20);
1443     }
1444     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1445     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1446     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1447     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1448     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1449     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1450         Sleep(20);
1451     Sleep(50);
1452
1453     return true;
1454 }
1455
1456 class CNetCleanup
1457 {
1458 public:
1459     CNetCleanup()
1460     {
1461     }
1462     ~CNetCleanup()
1463     {
1464         // Close sockets
1465         foreach(CNode* pnode, vNodes)
1466             if (pnode->hSocket != INVALID_SOCKET)
1467                 closesocket(pnode->hSocket);
1468         if (hListenSocket != INVALID_SOCKET)
1469             if (closesocket(hListenSocket) == SOCKET_ERROR)
1470                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1471
1472 #ifdef __WXMSW__
1473         // Shutdown Windows Sockets
1474         WSACleanup();
1475 #endif
1476     }
1477 }
1478 instance_of_cnetcleanup;