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