directory re-organization (keeps the old build system)
[novacoin.git] / src / 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     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
910     if (r == 1)
911     {
912         char intClient[16];
913         char intPort[6];
914
915 #ifndef __WXMSW__
916         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
917                                 port, port, lanaddr, 0, "TCP", 0);
918 #else
919         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
920                                 port, port, lanaddr, 0, "TCP", 0, "0");
921 #endif
922         if(r!=UPNPCOMMAND_SUCCESS)
923             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
924                 port, port, lanaddr, r, strupnperror(r));
925         else
926             printf("UPnP Port Mapping successful.\n");
927         loop {
928             if (fShutdown || !fUseUPnP)
929             {
930                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
931                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
932                 freeUPNPDevlist(devlist); devlist = 0;
933                 FreeUPNPUrls(&urls);
934                 return;
935             }
936             Sleep(2000);
937         }
938     } else {
939         printf("No valid UPnP IGDs found\n");
940         freeUPNPDevlist(devlist); devlist = 0;
941         if (r != 0)
942             FreeUPNPUrls(&urls);
943         loop {
944             if (fShutdown || !fUseUPnP)
945                 return;
946             Sleep(2000);
947         }
948     }
949 }
950
951 void MapPort(bool fMapPort)
952 {
953     if (fUseUPnP != fMapPort)
954     {
955         fUseUPnP = fMapPort;
956         CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
957     }
958     if (fUseUPnP && vnThreadsRunning[5] < 1)
959     {
960         if (!CreateThread(ThreadMapPort, NULL))
961             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
962     }
963 }
964 #endif
965
966
967
968
969
970
971
972
973
974
975 static const char *strDNSSeed[] = {
976     "bitseed.xf2.org",
977     "bitseed.bitcoin.org.uk",
978 };
979
980 void DNSAddressSeed()
981 {
982     int found = 0;
983
984     printf("Loading addresses from DNS seeds (could take a while)\n");
985
986     for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
987         struct hostent* phostent = gethostbyname(strDNSSeed[seed_idx]);
988         if (!phostent)
989             continue;
990
991         for (int host = 0; phostent->h_addr_list[host] != NULL; host++) {
992             CAddress addr(*(unsigned int*)phostent->h_addr_list[host],
993                           GetDefaultPort(), NODE_NETWORK);
994             addr.nTime = 0;
995             if (addr.IsValid() && addr.GetByte(3) != 127) {
996                 AddAddress(addr);
997                 found++;
998             }
999         }
1000     }
1001
1002     printf("%d addresses found from DNS seeds\n", found);
1003 }
1004
1005
1006
1007 unsigned int pnSeed[] =
1008 {
1009     0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1010     0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1011     0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1012     0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1013     0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1014     0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1015     0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1016     0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1017     0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1018     0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1019     0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1020     0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1021     0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1022     0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1023     0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1024     0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1025     0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1026     0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1027     0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1028     0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1029     0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1030     0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1031     0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1032     0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1033     0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1034     0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1035     0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1036     0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1037     0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1038     0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1039     0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1040     0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1041     0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1042     0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1043     0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1044     0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1045     0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1046     0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1047     0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1048     0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1049 };
1050
1051
1052
1053 void ThreadOpenConnections(void* parg)
1054 {
1055     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1056     try
1057     {
1058         vnThreadsRunning[1]++;
1059         ThreadOpenConnections2(parg);
1060         vnThreadsRunning[1]--;
1061     }
1062     catch (std::exception& e) {
1063         vnThreadsRunning[1]--;
1064         PrintException(&e, "ThreadOpenConnections()");
1065     } catch (...) {
1066         vnThreadsRunning[1]--;
1067         PrintException(NULL, "ThreadOpenConnections()");
1068     }
1069     printf("ThreadOpenConnections exiting\n");
1070 }
1071
1072 void ThreadOpenConnections2(void* parg)
1073 {
1074     printf("ThreadOpenConnections started\n");
1075
1076     // Connect to specific addresses
1077     if (mapArgs.count("-connect"))
1078     {
1079         for (int64 nLoop = 0;; nLoop++)
1080         {
1081             foreach(string strAddr, mapMultiArgs["-connect"])
1082             {
1083                 CAddress addr(strAddr, NODE_NETWORK);
1084                 if (addr.IsValid())
1085                     OpenNetworkConnection(addr);
1086                 for (int i = 0; i < 10 && i < nLoop; i++)
1087                 {
1088                     Sleep(500);
1089                     if (fShutdown)
1090                         return;
1091                 }
1092             }
1093         }
1094     }
1095
1096     // Connect to manually added nodes first
1097     if (mapArgs.count("-addnode"))
1098     {
1099         foreach(string strAddr, mapMultiArgs["-addnode"])
1100         {
1101             CAddress addr(strAddr, NODE_NETWORK);
1102             if (addr.IsValid())
1103             {
1104                 OpenNetworkConnection(addr);
1105                 Sleep(500);
1106                 if (fShutdown)
1107                     return;
1108             }
1109         }
1110     }
1111
1112     // Initiate network connections
1113     int64 nStart = GetTime();
1114     loop
1115     {
1116         // Limit outbound connections
1117         vnThreadsRunning[1]--;
1118         Sleep(500);
1119         loop
1120         {
1121             int nOutbound = 0;
1122             CRITICAL_BLOCK(cs_vNodes)
1123                 foreach(CNode* pnode, vNodes)
1124                     if (!pnode->fInbound)
1125                         nOutbound++;
1126             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1127             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1128             if (nOutbound < nMaxOutboundConnections)
1129                 break;
1130             Sleep(2000);
1131             if (fShutdown)
1132                 return;
1133         }
1134         vnThreadsRunning[1]++;
1135         if (fShutdown)
1136             return;
1137
1138         CRITICAL_BLOCK(cs_mapAddresses)
1139         {
1140             // Add seed nodes if IRC isn't working
1141             static bool fSeedUsed;
1142             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1143             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1144             {
1145                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1146                 {
1147                     // It'll only connect to one or two seed nodes because once it connects,
1148                     // it'll get a pile of addresses with newer timestamps.
1149                     CAddress addr;
1150                     addr.ip = pnSeed[i];
1151                     addr.nTime = 0;
1152                     AddAddress(addr);
1153                 }
1154                 fSeedUsed = true;
1155             }
1156
1157             if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1158             {
1159                 // Disconnect seed nodes
1160                 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1161                 static int64 nSeedDisconnected;
1162                 if (nSeedDisconnected == 0)
1163                 {
1164                     nSeedDisconnected = GetTime();
1165                     CRITICAL_BLOCK(cs_vNodes)
1166                         foreach(CNode* pnode, vNodes)
1167                             if (setSeed.count(pnode->addr.ip))
1168                                 pnode->fDisconnect = true;
1169                 }
1170
1171                 // Keep setting timestamps to 0 so they won't reconnect
1172                 if (GetTime() - nSeedDisconnected < 60 * 60)
1173                 {
1174                     foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1175                     {
1176                         if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1177                         {
1178                             item.second.nTime = 0;
1179                             CAddrDB().WriteAddress(item.second);
1180                         }
1181                     }
1182                 }
1183             }
1184         }
1185
1186
1187         //
1188         // Choose an address to connect to based on most recently seen
1189         //
1190         CAddress addrConnect;
1191         int64 nBest = INT64_MIN;
1192
1193         // Only connect to one address per a.b.?.? range.
1194         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1195         set<unsigned int> setConnected;
1196         CRITICAL_BLOCK(cs_vNodes)
1197             foreach(CNode* pnode, vNodes)
1198                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1199
1200         CRITICAL_BLOCK(cs_mapAddresses)
1201         {
1202             foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1203             {
1204                 const CAddress& addr = item.second;
1205                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1206                     continue;
1207                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1208                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1209
1210                 // Randomize the order in a deterministic way, putting the standard port first
1211                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1212                 if (addr.port != GetDefaultPort())
1213                     nRandomizer += 2 * 60 * 60;
1214
1215                 // Last seen  Base retry frequency
1216                 //   <1 hour   10 min
1217                 //    1 hour    1 hour
1218                 //    4 hours   2 hours
1219                 //   24 hours   5 hours
1220                 //   48 hours   7 hours
1221                 //    7 days   13 hours
1222                 //   30 days   27 hours
1223                 //   90 days   46 hours
1224                 //  365 days   93 hours
1225                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1226
1227                 // Fast reconnect for one hour after last seen
1228                 if (nSinceLastSeen < 60 * 60)
1229                     nDelay = 10 * 60;
1230
1231                 // Limit retry frequency
1232                 if (nSinceLastTry < nDelay)
1233                     continue;
1234
1235                 // If we have IRC, we'll be notified when they first come online,
1236                 // and again every 24 hours by the refresh broadcast.
1237                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1238                     continue;
1239
1240                 // Only try the old stuff if we don't have enough connections
1241                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1242                     continue;
1243
1244                 // If multiple addresses are ready, prioritize by time since
1245                 // last seen and time since last tried.
1246                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1247                 if (nScore > nBest)
1248                 {
1249                     nBest = nScore;
1250                     addrConnect = addr;
1251                 }
1252             }
1253         }
1254
1255         if (addrConnect.IsValid())
1256             OpenNetworkConnection(addrConnect);
1257     }
1258 }
1259
1260 bool OpenNetworkConnection(const CAddress& addrConnect)
1261 {
1262     //
1263     // Initiate outbound network connection
1264     //
1265     if (fShutdown)
1266         return false;
1267     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1268         return false;
1269
1270     vnThreadsRunning[1]--;
1271     CNode* pnode = ConnectNode(addrConnect);
1272     vnThreadsRunning[1]++;
1273     if (fShutdown)
1274         return false;
1275     if (!pnode)
1276         return false;
1277     pnode->fNetworkNode = true;
1278
1279     return true;
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289 void ThreadMessageHandler(void* parg)
1290 {
1291     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1292     try
1293     {
1294         vnThreadsRunning[2]++;
1295         ThreadMessageHandler2(parg);
1296         vnThreadsRunning[2]--;
1297     }
1298     catch (std::exception& e) {
1299         vnThreadsRunning[2]--;
1300         PrintException(&e, "ThreadMessageHandler()");
1301     } catch (...) {
1302         vnThreadsRunning[2]--;
1303         PrintException(NULL, "ThreadMessageHandler()");
1304     }
1305     printf("ThreadMessageHandler exiting\n");
1306 }
1307
1308 void ThreadMessageHandler2(void* parg)
1309 {
1310     printf("ThreadMessageHandler started\n");
1311     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1312     while (!fShutdown)
1313     {
1314         vector<CNode*> vNodesCopy;
1315         CRITICAL_BLOCK(cs_vNodes)
1316         {
1317             vNodesCopy = vNodes;
1318             foreach(CNode* pnode, vNodesCopy)
1319                 pnode->AddRef();
1320         }
1321
1322         // Poll the connected nodes for messages
1323         CNode* pnodeTrickle = NULL;
1324         if (!vNodesCopy.empty())
1325             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1326         foreach(CNode* pnode, vNodesCopy)
1327         {
1328             // Receive messages
1329             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1330                 ProcessMessages(pnode);
1331             if (fShutdown)
1332                 return;
1333
1334             // Send messages
1335             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1336                 SendMessages(pnode, pnode == pnodeTrickle);
1337             if (fShutdown)
1338                 return;
1339         }
1340
1341         CRITICAL_BLOCK(cs_vNodes)
1342         {
1343             foreach(CNode* pnode, vNodesCopy)
1344                 pnode->Release();
1345         }
1346
1347         // Wait and allow messages to bunch up.
1348         // Reduce vnThreadsRunning so StopNode has permission to exit while
1349         // we're sleeping, but we must always check fShutdown after doing this.
1350         vnThreadsRunning[2]--;
1351         Sleep(100);
1352         if (fRequestShutdown)
1353             Shutdown(NULL);
1354         vnThreadsRunning[2]++;
1355         if (fShutdown)
1356             return;
1357     }
1358 }
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368 bool BindListenPort(string& strError)
1369 {
1370     strError = "";
1371     int nOne = 1;
1372     addrLocalHost.port = GetDefaultPort();
1373
1374 #ifdef __WXMSW__
1375     // Initialize Windows Sockets
1376     WSADATA wsadata;
1377     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1378     if (ret != NO_ERROR)
1379     {
1380         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1381         printf("%s\n", strError.c_str());
1382         return false;
1383     }
1384 #endif
1385
1386     // Create socket for listening for incoming connections
1387     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1388     if (hListenSocket == INVALID_SOCKET)
1389     {
1390         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1391         printf("%s\n", strError.c_str());
1392         return false;
1393     }
1394
1395 #ifdef BSD
1396     // Different way of disabling SIGPIPE on BSD
1397     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1398 #endif
1399
1400 #ifndef __WXMSW__
1401     // Allow binding if the port is still in TIME_WAIT state after
1402     // the program was closed and restarted.  Not an issue on windows.
1403     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1404 #endif
1405
1406 #ifdef __WXMSW__
1407     // Set to nonblocking, incoming connections will also inherit this
1408     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1409 #else
1410     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1411 #endif
1412     {
1413         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1414         printf("%s\n", strError.c_str());
1415         return false;
1416     }
1417
1418     // The sockaddr_in structure specifies the address family,
1419     // IP address, and port for the socket that is being bound
1420     struct sockaddr_in sockaddr;
1421     memset(&sockaddr, 0, sizeof(sockaddr));
1422     sockaddr.sin_family = AF_INET;
1423     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1424     sockaddr.sin_port = GetDefaultPort();
1425     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1426     {
1427         int nErr = WSAGetLastError();
1428         if (nErr == WSAEADDRINUSE)
1429             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1430         else
1431             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1432         printf("%s\n", strError.c_str());
1433         return false;
1434     }
1435     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1436
1437     // Listen for incoming connections
1438     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1439     {
1440         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1441         printf("%s\n", strError.c_str());
1442         return false;
1443     }
1444
1445     return true;
1446 }
1447
1448 void StartNode(void* parg)
1449 {
1450     if (pnodeLocalHost == NULL)
1451         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
1452
1453 #ifdef __WXMSW__
1454     // Get local host ip
1455     char pszHostName[1000] = "";
1456     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1457     {
1458         struct hostent* phostent = gethostbyname(pszHostName);
1459         if (phostent)
1460         {
1461             // Take the first IP that isn't loopback 127.x.x.x
1462             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1463                 printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
1464             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1465             {
1466                 CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
1467                 if (addr.IsValid() && addr.GetByte(3) != 127)
1468                 {
1469                     addrLocalHost = addr;
1470                     break;
1471                 }
1472             }
1473         }
1474     }
1475 #else
1476     // Get local host ip
1477     struct ifaddrs* myaddrs;
1478     if (getifaddrs(&myaddrs) == 0)
1479     {
1480         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1481         {
1482             if (ifa->ifa_addr == NULL) continue;
1483             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1484             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1485             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1486             char pszIP[100];
1487             if (ifa->ifa_addr->sa_family == AF_INET)
1488             {
1489                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1490                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1491                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1492
1493                 // Take the first IP that isn't loopback 127.x.x.x
1494                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
1495                 if (addr.IsValid() && addr.GetByte(3) != 127)
1496                 {
1497                     addrLocalHost = addr;
1498                     break;
1499                 }
1500             }
1501             else if (ifa->ifa_addr->sa_family == AF_INET6)
1502             {
1503                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1504                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1505                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1506             }
1507         }
1508         freeifaddrs(myaddrs);
1509     }
1510 #endif
1511     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1512
1513     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1514     {
1515         // Proxies can't take incoming connections
1516         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1517         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1518     }
1519     else
1520     {
1521         CreateThread(ThreadGetMyExternalIP, NULL);
1522     }
1523
1524     //
1525     // Start threads
1526     //
1527
1528     // Map ports with UPnP
1529     if (fHaveUPnP)
1530         MapPort(fUseUPnP);
1531
1532     // Get addresses from IRC and advertise ours
1533     if (!CreateThread(ThreadIRCSeed, NULL))
1534         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1535
1536     // Send and receive from sockets, accept connections
1537     pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1538
1539     // Initiate outbound connections
1540     if (!CreateThread(ThreadOpenConnections, NULL))
1541         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1542
1543     // Process messages
1544     if (!CreateThread(ThreadMessageHandler, NULL))
1545         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1546
1547     // Generate coins in the background
1548     GenerateBitcoins(fGenerateBitcoins);
1549 }
1550
1551 bool StopNode()
1552 {
1553     printf("StopNode()\n");
1554     fShutdown = true;
1555     nTransactionsUpdated++;
1556     int64 nStart = GetTime();
1557     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1558 #ifdef USE_UPNP
1559         || vnThreadsRunning[5] > 0
1560 #endif
1561     )
1562     {
1563         if (GetTime() - nStart > 20)
1564             break;
1565         Sleep(20);
1566     }
1567     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1568     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1569     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1570     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1571     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1572     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1573     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1574         Sleep(20);
1575     Sleep(50);
1576
1577     return true;
1578 }
1579
1580 class CNetCleanup
1581 {
1582 public:
1583     CNetCleanup()
1584     {
1585     }
1586     ~CNetCleanup()
1587     {
1588         // Close sockets
1589         foreach(CNode* pnode, vNodes)
1590             if (pnode->hSocket != INVALID_SOCKET)
1591                 closesocket(pnode->hSocket);
1592         if (hListenSocket != INVALID_SOCKET)
1593             if (closesocket(hListenSocket) == SOCKET_ERROR)
1594                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1595
1596 #ifdef __WXMSW__
1597         // Shutdown Windows Sockets
1598         WSACleanup();
1599 #endif
1600     }
1601 }
1602 instance_of_cnetcleanup;