Update README now that main svn has -testnet built in
[novacoin.git] / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "headers.h"
6
7 static const int MAX_OUTBOUND_CONNECTIONS = 8;
8
9 void ThreadMessageHandler2(void* parg);
10 void ThreadSocketHandler2(void* parg);
11 void ThreadOpenConnections2(void* parg);
12 bool OpenNetworkConnection(const CAddress& addrConnect);
13
14
15
16
17
18 //
19 // Global state variables
20 //
21 bool fClient = false;
22 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
23 CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
24 CNode* pnodeLocalHost = NULL;
25 uint64 nLocalHostNonce = 0;
26 array<int, 10> vnThreadsRunning;
27 SOCKET hListenSocket = INVALID_SOCKET;
28
29 vector<CNode*> vNodes;
30 CCriticalSection cs_vNodes;
31 map<vector<unsigned char>, CAddress> mapAddresses;
32 CCriticalSection cs_mapAddresses;
33 map<CInv, CDataStream> mapRelay;
34 deque<pair<int64, CInv> > vRelayExpiration;
35 CCriticalSection cs_mapRelay;
36 map<CInv, int64> mapAlreadyAskedFor;
37
38 // Settings
39 int fUseProxy = false;
40 CAddress addrProxy("127.0.0.1:9050");
41
42
43
44
45
46 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
47 {
48     // Filter out duplicate requests
49     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
50         return;
51     pindexLastGetBlocksBegin = pindexBegin;
52     hashLastGetBlocksEnd = hashEnd;
53
54     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
55 }
56
57
58
59
60
61 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
62 {
63     hSocketRet = INVALID_SOCKET;
64
65     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
66     if (hSocket == INVALID_SOCKET)
67         return false;
68 #ifdef BSD
69     int set = 1;
70     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
71 #endif
72
73     bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
74     bool fProxy = (fUseProxy && fRoutable);
75     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
76
77     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
78     {
79         closesocket(hSocket);
80         return false;
81     }
82
83     if (fProxy)
84     {
85         printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str());
86         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
87         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
88         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
89         char* pszSocks4 = pszSocks4IP;
90         int nSize = sizeof(pszSocks4IP);
91
92         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
93         if (ret != nSize)
94         {
95             closesocket(hSocket);
96             return error("Error sending to proxy");
97         }
98         char pchRet[8];
99         if (recv(hSocket, pchRet, 8, 0) != 8)
100         {
101             closesocket(hSocket);
102             return error("Error reading proxy response");
103         }
104         if (pchRet[1] != 0x5a)
105         {
106             closesocket(hSocket);
107             if (pchRet[1] != 0x5b)
108                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
109             return false;
110         }
111         printf("proxy connected %s\n", addrConnect.ToStringLog().c_str());
112     }
113
114     hSocketRet = hSocket;
115     return true;
116 }
117
118
119
120 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
121 {
122     SOCKET hSocket;
123     if (!ConnectSocket(addrConnect, hSocket))
124         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
125
126     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
127
128     string strLine;
129     while (RecvLine(hSocket, strLine))
130     {
131         if (strLine.empty())
132         {
133             loop
134             {
135                 if (!RecvLine(hSocket, strLine))
136                 {
137                     closesocket(hSocket);
138                     return false;
139                 }
140                 if (strLine.find(pszKeyword) != -1)
141                 {
142                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
143                     break;
144                 }
145             }
146             closesocket(hSocket);
147             if (strLine.find("<"))
148                 strLine = strLine.substr(0, strLine.find("<"));
149             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
150             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
151                 strLine.resize(strLine.size()-1);
152             CAddress addr(strLine.c_str());
153             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
154             if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
155                 return false;
156             ipRet = addr.ip;
157             return true;
158         }
159     }
160     closesocket(hSocket);
161     return error("GetMyExternalIP() : connection closed");
162 }
163
164
165 bool GetMyExternalIP(unsigned int& ipRet)
166 {
167     CAddress addrConnect;
168     const char* pszGet;
169     const char* pszKeyword;
170
171     if (fUseProxy)
172         return false;
173
174     for (int nLookup = 0; nLookup <= 1; nLookup++)
175     for (int nHost = 1; nHost <= 2; nHost++)
176     {
177         if (nHost == 1)
178         {
179             addrConnect = CAddress("70.86.96.218:80"); // www.ipaddressworld.com
180
181             if (nLookup == 1)
182             {
183                 struct hostent* phostent = gethostbyname("www.ipaddressworld.com");
184                 if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
185                     addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
186             }
187
188             pszGet = "GET /ip.php HTTP/1.1\r\n"
189                      "Host: www.ipaddressworld.com\r\n"
190                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
191                      "Connection: close\r\n"
192                      "\r\n";
193
194             pszKeyword = "IP:";
195         }
196         else if (nHost == 2)
197         {
198             addrConnect = CAddress("208.78.68.70:80"); // checkip.dyndns.org
199
200             if (nLookup == 1)
201             {
202                 struct hostent* phostent = gethostbyname("checkip.dyndns.org");
203                 if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
204                     addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
205             }
206
207             pszGet = "GET / HTTP/1.1\r\n"
208                      "Host: checkip.dyndns.org\r\n"
209                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
210                      "Connection: close\r\n"
211                      "\r\n";
212
213             pszKeyword = "Address:";
214         }
215
216         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
217             return true;
218     }
219
220     return false;
221 }
222
223
224
225
226
227 bool AddAddress(CAddress addr)
228 {
229     if (!addr.IsRoutable())
230         return false;
231     if (addr.ip == addrLocalHost.ip)
232         return false;
233     CRITICAL_BLOCK(cs_mapAddresses)
234     {
235         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
236         if (it == mapAddresses.end())
237         {
238             // New address
239             printf("AddAddress(%s)\n", addr.ToStringLog().c_str());
240             mapAddresses.insert(make_pair(addr.GetKey(), addr));
241             CAddrDB().WriteAddress(addr);
242             return true;
243         }
244         else
245         {
246             bool fUpdated = false;
247             CAddress& addrFound = (*it).second;
248             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
249             {
250                 // Services have been added
251                 addrFound.nServices |= addr.nServices;
252                 fUpdated = true;
253             }
254             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
255             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
256             if (addrFound.nTime < addr.nTime - nUpdateInterval)
257             {
258                 // Periodically update most recently seen time
259                 addrFound.nTime = addr.nTime;
260                 fUpdated = true;
261             }
262             if (fUpdated)
263                 CAddrDB().WriteAddress(addrFound);
264         }
265     }
266     return false;
267 }
268
269 void AddressCurrentlyConnected(const CAddress& addr)
270 {
271     CRITICAL_BLOCK(cs_mapAddresses)
272     {
273         // Only if it's been published already
274         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
275         if (it != mapAddresses.end())
276         {
277             CAddress& addrFound = (*it).second;
278             int64 nUpdateInterval = 20 * 60;
279             if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
280             {
281                 // Periodically update most recently seen time
282                 addrFound.nTime = GetAdjustedTime();
283                 CAddrDB addrdb;
284                 addrdb.WriteAddress(addrFound);
285             }
286         }
287     }
288 }
289
290
291
292
293
294 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
295 {
296     // If the dialog might get closed before the reply comes back,
297     // call this in the destructor so it doesn't get called after it's deleted.
298     CRITICAL_BLOCK(cs_vNodes)
299     {
300         foreach(CNode* pnode, vNodes)
301         {
302             CRITICAL_BLOCK(pnode->cs_mapRequests)
303             {
304                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
305                 {
306                     CRequestTracker& tracker = (*mi).second;
307                     if (tracker.fn == fn && tracker.param1 == param1)
308                         pnode->mapRequests.erase(mi++);
309                     else
310                         mi++;
311                 }
312             }
313         }
314     }
315 }
316
317
318
319
320
321
322
323 //
324 // Subscription methods for the broadcast and subscription system.
325 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
326 //
327 // The subscription system uses a meet-in-the-middle strategy.
328 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
329 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
330 //
331
332 bool AnySubscribed(unsigned int nChannel)
333 {
334     if (pnodeLocalHost->IsSubscribed(nChannel))
335         return true;
336     CRITICAL_BLOCK(cs_vNodes)
337         foreach(CNode* pnode, vNodes)
338             if (pnode->IsSubscribed(nChannel))
339                 return true;
340     return false;
341 }
342
343 bool CNode::IsSubscribed(unsigned int nChannel)
344 {
345     if (nChannel >= vfSubscribe.size())
346         return false;
347     return vfSubscribe[nChannel];
348 }
349
350 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
351 {
352     if (nChannel >= vfSubscribe.size())
353         return;
354
355     if (!AnySubscribed(nChannel))
356     {
357         // Relay subscribe
358         CRITICAL_BLOCK(cs_vNodes)
359             foreach(CNode* pnode, vNodes)
360                 if (pnode != this)
361                     pnode->PushMessage("subscribe", nChannel, nHops);
362     }
363
364     vfSubscribe[nChannel] = true;
365 }
366
367 void CNode::CancelSubscribe(unsigned int nChannel)
368 {
369     if (nChannel >= vfSubscribe.size())
370         return;
371
372     // Prevent from relaying cancel if wasn't subscribed
373     if (!vfSubscribe[nChannel])
374         return;
375     vfSubscribe[nChannel] = false;
376
377     if (!AnySubscribed(nChannel))
378     {
379         // Relay subscription cancel
380         CRITICAL_BLOCK(cs_vNodes)
381             foreach(CNode* pnode, vNodes)
382                 if (pnode != this)
383                     pnode->PushMessage("sub-cancel", nChannel);
384     }
385 }
386
387
388
389
390
391
392
393
394
395 CNode* FindNode(unsigned int ip)
396 {
397     CRITICAL_BLOCK(cs_vNodes)
398     {
399         foreach(CNode* pnode, vNodes)
400             if (pnode->addr.ip == ip)
401                 return (pnode);
402     }
403     return NULL;
404 }
405
406 CNode* FindNode(CAddress addr)
407 {
408     CRITICAL_BLOCK(cs_vNodes)
409     {
410         foreach(CNode* pnode, vNodes)
411             if (pnode->addr == addr)
412                 return (pnode);
413     }
414     return NULL;
415 }
416
417 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
418 {
419     if (addrConnect.ip == addrLocalHost.ip)
420         return NULL;
421
422     // Look for an existing connection
423     CNode* pnode = FindNode(addrConnect.ip);
424     if (pnode)
425     {
426         if (nTimeout != 0)
427             pnode->AddRef(nTimeout);
428         else
429             pnode->AddRef();
430         return pnode;
431     }
432
433     /// debug print
434     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
435         addrConnect.ToStringLog().c_str(),
436         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
437         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
438
439     CRITICAL_BLOCK(cs_mapAddresses)
440         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
441
442     // Connect
443     SOCKET hSocket;
444     if (ConnectSocket(addrConnect, hSocket))
445     {
446         /// debug print
447         printf("connected %s\n", addrConnect.ToStringLog().c_str());
448
449         // Set to nonblocking
450 #ifdef __WXMSW__
451         u_long nOne = 1;
452         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
453             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
454 #else
455         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
456             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
457 #endif
458
459         // Add node
460         CNode* pnode = new CNode(hSocket, addrConnect, false);
461         if (nTimeout != 0)
462             pnode->AddRef(nTimeout);
463         else
464             pnode->AddRef();
465         CRITICAL_BLOCK(cs_vNodes)
466             vNodes.push_back(pnode);
467
468         pnode->nTimeConnected = GetTime();
469         return pnode;
470     }
471     else
472     {
473         return NULL;
474     }
475 }
476
477 void CNode::CloseSocketDisconnect()
478 {
479     fDisconnect = true;
480     if (hSocket != INVALID_SOCKET)
481     {
482         if (fDebug)
483             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
484         printf("disconnecting node %s\n", addr.ToStringLog().c_str());
485         closesocket(hSocket);
486         hSocket = INVALID_SOCKET;
487     }
488 }
489
490 void CNode::Cleanup()
491 {
492     // All of a nodes broadcasts and subscriptions are automatically torn down
493     // when it goes down, so a node has to stay up to keep its broadcast going.
494
495     // Cancel subscriptions
496     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
497         if (vfSubscribe[nChannel])
498             CancelSubscribe(nChannel);
499 }
500
501
502
503
504
505
506
507
508
509
510
511
512
513 void ThreadSocketHandler(void* parg)
514 {
515     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
516     try
517     {
518         vnThreadsRunning[0]++;
519         ThreadSocketHandler2(parg);
520         vnThreadsRunning[0]--;
521     }
522     catch (std::exception& e) {
523         vnThreadsRunning[0]--;
524         PrintException(&e, "ThreadSocketHandler()");
525     } catch (...) {
526         vnThreadsRunning[0]--;
527         throw; // support pthread_cancel()
528     }
529     printf("ThreadSocketHandler exiting\n");
530 }
531
532 void ThreadSocketHandler2(void* parg)
533 {
534     printf("ThreadSocketHandler started\n");
535     list<CNode*> vNodesDisconnected;
536     int nPrevNodeCount = 0;
537
538     loop
539     {
540         //
541         // Disconnect nodes
542         //
543         CRITICAL_BLOCK(cs_vNodes)
544         {
545             // Disconnect unused nodes
546             vector<CNode*> vNodesCopy = vNodes;
547             foreach(CNode* pnode, vNodesCopy)
548             {
549                 if (pnode->fDisconnect ||
550                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
551                 {
552                     // remove from vNodes
553                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
554
555                     // close socket and cleanup
556                     pnode->CloseSocketDisconnect();
557                     pnode->Cleanup();
558
559                     // hold in disconnected pool until all refs are released
560                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
561                     if (pnode->fNetworkNode || pnode->fInbound)
562                         pnode->Release();
563                     vNodesDisconnected.push_back(pnode);
564                 }
565             }
566
567             // Delete disconnected nodes
568             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
569             foreach(CNode* pnode, vNodesDisconnectedCopy)
570             {
571                 // wait until threads are done using it
572                 if (pnode->GetRefCount() <= 0)
573                 {
574                     bool fDelete = false;
575                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
576                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
577                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
578                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
579                         fDelete = true;
580                     if (fDelete)
581                     {
582                         vNodesDisconnected.remove(pnode);
583                         delete pnode;
584                     }
585                 }
586             }
587         }
588         if (vNodes.size() != nPrevNodeCount)
589         {
590             nPrevNodeCount = vNodes.size();
591             MainFrameRepaint();
592         }
593
594
595         //
596         // Find which sockets have data to receive
597         //
598         struct timeval timeout;
599         timeout.tv_sec  = 0;
600         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
601
602         fd_set fdsetRecv;
603         fd_set fdsetSend;
604         fd_set fdsetError;
605         FD_ZERO(&fdsetRecv);
606         FD_ZERO(&fdsetSend);
607         FD_ZERO(&fdsetError);
608         SOCKET hSocketMax = 0;
609         FD_SET(hListenSocket, &fdsetRecv);
610         hSocketMax = max(hSocketMax, hListenSocket);
611         CRITICAL_BLOCK(cs_vNodes)
612         {
613             foreach(CNode* pnode, vNodes)
614             {
615                 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
616                     continue;
617                 FD_SET(pnode->hSocket, &fdsetRecv);
618                 FD_SET(pnode->hSocket, &fdsetError);
619                 hSocketMax = max(hSocketMax, pnode->hSocket);
620                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
621                     if (!pnode->vSend.empty())
622                         FD_SET(pnode->hSocket, &fdsetSend);
623             }
624         }
625
626         vnThreadsRunning[0]--;
627         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
628         vnThreadsRunning[0]++;
629         if (fShutdown)
630             return;
631         if (nSelect == SOCKET_ERROR)
632         {
633             int nErr = WSAGetLastError();
634             printf("socket select error %d\n", nErr);
635             for (int i = 0; i <= hSocketMax; i++)
636                 FD_SET(i, &fdsetRecv);
637             FD_ZERO(&fdsetSend);
638             FD_ZERO(&fdsetError);
639             Sleep(timeout.tv_usec/1000);
640         }
641
642
643         //
644         // Accept new connections
645         //
646         if (FD_ISSET(hListenSocket, &fdsetRecv))
647         {
648             struct sockaddr_in sockaddr;
649             socklen_t len = sizeof(sockaddr);
650             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
651             CAddress addr(sockaddr);
652             if (hSocket == INVALID_SOCKET)
653             {
654                 if (WSAGetLastError() != WSAEWOULDBLOCK)
655                     printf("socket error accept failed: %d\n", WSAGetLastError());
656             }
657             else if (mapArgs.count("-maxconnections") && (int)vNodes.size() >= atoi(mapArgs["-maxconnections"]) - MAX_OUTBOUND_CONNECTIONS)
658             {
659                 closesocket(hSocket);
660             }
661             else
662             {
663                 printf("accepted connection %s\n", addr.ToStringLog().c_str());
664                 CNode* pnode = new CNode(hSocket, addr, true);
665                 pnode->AddRef();
666                 CRITICAL_BLOCK(cs_vNodes)
667                     vNodes.push_back(pnode);
668             }
669         }
670
671
672         //
673         // Service each socket
674         //
675         vector<CNode*> vNodesCopy;
676         CRITICAL_BLOCK(cs_vNodes)
677         {
678             vNodesCopy = vNodes;
679             foreach(CNode* pnode, vNodesCopy)
680                 pnode->AddRef();
681         }
682         foreach(CNode* pnode, vNodesCopy)
683         {
684             if (fShutdown)
685                 return;
686
687             //
688             // Receive
689             //
690             if (pnode->hSocket == INVALID_SOCKET)
691                 continue;
692             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
693             {
694                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
695                 {
696                     CDataStream& vRecv = pnode->vRecv;
697                     unsigned int nPos = vRecv.size();
698
699                     // typical socket buffer is 8K-64K
700                     char pchBuf[0x10000];
701                     int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
702                     if (nBytes > 0)
703                     {
704                         vRecv.resize(nPos + nBytes);
705                         memcpy(&vRecv[nPos], pchBuf, nBytes);
706                         pnode->nLastRecv = GetTime();
707                     }
708                     else if (nBytes == 0)
709                     {
710                         // socket closed gracefully
711                         if (!pnode->fDisconnect)
712                             printf("socket closed\n");
713                         pnode->CloseSocketDisconnect();
714                     }
715                     else if (nBytes < 0)
716                     {
717                         // error
718                         int nErr = WSAGetLastError();
719                         if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
720                         {
721                             if (!pnode->fDisconnect)
722                                 printf("socket recv error %d\n", nErr);
723                             pnode->CloseSocketDisconnect();
724                         }
725                     }
726                 }
727             }
728
729             //
730             // Send
731             //
732             if (pnode->hSocket == INVALID_SOCKET)
733                 continue;
734             if (FD_ISSET(pnode->hSocket, &fdsetSend))
735             {
736                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
737                 {
738                     CDataStream& vSend = pnode->vSend;
739                     if (!vSend.empty())
740                     {
741                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
742                         if (nBytes > 0)
743                         {
744                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
745                             pnode->nLastSend = GetTime();
746                         }
747                         else if (nBytes < 0)
748                         {
749                             // error
750                             int nErr = WSAGetLastError();
751                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
752                             {
753                                 printf("socket send error %d\n", nErr);
754                                 pnode->CloseSocketDisconnect();
755                             }
756                         }
757                     }
758                 }
759             }
760
761             //
762             // Inactivity checking
763             //
764             if (pnode->vSend.empty())
765                 pnode->nLastSendEmpty = GetTime();
766             if (GetTime() - pnode->nTimeConnected > 60)
767             {
768                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
769                 {
770                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
771                     pnode->fDisconnect = true;
772                 }
773                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
774                 {
775                     printf("socket not sending\n");
776                     pnode->fDisconnect = true;
777                 }
778                 else if (GetTime() - pnode->nLastRecv > 90*60)
779                 {
780                     printf("socket inactivity timeout\n");
781                     pnode->fDisconnect = true;
782                 }
783             }
784         }
785         CRITICAL_BLOCK(cs_vNodes)
786         {
787             foreach(CNode* pnode, vNodesCopy)
788                 pnode->Release();
789         }
790
791         Sleep(10);
792     }
793 }
794
795
796
797
798
799
800
801
802
803
804
805
806
807 unsigned int pnSeed[] =
808 {
809     // 2010/06
810     0x35218252, 0x9c9c9618, 0xda6bacad, 0xb9aca862, 0x97c235c6,
811     0x146f9562, 0xb67b9e4b, 0x87cf4bc0, 0xb83945d0, 0x984333ad,
812     0xbbeec555, 0x6f0eb440, 0xe0005318, 0x7797e460, 0xddc60fcc,
813     0xb3bbd24a, 0x1ac85746, 0x641846a6, 0x85ee1155, 0xbb2e7a4c,
814     0x9cb8514b, 0xfc342648, 0x62958fae, 0xd0a8c87a, 0xa800795b,
815     0xda8c814e, 0x256a0c80, 0x3f23ec63, 0xd565df43, 0x997d9044,
816     0xaa121448, 0xbed8688e, 0x59d09a5e, 0xb2931243, 0x3730ba18,
817     0xdd3462d0, 0x4e4d1448, 0x171df645, 0x84ee1155,
818     0x248ac445, 0x0e634444, 0x0ded1b63, 0x30c01e60,
819     0xa2b9a094, 0x29e4fd43, 0x9ce61b4c, 0xdae09744,
820
821     // 2010/08
822     0x5ae6bf43, 0x460be257, 0x7245c0cf, 0x4e0f028d, 0x26501760, 0x38643255, 0x67094f4f, 0x480449b8,
823     0x16545143, 0x1f082e5a, 0xaa428018, 0xe411e793, 0x14c1f862, 0x2726105b, 0x9b33ea50, 0xeeef86ca,
824     0xe3210d44, 0x0dca8b63, 0x3f9dfb18, 0x860340ad, 0xf33ba17a, 0x9018375c, 0x1de4e353, 0x0fa52dcb,
825     0x89c4555b, 0x109cf37b, 0x28c55b40, 0x04c801ae, 0x275c1e80, 0x6f7f745d, 0x7a2a5653, 0xa28e26d8,
826     0xa4e65db2, 0x99a06580, 0xf253ba44, 0x82cf6ab8, 0x859c2e8e, 0xf71a815d, 0xc18f1454, 0x71c8a943,
827     0x90d24e18, 0x311789b2, 0x74aba645, 0xde0bbfc3, 0xad724fad, 0xbf1ae15e, 0xbaa6fb54, 0x06e4d145,
828     0x51528645, 0x72120cd4, 0xd4cfd145, 0x0a7afed8, 0x9b9a5fad, 0x9e9ff45e, 0x10128355, 0xd44e8646,
829     0x04a07b47, 0x5fc9d547, 0xe0491e45, 0xbac21b41, 0x7aa31bae, 0x10483c5f, 0x94a23055, 0x73d9dc47,
830     0x1a99c247, 0x822fe847, 0x7e57ba48, 0xb19ea843, 0xa60621b2, 0x778cf163, 0x125c6556, 0xf94ba44f,
831     0xa61a0948, 0x6c839e4b, 0x29af5348, 0x68d84845, 0x752b95c3, 0xcf0d4663, 0x08e11e56, 0x75109550,
832     0x5f24b94c, 0x42426d4d, 0xfbbc0a4c, 0x70a9a246, 0xda7837cb, 0xae2a986d, 0xe283c358, 0x0c7ca954,
833     0x8e9bde59, 0x61521760, 0x6884444c, 0xa194e548, 0x9b8809cc, 0x16e96a8f, 0x956ff859, 0xfad5e555,
834     0x0ea70c80, 0x5b4ce26d, 0x7984444c, 0x1080d24a, 0x22a686cf, 0x6bf8c2ad, 0xb0f7485f, 0x06b66e56,
835     0x668373bc, 0x75506279, 0x3868694e, 0x12a5954b, 0x3a8b62d1, 0xb74fcbad, 0xa7dc3360, 0xc070b359,
836     0xa2b87242, 0xc45cab7c, 0x69882050, 0x14a5464b, 0x386acad5, 0x80b85db2, 0x1f78a062, 0xc608c55b,
837     0x4257d543, 0x7636ad80, 0x4432d655, 0xb2114d4b, 0x32639bd9, 0xadd75db2, 0x9be5a362, 0x6831bc5e,
838     0xf7f77046, 0x8f35ba81, 0x09bb4e59, 0xd0fb6b4e, 0xc5daa445, 0x9c611618, 0x355dcc62, 0xf2cf435e,
839     0x31e72c46, 0xdd8a43ad, 0x171f9c5b, 0xb4c2e355, 0xbe8af945, 0x613d3942, 0xe6f9e863, 0x7a3d855f,
840     0xa66adc47, 0x261089b2, 0x5a27105b, 0x6c28105b, 0xdd247946, 0xe6c3a445, 0x43a1ec63, 0x99b4dd5f,
841     0xb6834347, 0x5e9649bc, 0xf9dd545d, 0x6ae4c15b, 0xa5318a47, 0x7984ec47, 0x93a73b63, 0x0c60195f,
842     0xa5c85e4b, 0xa0a36dc2, 0x0739a95e, 0x3d44c15b, 0xfb940f4b, 0xd67c9148, 0x614f9876, 0x0a241c5f,
843     0xad9da74c, 0x4459abc8, 0x12e71b5f, 0x1c534a5d, 0x8ff5fc50, 0x2ca8864b, 0xd894fd80, 0x82ab3160,
844     0x390d804e, 0x2cf310cc, 0x680dad80, 0x691be15e, 0x5a8f4652, 0xaad0784d, 0x0d2431ad,
845 };
846
847
848
849 void ThreadOpenConnections(void* parg)
850 {
851     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
852     try
853     {
854         vnThreadsRunning[1]++;
855         ThreadOpenConnections2(parg);
856         vnThreadsRunning[1]--;
857     }
858     catch (std::exception& e) {
859         vnThreadsRunning[1]--;
860         PrintException(&e, "ThreadOpenConnections()");
861     } catch (...) {
862         vnThreadsRunning[1]--;
863         PrintException(NULL, "ThreadOpenConnections()");
864     }
865     printf("ThreadOpenConnections exiting\n");
866 }
867
868 void ThreadOpenConnections2(void* parg)
869 {
870     printf("ThreadOpenConnections started\n");
871
872     // Connect to specific addresses
873     if (mapArgs.count("-connect"))
874     {
875         for (int64 nLoop = 0;; nLoop++)
876         {
877             foreach(string strAddr, mapMultiArgs["-connect"])
878             {
879                 CAddress addr(strAddr, NODE_NETWORK);
880                 if (addr.IsValid())
881                     OpenNetworkConnection(addr);
882                 for (int i = 0; i < 10 && i < nLoop; i++)
883                 {
884                     Sleep(500);
885                     if (fShutdown)
886                         return;
887                 }
888             }
889         }
890     }
891
892     // Connect to manually added nodes first
893     if (mapArgs.count("-addnode"))
894     {
895         foreach(string strAddr, mapMultiArgs["-addnode"])
896         {
897             CAddress addr(strAddr, NODE_NETWORK);
898             if (addr.IsValid())
899             {
900                 OpenNetworkConnection(addr);
901                 Sleep(500);
902                 if (fShutdown)
903                     return;
904             }
905         }
906     }
907
908     // Initiate network connections
909     int64 nStart = GetTime();
910     loop
911     {
912         // Limit outbound connections
913         vnThreadsRunning[1]--;
914         Sleep(500);
915         loop
916         {
917             int nOutbound = 0;
918             CRITICAL_BLOCK(cs_vNodes)
919                 foreach(CNode* pnode, vNodes)
920                     if (!pnode->fInbound)
921                         nOutbound++;
922             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
923             if (mapArgs.count("-maxconnections"))
924                 nMaxOutboundConnections = min(nMaxOutboundConnections, atoi(mapArgs["-maxconnections"]));
925             if (nOutbound < nMaxOutboundConnections)
926                 break;
927             Sleep(2000);
928             if (fShutdown)
929                 return;
930         }
931         vnThreadsRunning[1]++;
932         if (fShutdown)
933             return;
934
935         CRITICAL_BLOCK(cs_mapAddresses)
936         {
937             // Add seed nodes if IRC isn't working
938             static bool fSeedUsed;
939             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
940             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
941             {
942                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
943                 {
944                     // It'll only connect to one or two seed nodes because once it connects,
945                     // it'll get a pile of addresses with newer timestamps.
946                     CAddress addr;
947                     addr.ip = pnSeed[i];
948                     addr.nTime = 0;
949                     AddAddress(addr);
950                 }
951                 fSeedUsed = true;
952             }
953
954             if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
955             {
956                 // Disconnect seed nodes
957                 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
958                 static int64 nSeedDisconnected;
959                 if (nSeedDisconnected == 0)
960                 {
961                     nSeedDisconnected = GetTime();
962                     CRITICAL_BLOCK(cs_vNodes)
963                         foreach(CNode* pnode, vNodes)
964                             if (setSeed.count(pnode->addr.ip))
965                                 pnode->fDisconnect = true;
966                 }
967
968                 // Keep setting timestamps to 0 so they won't reconnect
969                 if (GetTime() - nSeedDisconnected < 60 * 60)
970                 {
971                     foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
972                     {
973                         if (setSeed.count(item.second.ip))
974                         {
975                             item.second.nTime = 0;
976                             CAddrDB().WriteAddress(item.second);
977                         }
978                     }
979                 }
980             }
981         }
982
983
984         //
985         // Choose an address to connect to based on most recently seen
986         //
987         CAddress addrConnect;
988         int64 nBest = INT64_MIN;
989
990         // Only connect to one address per a.b.?.? range.
991         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
992         set<unsigned int> setConnected;
993         CRITICAL_BLOCK(cs_vNodes)
994             foreach(CNode* pnode, vNodes)
995                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
996
997         CRITICAL_BLOCK(cs_mapAddresses)
998         {
999             foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1000             {
1001                 const CAddress& addr = item.second;
1002                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1003                     continue;
1004                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1005                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1006
1007                 // Randomize the order in a deterministic way, putting the standard port first
1008                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1009                 if (addr.port != DEFAULT_PORT)
1010                     nRandomizer += 2 * 60 * 60;
1011
1012                 // Last seen  Base retry frequency
1013                 //   <1 hour   10 min
1014                 //    1 hour    1 hour
1015                 //    4 hours   2 hours
1016                 //   24 hours   5 hours
1017                 //   48 hours   7 hours
1018                 //    7 days   13 hours
1019                 //   30 days   27 hours
1020                 //   90 days   46 hours
1021                 //  365 days   93 hours
1022                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1023
1024                 // Fast reconnect for one hour after last seen
1025                 if (nSinceLastSeen < 60 * 60)
1026                     nDelay = 10 * 60;
1027
1028                 // Limit retry frequency
1029                 if (nSinceLastTry < nDelay)
1030                     continue;
1031
1032                 // If we have IRC, we'll be notified when they first come online,
1033                 // and again every 24 hours by the refresh broadcast.
1034                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1035                     continue;
1036
1037                 // Only try the old stuff if we don't have enough connections
1038                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1039                     continue;
1040
1041                 // If multiple addresses are ready, prioritize by time since
1042                 // last seen and time since last tried.
1043                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1044                 if (nScore > nBest)
1045                 {
1046                     nBest = nScore;
1047                     addrConnect = addr;
1048                 }
1049             }
1050         }
1051
1052         if (addrConnect.IsValid())
1053             OpenNetworkConnection(addrConnect);
1054     }
1055 }
1056
1057 bool OpenNetworkConnection(const CAddress& addrConnect)
1058 {
1059     //
1060     // Initiate outbound network connection
1061     //
1062     if (fShutdown)
1063         return false;
1064     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1065         return false;
1066
1067     vnThreadsRunning[1]--;
1068     CNode* pnode = ConnectNode(addrConnect);
1069     vnThreadsRunning[1]++;
1070     if (fShutdown)
1071         return false;
1072     if (!pnode)
1073         return false;
1074     pnode->fNetworkNode = true;
1075
1076     if (addrLocalHost.IsRoutable() && !fUseProxy)
1077     {
1078         // Advertise our address
1079         vector<CAddress> vAddr;
1080         vAddr.push_back(addrLocalHost);
1081         pnode->PushMessage("addr", vAddr);
1082     }
1083
1084     // Get as many addresses as we can
1085     pnode->PushMessage("getaddr");
1086     pnode->fGetAddr = true; // don't relay the results of the getaddr
1087
1088     ////// should the one on the receiving end do this too?
1089     // Subscribe our local subscription list
1090     const unsigned int nHops = 0;
1091     for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
1092         if (pnodeLocalHost->vfSubscribe[nChannel])
1093             pnode->PushMessage("subscribe", nChannel, nHops);
1094
1095     return true;
1096 }
1097
1098
1099
1100
1101
1102
1103
1104
1105 void ThreadMessageHandler(void* parg)
1106 {
1107     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1108     try
1109     {
1110         vnThreadsRunning[2]++;
1111         ThreadMessageHandler2(parg);
1112         vnThreadsRunning[2]--;
1113     }
1114     catch (std::exception& e) {
1115         vnThreadsRunning[2]--;
1116         PrintException(&e, "ThreadMessageHandler()");
1117     } catch (...) {
1118         vnThreadsRunning[2]--;
1119         PrintException(NULL, "ThreadMessageHandler()");
1120     }
1121     printf("ThreadMessageHandler exiting\n");
1122 }
1123
1124 void ThreadMessageHandler2(void* parg)
1125 {
1126     printf("ThreadMessageHandler started\n");
1127     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1128     while (!fShutdown)
1129     {
1130         vector<CNode*> vNodesCopy;
1131         CRITICAL_BLOCK(cs_vNodes)
1132         {
1133             vNodesCopy = vNodes;
1134             foreach(CNode* pnode, vNodesCopy)
1135                 pnode->AddRef();
1136         }
1137
1138         // Poll the connected nodes for messages
1139         CNode* pnodeTrickle = NULL;
1140         if (!vNodesCopy.empty())
1141             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1142         foreach(CNode* pnode, vNodesCopy)
1143         {
1144             // Receive messages
1145             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1146                 ProcessMessages(pnode);
1147             if (fShutdown)
1148                 return;
1149
1150             // Send messages
1151             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1152                 SendMessages(pnode, pnode == pnodeTrickle);
1153             if (fShutdown)
1154                 return;
1155         }
1156
1157         CRITICAL_BLOCK(cs_vNodes)
1158         {
1159             foreach(CNode* pnode, vNodesCopy)
1160                 pnode->Release();
1161         }
1162
1163         // Wait and allow messages to bunch up.
1164         // Reduce vnThreadsRunning so StopNode has permission to exit while
1165         // we're sleeping, but we must always check fShutdown after doing this.
1166         vnThreadsRunning[2]--;
1167         Sleep(100);
1168         if (fRequestShutdown)
1169             Shutdown(NULL);
1170         vnThreadsRunning[2]++;
1171         if (fShutdown)
1172             return;
1173     }
1174 }
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184 bool BindListenPort(string& strError)
1185 {
1186     strError = "";
1187     int nOne = 1;
1188
1189 #ifdef __WXMSW__
1190     // Initialize Windows Sockets
1191     WSADATA wsadata;
1192     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1193     if (ret != NO_ERROR)
1194     {
1195         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1196         printf("%s\n", strError.c_str());
1197         return false;
1198     }
1199 #endif
1200
1201     // Create socket for listening for incoming connections
1202     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1203     if (hListenSocket == INVALID_SOCKET)
1204     {
1205         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1206         printf("%s\n", strError.c_str());
1207         return false;
1208     }
1209
1210 #ifdef BSD
1211     // Different way of disabling SIGPIPE on BSD
1212     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1213 #endif
1214
1215 #ifndef __WXMSW__
1216     // Allow binding if the port is still in TIME_WAIT state after
1217     // the program was closed and restarted.  Not an issue on windows.
1218     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1219 #endif
1220
1221 #ifdef __WXMSW__
1222     // Set to nonblocking, incoming connections will also inherit this
1223     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1224 #else
1225     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1226 #endif
1227     {
1228         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1229         printf("%s\n", strError.c_str());
1230         return false;
1231     }
1232
1233     // The sockaddr_in structure specifies the address family,
1234     // IP address, and port for the socket that is being bound
1235     struct sockaddr_in sockaddr;
1236     memset(&sockaddr, 0, sizeof(sockaddr));
1237     sockaddr.sin_family = AF_INET;
1238     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1239     sockaddr.sin_port = DEFAULT_PORT;
1240     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1241     {
1242         int nErr = WSAGetLastError();
1243         if (nErr == WSAEADDRINUSE)
1244             strError = strprintf("Unable to bind to port %d on this computer.  Bitcoin is probably already running.", ntohs(sockaddr.sin_port));
1245         else
1246             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1247         printf("%s\n", strError.c_str());
1248         return false;
1249     }
1250     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1251
1252     // Listen for incoming connections
1253     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1254     {
1255         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1256         printf("%s\n", strError.c_str());
1257         return false;
1258     }
1259
1260     return true;
1261 }
1262
1263 void StartNode(void* parg)
1264 {
1265     if (pnodeLocalHost == NULL)
1266         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
1267
1268 #ifdef __WXMSW__
1269     // Get local host ip
1270     char pszHostName[1000] = "";
1271     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1272     {
1273         struct hostent* phostent = gethostbyname(pszHostName);
1274         if (phostent)
1275         {
1276             // Take the first IP that isn't loopback 127.x.x.x
1277             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1278                 printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
1279             for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1280             {
1281                 CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices);
1282                 if (addr.IsValid() && addr.GetByte(3) != 127)
1283                 {
1284                     addrLocalHost = addr;
1285                     break;
1286                 }
1287             }
1288         }
1289     }
1290 #else
1291     // Get local host ip
1292     struct ifaddrs* myaddrs;
1293     if (getifaddrs(&myaddrs) == 0)
1294     {
1295         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1296         {
1297             if (ifa->ifa_addr == NULL) continue;
1298             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1299             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1300             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1301             char pszIP[100];
1302             if (ifa->ifa_addr->sa_family == AF_INET)
1303             {
1304                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1305                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1306                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1307
1308                 // Take the first IP that isn't loopback 127.x.x.x
1309                 CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices);
1310                 if (addr.IsValid() && addr.GetByte(3) != 127)
1311                 {
1312                     addrLocalHost = addr;
1313                     break;
1314                 }
1315             }
1316             else if (ifa->ifa_addr->sa_family == AF_INET6)
1317             {
1318                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1319                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1320                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1321             }
1322         }
1323         freeifaddrs(myaddrs);
1324     }
1325 #endif
1326     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1327
1328     // Get our external IP address for incoming connections
1329     if (fUseProxy)
1330     {
1331         // Proxies can't take incoming connections
1332         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1333         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1334     }
1335     else
1336     {
1337         if (addrIncoming.IsValid())
1338             addrLocalHost.ip = addrIncoming.ip;
1339
1340         if (GetMyExternalIP(addrLocalHost.ip))
1341         {
1342             addrIncoming = addrLocalHost;
1343             CWalletDB().WriteSetting("addrIncoming", addrIncoming);
1344             printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1345         }
1346     }
1347
1348     //
1349     // Start threads
1350     //
1351
1352     // Get addresses from IRC and advertise ours
1353     if (!CreateThread(ThreadIRCSeed, NULL))
1354         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1355
1356     // Send and receive from sockets, accept connections
1357     pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1358
1359     // Initiate outbound connections
1360     if (!CreateThread(ThreadOpenConnections, NULL))
1361         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1362
1363     // Process messages
1364     if (!CreateThread(ThreadMessageHandler, NULL))
1365         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1366
1367     // Generate coins in the background
1368     GenerateBitcoins(fGenerateBitcoins);
1369 }
1370
1371 bool StopNode()
1372 {
1373     printf("StopNode()\n");
1374     fShutdown = true;
1375     nTransactionsUpdated++;
1376     int64 nStart = GetTime();
1377     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0)
1378     {
1379         if (GetTime() - nStart > 20)
1380             break;
1381         Sleep(20);
1382     }
1383     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1384     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1385     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1386     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1387     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1388     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1389         Sleep(20);
1390     Sleep(50);
1391
1392     return true;
1393 }
1394
1395 class CNetCleanup
1396 {
1397 public:
1398     CNetCleanup()
1399     {
1400     }
1401     ~CNetCleanup()
1402     {
1403         // Close sockets
1404         foreach(CNode* pnode, vNodes)
1405             if (pnode->hSocket != INVALID_SOCKET)
1406                 closesocket(pnode->hSocket);
1407         if (hListenSocket != INVALID_SOCKET)
1408             if (closesocket(hListenSocket) == SOCKET_ERROR)
1409                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1410
1411 #ifdef __WXMSW__
1412         // Shutdown Windows Sockets
1413         WSACleanup();
1414 #endif
1415     }
1416 }
1417 instance_of_cnetcleanup;