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