Always reserialize transactions before relaying
[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     while (true)
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             while (true)
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     while (true)
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         while (true)
1082         {
1083             if (fShutdown || !fUseUPnP)
1084             {
1085                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1086                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1087                 freeUPNPDevlist(devlist); devlist = 0;
1088                 FreeUPNPUrls(&urls);
1089                 return;
1090             }
1091             if (i % 600 == 0) // Refresh every 20 minutes
1092             {
1093 #ifndef UPNPDISCOVER_SUCCESS
1094                 /* miniupnpc 1.5 */
1095                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1096                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1097 #else
1098                 /* miniupnpc 1.6 */
1099                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1100                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1101 #endif
1102
1103                 if(r!=UPNPCOMMAND_SUCCESS)
1104                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1105                         port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
1106                 else
1107                     printf("UPnP Port Mapping successful.\n");;
1108             }
1109             Sleep(2000);
1110             i++;
1111         }
1112     } else {
1113         printf("No valid UPnP IGDs found\n");
1114         freeUPNPDevlist(devlist); devlist = 0;
1115         if (r != 0)
1116             FreeUPNPUrls(&urls);
1117         while (true)
1118         {
1119             if (fShutdown || !fUseUPnP)
1120                 return;
1121             Sleep(2000);
1122         }
1123     }
1124 }
1125
1126 void MapPort()
1127 {
1128     if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1129     {
1130         if (!NewThread(ThreadMapPort, NULL))
1131             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1132     }
1133 }
1134 #else
1135 void MapPort()
1136 {
1137     // Intentionally left blank.
1138 }
1139 #endif
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149 // DNS seeds
1150 // Each pair gives a source name and a seed name.
1151 // The first name is used as information source for addrman.
1152 // The second name should resolve to a list of seed addresses.
1153 static const char *strDNSSeed[][2] = {
1154     {"novacoin.su", "dnsseed.novacoin.su"},
1155 };
1156
1157 void ThreadDNSAddressSeed(void* parg)
1158 {
1159     // Make this thread recognisable as the DNS seeding thread
1160     RenameThread("bitcoin-dnsseed");
1161
1162     try
1163     {
1164         vnThreadsRunning[THREAD_DNSSEED]++;
1165         ThreadDNSAddressSeed2(parg);
1166         vnThreadsRunning[THREAD_DNSSEED]--;
1167     }
1168     catch (std::exception& e) {
1169         vnThreadsRunning[THREAD_DNSSEED]--;
1170         PrintException(&e, "ThreadDNSAddressSeed()");
1171     } catch (...) {
1172         vnThreadsRunning[THREAD_DNSSEED]--;
1173         throw; // support pthread_cancel()
1174     }
1175     printf("ThreadDNSAddressSeed exited\n");
1176 }
1177
1178 void ThreadDNSAddressSeed2(void* parg)
1179 {
1180     printf("ThreadDNSAddressSeed started\n");
1181     int found = 0;
1182
1183     if (!fTestNet)
1184     {
1185         printf("Loading addresses from DNS seeds (could take a while)\n");
1186
1187         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1188             if (HaveNameProxy()) {
1189                 AddOneShot(strDNSSeed[seed_idx][1]);
1190             } else {
1191                 vector<CNetAddr> vaddr;
1192                 vector<CAddress> vAdd;
1193                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1194                 {
1195                     BOOST_FOREACH(CNetAddr& ip, vaddr)
1196                     {
1197                         int nOneDay = 24*3600;
1198                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1199                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1200                         vAdd.push_back(addr);
1201                         found++;
1202                     }
1203                 }
1204                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1205             }
1206         }
1207     }
1208
1209     printf("%d addresses found from DNS seeds\n", found);
1210 }
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 unsigned int pnSeed[] =
1224 {
1225     0x90EF78BC, 0x33F1C851, 0x36F1C851, 0xC6F5C851,
1226 };
1227
1228 void DumpAddresses()
1229 {
1230     int64 nStart = GetTimeMillis();
1231
1232     CAddrDB adb;
1233     adb.Write(addrman);
1234
1235     printf("Flushed %d addresses to peers.dat  %"PRI64d"ms\n",
1236            addrman.size(), GetTimeMillis() - nStart);
1237 }
1238
1239 void ThreadDumpAddress2(void* parg)
1240 {
1241     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1242     while (!fShutdown)
1243     {
1244         DumpAddresses();
1245         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1246         Sleep(600000);
1247         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1248     }
1249     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1250 }
1251
1252 void ThreadDumpAddress(void* parg)
1253 {
1254     // Make this thread recognisable as the address dumping thread
1255     RenameThread("bitcoin-adrdump");
1256
1257     try
1258     {
1259         ThreadDumpAddress2(parg);
1260     }
1261     catch (std::exception& e) {
1262         PrintException(&e, "ThreadDumpAddress()");
1263     }
1264     printf("ThreadDumpAddress exited\n");
1265 }
1266
1267 void ThreadOpenConnections(void* parg)
1268 {
1269     // Make this thread recognisable as the connection opening thread
1270     RenameThread("bitcoin-opencon");
1271
1272     try
1273     {
1274         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1275         ThreadOpenConnections2(parg);
1276         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1277     }
1278     catch (std::exception& e) {
1279         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1280         PrintException(&e, "ThreadOpenConnections()");
1281     } catch (...) {
1282         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1283         PrintException(NULL, "ThreadOpenConnections()");
1284     }
1285     printf("ThreadOpenConnections exited\n");
1286 }
1287
1288 void static ProcessOneShot()
1289 {
1290     string strDest;
1291     {
1292         LOCK(cs_vOneShots);
1293         if (vOneShots.empty())
1294             return;
1295         strDest = vOneShots.front();
1296         vOneShots.pop_front();
1297     }
1298     CAddress addr;
1299     CSemaphoreGrant grant(*semOutbound, true);
1300     if (grant) {
1301         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1302             AddOneShot(strDest);
1303     }
1304 }
1305
1306 // ppcoin: stake minter thread
1307 void static ThreadStakeMinter(void* parg)
1308 {
1309     printf("ThreadStakeMinter started\n");
1310     CWallet* pwallet = (CWallet*)parg;
1311     try
1312     {
1313         vnThreadsRunning[THREAD_MINTER]++;
1314         StakeMiner(pwallet);
1315         vnThreadsRunning[THREAD_MINTER]--;
1316     }
1317     catch (std::exception& e) {
1318         vnThreadsRunning[THREAD_MINTER]--;
1319         PrintException(&e, "ThreadStakeMinter()");
1320     } catch (...) {
1321         vnThreadsRunning[THREAD_MINTER]--;
1322         PrintException(NULL, "ThreadStakeMinter()");
1323     }
1324     printf("ThreadStakeMinter exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINTER]);
1325 }
1326
1327 void ThreadOpenConnections2(void* parg)
1328 {
1329     printf("ThreadOpenConnections started\n");
1330
1331     // Connect to specific addresses
1332     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1333     {
1334         for (int64 nLoop = 0;; nLoop++)
1335         {
1336             ProcessOneShot();
1337             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1338             {
1339                 CAddress addr;
1340                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1341                 for (int i = 0; i < 10 && i < nLoop; i++)
1342                 {
1343                     Sleep(500);
1344                     if (fShutdown)
1345                         return;
1346                 }
1347             }
1348             Sleep(500);
1349         }
1350     }
1351
1352     // Initiate network connections
1353     int64 nStart = GetTime();
1354     while (true)
1355     {
1356         ProcessOneShot();
1357
1358         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1359         Sleep(500);
1360         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1361         if (fShutdown)
1362             return;
1363
1364
1365         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1366         CSemaphoreGrant grant(*semOutbound);
1367         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1368         if (fShutdown)
1369             return;
1370
1371         // Add seed nodes if IRC isn't working
1372         if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1373         {
1374             std::vector<CAddress> vAdd;
1375             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1376             {
1377                 // It'll only connect to one or two seed nodes because once it connects,
1378                 // it'll get a pile of addresses with newer timestamps.
1379                 // Seed nodes are given a random 'last seen time' of between one and two
1380                 // weeks ago.
1381                 const int64 nOneWeek = 7*24*60*60;
1382                 struct in_addr ip;
1383                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1384                 CAddress addr(CService(ip, GetDefaultPort()));
1385                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1386                 vAdd.push_back(addr);
1387             }
1388             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1389         }
1390
1391         //
1392         // Choose an address to connect to based on most recently seen
1393         //
1394         CAddress addrConnect;
1395
1396         // Only connect out to one peer per network group (/16 for IPv4).
1397         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1398         int nOutbound = 0;
1399         set<vector<unsigned char> > setConnected;
1400         {
1401             LOCK(cs_vNodes);
1402             BOOST_FOREACH(CNode* pnode, vNodes) {
1403                 if (!pnode->fInbound) {
1404                     setConnected.insert(pnode->addr.GetGroup());
1405                     nOutbound++;
1406                 }
1407             }
1408         }
1409
1410         int64 nANow = GetAdjustedTime();
1411
1412         int nTries = 0;
1413         while (true)
1414         {
1415             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1416             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1417
1418             // if we selected an invalid address, restart
1419             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1420                 break;
1421
1422             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1423             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1424             // already-connected network ranges, ...) before trying new addrman addresses.
1425             nTries++;
1426             if (nTries > 100)
1427                 break;
1428
1429             if (IsLimited(addr))
1430                 continue;
1431
1432             // only consider very recently tried nodes after 30 failed attempts
1433             if (nANow - addr.nLastTry < 600 && nTries < 30)
1434                 continue;
1435
1436             // do not allow non-default ports, unless after 50 invalid addresses selected already
1437             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1438                 continue;
1439
1440             addrConnect = addr;
1441             break;
1442         }
1443
1444         if (addrConnect.IsValid())
1445             OpenNetworkConnection(addrConnect, &grant);
1446     }
1447 }
1448
1449 void ThreadOpenAddedConnections(void* parg)
1450 {
1451     // Make this thread recognisable as the connection opening thread
1452     RenameThread("bitcoin-opencon");
1453
1454     try
1455     {
1456         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1457         ThreadOpenAddedConnections2(parg);
1458         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1459     }
1460     catch (std::exception& e) {
1461         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1462         PrintException(&e, "ThreadOpenAddedConnections()");
1463     } catch (...) {
1464         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1465         PrintException(NULL, "ThreadOpenAddedConnections()");
1466     }
1467     printf("ThreadOpenAddedConnections exited\n");
1468 }
1469
1470 void ThreadOpenAddedConnections2(void* parg)
1471 {
1472     printf("ThreadOpenAddedConnections started\n");
1473
1474     if (mapArgs.count("-addnode") == 0)
1475         return;
1476
1477     if (HaveNameProxy()) {
1478         while(!fShutdown) {
1479             BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
1480                 CAddress addr;
1481                 CSemaphoreGrant grant(*semOutbound);
1482                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1483                 Sleep(500);
1484             }
1485             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1486             Sleep(120000); // Retry every 2 minutes
1487             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1488         }
1489         return;
1490     }
1491
1492     vector<vector<CService> > vservAddressesToAdd(0);
1493     BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1494     {
1495         vector<CService> vservNode(0);
1496         if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1497         {
1498             vservAddressesToAdd.push_back(vservNode);
1499             {
1500                 LOCK(cs_setservAddNodeAddresses);
1501                 BOOST_FOREACH(CService& serv, vservNode)
1502                     setservAddNodeAddresses.insert(serv);
1503             }
1504         }
1505     }
1506     while (true)
1507     {
1508         vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1509         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1510         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1511         {
1512             LOCK(cs_vNodes);
1513             BOOST_FOREACH(CNode* pnode, vNodes)
1514                 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1515                     BOOST_FOREACH(CService& addrNode, *(it))
1516                         if (pnode->addr == addrNode)
1517                         {
1518                             it = vservConnectAddresses.erase(it);
1519                             it--;
1520                             break;
1521                         }
1522         }
1523         BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1524         {
1525             CSemaphoreGrant grant(*semOutbound);
1526             OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
1527             Sleep(500);
1528             if (fShutdown)
1529                 return;
1530         }
1531         if (fShutdown)
1532             return;
1533         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1534         Sleep(120000); // Retry every 2 minutes
1535         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1536         if (fShutdown)
1537             return;
1538     }
1539 }
1540
1541 // if successful, this moves the passed grant to the constructed node
1542 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1543 {
1544     //
1545     // Initiate outbound network connection
1546     //
1547     if (fShutdown)
1548         return false;
1549     if (!strDest)
1550         if (IsLocal(addrConnect) ||
1551             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1552             FindNode(addrConnect.ToStringIPPort().c_str()))
1553             return false;
1554     if (strDest && FindNode(strDest))
1555         return false;
1556
1557     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1558     CNode* pnode = ConnectNode(addrConnect, strDest);
1559     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1560     if (fShutdown)
1561         return false;
1562     if (!pnode)
1563         return false;
1564     if (grantOutbound)
1565         grantOutbound->MoveTo(pnode->grantOutbound);
1566     pnode->fNetworkNode = true;
1567     if (fOneShot)
1568         pnode->fOneShot = true;
1569
1570     return true;
1571 }
1572
1573
1574
1575
1576
1577
1578
1579
1580 void ThreadMessageHandler(void* parg)
1581 {
1582     // Make this thread recognisable as the message handling thread
1583     RenameThread("bitcoin-msghand");
1584
1585     try
1586     {
1587         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1588         ThreadMessageHandler2(parg);
1589         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1590     }
1591     catch (std::exception& e) {
1592         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1593         PrintException(&e, "ThreadMessageHandler()");
1594     } catch (...) {
1595         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1596         PrintException(NULL, "ThreadMessageHandler()");
1597     }
1598     printf("ThreadMessageHandler exited\n");
1599 }
1600
1601 void ThreadMessageHandler2(void* parg)
1602 {
1603     printf("ThreadMessageHandler started\n");
1604     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1605     while (!fShutdown)
1606     {
1607         vector<CNode*> vNodesCopy;
1608         {
1609             LOCK(cs_vNodes);
1610             vNodesCopy = vNodes;
1611             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1612                 pnode->AddRef();
1613         }
1614
1615         // Poll the connected nodes for messages
1616         CNode* pnodeTrickle = NULL;
1617         if (!vNodesCopy.empty())
1618             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1619         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1620         {
1621             // Receive messages
1622             {
1623                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1624                 if (lockRecv)
1625                     ProcessMessages(pnode);
1626             }
1627             if (fShutdown)
1628                 return;
1629
1630             // Send messages
1631             {
1632                 TRY_LOCK(pnode->cs_vSend, lockSend);
1633                 if (lockSend)
1634                     SendMessages(pnode, pnode == pnodeTrickle);
1635             }
1636             if (fShutdown)
1637                 return;
1638         }
1639
1640         {
1641             LOCK(cs_vNodes);
1642             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1643                 pnode->Release();
1644         }
1645
1646         // Wait and allow messages to bunch up.
1647         // Reduce vnThreadsRunning so StopNode has permission to exit while
1648         // we're sleeping, but we must always check fShutdown after doing this.
1649         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1650         Sleep(100);
1651         if (fRequestShutdown)
1652             StartShutdown();
1653         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1654         if (fShutdown)
1655             return;
1656     }
1657 }
1658
1659
1660
1661
1662
1663
1664 bool BindListenPort(const CService &addrBind, string& strError)
1665 {
1666     strError = "";
1667     int nOne = 1;
1668
1669 #ifdef WIN32
1670     // Initialize Windows Sockets
1671     WSADATA wsadata;
1672     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1673     if (ret != NO_ERROR)
1674     {
1675         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1676         printf("%s\n", strError.c_str());
1677         return false;
1678     }
1679 #endif
1680
1681     // Create socket for listening for incoming connections
1682 #ifdef USE_IPV6
1683     struct sockaddr_storage sockaddr;
1684 #else
1685     struct sockaddr sockaddr;
1686 #endif
1687     socklen_t len = sizeof(sockaddr);
1688     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1689     {
1690         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1691         printf("%s\n", strError.c_str());
1692         return false;
1693     }
1694
1695     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1696     if (hListenSocket == INVALID_SOCKET)
1697     {
1698         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1699         printf("%s\n", strError.c_str());
1700         return false;
1701     }
1702
1703 #ifdef SO_NOSIGPIPE
1704     // Different way of disabling SIGPIPE on BSD
1705     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1706 #endif
1707
1708 #ifndef WIN32
1709     // Allow binding if the port is still in TIME_WAIT state after
1710     // the program was closed and restarted.  Not an issue on windows.
1711     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1712 #endif
1713
1714
1715 #ifdef WIN32
1716     // Set to non-blocking, incoming connections will also inherit this
1717     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1718 #else
1719     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1720 #endif
1721     {
1722         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1723         printf("%s\n", strError.c_str());
1724         return false;
1725     }
1726
1727 #ifdef USE_IPV6
1728     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1729     // and enable it by default or not. Try to enable it, if possible.
1730     if (addrBind.IsIPv6()) {
1731 #ifdef IPV6_V6ONLY
1732 #ifdef WIN32
1733         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1734 #else
1735         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1736 #endif
1737 #endif
1738 #ifdef WIN32
1739         int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1740         int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1741         // this call is allowed to fail
1742         setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1743 #endif
1744     }
1745 #endif
1746
1747     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1748     {
1749         int nErr = WSAGetLastError();
1750         if (nErr == WSAEADDRINUSE)
1751             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1752         else
1753             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1754         printf("%s\n", strError.c_str());
1755         return false;
1756     }
1757     printf("Bound to %s\n", addrBind.ToString().c_str());
1758
1759     // Listen for incoming connections
1760     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1761     {
1762         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1763         printf("%s\n", strError.c_str());
1764         return false;
1765     }
1766
1767     vhListenSocket.push_back(hListenSocket);
1768
1769     if (addrBind.IsRoutable() && fDiscover)
1770         AddLocal(addrBind, LOCAL_BIND);
1771
1772     return true;
1773 }
1774
1775 void static Discover()
1776 {
1777     if (!fDiscover)
1778         return;
1779
1780 #ifdef WIN32
1781     // Get local host IP
1782     char pszHostName[1000] = "";
1783     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1784     {
1785         vector<CNetAddr> vaddr;
1786         if (LookupHost(pszHostName, vaddr))
1787         {
1788             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1789             {
1790                 AddLocal(addr, LOCAL_IF);
1791             }
1792         }
1793     }
1794 #else
1795     // Get local host ip
1796     struct ifaddrs* myaddrs;
1797     if (getifaddrs(&myaddrs) == 0)
1798     {
1799         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1800         {
1801             if (ifa->ifa_addr == NULL) continue;
1802             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1803             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1804             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1805             if (ifa->ifa_addr->sa_family == AF_INET)
1806             {
1807                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1808                 CNetAddr addr(s4->sin_addr);
1809                 if (AddLocal(addr, LOCAL_IF))
1810                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1811             }
1812 #ifdef USE_IPV6
1813             else if (ifa->ifa_addr->sa_family == AF_INET6)
1814             {
1815                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1816                 CNetAddr addr(s6->sin6_addr);
1817                 if (AddLocal(addr, LOCAL_IF))
1818                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1819             }
1820 #endif
1821         }
1822         freeifaddrs(myaddrs);
1823     }
1824 #endif
1825
1826     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1827     if (!IsLimited(NET_IPV4))
1828         NewThread(ThreadGetMyExternalIP, NULL);
1829 }
1830
1831 void StartNode(void* parg)
1832 {
1833     // Make this thread recognisable as the startup thread
1834     RenameThread("bitcoin-start");
1835
1836     if (semOutbound == NULL) {
1837         // initialize semaphore
1838         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1839         semOutbound = new CSemaphore(nMaxOutbound);
1840     }
1841
1842     if (pnodeLocalHost == NULL)
1843         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1844
1845     Discover();
1846
1847     //
1848     // Start threads
1849     //
1850
1851     if (!GetBoolArg("-dnsseed", true))
1852         printf("DNS seeding disabled\n");
1853     else
1854         if (!NewThread(ThreadDNSAddressSeed, NULL))
1855             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1856
1857     // Map ports with UPnP
1858     if (fUseUPnP)
1859         MapPort();
1860
1861     // Get addresses from IRC and advertise ours
1862     if (!NewThread(ThreadIRCSeed, NULL))
1863         printf("Error: NewThread(ThreadIRCSeed) failed\n");
1864
1865     // Send and receive from sockets, accept connections
1866     if (!NewThread(ThreadSocketHandler, NULL))
1867         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1868
1869     // Initiate outbound connections from -addnode
1870     if (!NewThread(ThreadOpenAddedConnections, NULL))
1871         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1872
1873     // Initiate outbound connections
1874     if (!NewThread(ThreadOpenConnections, NULL))
1875         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1876
1877     // Process messages
1878     if (!NewThread(ThreadMessageHandler, NULL))
1879         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1880
1881     // Dump network addresses
1882     if (!NewThread(ThreadDumpAddress, NULL))
1883         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1884
1885     // ppcoin: mint proof-of-stake blocks in the background
1886     if (!NewThread(ThreadStakeMinter, pwalletMain))
1887         printf("Error: NewThread(ThreadStakeMinter) failed\n");
1888 }
1889
1890 bool StopNode()
1891 {
1892     printf("StopNode()\n");
1893     fShutdown = true;
1894     nTransactionsUpdated++;
1895     int64 nStart = GetTime();
1896     if (semOutbound)
1897         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1898             semOutbound->post();
1899     do
1900     {
1901         int nThreadsRunning = 0;
1902         for (int n = 0; n < THREAD_MAX; n++)
1903             nThreadsRunning += vnThreadsRunning[n];
1904         if (nThreadsRunning == 0)
1905             break;
1906         if (GetTime() - nStart > 20)
1907             break;
1908         Sleep(20);
1909     } while(true);
1910     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1911     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1912     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1913     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1914     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1915 #ifdef USE_UPNP
1916     if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1917 #endif
1918     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1919     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1920     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1921     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1922     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
1923         Sleep(20);
1924     Sleep(50);
1925     DumpAddresses();
1926     return true;
1927 }
1928
1929 class CNetCleanup
1930 {
1931 public:
1932     CNetCleanup()
1933     {
1934     }
1935     ~CNetCleanup()
1936     {
1937         // Close sockets
1938         BOOST_FOREACH(CNode* pnode, vNodes)
1939             if (pnode->hSocket != INVALID_SOCKET)
1940                 closesocket(pnode->hSocket);
1941         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1942             if (hListenSocket != INVALID_SOCKET)
1943                 if (closesocket(hListenSocket) == SOCKET_ERROR)
1944                     printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1945
1946 #ifdef WIN32
1947         // Shutdown Windows Sockets
1948         WSACleanup();
1949 #endif
1950     }
1951 }
1952 instance_of_cnetcleanup;
1953
1954 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1955 {
1956     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1957     ss.reserve(10000);
1958     ss << tx;
1959     RelayTransaction(tx, hash, ss);
1960 }
1961
1962 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1963 {
1964     CInv inv(MSG_TX, hash);
1965     {
1966         LOCK(cs_mapRelay);
1967         // Expire old relay messages
1968         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1969         {
1970             mapRelay.erase(vRelayExpiration.front().second);
1971             vRelayExpiration.pop_front();
1972         }
1973
1974         // Save original serialized message so newer versions are preserved
1975         mapRelay.insert(std::make_pair(inv, ss));
1976         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1977     }
1978
1979     RelayInventory(inv);
1980 }