Denial-of-service flood control
[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             bool fLimitConnections = false;
692             int nInbound = 0;
693
694             if (mapArgs.count("-maxconnections"))
695                 fLimitConnections = true;
696
697             if (fLimitConnections)
698             {
699                 CRITICAL_BLOCK(cs_vNodes)
700                     foreach(CNode* pnode, vNodes)
701                     if (pnode->fInbound)
702                         nInbound++;
703             }
704             if (hSocket == INVALID_SOCKET)
705             {
706                 if (WSAGetLastError() != WSAEWOULDBLOCK)
707                     printf("socket error accept failed: %d\n", WSAGetLastError());
708             }
709             else if (fLimitConnections && nInbound >= atoi(mapArgs["-maxconnections"]) - MAX_OUTBOUND_CONNECTIONS)
710             {
711                 closesocket(hSocket);
712             }
713             else
714             {
715                 printf("accepted connection %s\n", addr.ToStringLog().c_str());
716                 CNode* pnode = new CNode(hSocket, addr, true);
717                 pnode->AddRef();
718                 CRITICAL_BLOCK(cs_vNodes)
719                     vNodes.push_back(pnode);
720             }
721         }
722
723
724         //
725         // Service each socket
726         //
727         vector<CNode*> vNodesCopy;
728         CRITICAL_BLOCK(cs_vNodes)
729         {
730             vNodesCopy = vNodes;
731             foreach(CNode* pnode, vNodesCopy)
732                 pnode->AddRef();
733         }
734         foreach(CNode* pnode, vNodesCopy)
735         {
736             if (fShutdown)
737                 return;
738
739             //
740             // Receive
741             //
742             if (pnode->hSocket == INVALID_SOCKET)
743                 continue;
744             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
745             {
746                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
747                 {
748                     CDataStream& vRecv = pnode->vRecv;
749                     unsigned int nPos = vRecv.size();
750
751                     if (nPos > 1000*GetArg("-maxreceivebuffer", 2*1000)) {
752                         if (!pnode->fDisconnect)
753                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
754                         pnode->CloseSocketDisconnect();
755                     }
756                     else {
757                         // typical socket buffer is 8K-64K
758                         char pchBuf[0x10000];
759                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
760                         if (nBytes > 0)
761                         {
762                             vRecv.resize(nPos + nBytes);
763                             memcpy(&vRecv[nPos], pchBuf, nBytes);
764                             pnode->nLastRecv = GetTime();
765                         }
766                         else if (nBytes == 0)
767                         {
768                             // socket closed gracefully
769                             if (!pnode->fDisconnect)
770                                 printf("socket closed\n");
771                             pnode->CloseSocketDisconnect();
772                         }
773                         else if (nBytes < 0)
774                         {
775                             // error
776                             int nErr = WSAGetLastError();
777                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
778                             {
779                                 if (!pnode->fDisconnect)
780                                     printf("socket recv error %d\n", nErr);
781                                 pnode->CloseSocketDisconnect();
782                             }
783                         }
784                     }
785                 }
786             }
787
788             //
789             // Send
790             //
791             if (pnode->hSocket == INVALID_SOCKET)
792                 continue;
793             if (FD_ISSET(pnode->hSocket, &fdsetSend))
794             {
795                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
796                 {
797                     CDataStream& vSend = pnode->vSend;
798                     if (!vSend.empty())
799                     {
800                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
801                         if (nBytes > 0)
802                         {
803                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
804                             pnode->nLastSend = GetTime();
805                         }
806                         else if (nBytes < 0)
807                         {
808                             // error
809                             int nErr = WSAGetLastError();
810                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
811                             {
812                                 printf("socket send error %d\n", nErr);
813                                 pnode->CloseSocketDisconnect();
814                             }
815                         }
816                         if (vSend.size() > 1000*GetArg("-maxsendbuffer", 256)) {
817                             if (!pnode->fDisconnect)
818                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
819                             pnode->CloseSocketDisconnect();
820                         }
821                     }
822                 }
823             }
824
825             //
826             // Inactivity checking
827             //
828             if (pnode->vSend.empty())
829                 pnode->nLastSendEmpty = GetTime();
830             if (GetTime() - pnode->nTimeConnected > 60)
831             {
832                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
833                 {
834                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
835                     pnode->fDisconnect = true;
836                 }
837                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
838                 {
839                     printf("socket not sending\n");
840                     pnode->fDisconnect = true;
841                 }
842                 else if (GetTime() - pnode->nLastRecv > 90*60)
843                 {
844                     printf("socket inactivity timeout\n");
845                     pnode->fDisconnect = true;
846                 }
847             }
848         }
849         CRITICAL_BLOCK(cs_vNodes)
850         {
851             foreach(CNode* pnode, vNodesCopy)
852                 pnode->Release();
853         }
854
855         Sleep(10);
856     }
857 }
858
859
860
861
862
863
864
865
866
867
868
869
870
871 unsigned int pnSeed[] =
872 {
873     0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
874     0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
875     0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
876     0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
877     0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
878     0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
879     0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
880     0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
881     0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
882     0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
883     0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
884     0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
885     0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
886     0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
887     0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
888     0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
889     0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
890     0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
891     0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
892     0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
893     0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
894     0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
895     0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
896     0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
897     0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
898     0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
899     0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
900     0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
901     0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
902     0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
903     0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
904     0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
905     0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
906     0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
907     0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
908     0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
909     0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
910     0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
911     0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
912     0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
913 };
914
915
916
917 void ThreadOpenConnections(void* parg)
918 {
919     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
920     try
921     {
922         vnThreadsRunning[1]++;
923         ThreadOpenConnections2(parg);
924         vnThreadsRunning[1]--;
925     }
926     catch (std::exception& e) {
927         vnThreadsRunning[1]--;
928         PrintException(&e, "ThreadOpenConnections()");
929     } catch (...) {
930         vnThreadsRunning[1]--;
931         PrintException(NULL, "ThreadOpenConnections()");
932     }
933     printf("ThreadOpenConnections exiting\n");
934 }
935
936 void ThreadOpenConnections2(void* parg)
937 {
938     printf("ThreadOpenConnections started\n");
939
940     // Connect to specific addresses
941     if (mapArgs.count("-connect"))
942     {
943         for (int64 nLoop = 0;; nLoop++)
944         {
945             foreach(string strAddr, mapMultiArgs["-connect"])
946             {
947                 CAddress addr(strAddr, NODE_NETWORK);
948                 if (addr.IsValid())
949                     OpenNetworkConnection(addr);
950                 for (int i = 0; i < 10 && i < nLoop; i++)
951                 {
952                     Sleep(500);
953                     if (fShutdown)
954                         return;
955                 }
956             }
957         }
958     }
959
960     // Connect to manually added nodes first
961     if (mapArgs.count("-addnode"))
962     {
963         foreach(string strAddr, mapMultiArgs["-addnode"])
964         {
965             CAddress addr(strAddr, NODE_NETWORK);
966             if (addr.IsValid())
967             {
968                 OpenNetworkConnection(addr);
969                 Sleep(500);
970                 if (fShutdown)
971                     return;
972             }
973         }
974     }
975
976     // Initiate network connections
977     int64 nStart = GetTime();
978     loop
979     {
980         // Limit outbound connections
981         vnThreadsRunning[1]--;
982         Sleep(500);
983         loop
984         {
985             int nOutbound = 0;
986             CRITICAL_BLOCK(cs_vNodes)
987                 foreach(CNode* pnode, vNodes)
988                     if (!pnode->fInbound)
989                         nOutbound++;
990             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
991             if (mapArgs.count("-maxconnections"))
992                 nMaxOutboundConnections = min(nMaxOutboundConnections, atoi(mapArgs["-maxconnections"]));
993             if (nOutbound < nMaxOutboundConnections)
994                 break;
995             Sleep(2000);
996             if (fShutdown)
997                 return;
998         }
999         vnThreadsRunning[1]++;
1000         if (fShutdown)
1001             return;
1002
1003         CRITICAL_BLOCK(cs_mapAddresses)
1004         {
1005             // Add seed nodes if IRC isn't working
1006             static bool fSeedUsed;
1007             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1008             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1009             {
1010                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1011                 {
1012                     // It'll only connect to one or two seed nodes because once it connects,
1013                     // it'll get a pile of addresses with newer timestamps.
1014                     CAddress addr;
1015                     addr.ip = pnSeed[i];
1016                     addr.nTime = 0;
1017                     AddAddress(addr);
1018                 }
1019                 fSeedUsed = true;
1020             }
1021
1022             if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1023             {
1024                 // Disconnect seed nodes
1025                 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1026                 static int64 nSeedDisconnected;
1027                 if (nSeedDisconnected == 0)
1028                 {
1029                     nSeedDisconnected = GetTime();
1030                     CRITICAL_BLOCK(cs_vNodes)
1031                         foreach(CNode* pnode, vNodes)
1032                             if (setSeed.count(pnode->addr.ip))
1033                                 pnode->fDisconnect = true;
1034                 }
1035
1036                 // Keep setting timestamps to 0 so they won't reconnect
1037                 if (GetTime() - nSeedDisconnected < 60 * 60)
1038                 {
1039                     foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1040                     {
1041                         if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1042                         {
1043                             item.second.nTime = 0;
1044                             CAddrDB().WriteAddress(item.second);
1045                         }
1046                     }
1047                 }
1048             }
1049         }
1050
1051
1052         //
1053         // Choose an address to connect to based on most recently seen
1054         //
1055         CAddress addrConnect;
1056         int64 nBest = INT64_MIN;
1057
1058         // Only connect to one address per a.b.?.? range.
1059         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1060         set<unsigned int> setConnected;
1061         CRITICAL_BLOCK(cs_vNodes)
1062             foreach(CNode* pnode, vNodes)
1063                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1064
1065         CRITICAL_BLOCK(cs_mapAddresses)
1066         {
1067             foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1068             {
1069                 const CAddress& addr = item.second;
1070                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1071                     continue;
1072                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1073                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1074
1075                 // Randomize the order in a deterministic way, putting the standard port first
1076                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1077                 if (addr.port != GetDefaultPort())
1078                     nRandomizer += 2 * 60 * 60;
1079
1080                 // Last seen  Base retry frequency
1081                 //   <1 hour   10 min
1082                 //    1 hour    1 hour
1083                 //    4 hours   2 hours
1084                 //   24 hours   5 hours
1085                 //   48 hours   7 hours
1086                 //    7 days   13 hours
1087                 //   30 days   27 hours
1088                 //   90 days   46 hours
1089                 //  365 days   93 hours
1090                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1091
1092                 // Fast reconnect for one hour after last seen
1093                 if (nSinceLastSeen < 60 * 60)
1094                     nDelay = 10 * 60;
1095
1096                 // Limit retry frequency
1097                 if (nSinceLastTry < nDelay)
1098                     continue;
1099
1100                 // If we have IRC, we'll be notified when they first come online,
1101                 // and again every 24 hours by the refresh broadcast.
1102                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1103                     continue;
1104
1105                 // Only try the old stuff if we don't have enough connections
1106                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1107                     continue;
1108
1109                 // If multiple addresses are ready, prioritize by time since
1110                 // last seen and time since last tried.
1111                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1112                 if (nScore > nBest)
1113                 {
1114                     nBest = nScore;
1115                     addrConnect = addr;
1116                 }
1117             }
1118         }
1119
1120         if (addrConnect.IsValid())
1121             OpenNetworkConnection(addrConnect);
1122     }
1123 }
1124
1125 bool OpenNetworkConnection(const CAddress& addrConnect)
1126 {
1127     //
1128     // Initiate outbound network connection
1129     //
1130     if (fShutdown)
1131         return false;
1132     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1133         return false;
1134
1135     vnThreadsRunning[1]--;
1136     CNode* pnode = ConnectNode(addrConnect);
1137     vnThreadsRunning[1]++;
1138     if (fShutdown)
1139         return false;
1140     if (!pnode)
1141         return false;
1142     pnode->fNetworkNode = true;
1143
1144     return true;
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154 void ThreadMessageHandler(void* parg)
1155 {
1156     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1157     try
1158     {
1159         vnThreadsRunning[2]++;
1160         ThreadMessageHandler2(parg);
1161         vnThreadsRunning[2]--;
1162     }
1163     catch (std::exception& e) {
1164         vnThreadsRunning[2]--;
1165         PrintException(&e, "ThreadMessageHandler()");
1166     } catch (...) {
1167         vnThreadsRunning[2]--;
1168         PrintException(NULL, "ThreadMessageHandler()");
1169     }
1170     printf("ThreadMessageHandler exiting\n");
1171 }
1172
1173 void ThreadMessageHandler2(void* parg)
1174 {
1175     printf("ThreadMessageHandler started\n");
1176     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1177     while (!fShutdown)
1178     {
1179         vector<CNode*> vNodesCopy;
1180         CRITICAL_BLOCK(cs_vNodes)
1181         {
1182             vNodesCopy = vNodes;
1183             foreach(CNode* pnode, vNodesCopy)
1184                 pnode->AddRef();
1185         }
1186
1187         // Poll the connected nodes for messages
1188         CNode* pnodeTrickle = NULL;
1189         if (!vNodesCopy.empty())
1190             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1191         foreach(CNode* pnode, vNodesCopy)
1192         {
1193             // Receive messages
1194             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1195                 ProcessMessages(pnode);
1196             if (fShutdown)
1197                 return;
1198
1199             // Send messages
1200             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1201                 SendMessages(pnode, pnode == pnodeTrickle);
1202             if (fShutdown)
1203                 return;
1204         }
1205
1206         CRITICAL_BLOCK(cs_vNodes)
1207         {
1208             foreach(CNode* pnode, vNodesCopy)
1209                 pnode->Release();
1210         }
1211
1212         // Wait and allow messages to bunch up.
1213         // Reduce vnThreadsRunning so StopNode has permission to exit while
1214         // we're sleeping, but we must always check fShutdown after doing this.
1215         vnThreadsRunning[2]--;
1216         Sleep(100);
1217         if (fRequestShutdown)
1218             Shutdown(NULL);
1219         vnThreadsRunning[2]++;
1220         if (fShutdown)
1221             return;
1222     }
1223 }
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233 bool BindListenPort(string& strError)
1234 {
1235     strError = "";
1236     int nOne = 1;
1237     addrLocalHost.port = GetDefaultPort();
1238
1239 #ifdef __WXMSW__
1240     // Initialize Windows Sockets
1241     WSADATA wsadata;
1242     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1243     if (ret != NO_ERROR)
1244     {
1245         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1246         printf("%s\n", strError.c_str());
1247         return false;
1248     }
1249 #endif
1250
1251     // Create socket for listening for incoming connections
1252     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1253     if (hListenSocket == INVALID_SOCKET)
1254     {
1255         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1256         printf("%s\n", strError.c_str());
1257         return false;
1258     }
1259
1260 #ifdef BSD
1261     // Different way of disabling SIGPIPE on BSD
1262     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1263 #endif
1264
1265 #ifndef __WXMSW__
1266     // Allow binding if the port is still in TIME_WAIT state after
1267     // the program was closed and restarted.  Not an issue on windows.
1268     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1269 #endif
1270
1271 #ifdef __WXMSW__
1272     // Set to nonblocking, incoming connections will also inherit this
1273     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1274 #else
1275     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1276 #endif
1277     {
1278         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1279         printf("%s\n", strError.c_str());
1280         return false;
1281     }
1282
1283     // The sockaddr_in structure specifies the address family,
1284     // IP address, and port for the socket that is being bound
1285     struct sockaddr_in sockaddr;
1286     memset(&sockaddr, 0, sizeof(sockaddr));
1287     sockaddr.sin_family = AF_INET;
1288     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1289     sockaddr.sin_port = GetDefaultPort();
1290     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1291     {
1292         int nErr = WSAGetLastError();
1293         if (nErr == WSAEADDRINUSE)
1294             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1295         else
1296             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1297         printf("%s\n", strError.c_str());
1298         return false;
1299     }
1300     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1301
1302     // Listen for incoming connections
1303     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1304     {
1305         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1306         printf("%s\n", strError.c_str());
1307         return false;
1308     }
1309
1310     return true;
1311 }
1312
1313 void StartNode(void* parg)
1314 {
1315     if (pnodeLocalHost == NULL)
1316         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
1317
1318 #ifdef __WXMSW__
1319     // Get local host ip
1320     char pszHostName[1000] = "";
1321     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1322     {
1323         struct hostent* phostent = gethostbyname(pszHostName);
1324         if (phostent)
1325         {
1326             // Take the first IP that isn't loopback 127.x.x.x
1327             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1328                 printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
1329             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1330             {
1331                 CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
1332                 if (addr.IsValid() && addr.GetByte(3) != 127)
1333                 {
1334                     addrLocalHost = addr;
1335                     break;
1336                 }
1337             }
1338         }
1339     }
1340 #else
1341     // Get local host ip
1342     struct ifaddrs* myaddrs;
1343     if (getifaddrs(&myaddrs) == 0)
1344     {
1345         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1346         {
1347             if (ifa->ifa_addr == NULL) continue;
1348             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1349             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1350             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1351             char pszIP[100];
1352             if (ifa->ifa_addr->sa_family == AF_INET)
1353             {
1354                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1355                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1356                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1357
1358                 // Take the first IP that isn't loopback 127.x.x.x
1359                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
1360                 if (addr.IsValid() && addr.GetByte(3) != 127)
1361                 {
1362                     addrLocalHost = addr;
1363                     break;
1364                 }
1365             }
1366             else if (ifa->ifa_addr->sa_family == AF_INET6)
1367             {
1368                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1369                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1370                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1371             }
1372         }
1373         freeifaddrs(myaddrs);
1374     }
1375 #endif
1376     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1377
1378     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1379     {
1380         // Proxies can't take incoming connections
1381         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1382         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1383     }
1384     else
1385     {
1386         CreateThread(ThreadGetMyExternalIP, NULL);
1387     }
1388
1389     //
1390     // Start threads
1391     //
1392
1393     // Get addresses from IRC and advertise ours
1394     if (!CreateThread(ThreadIRCSeed, NULL))
1395         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1396
1397     // Send and receive from sockets, accept connections
1398     pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1399
1400     // Initiate outbound connections
1401     if (!CreateThread(ThreadOpenConnections, NULL))
1402         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1403
1404     // Process messages
1405     if (!CreateThread(ThreadMessageHandler, NULL))
1406         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1407
1408     // Generate coins in the background
1409     GenerateBitcoins(fGenerateBitcoins);
1410 }
1411
1412 bool StopNode()
1413 {
1414     printf("StopNode()\n");
1415     fShutdown = true;
1416     nTransactionsUpdated++;
1417     int64 nStart = GetTime();
1418     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0)
1419     {
1420         if (GetTime() - nStart > 20)
1421             break;
1422         Sleep(20);
1423     }
1424     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1425     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1426     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1427     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1428     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1429     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1430         Sleep(20);
1431     Sleep(50);
1432
1433     return true;
1434 }
1435
1436 class CNetCleanup
1437 {
1438 public:
1439     CNetCleanup()
1440     {
1441     }
1442     ~CNetCleanup()
1443     {
1444         // Close sockets
1445         foreach(CNode* pnode, vNodes)
1446             if (pnode->hSocket != INVALID_SOCKET)
1447                 closesocket(pnode->hSocket);
1448         if (hListenSocket != INVALID_SOCKET)
1449             if (closesocket(hListenSocket) == SOCKET_ERROR)
1450                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1451
1452 #ifdef __WXMSW__
1453         // Shutdown Windows Sockets
1454         WSACleanup();
1455 #endif
1456     }
1457 }
1458 instance_of_cnetcleanup;