Dump addresses every 600s
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "irc.h"
7 #include "db.h"
8 #include "net.h"
9 #include "init.h"
10 #include "strlcpy.h"
11 #include "addrman.h"
12 #include "ui_interface.h"
13
14 #ifdef WIN32
15 #include <string.h>
16 #endif
17
18 #ifdef USE_UPNP
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
23 #endif
24
25 using namespace std;
26 using namespace boost;
27
28 static const int MAX_OUTBOUND_CONNECTIONS = 16;
29
30 void ThreadMessageHandler2(void* parg);
31 void ThreadSocketHandler2(void* parg);
32 void ThreadOpenConnections2(void* parg);
33 void ThreadOpenAddedConnections2(void* parg);
34 #ifdef USE_UPNP
35 void ThreadMapPort2(void* parg);
36 #endif
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
39
40
41 struct LocalServiceInfo {
42     int nScore;
43     int nPort;
44 };
45
46 //
47 // Global state variables
48 //
49 bool fClient = false;
50 bool fDiscover = true;
51 bool fUseUPnP = false;
52 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
53 static CCriticalSection cs_mapLocalHost;
54 static map<CNetAddr, LocalServiceInfo> mapLocalHost;
55 static bool vfReachable[NET_MAX] = {};
56 static bool vfLimited[NET_MAX] = {};
57 static CNode* pnodeLocalHost = NULL;
58 CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices);
59 uint64 nLocalHostNonce = 0;
60 array<int, THREAD_MAX> vnThreadsRunning;
61 static std::vector<SOCKET> vhListenSocket;
62 CAddrMan addrman;
63
64 vector<CNode*> vNodes;
65 CCriticalSection cs_vNodes;
66 map<CInv, CDataStream> mapRelay;
67 deque<pair<int64, CInv> > vRelayExpiration;
68 CCriticalSection cs_mapRelay;
69 map<CInv, int64> mapAlreadyAskedFor;
70
71 static deque<string> vOneShots;
72 CCriticalSection cs_vOneShots;
73
74 set<CNetAddr> setservAddNodeAddresses;
75 CCriticalSection cs_setservAddNodeAddresses;
76
77 static CSemaphore *semOutbound = NULL;
78
79 void AddOneShot(string strDest)
80 {
81     LOCK(cs_vOneShots);
82     vOneShots.push_back(strDest);
83 }
84
85 unsigned short GetListenPort()
86 {
87     return (unsigned short)(GetArg("-port", GetDefaultPort()));
88 }
89
90 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
91 {
92     // Filter out duplicate requests
93     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
94         return;
95     pindexLastGetBlocksBegin = pindexBegin;
96     hashLastGetBlocksEnd = hashEnd;
97
98     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
99 }
100
101 // find 'best' local address for a particular peer
102 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
103 {
104     if (fNoListen)
105         return false;
106
107     int nBestScore = -1;
108     int nBestReachability = -1;
109     {
110         LOCK(cs_mapLocalHost);
111         for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
112         {
113             int nScore = (*it).second.nScore;
114             int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
115             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
116             {
117                 addr = CService((*it).first, (*it).second.nPort);
118                 nBestReachability = nReachability;
119                 nBestScore = nScore;
120             }
121         }
122     }
123     return nBestScore >= 0;
124 }
125
126 // get best local address for a particular peer as a CAddress
127 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
128 {
129     CAddress ret(CService("0.0.0.0",0),0);
130     CService addr;
131     if (GetLocal(addr, paddrPeer))
132     {
133         ret = CAddress(addr);
134         ret.nServices = nLocalServices;
135         ret.nTime = GetAdjustedTime();
136     }
137     return ret;
138 }
139
140 bool RecvLine(SOCKET hSocket, string& strLine)
141 {
142     strLine = "";
143     loop
144     {
145         char c;
146         int nBytes = recv(hSocket, &c, 1, 0);
147         if (nBytes > 0)
148         {
149             if (c == '\n')
150                 continue;
151             if (c == '\r')
152                 return true;
153             strLine += c;
154             if (strLine.size() >= 9000)
155                 return true;
156         }
157         else if (nBytes <= 0)
158         {
159             if (fShutdown)
160                 return false;
161             if (nBytes < 0)
162             {
163                 int nErr = WSAGetLastError();
164                 if (nErr == WSAEMSGSIZE)
165                     continue;
166                 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
167                 {
168                     Sleep(10);
169                     continue;
170                 }
171             }
172             if (!strLine.empty())
173                 return true;
174             if (nBytes == 0)
175             {
176                 // socket closed
177                 printf("socket closed\n");
178                 return false;
179             }
180             else
181             {
182                 // socket error
183                 int nErr = WSAGetLastError();
184                 printf("recv failed: %d\n", nErr);
185                 return false;
186             }
187         }
188     }
189 }
190
191 // used when scores of local addresses may have changed
192 // pushes better local address to peers
193 void static AdvertizeLocal()
194 {
195     LOCK(cs_vNodes);
196     BOOST_FOREACH(CNode* pnode, vNodes)
197     {
198         if (pnode->fSuccessfullyConnected)
199         {
200             CAddress addrLocal = GetLocalAddress(&pnode->addr);
201             if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
202             {
203                 pnode->PushAddress(addrLocal);
204                 pnode->addrLocal = addrLocal;
205             }
206         }
207     }
208 }
209
210 void SetReachable(enum Network net, bool fFlag)
211 {
212     LOCK(cs_mapLocalHost);
213     vfReachable[net] = fFlag;
214     if (net == NET_IPV6 && fFlag)
215         vfReachable[NET_IPV4] = true;
216 }
217
218 // learn a new local address
219 bool AddLocal(const CService& addr, int nScore)
220 {
221     if (!addr.IsRoutable())
222         return false;
223
224     if (!fDiscover && nScore < LOCAL_MANUAL)
225         return false;
226
227     if (IsLimited(addr))
228         return false;
229
230     printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
231
232     {
233         LOCK(cs_mapLocalHost);
234         bool fAlready = mapLocalHost.count(addr) > 0;
235         LocalServiceInfo &info = mapLocalHost[addr];
236         if (!fAlready || nScore >= info.nScore) {
237             info.nScore = nScore + (fAlready ? 1 : 0);
238             info.nPort = addr.GetPort();
239         }
240         SetReachable(addr.GetNetwork());
241     }
242
243     AdvertizeLocal();
244
245     return true;
246 }
247
248 bool AddLocal(const CNetAddr &addr, int nScore)
249 {
250     return AddLocal(CService(addr, GetListenPort()), nScore);
251 }
252
253 /** Make a particular network entirely off-limits (no automatic connects to it) */
254 void SetLimited(enum Network net, bool fLimited)
255 {
256     if (net == NET_UNROUTABLE)
257         return;
258     LOCK(cs_mapLocalHost);
259     vfLimited[net] = fLimited;
260 }
261
262 bool IsLimited(enum Network net)
263 {
264     LOCK(cs_mapLocalHost);
265     return vfLimited[net];
266 }
267
268 bool IsLimited(const CNetAddr &addr)
269 {
270     return IsLimited(addr.GetNetwork());
271 }
272
273 /** vote for a local address */
274 bool SeenLocal(const CService& addr)
275 {
276     {
277         LOCK(cs_mapLocalHost);
278         if (mapLocalHost.count(addr) == 0)
279             return false;
280         mapLocalHost[addr].nScore++;
281     }
282
283     AdvertizeLocal();
284
285     return true;
286 }
287
288 /** check whether a given address is potentially local */
289 bool IsLocal(const CService& addr)
290 {
291     LOCK(cs_mapLocalHost);
292     return mapLocalHost.count(addr) > 0;
293 }
294
295 /** check whether a given address is in a network we can probably connect to */
296 bool IsReachable(const CNetAddr& addr)
297 {
298     LOCK(cs_mapLocalHost);
299     enum Network net = addr.GetNetwork();
300     return vfReachable[net] && !vfLimited[net];
301 }
302
303 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
304 {
305     SOCKET hSocket;
306     if (!ConnectSocket(addrConnect, hSocket))
307         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
308
309     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
310
311     string strLine;
312     while (RecvLine(hSocket, strLine))
313     {
314         if (strLine.empty()) // HTTP response is separated from headers by blank line
315         {
316             loop
317             {
318                 if (!RecvLine(hSocket, strLine))
319                 {
320                     closesocket(hSocket);
321                     return false;
322                 }
323                 if (pszKeyword == NULL)
324                     break;
325                 if (strLine.find(pszKeyword) != string::npos)
326                 {
327                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
328                     break;
329                 }
330             }
331             closesocket(hSocket);
332             if (strLine.find("<") != string::npos)
333                 strLine = strLine.substr(0, strLine.find("<"));
334             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
335             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
336                 strLine.resize(strLine.size()-1);
337             CService addr(strLine,0,true);
338             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
339             if (!addr.IsValid() || !addr.IsRoutable())
340                 return false;
341             ipRet.SetIP(addr);
342             return true;
343         }
344     }
345     closesocket(hSocket);
346     return error("GetMyExternalIP() : connection closed");
347 }
348
349 // We now get our external IP from the IRC server first and only use this as a backup
350 bool GetMyExternalIP(CNetAddr& ipRet)
351 {
352     CService addrConnect;
353     const char* pszGet;
354     const char* pszKeyword;
355
356     for (int nLookup = 0; nLookup <= 1; nLookup++)
357     for (int nHost = 1; nHost <= 2; nHost++)
358     {
359         // We should be phasing out our use of sites like these.  If we need
360         // replacements, we should ask for volunteers to put this simple
361         // php file on their web server that prints the client IP:
362         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
363         if (nHost == 1)
364         {
365             addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
366
367             if (nLookup == 1)
368             {
369                 CService addrIP("checkip.dyndns.org", 80, true);
370                 if (addrIP.IsValid())
371                     addrConnect = addrIP;
372             }
373
374             pszGet = "GET / HTTP/1.1\r\n"
375                      "Host: checkip.dyndns.org\r\n"
376                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
377                      "Connection: close\r\n"
378                      "\r\n";
379
380             pszKeyword = "Address:";
381         }
382         else if (nHost == 2)
383         {
384             addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
385
386             if (nLookup == 1)
387             {
388                 CService addrIP("www.showmyip.com", 80, true);
389                 if (addrIP.IsValid())
390                     addrConnect = addrIP;
391             }
392
393             pszGet = "GET /simple/ HTTP/1.1\r\n"
394                      "Host: www.showmyip.com\r\n"
395                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
396                      "Connection: close\r\n"
397                      "\r\n";
398
399             pszKeyword = NULL; // Returns just IP address
400         }
401
402         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
403             return true;
404     }
405
406     return false;
407 }
408
409 void ThreadGetMyExternalIP(void* parg)
410 {
411     // Make this thread recognisable as the external IP detection thread
412     RenameThread("bitcoin-ext-ip");
413
414     CNetAddr addrLocalHost;
415     if (GetMyExternalIP(addrLocalHost))
416     {
417         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
418         AddLocal(addrLocalHost, LOCAL_HTTP);
419     }
420 }
421
422
423
424
425
426 void AddressCurrentlyConnected(const CService& addr)
427 {
428     addrman.Connected(addr);
429 }
430
431
432
433
434
435
436
437 CNode* FindNode(const CNetAddr& ip)
438 {
439     {
440         LOCK(cs_vNodes);
441         BOOST_FOREACH(CNode* pnode, vNodes)
442             if ((CNetAddr)pnode->addr == ip)
443                 return (pnode);
444     }
445     return NULL;
446 }
447
448 CNode* FindNode(std::string addrName)
449 {
450     LOCK(cs_vNodes);
451     BOOST_FOREACH(CNode* pnode, vNodes)
452         if (pnode->addrName == addrName)
453             return (pnode);
454     return NULL;
455 }
456
457 CNode* FindNode(const CService& addr)
458 {
459     {
460         LOCK(cs_vNodes);
461         BOOST_FOREACH(CNode* pnode, vNodes)
462             if ((CService)pnode->addr == addr)
463                 return (pnode);
464     }
465     return NULL;
466 }
467
468 CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout)
469 {
470     if (pszDest == NULL) {
471         if (IsLocal(addrConnect))
472             return NULL;
473
474         // Look for an existing connection
475         CNode* pnode = FindNode((CService)addrConnect);
476         if (pnode)
477         {
478             if (nTimeout != 0)
479                 pnode->AddRef(nTimeout);
480             else
481                 pnode->AddRef();
482             return pnode;
483         }
484     }
485
486
487     /// debug print
488     printf("trying connection %s lastseen=%.1fhrs\n",
489         pszDest ? pszDest : addrConnect.ToString().c_str(),
490         pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
491
492     // Connect
493     SOCKET hSocket;
494     if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
495     {
496         addrman.Attempt(addrConnect);
497
498         /// debug print
499         printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
500
501         // Set to non-blocking
502 #ifdef WIN32
503         u_long nOne = 1;
504         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
505             printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
506 #else
507         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
508             printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
509 #endif
510
511         // Add node
512         CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
513         if (nTimeout != 0)
514             pnode->AddRef(nTimeout);
515         else
516             pnode->AddRef();
517
518         {
519             LOCK(cs_vNodes);
520             vNodes.push_back(pnode);
521         }
522
523         pnode->nTimeConnected = GetTime();
524         return pnode;
525     }
526     else
527     {
528         return NULL;
529     }
530 }
531
532 void CNode::CloseSocketDisconnect()
533 {
534     fDisconnect = true;
535     if (hSocket != INVALID_SOCKET)
536     {
537         printf("disconnecting node %s\n", addrName.c_str());
538         closesocket(hSocket);
539         hSocket = INVALID_SOCKET;
540         vRecv.clear();
541     }
542 }
543
544 void CNode::Cleanup()
545 {
546 }
547
548
549 void CNode::PushVersion()
550 {
551     /// when NTP implemented, change to just nTime = GetAdjustedTime()
552     int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
553     CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
554     CAddress addrMe = GetLocalAddress(&addr);
555     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
556     printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
557     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
558                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
559 }
560
561
562
563
564
565 std::map<CNetAddr, int64> CNode::setBanned;
566 CCriticalSection CNode::cs_setBanned;
567
568 void CNode::ClearBanned()
569 {
570     setBanned.clear();
571 }
572
573 bool CNode::IsBanned(CNetAddr ip)
574 {
575     bool fResult = false;
576     {
577         LOCK(cs_setBanned);
578         std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
579         if (i != setBanned.end())
580         {
581             int64 t = (*i).second;
582             if (GetTime() < t)
583                 fResult = true;
584         }
585     }
586     return fResult;
587 }
588
589 bool CNode::Misbehaving(int howmuch)
590 {
591     if (addr.IsLocal())
592     {
593         printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
594         return false;
595     }
596
597     nMisbehavior += howmuch;
598     if (nMisbehavior >= GetArg("-banscore", 100))
599     {
600         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
601         printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
602         {
603             LOCK(cs_setBanned);
604             if (setBanned[addr] < banTime)
605                 setBanned[addr] = banTime;
606         }
607         CloseSocketDisconnect();
608         return true;
609     } else
610         printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
611     return false;
612 }
613
614 #undef X
615 #define X(name) stats.name = name
616 void CNode::copyStats(CNodeStats &stats)
617 {
618     X(nServices);
619     X(nLastSend);
620     X(nLastRecv);
621     X(nTimeConnected);
622     X(addrName);
623     X(nVersion);
624     X(strSubVer);
625     X(fInbound);
626     X(nReleaseTime);
627     X(nStartingHeight);
628     X(nMisbehavior);
629 }
630 #undef X
631
632
633
634
635
636
637
638
639
640
641 void ThreadSocketHandler(void* parg)
642 {
643     // Make this thread recognisable as the networking thread
644     RenameThread("bitcoin-net");
645
646     try
647     {
648         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
649         ThreadSocketHandler2(parg);
650         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
651     }
652     catch (std::exception& e) {
653         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
654         PrintException(&e, "ThreadSocketHandler()");
655     } catch (...) {
656         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
657         throw; // support pthread_cancel()
658     }
659     printf("ThreadSocketHandler exited\n");
660 }
661
662 void ThreadSocketHandler2(void* parg)
663 {
664     printf("ThreadSocketHandler started\n");
665     list<CNode*> vNodesDisconnected;
666     unsigned int nPrevNodeCount = 0;
667
668     loop
669     {
670         //
671         // Disconnect nodes
672         //
673         {
674             LOCK(cs_vNodes);
675             // Disconnect unused nodes
676             vector<CNode*> vNodesCopy = vNodes;
677             BOOST_FOREACH(CNode* pnode, vNodesCopy)
678             {
679                 if (pnode->fDisconnect ||
680                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
681                 {
682                     // remove from vNodes
683                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
684
685                     // release outbound grant (if any)
686                     pnode->grantOutbound.Release();
687
688                     // close socket and cleanup
689                     pnode->CloseSocketDisconnect();
690                     pnode->Cleanup();
691
692                     // hold in disconnected pool until all refs are released
693                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
694                     if (pnode->fNetworkNode || pnode->fInbound)
695                         pnode->Release();
696                     vNodesDisconnected.push_back(pnode);
697                 }
698             }
699
700             // Delete disconnected nodes
701             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
702             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
703             {
704                 // wait until threads are done using it
705                 if (pnode->GetRefCount() <= 0)
706                 {
707                     bool fDelete = false;
708                     {
709                         TRY_LOCK(pnode->cs_vSend, lockSend);
710                         if (lockSend)
711                         {
712                             TRY_LOCK(pnode->cs_vRecv, lockRecv);
713                             if (lockRecv)
714                             {
715                                 TRY_LOCK(pnode->cs_mapRequests, lockReq);
716                                 if (lockReq)
717                                 {
718                                     TRY_LOCK(pnode->cs_inventory, lockInv);
719                                     if (lockInv)
720                                         fDelete = true;
721                                 }
722                             }
723                         }
724                     }
725                     if (fDelete)
726                     {
727                         vNodesDisconnected.remove(pnode);
728                         delete pnode;
729                     }
730                 }
731             }
732         }
733         if (vNodes.size() != nPrevNodeCount)
734         {
735             nPrevNodeCount = vNodes.size();
736             uiInterface.NotifyNumConnectionsChanged(vNodes.size());
737         }
738
739
740         //
741         // Find which sockets have data to receive
742         //
743         struct timeval timeout;
744         timeout.tv_sec  = 0;
745         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
746
747         fd_set fdsetRecv;
748         fd_set fdsetSend;
749         fd_set fdsetError;
750         FD_ZERO(&fdsetRecv);
751         FD_ZERO(&fdsetSend);
752         FD_ZERO(&fdsetError);
753         SOCKET hSocketMax = 0;
754         bool have_fds = false;
755
756         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
757             FD_SET(hListenSocket, &fdsetRecv);
758             hSocketMax = max(hSocketMax, hListenSocket);
759             have_fds = true;
760         }
761         {
762             LOCK(cs_vNodes);
763             BOOST_FOREACH(CNode* pnode, vNodes)
764             {
765                 if (pnode->hSocket == INVALID_SOCKET)
766                     continue;
767                 FD_SET(pnode->hSocket, &fdsetRecv);
768                 FD_SET(pnode->hSocket, &fdsetError);
769                 hSocketMax = max(hSocketMax, pnode->hSocket);
770                 have_fds = true;
771                 {
772                     TRY_LOCK(pnode->cs_vSend, lockSend);
773                     if (lockSend && !pnode->vSend.empty())
774                         FD_SET(pnode->hSocket, &fdsetSend);
775                 }
776             }
777         }
778
779         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
780         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
781                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
782         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
783         if (fShutdown)
784             return;
785         if (nSelect == SOCKET_ERROR)
786         {
787             if (have_fds)
788             {
789                 int nErr = WSAGetLastError();
790                 printf("socket select error %d\n", nErr);
791                 for (unsigned int i = 0; i <= hSocketMax; i++)
792                     FD_SET(i, &fdsetRecv);
793             }
794             FD_ZERO(&fdsetSend);
795             FD_ZERO(&fdsetError);
796             Sleep(timeout.tv_usec/1000);
797         }
798
799
800         //
801         // Accept new connections
802         //
803         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
804         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
805         {
806 #ifdef USE_IPV6
807             struct sockaddr_storage sockaddr;
808 #else
809             struct sockaddr sockaddr;
810 #endif
811             socklen_t len = sizeof(sockaddr);
812             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
813             CAddress addr;
814             int nInbound = 0;
815
816             if (hSocket != INVALID_SOCKET)
817                 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
818                     printf("Warning: Unknown socket family\n");
819
820             {
821                 LOCK(cs_vNodes);
822                 BOOST_FOREACH(CNode* pnode, vNodes)
823                     if (pnode->fInbound)
824                         nInbound++;
825             }
826
827             if (hSocket == INVALID_SOCKET)
828             {
829                 int nErr = WSAGetLastError();
830                 if (nErr != WSAEWOULDBLOCK)
831                     printf("socket error accept failed: %d\n", nErr);
832             }
833             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
834             {
835                 {
836                     LOCK(cs_setservAddNodeAddresses);
837                     if (!setservAddNodeAddresses.count(addr))
838                         closesocket(hSocket);
839                 }
840             }
841             else if (CNode::IsBanned(addr))
842             {
843                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
844                 closesocket(hSocket);
845             }
846             else
847             {
848                 printf("accepted connection %s\n", addr.ToString().c_str());
849                 CNode* pnode = new CNode(hSocket, addr, "", true);
850                 pnode->AddRef();
851                 {
852                     LOCK(cs_vNodes);
853                     vNodes.push_back(pnode);
854                 }
855             }
856         }
857
858
859         //
860         // Service each socket
861         //
862         vector<CNode*> vNodesCopy;
863         {
864             LOCK(cs_vNodes);
865             vNodesCopy = vNodes;
866             BOOST_FOREACH(CNode* pnode, vNodesCopy)
867                 pnode->AddRef();
868         }
869         BOOST_FOREACH(CNode* pnode, vNodesCopy)
870         {
871             if (fShutdown)
872                 return;
873
874             //
875             // Receive
876             //
877             if (pnode->hSocket == INVALID_SOCKET)
878                 continue;
879             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
880             {
881                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
882                 if (lockRecv)
883                 {
884                     CDataStream& vRecv = pnode->vRecv;
885                     unsigned int nPos = vRecv.size();
886
887                     if (nPos > ReceiveBufferSize()) {
888                         if (!pnode->fDisconnect)
889                             printf("socket recv flood control disconnect (%"PRIszu" bytes)\n", vRecv.size());
890                         pnode->CloseSocketDisconnect();
891                     }
892                     else {
893                         // typical socket buffer is 8K-64K
894                         char pchBuf[0x10000];
895                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
896                         if (nBytes > 0)
897                         {
898                             vRecv.resize(nPos + nBytes);
899                             memcpy(&vRecv[nPos], pchBuf, nBytes);
900                             pnode->nLastRecv = GetTime();
901                         }
902                         else if (nBytes == 0)
903                         {
904                             // socket closed gracefully
905                             if (!pnode->fDisconnect)
906                                 printf("socket closed\n");
907                             pnode->CloseSocketDisconnect();
908                         }
909                         else if (nBytes < 0)
910                         {
911                             // error
912                             int nErr = WSAGetLastError();
913                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
914                             {
915                                 if (!pnode->fDisconnect)
916                                     printf("socket recv error %d\n", nErr);
917                                 pnode->CloseSocketDisconnect();
918                             }
919                         }
920                     }
921                 }
922             }
923
924             //
925             // Send
926             //
927             if (pnode->hSocket == INVALID_SOCKET)
928                 continue;
929             if (FD_ISSET(pnode->hSocket, &fdsetSend))
930             {
931                 TRY_LOCK(pnode->cs_vSend, lockSend);
932                 if (lockSend)
933                 {
934                     CDataStream& vSend = pnode->vSend;
935                     if (!vSend.empty())
936                     {
937                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
938                         if (nBytes > 0)
939                         {
940                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
941                             pnode->nLastSend = GetTime();
942                         }
943                         else if (nBytes < 0)
944                         {
945                             // error
946                             int nErr = WSAGetLastError();
947                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
948                             {
949                                 printf("socket send error %d\n", nErr);
950                                 pnode->CloseSocketDisconnect();
951                             }
952                         }
953                     }
954                 }
955             }
956
957             //
958             // Inactivity checking
959             //
960             if (pnode->vSend.empty())
961                 pnode->nLastSendEmpty = GetTime();
962             if (GetTime() - pnode->nTimeConnected > 60)
963             {
964                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
965                 {
966                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
967                     pnode->fDisconnect = true;
968                 }
969                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
970                 {
971                     printf("socket not sending\n");
972                     pnode->fDisconnect = true;
973                 }
974                 else if (GetTime() - pnode->nLastRecv > 90*60)
975                 {
976                     printf("socket inactivity timeout\n");
977                     pnode->fDisconnect = true;
978                 }
979             }
980         }
981         {
982             LOCK(cs_vNodes);
983             BOOST_FOREACH(CNode* pnode, vNodesCopy)
984                 pnode->Release();
985         }
986
987         Sleep(10);
988     }
989 }
990
991
992
993
994
995
996
997
998
999 #ifdef USE_UPNP
1000 void ThreadMapPort(void* parg)
1001 {
1002     // Make this thread recognisable as the UPnP thread
1003     RenameThread("bitcoin-UPnP");
1004
1005     try
1006     {
1007         vnThreadsRunning[THREAD_UPNP]++;
1008         ThreadMapPort2(parg);
1009         vnThreadsRunning[THREAD_UPNP]--;
1010     }
1011     catch (std::exception& e) {
1012         vnThreadsRunning[THREAD_UPNP]--;
1013         PrintException(&e, "ThreadMapPort()");
1014     } catch (...) {
1015         vnThreadsRunning[THREAD_UPNP]--;
1016         PrintException(NULL, "ThreadMapPort()");
1017     }
1018     printf("ThreadMapPort exited\n");
1019 }
1020
1021 void ThreadMapPort2(void* parg)
1022 {
1023     printf("ThreadMapPort started\n");
1024
1025     std::string port = strprintf("%u", GetListenPort());
1026     const char * multicastif = 0;
1027     const char * minissdpdpath = 0;
1028     struct UPNPDev * devlist = 0;
1029     char lanaddr[64];
1030
1031 #ifndef UPNPDISCOVER_SUCCESS
1032     /* miniupnpc 1.5 */
1033     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1034 #else
1035     /* miniupnpc 1.6 */
1036     int error = 0;
1037     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1038 #endif
1039
1040     struct UPNPUrls urls;
1041     struct IGDdatas data;
1042     int r;
1043
1044     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1045     if (r == 1)
1046     {
1047         if (fDiscover) {
1048             char externalIPAddress[40];
1049             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1050             if(r != UPNPCOMMAND_SUCCESS)
1051                 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1052             else
1053             {
1054                 if(externalIPAddress[0])
1055                 {
1056                     printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1057                     AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1058                 }
1059                 else
1060                     printf("UPnP: GetExternalIPAddress failed.\n");
1061             }
1062         }
1063
1064         string strDesc = "NovaCoin " + FormatFullVersion();
1065 #ifndef UPNPDISCOVER_SUCCESS
1066         /* miniupnpc 1.5 */
1067         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1068                             port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1069 #else
1070         /* miniupnpc 1.6 */
1071         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1072                             port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1073 #endif
1074
1075         if(r!=UPNPCOMMAND_SUCCESS)
1076             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1077                 port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
1078         else
1079             printf("UPnP Port Mapping successful.\n");
1080         int i = 1;
1081         loop {
1082             if (fShutdown || !fUseUPnP)
1083             {
1084                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1085                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1086                 freeUPNPDevlist(devlist); devlist = 0;
1087                 FreeUPNPUrls(&urls);
1088                 return;
1089             }
1090             if (i % 600 == 0) // Refresh every 20 minutes
1091             {
1092 #ifndef UPNPDISCOVER_SUCCESS
1093                 /* miniupnpc 1.5 */
1094                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1095                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1096 #else
1097                 /* miniupnpc 1.6 */
1098                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1099                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1100 #endif
1101
1102                 if(r!=UPNPCOMMAND_SUCCESS)
1103                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1104                         port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
1105                 else
1106                     printf("UPnP Port Mapping successful.\n");;
1107             }
1108             Sleep(2000);
1109             i++;
1110         }
1111     } else {
1112         printf("No valid UPnP IGDs found\n");
1113         freeUPNPDevlist(devlist); devlist = 0;
1114         if (r != 0)
1115             FreeUPNPUrls(&urls);
1116         loop {
1117             if (fShutdown || !fUseUPnP)
1118                 return;
1119             Sleep(2000);
1120         }
1121     }
1122 }
1123
1124 void MapPort()
1125 {
1126     if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1127     {
1128         if (!NewThread(ThreadMapPort, NULL))
1129             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1130     }
1131 }
1132 #else
1133 void MapPort()
1134 {
1135     // Intentionally left blank.
1136 }
1137 #endif
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147 // DNS seeds
1148 // Each pair gives a source name and a seed name.
1149 // The first name is used as information source for addrman.
1150 // The second name should resolve to a list of seed addresses.
1151 static const char *strDNSSeed[][2] = {
1152     {"novacoin.su", "seed.novacoin.su"},
1153 };
1154
1155 void ThreadDNSAddressSeed(void* parg)
1156 {
1157     // Make this thread recognisable as the DNS seeding thread
1158     RenameThread("bitcoin-dnsseed");
1159
1160     try
1161     {
1162         vnThreadsRunning[THREAD_DNSSEED]++;
1163         ThreadDNSAddressSeed2(parg);
1164         vnThreadsRunning[THREAD_DNSSEED]--;
1165     }
1166     catch (std::exception& e) {
1167         vnThreadsRunning[THREAD_DNSSEED]--;
1168         PrintException(&e, "ThreadDNSAddressSeed()");
1169     } catch (...) {
1170         vnThreadsRunning[THREAD_DNSSEED]--;
1171         throw; // support pthread_cancel()
1172     }
1173     printf("ThreadDNSAddressSeed exited\n");
1174 }
1175
1176 void ThreadDNSAddressSeed2(void* parg)
1177 {
1178     printf("ThreadDNSAddressSeed started\n");
1179     int found = 0;
1180
1181     if (!fTestNet)
1182     {
1183         printf("Loading addresses from DNS seeds (could take a while)\n");
1184
1185         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1186             if (HaveNameProxy()) {
1187                 AddOneShot(strDNSSeed[seed_idx][1]);
1188             } else {
1189                 vector<CNetAddr> vaddr;
1190                 vector<CAddress> vAdd;
1191                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1192                 {
1193                     BOOST_FOREACH(CNetAddr& ip, vaddr)
1194                     {
1195                         int nOneDay = 24*3600;
1196                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1197                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1198                         vAdd.push_back(addr);
1199                         found++;
1200                     }
1201                 }
1202                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1203             }
1204         }
1205     }
1206
1207     printf("%d addresses found from DNS seeds\n", found);
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 unsigned int pnSeed[] =
1222 {
1223     0x90EF78BC, 0x33F1C851, 0x36F1C851, 0xC6F5C851,
1224 };
1225
1226 void DumpAddresses()
1227 {
1228     int64 nStart = GetTimeMillis();
1229
1230     CAddrDB adb;
1231     adb.Write(addrman);
1232
1233     printf("Flushed %d addresses to peers.dat  %"PRI64d"ms\n",
1234            addrman.size(), GetTimeMillis() - nStart);
1235 }
1236
1237 void ThreadDumpAddress2(void* parg)
1238 {
1239     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1240     while (!fShutdown)
1241     {
1242         DumpAddresses();
1243         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1244         Sleep(600000);
1245         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1246     }
1247     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1248 }
1249
1250 void ThreadDumpAddress(void* parg)
1251 {
1252     // Make this thread recognisable as the address dumping thread
1253     RenameThread("bitcoin-adrdump");
1254
1255     try
1256     {
1257         ThreadDumpAddress2(parg);
1258     }
1259     catch (std::exception& e) {
1260         PrintException(&e, "ThreadDumpAddress()");
1261     }
1262     printf("ThreadDumpAddress exited\n");
1263 }
1264
1265 void ThreadOpenConnections(void* parg)
1266 {
1267     // Make this thread recognisable as the connection opening thread
1268     RenameThread("bitcoin-opencon");
1269
1270     try
1271     {
1272         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1273         ThreadOpenConnections2(parg);
1274         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1275     }
1276     catch (std::exception& e) {
1277         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1278         PrintException(&e, "ThreadOpenConnections()");
1279     } catch (...) {
1280         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1281         PrintException(NULL, "ThreadOpenConnections()");
1282     }
1283     printf("ThreadOpenConnections exited\n");
1284 }
1285
1286 void static ProcessOneShot()
1287 {
1288     string strDest;
1289     {
1290         LOCK(cs_vOneShots);
1291         if (vOneShots.empty())
1292             return;
1293         strDest = vOneShots.front();
1294         vOneShots.pop_front();
1295     }
1296     CAddress addr;
1297     CSemaphoreGrant grant(*semOutbound, true);
1298     if (grant) {
1299         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1300             AddOneShot(strDest);
1301     }
1302 }
1303
1304 // ppcoin: stake minter thread
1305 void static ThreadStakeMinter(void* parg)
1306 {
1307     printf("ThreadStakeMinter started\n");
1308     CWallet* pwallet = (CWallet*)parg;
1309     try
1310     {
1311         vnThreadsRunning[THREAD_MINTER]++;
1312         BitcoinMiner(pwallet, true);
1313         vnThreadsRunning[THREAD_MINTER]--;
1314     }
1315     catch (std::exception& e) {
1316         vnThreadsRunning[THREAD_MINTER]--;
1317         PrintException(&e, "ThreadStakeMinter()");
1318     } catch (...) {
1319         vnThreadsRunning[THREAD_MINTER]--;
1320         PrintException(NULL, "ThreadStakeMinter()");
1321     }
1322     printf("ThreadStakeMinter exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINTER]);
1323 }
1324
1325 void ThreadOpenConnections2(void* parg)
1326 {
1327     printf("ThreadOpenConnections started\n");
1328
1329     // Connect to specific addresses
1330     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1331     {
1332         for (int64 nLoop = 0;; nLoop++)
1333         {
1334             ProcessOneShot();
1335             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1336             {
1337                 CAddress addr;
1338                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1339                 for (int i = 0; i < 10 && i < nLoop; i++)
1340                 {
1341                     Sleep(500);
1342                     if (fShutdown)
1343                         return;
1344                 }
1345             }
1346             Sleep(500);
1347         }
1348     }
1349
1350     // Initiate network connections
1351     int64 nStart = GetTime();
1352     loop
1353     {
1354         ProcessOneShot();
1355
1356         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1357         Sleep(500);
1358         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1359         if (fShutdown)
1360             return;
1361
1362
1363         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1364         CSemaphoreGrant grant(*semOutbound);
1365         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1366         if (fShutdown)
1367             return;
1368
1369         // Add seed nodes if IRC isn't working
1370         if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1371         {
1372             std::vector<CAddress> vAdd;
1373             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1374             {
1375                 // It'll only connect to one or two seed nodes because once it connects,
1376                 // it'll get a pile of addresses with newer timestamps.
1377                 // Seed nodes are given a random 'last seen time' of between one and two
1378                 // weeks ago.
1379                 const int64 nOneWeek = 7*24*60*60;
1380                 struct in_addr ip;
1381                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1382                 CAddress addr(CService(ip, GetDefaultPort()));
1383                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1384                 vAdd.push_back(addr);
1385             }
1386             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1387         }
1388
1389         //
1390         // Choose an address to connect to based on most recently seen
1391         //
1392         CAddress addrConnect;
1393
1394         // Only connect out to one peer per network group (/16 for IPv4).
1395         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1396         int nOutbound = 0;
1397         set<vector<unsigned char> > setConnected;
1398         {
1399             LOCK(cs_vNodes);
1400             BOOST_FOREACH(CNode* pnode, vNodes) {
1401                 if (!pnode->fInbound) {
1402                     setConnected.insert(pnode->addr.GetGroup());
1403                     nOutbound++;
1404                 }
1405             }
1406         }
1407
1408         int64 nANow = GetAdjustedTime();
1409
1410         int nTries = 0;
1411         loop
1412         {
1413             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1414             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1415
1416             // if we selected an invalid address, restart
1417             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1418                 break;
1419
1420             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1421             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1422             // already-connected network ranges, ...) before trying new addrman addresses.
1423             nTries++;
1424             if (nTries > 100)
1425                 break;
1426
1427             if (IsLimited(addr))
1428                 continue;
1429
1430             // only consider very recently tried nodes after 30 failed attempts
1431             if (nANow - addr.nLastTry < 600 && nTries < 30)
1432                 continue;
1433
1434             // do not allow non-default ports, unless after 50 invalid addresses selected already
1435             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1436                 continue;
1437
1438             addrConnect = addr;
1439             break;
1440         }
1441
1442         if (addrConnect.IsValid())
1443             OpenNetworkConnection(addrConnect, &grant);
1444     }
1445 }
1446
1447 void ThreadOpenAddedConnections(void* parg)
1448 {
1449     // Make this thread recognisable as the connection opening thread
1450     RenameThread("bitcoin-opencon");
1451
1452     try
1453     {
1454         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1455         ThreadOpenAddedConnections2(parg);
1456         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1457     }
1458     catch (std::exception& e) {
1459         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1460         PrintException(&e, "ThreadOpenAddedConnections()");
1461     } catch (...) {
1462         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1463         PrintException(NULL, "ThreadOpenAddedConnections()");
1464     }
1465     printf("ThreadOpenAddedConnections exited\n");
1466 }
1467
1468 void ThreadOpenAddedConnections2(void* parg)
1469 {
1470     printf("ThreadOpenAddedConnections started\n");
1471
1472     if (mapArgs.count("-addnode") == 0)
1473         return;
1474
1475     if (HaveNameProxy()) {
1476         while(!fShutdown) {
1477             BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
1478                 CAddress addr;
1479                 CSemaphoreGrant grant(*semOutbound);
1480                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1481                 Sleep(500);
1482             }
1483             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1484             Sleep(120000); // Retry every 2 minutes
1485             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1486         }
1487         return;
1488     }
1489
1490     vector<vector<CService> > vservAddressesToAdd(0);
1491     BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1492     {
1493         vector<CService> vservNode(0);
1494         if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1495         {
1496             vservAddressesToAdd.push_back(vservNode);
1497             {
1498                 LOCK(cs_setservAddNodeAddresses);
1499                 BOOST_FOREACH(CService& serv, vservNode)
1500                     setservAddNodeAddresses.insert(serv);
1501             }
1502         }
1503     }
1504     loop
1505     {
1506         vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1507         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1508         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1509         {
1510             LOCK(cs_vNodes);
1511             BOOST_FOREACH(CNode* pnode, vNodes)
1512                 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1513                     BOOST_FOREACH(CService& addrNode, *(it))
1514                         if (pnode->addr == addrNode)
1515                         {
1516                             it = vservConnectAddresses.erase(it);
1517                             it--;
1518                             break;
1519                         }
1520         }
1521         BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1522         {
1523             CSemaphoreGrant grant(*semOutbound);
1524             OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
1525             Sleep(500);
1526             if (fShutdown)
1527                 return;
1528         }
1529         if (fShutdown)
1530             return;
1531         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1532         Sleep(120000); // Retry every 2 minutes
1533         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1534         if (fShutdown)
1535             return;
1536     }
1537 }
1538
1539 // if successful, this moves the passed grant to the constructed node
1540 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1541 {
1542     //
1543     // Initiate outbound network connection
1544     //
1545     if (fShutdown)
1546         return false;
1547     if (!strDest)
1548         if (IsLocal(addrConnect) ||
1549             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1550             FindNode(addrConnect.ToStringIPPort().c_str()))
1551             return false;
1552     if (strDest && FindNode(strDest))
1553         return false;
1554
1555     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1556     CNode* pnode = ConnectNode(addrConnect, strDest);
1557     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1558     if (fShutdown)
1559         return false;
1560     if (!pnode)
1561         return false;
1562     if (grantOutbound)
1563         grantOutbound->MoveTo(pnode->grantOutbound);
1564     pnode->fNetworkNode = true;
1565     if (fOneShot)
1566         pnode->fOneShot = true;
1567
1568     return true;
1569 }
1570
1571
1572
1573
1574
1575
1576
1577
1578 void ThreadMessageHandler(void* parg)
1579 {
1580     // Make this thread recognisable as the message handling thread
1581     RenameThread("bitcoin-msghand");
1582
1583     try
1584     {
1585         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1586         ThreadMessageHandler2(parg);
1587         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1588     }
1589     catch (std::exception& e) {
1590         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1591         PrintException(&e, "ThreadMessageHandler()");
1592     } catch (...) {
1593         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1594         PrintException(NULL, "ThreadMessageHandler()");
1595     }
1596     printf("ThreadMessageHandler exited\n");
1597 }
1598
1599 void ThreadMessageHandler2(void* parg)
1600 {
1601     printf("ThreadMessageHandler started\n");
1602     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1603     while (!fShutdown)
1604     {
1605         vector<CNode*> vNodesCopy;
1606         {
1607             LOCK(cs_vNodes);
1608             vNodesCopy = vNodes;
1609             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1610                 pnode->AddRef();
1611         }
1612
1613         // Poll the connected nodes for messages
1614         CNode* pnodeTrickle = NULL;
1615         if (!vNodesCopy.empty())
1616             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1617         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1618         {
1619             // Receive messages
1620             {
1621                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1622                 if (lockRecv)
1623                     ProcessMessages(pnode);
1624             }
1625             if (fShutdown)
1626                 return;
1627
1628             // Send messages
1629             {
1630                 TRY_LOCK(pnode->cs_vSend, lockSend);
1631                 if (lockSend)
1632                     SendMessages(pnode, pnode == pnodeTrickle);
1633             }
1634             if (fShutdown)
1635                 return;
1636         }
1637
1638         {
1639             LOCK(cs_vNodes);
1640             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1641                 pnode->Release();
1642         }
1643
1644         // Wait and allow messages to bunch up.
1645         // Reduce vnThreadsRunning so StopNode has permission to exit while
1646         // we're sleeping, but we must always check fShutdown after doing this.
1647         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1648         Sleep(100);
1649         if (fRequestShutdown)
1650             StartShutdown();
1651         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1652         if (fShutdown)
1653             return;
1654     }
1655 }
1656
1657
1658
1659
1660
1661
1662 bool BindListenPort(const CService &addrBind, string& strError)
1663 {
1664     strError = "";
1665     int nOne = 1;
1666
1667 #ifdef WIN32
1668     // Initialize Windows Sockets
1669     WSADATA wsadata;
1670     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1671     if (ret != NO_ERROR)
1672     {
1673         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1674         printf("%s\n", strError.c_str());
1675         return false;
1676     }
1677 #endif
1678
1679     // Create socket for listening for incoming connections
1680 #ifdef USE_IPV6
1681     struct sockaddr_storage sockaddr;
1682 #else
1683     struct sockaddr sockaddr;
1684 #endif
1685     socklen_t len = sizeof(sockaddr);
1686     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1687     {
1688         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1689         printf("%s\n", strError.c_str());
1690         return false;
1691     }
1692
1693     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1694     if (hListenSocket == INVALID_SOCKET)
1695     {
1696         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1697         printf("%s\n", strError.c_str());
1698         return false;
1699     }
1700
1701 #ifdef SO_NOSIGPIPE
1702     // Different way of disabling SIGPIPE on BSD
1703     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1704 #endif
1705
1706 #ifndef WIN32
1707     // Allow binding if the port is still in TIME_WAIT state after
1708     // the program was closed and restarted.  Not an issue on windows.
1709     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1710 #endif
1711
1712
1713 #ifdef WIN32
1714     // Set to non-blocking, incoming connections will also inherit this
1715     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1716 #else
1717     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1718 #endif
1719     {
1720         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1721         printf("%s\n", strError.c_str());
1722         return false;
1723     }
1724
1725 #ifdef USE_IPV6
1726     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1727     // and enable it by default or not. Try to enable it, if possible.
1728     if (addrBind.IsIPv6()) {
1729 #ifdef IPV6_V6ONLY
1730 #ifdef WIN32
1731         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1732 #else
1733         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1734 #endif
1735 #endif
1736 #ifdef WIN32
1737         int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1738         int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1739         // this call is allowed to fail
1740         setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1741 #endif
1742     }
1743 #endif
1744
1745     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1746     {
1747         int nErr = WSAGetLastError();
1748         if (nErr == WSAEADDRINUSE)
1749             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1750         else
1751             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1752         printf("%s\n", strError.c_str());
1753         return false;
1754     }
1755     printf("Bound to %s\n", addrBind.ToString().c_str());
1756
1757     // Listen for incoming connections
1758     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1759     {
1760         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1761         printf("%s\n", strError.c_str());
1762         return false;
1763     }
1764
1765     vhListenSocket.push_back(hListenSocket);
1766
1767     if (addrBind.IsRoutable() && fDiscover)
1768         AddLocal(addrBind, LOCAL_BIND);
1769
1770     return true;
1771 }
1772
1773 void static Discover()
1774 {
1775     if (!fDiscover)
1776         return;
1777
1778 #ifdef WIN32
1779     // Get local host IP
1780     char pszHostName[1000] = "";
1781     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1782     {
1783         vector<CNetAddr> vaddr;
1784         if (LookupHost(pszHostName, vaddr))
1785         {
1786             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1787             {
1788                 AddLocal(addr, LOCAL_IF);
1789             }
1790         }
1791     }
1792 #else
1793     // Get local host ip
1794     struct ifaddrs* myaddrs;
1795     if (getifaddrs(&myaddrs) == 0)
1796     {
1797         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1798         {
1799             if (ifa->ifa_addr == NULL) continue;
1800             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1801             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1802             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1803             if (ifa->ifa_addr->sa_family == AF_INET)
1804             {
1805                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1806                 CNetAddr addr(s4->sin_addr);
1807                 if (AddLocal(addr, LOCAL_IF))
1808                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1809             }
1810 #ifdef USE_IPV6
1811             else if (ifa->ifa_addr->sa_family == AF_INET6)
1812             {
1813                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1814                 CNetAddr addr(s6->sin6_addr);
1815                 if (AddLocal(addr, LOCAL_IF))
1816                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1817             }
1818 #endif
1819         }
1820         freeifaddrs(myaddrs);
1821     }
1822 #endif
1823
1824     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1825     if (!IsLimited(NET_IPV4))
1826         NewThread(ThreadGetMyExternalIP, NULL);
1827 }
1828
1829 void StartNode(void* parg)
1830 {
1831     // Make this thread recognisable as the startup thread
1832     RenameThread("bitcoin-start");
1833
1834     if (semOutbound == NULL) {
1835         // initialize semaphore
1836         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1837         semOutbound = new CSemaphore(nMaxOutbound);
1838     }
1839
1840     if (pnodeLocalHost == NULL)
1841         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1842
1843     Discover();
1844
1845     //
1846     // Start threads
1847     //
1848
1849 /*
1850     if (!GetBoolArg("-dnsseed", true))
1851         printf("DNS seeding disabled\n");
1852     else
1853         if (!NewThread(ThreadDNSAddressSeed, NULL))
1854             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1855 */
1856
1857     if (!GetBoolArg("-dnsseed", false))
1858         printf("DNS seeding disabled\n");
1859     if (GetBoolArg("-dnsseed", false))
1860         printf("DNS seeding NYI\n");
1861
1862     // Map ports with UPnP
1863     if (fUseUPnP)
1864         MapPort();
1865
1866     // Get addresses from IRC and advertise ours
1867     if (!NewThread(ThreadIRCSeed, NULL))
1868         printf("Error: NewThread(ThreadIRCSeed) failed\n");
1869
1870     // Send and receive from sockets, accept connections
1871     if (!NewThread(ThreadSocketHandler, NULL))
1872         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1873
1874     // Initiate outbound connections from -addnode
1875     if (!NewThread(ThreadOpenAddedConnections, NULL))
1876         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1877
1878     // Initiate outbound connections
1879     if (!NewThread(ThreadOpenConnections, NULL))
1880         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1881
1882     // Process messages
1883     if (!NewThread(ThreadMessageHandler, NULL))
1884         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1885
1886     // Dump network addresses
1887     if (!NewThread(ThreadDumpAddress, NULL))
1888         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1889
1890     // ppcoin: mint proof-of-stake blocks in the background
1891     if (!NewThread(ThreadStakeMinter, pwalletMain))
1892         printf("Error: NewThread(ThreadStakeMinter) failed\n");
1893 }
1894
1895 bool StopNode()
1896 {
1897     printf("StopNode()\n");
1898     fShutdown = true;
1899     nTransactionsUpdated++;
1900     int64 nStart = GetTime();
1901     if (semOutbound)
1902         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1903             semOutbound->post();
1904     do
1905     {
1906         int nThreadsRunning = 0;
1907         for (int n = 0; n < THREAD_MAX; n++)
1908             nThreadsRunning += vnThreadsRunning[n];
1909         if (nThreadsRunning == 0)
1910             break;
1911         if (GetTime() - nStart > 20)
1912             break;
1913         Sleep(20);
1914     } while(true);
1915     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1916     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1917     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1918     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1919     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1920 #ifdef USE_UPNP
1921     if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1922 #endif
1923     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1924     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1925     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1926     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1927     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
1928         Sleep(20);
1929     Sleep(50);
1930     DumpAddresses();
1931     return true;
1932 }
1933
1934 class CNetCleanup
1935 {
1936 public:
1937     CNetCleanup()
1938     {
1939     }
1940     ~CNetCleanup()
1941     {
1942         // Close sockets
1943         BOOST_FOREACH(CNode* pnode, vNodes)
1944             if (pnode->hSocket != INVALID_SOCKET)
1945                 closesocket(pnode->hSocket);
1946         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1947             if (hListenSocket != INVALID_SOCKET)
1948                 if (closesocket(hListenSocket) == SOCKET_ERROR)
1949                     printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1950
1951 #ifdef WIN32
1952         // Shutdown Windows Sockets
1953         WSACleanup();
1954 #endif
1955     }
1956 }
1957 instance_of_cnetcleanup;