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