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