Introduce nOneWeek constant
[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                 struct in_addr ip;
1185                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1186                 CAddress addr(CService(ip, GetDefaultPort()));
1187                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1188                 vAdd.push_back(addr);
1189             }
1190             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1191         }
1192
1193         // Add Tor nodes if we have connection with onion router
1194         if (mapArgs.count("-tor"))
1195         {
1196             std::vector<CAddress> vAdd;
1197             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1198             {
1199                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1200                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1201                 vAdd.push_back(addr);
1202             }
1203             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1204         }
1205
1206         //
1207         // Choose an address to connect to based on most recently seen
1208         //
1209         CAddress addrConnect;
1210
1211         // Only connect out to one peer per network group (/16 for IPv4).
1212         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1213         int nOutbound = 0;
1214         set<vector<unsigned char> > setConnected;
1215         {
1216             LOCK(cs_vNodes);
1217             BOOST_FOREACH(CNode* pnode, vNodes) {
1218                 if (!pnode->fInbound) {
1219                     setConnected.insert(pnode->addr.GetGroup());
1220                     nOutbound++;
1221                 }
1222             }
1223         }
1224
1225         int64_t nANow = GetAdjustedTime();
1226
1227         int nTries = 0;
1228         while (true)
1229         {
1230             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1231             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1232
1233             // if we selected an invalid address, restart
1234             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1235                 break;
1236
1237             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1238             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1239             // already-connected network ranges, ...) before trying new addrman addresses.
1240             nTries++;
1241             if (nTries > 100)
1242                 break;
1243
1244             if (IsLimited(addr))
1245                 continue;
1246
1247             // only consider very recently tried nodes after 30 failed attempts
1248             if (nANow - addr.nLastTry < 600 && nTries < 30)
1249                 continue;
1250
1251             // do not allow non-default ports, unless after 50 invalid addresses selected already
1252             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1253                 continue;
1254
1255             addrConnect = addr;
1256             break;
1257         }
1258
1259         if (addrConnect.IsValid())
1260             OpenNetworkConnection(addrConnect, &grant);
1261     }
1262 }
1263
1264 void ThreadOpenAddedConnections(void* parg)
1265 {
1266     // Make this thread recognisable as the connection opening thread
1267     RenameThread("novacoin-opencon");
1268
1269     try
1270     {
1271         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1272         ThreadOpenAddedConnections2(parg);
1273         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1274     }
1275     catch (std::exception& e) {
1276         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1277         PrintException(&e, "ThreadOpenAddedConnections()");
1278     } catch (...) {
1279         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1280         PrintException(NULL, "ThreadOpenAddedConnections()");
1281     }
1282     printf("ThreadOpenAddedConnections exited\n");
1283 }
1284
1285 void ThreadOpenAddedConnections2(void* parg)
1286 {
1287     printf("ThreadOpenAddedConnections started\n");
1288
1289     {
1290         LOCK(cs_vAddedNodes);
1291         vAddedNodes = mapMultiArgs["-addnode"];
1292     }
1293
1294     if (HaveNameProxy()) {
1295         while(!fShutdown) {
1296             list<string> lAddresses(0);
1297             {
1298                 LOCK(cs_vAddedNodes);
1299                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1300                     lAddresses.push_back(strAddNode);
1301             }
1302             BOOST_FOREACH(string& strAddNode, lAddresses) {
1303                 CAddress addr;
1304                 CSemaphoreGrant grant(*semOutbound);
1305                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1306                 Sleep(500);
1307             }
1308             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1309             Sleep(120000); // Retry every 2 minutes
1310             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1311         }
1312         return;
1313     }
1314
1315     for (uint32_t i = 0; true; i++)
1316     {
1317         list<string> lAddresses(0);
1318         {
1319             LOCK(cs_vAddedNodes);
1320             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1321                 lAddresses.push_back(strAddNode);
1322         }
1323
1324         list<vector<CService> > lservAddressesToAdd(0);
1325         BOOST_FOREACH(string& strAddNode, lAddresses)
1326         {
1327             vector<CService> vservNode(0);
1328             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1329             {
1330                 lservAddressesToAdd.push_back(vservNode);
1331                 {
1332                     LOCK(cs_setservAddNodeAddresses);
1333                     BOOST_FOREACH(CService& serv, vservNode)
1334                         setservAddNodeAddresses.insert(serv);
1335                 }
1336             }
1337         }
1338         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1339         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1340         {
1341             LOCK(cs_vNodes);
1342             BOOST_FOREACH(CNode* pnode, vNodes)
1343                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1344                 {
1345                     BOOST_FOREACH(CService& addrNode, *(it))
1346                         if (pnode->addr == addrNode)
1347                         {
1348                             it = lservAddressesToAdd.erase(it);
1349                             if(it != lservAddressesToAdd.begin())
1350                                 it--;
1351                             break;
1352                         }
1353                     if (it == lservAddressesToAdd.end())
1354                         break;
1355                 }
1356         }
1357         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1358         {
1359             if (vserv.size() == 0)
1360                 continue;
1361             CSemaphoreGrant grant(*semOutbound);
1362             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1363             Sleep(500);
1364             if (fShutdown)
1365                 return;
1366         }
1367         if (fShutdown)
1368             return;
1369         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1370         Sleep(120000); // Retry every 2 minutes
1371         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1372         if (fShutdown)
1373             return;
1374     }
1375 }
1376
1377 // if successful, this moves the passed grant to the constructed node
1378 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1379 {
1380     //
1381     // Initiate outbound network connection
1382     //
1383     if (fShutdown)
1384         return false;
1385     if (!strDest)
1386         if (IsLocal(addrConnect) ||
1387             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1388             FindNode(addrConnect.ToStringIPPort().c_str()))
1389             return false;
1390     if (strDest && FindNode(strDest))
1391         return false;
1392
1393     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1394     CNode* pnode = ConnectNode(addrConnect, strDest);
1395     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1396     if (fShutdown)
1397         return false;
1398     if (!pnode)
1399         return false;
1400     if (grantOutbound)
1401         grantOutbound->MoveTo(pnode->grantOutbound);
1402     pnode->fNetworkNode = true;
1403     if (fOneShot)
1404         pnode->fOneShot = true;
1405
1406     return true;
1407 }
1408
1409 // for now, use a very simple selection metric: the node from which we received
1410 // most recently
1411 static int64_t NodeSyncScore(const CNode *pnode) {
1412     return pnode->nLastRecv;
1413 }
1414
1415 void static StartSync(const vector<CNode*> &vNodes) {
1416     CNode *pnodeNewSync = NULL;
1417     int64_t nBestScore = 0;
1418
1419     // Iterate over all nodes
1420     BOOST_FOREACH(CNode* pnode, vNodes) {
1421         // check preconditions for allowing a sync
1422         if (!pnode->fClient && !pnode->fOneShot &&
1423             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1424             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1425             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1426             // if ok, compare node's score with the best so far
1427             int64_t nScore = NodeSyncScore(pnode);
1428             if (pnodeNewSync == NULL || nScore > nBestScore) {
1429                 pnodeNewSync = pnode;
1430                 nBestScore = nScore;
1431             }
1432         }
1433     }
1434     // if a new sync candidate was found, start sync!
1435     if (pnodeNewSync) {
1436         pnodeNewSync->fStartSync = true;
1437         pnodeSync = pnodeNewSync;
1438     }
1439 }
1440
1441 void ThreadMessageHandler(void* parg)
1442 {
1443     // Make this thread recognisable as the message handling thread
1444     RenameThread("novacoin-msghand");
1445
1446     try
1447     {
1448         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1449         ThreadMessageHandler2(parg);
1450         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1451     }
1452     catch (std::exception& e) {
1453         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1454         PrintException(&e, "ThreadMessageHandler()");
1455     } catch (...) {
1456         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1457         PrintException(NULL, "ThreadMessageHandler()");
1458     }
1459     printf("ThreadMessageHandler exited\n");
1460 }
1461
1462 void ThreadMessageHandler2(void* parg)
1463 {
1464     printf("ThreadMessageHandler started\n");
1465     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1466     while (!fShutdown)
1467     {
1468         bool fHaveSyncNode = false;
1469         vector<CNode*> vNodesCopy;
1470         {
1471             LOCK(cs_vNodes);
1472             vNodesCopy = vNodes;
1473             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1474                 pnode->AddRef();
1475                 if (pnode == pnodeSync)
1476                     fHaveSyncNode = true;
1477             }
1478         }
1479
1480         if (!fHaveSyncNode)
1481             StartSync(vNodesCopy);
1482
1483         // Poll the connected nodes for messages
1484         CNode* pnodeTrickle = NULL;
1485         if (!vNodesCopy.empty())
1486             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1487         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1488         {
1489             // Receive messages
1490             {
1491                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1492                 if (lockRecv)
1493                     ProcessMessages(pnode);
1494             }
1495             if (fShutdown)
1496                 return;
1497
1498             // Send messages
1499             {
1500                 TRY_LOCK(pnode->cs_vSend, lockSend);
1501                 if (lockSend)
1502                     SendMessages(pnode, pnode == pnodeTrickle);
1503             }
1504             if (fShutdown)
1505                 return;
1506         }
1507
1508         {
1509             LOCK(cs_vNodes);
1510             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1511                 pnode->Release();
1512         }
1513
1514         // Wait and allow messages to bunch up.
1515         // Reduce vnThreadsRunning so StopNode has permission to exit while
1516         // we're sleeping, but we must always check fShutdown after doing this.
1517         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1518         Sleep(100);
1519         if (fRequestShutdown)
1520             StartShutdown();
1521         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1522         if (fShutdown)
1523             return;
1524     }
1525 }
1526
1527
1528
1529
1530
1531
1532 bool BindListenPort(const CService &addrBind, string& strError)
1533 {
1534     strError = "";
1535     int nOne = 1;
1536
1537     // Create socket for listening for incoming connections
1538 #ifdef USE_IPV6
1539     struct sockaddr_storage sockaddr;
1540 #else
1541     struct sockaddr sockaddr;
1542 #endif
1543     socklen_t len = sizeof(sockaddr);
1544     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1545     {
1546         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1547         printf("%s\n", strError.c_str());
1548         return false;
1549     }
1550
1551     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1552     if (hListenSocket == INVALID_SOCKET)
1553     {
1554         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1555         printf("%s\n", strError.c_str());
1556         return false;
1557     }
1558
1559 #ifndef WIN32
1560 #ifdef SO_NOSIGPIPE
1561     // Different way of disabling SIGPIPE on BSD
1562     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1563 #endif
1564     // Allow binding if the port is still in TIME_WAIT state after
1565     // the program was closed and restarted. Not an issue on windows!
1566     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1567 #endif
1568
1569 #ifdef WIN32
1570     // Set to non-blocking, incoming connections will also inherit this
1571     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1572 #else
1573     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1574 #endif
1575     {
1576         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1577         printf("%s\n", strError.c_str());
1578         return false;
1579     }
1580
1581 #ifdef USE_IPV6
1582     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1583     // and enable it by default or not. Try to enable it, if possible.
1584     if (addrBind.IsIPv6()) {
1585 #ifdef IPV6_V6ONLY
1586 #ifdef WIN32
1587         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1588 #else
1589         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1590 #endif
1591 #endif
1592 #ifdef WIN32
1593         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1594         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1595 #endif
1596     }
1597 #endif
1598
1599     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1600     {
1601         int nErr = WSAGetLastError();
1602         if (nErr == WSAEADDRINUSE)
1603             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1604         else
1605             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1606         printf("%s\n", strError.c_str());
1607         CloseSocket(hListenSocket);
1608         return false;
1609     }
1610     printf("Bound to %s\n", addrBind.ToString().c_str());
1611
1612     // Listen for incoming connections
1613     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1614     {
1615         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1616         printf("%s\n", strError.c_str());
1617         CloseSocket(hListenSocket);
1618         return false;
1619     }
1620
1621     vhListenSocket.push_back(hListenSocket);
1622
1623     if (addrBind.IsRoutable() && fDiscover)
1624         AddLocal(addrBind, LOCAL_BIND);
1625
1626     return true;
1627 }
1628
1629 void static Discover()
1630 {
1631     if (!fDiscover)
1632         return;
1633
1634 #ifdef WIN32
1635     // Get local host IP
1636     char pszHostName[1000] = "";
1637     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1638     {
1639         vector<CNetAddr> vaddr;
1640         if (LookupHost(pszHostName, vaddr))
1641         {
1642             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1643             {
1644                 AddLocal(addr, LOCAL_IF);
1645             }
1646         }
1647     }
1648 #else
1649     // Get local host ip
1650     struct ifaddrs* myaddrs;
1651     if (getifaddrs(&myaddrs) == 0)
1652     {
1653         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1654         {
1655             if (ifa->ifa_addr == NULL) continue;
1656             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1657             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1658             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1659             if (ifa->ifa_addr->sa_family == AF_INET)
1660             {
1661                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1662                 CNetAddr addr(s4->sin_addr);
1663                 if (AddLocal(addr, LOCAL_IF))
1664                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1665             }
1666 #ifdef USE_IPV6
1667             else if (ifa->ifa_addr->sa_family == AF_INET6)
1668             {
1669                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1670                 CNetAddr addr(s6->sin6_addr);
1671                 if (AddLocal(addr, LOCAL_IF))
1672                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1673             }
1674 #endif
1675         }
1676         freeifaddrs(myaddrs);
1677     }
1678 #endif
1679
1680     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1681     if (!IsLimited(NET_IPV4))
1682         NewThread(ThreadGetMyExternalIP, NULL);
1683 }
1684
1685 void StartNode(void* parg)
1686 {
1687     // Make this thread recognisable as the startup thread
1688     RenameThread("novacoin-start");
1689
1690     if (semOutbound == NULL) {
1691         // initialize semaphore
1692         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1693         semOutbound = new CSemaphore(nMaxOutbound);
1694     }
1695
1696     if (pnodeLocalHost == NULL)
1697         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1698
1699     Discover();
1700
1701     //
1702     // Start threads
1703     //
1704
1705     if (!GetBoolArg("-dnsseed", true))
1706         printf("DNS seeding disabled\n");
1707     else
1708         if (!NewThread(ThreadDNSAddressSeed, NULL))
1709             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1710
1711     // Get addresses from IRC and advertise ours
1712     if (!GetBoolArg("-irc", true))
1713         printf("IRC seeding disabled\n");
1714     else
1715         if (!NewThread(ThreadIRCSeed, NULL))
1716             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1717
1718     // Send and receive from sockets, accept connections
1719     if (!NewThread(ThreadSocketHandler, NULL))
1720         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1721
1722     // Initiate outbound connections from -addnode
1723     if (!NewThread(ThreadOpenAddedConnections, NULL))
1724         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1725
1726     // Initiate outbound connections
1727     if (!NewThread(ThreadOpenConnections, NULL))
1728         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1729
1730     // Process messages
1731     if (!NewThread(ThreadMessageHandler, NULL))
1732         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1733
1734     // Dump network addresses
1735     if (!NewThread(ThreadDumpAddress, NULL))
1736         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1737
1738     // Mine proof-of-stake blocks in the background
1739     if (!NewThread(ThreadStakeMiner, pwalletMain))
1740         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1741
1742     // Trusted NTP server, it's localhost by default.
1743     strTrustedUpstream = GetArg("-ntp", "localhost");
1744
1745     // Start periodical NTP sampling thread
1746     NewThread(ThreadNtpSamples, NULL);
1747
1748 }
1749
1750 bool StopNode()
1751 {
1752     printf("StopNode()\n");
1753     fShutdown = true;
1754     nTransactionsUpdated++;
1755     int64_t nStart = GetTime();
1756     {
1757         LOCK(cs_main);
1758         ThreadScriptCheckQuit();
1759     }
1760     if (semOutbound)
1761         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1762             semOutbound->post();
1763     do
1764     {
1765         int nThreadsRunning = 0;
1766         for (int n = 0; n < THREAD_MAX; n++)
1767             nThreadsRunning += vnThreadsRunning[n];
1768         if (nThreadsRunning == 0)
1769             break;
1770         if (GetTime() - nStart > 20)
1771             break;
1772         Sleep(20);
1773     } while(true);
1774     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1775     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1776     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1777     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1778     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1779     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1780     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1781     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1782     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1783     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1784     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1785         Sleep(20);
1786     Sleep(50);
1787     DumpAddresses();
1788
1789     return true;
1790 }
1791
1792 class CNetCleanup
1793 {
1794 public:
1795     CNetCleanup()
1796     {
1797     }
1798     ~CNetCleanup()
1799     {
1800         // Close sockets
1801         BOOST_FOREACH(CNode* pnode, vNodes)
1802             if (pnode->hSocket != INVALID_SOCKET)
1803                 CloseSocket(pnode->hSocket);
1804         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1805             if (hListenSocket != INVALID_SOCKET)
1806                 if (!CloseSocket(hListenSocket))
1807                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1808
1809         // clean up some globals (to help leak detection)
1810         BOOST_FOREACH(CNode *pnode, vNodes)
1811             delete pnode;
1812         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1813             delete pnode;
1814         vNodes.clear();
1815         vNodesDisconnected.clear();
1816         delete semOutbound;
1817         semOutbound = NULL;
1818         delete pnodeLocalHost;
1819         pnodeLocalHost = NULL;
1820
1821 #ifdef WIN32
1822         // Shutdown Windows Sockets
1823         WSACleanup();
1824 #endif
1825     }
1826 }
1827 instance_of_cnetcleanup;
1828
1829 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1830 {
1831     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1832     ss.reserve(10000);
1833     ss << tx;
1834     RelayTransaction(tx, hash, ss);
1835 }
1836
1837 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1838 {
1839     CInv inv(MSG_TX, hash);
1840     {
1841         LOCK(cs_mapRelay);
1842         // Expire old relay messages
1843         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1844         {
1845             mapRelay.erase(vRelayExpiration.front().second);
1846             vRelayExpiration.pop_front();
1847         }
1848
1849         // Save original serialized message so newer versions are preserved
1850         mapRelay.insert(std::make_pair(inv, ss));
1851         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1852     }
1853
1854     RelayInventory(inv);
1855 }
1856
1857 void CNode::RecordBytesRecv(uint64_t bytes)
1858 {
1859     LOCK(cs_totalBytesRecv);
1860     nTotalBytesRecv += bytes;
1861 }
1862
1863 void CNode::RecordBytesSent(uint64_t bytes)
1864 {
1865     LOCK(cs_totalBytesSent);
1866     nTotalBytesSent += bytes;
1867 }
1868
1869 uint64_t CNode::GetTotalBytesRecv()
1870 {
1871     LOCK(cs_totalBytesRecv);
1872     return nTotalBytesRecv;
1873 }
1874
1875 uint64_t CNode::GetTotalBytesSent()
1876 {
1877     LOCK(cs_totalBytesSent);
1878     return nTotalBytesSent;
1879 }