Merge pull request #295 from svost/patch
[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.clear();
146     for ( ; ; )
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 void Release(CNode* node) {
574     node->Release();
575 }
576
577
578
579
580
581 void ThreadSocketHandler(void* parg)
582 {
583     // Make this thread recognisable as the networking thread
584     RenameThread("novacoin-net");
585
586     try
587     {
588         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
589         ThreadSocketHandler2(parg);
590         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
591     }
592     catch (std::exception& e) {
593         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
594         PrintException(&e, "ThreadSocketHandler()");
595     } catch (...) {
596         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
597         throw; // support pthread_cancel()
598     }
599     printf("ThreadSocketHandler exited\n");
600 }
601
602 static list<CNode*> vNodesDisconnected;
603
604 void ThreadSocketHandler2(void* parg)
605 {
606     printf("ThreadSocketHandler started\n");
607     size_t nPrevNodeCount = 0;
608     for ( ; ; )
609     {
610         //
611         // Disconnect nodes
612         //
613         {
614             LOCK(cs_vNodes);
615             // Disconnect unused nodes
616             vector<CNode*> vNodesCopy = vNodes;
617             BOOST_FOREACH(CNode* pnode, vNodesCopy)
618             {
619                 if (pnode->fDisconnect ||
620                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
621                 {
622                     // remove from vNodes
623                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
624
625                     // release outbound grant (if any)
626                     pnode->grantOutbound.Release();
627
628                     // close socket and cleanup
629                     pnode->CloseSocketDisconnect();
630                     pnode->Cleanup();
631
632                     // hold in disconnected pool until all refs are released
633                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
634                     if (pnode->fNetworkNode || pnode->fInbound)
635                         pnode->Release();
636                     vNodesDisconnected.push_back(pnode);
637                 }
638             }
639
640             // Delete disconnected nodes
641             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
642             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
643             {
644                 // wait until threads are done using it
645                 if (pnode->GetRefCount() <= 0)
646                 {
647                     bool fDelete = false;
648                     {
649                         TRY_LOCK(pnode->cs_vSend, lockSend);
650                         if (lockSend)
651                         {
652                             TRY_LOCK(pnode->cs_vRecv, lockRecv);
653                             if (lockRecv)
654                             {
655                                 TRY_LOCK(pnode->cs_mapRequests, lockReq);
656                                 if (lockReq)
657                                 {
658                                     TRY_LOCK(pnode->cs_inventory, lockInv);
659                                     if (lockInv)
660                                         fDelete = true;
661                                 }
662                             }
663                         }
664                     }
665                     if (fDelete)
666                     {
667                         vNodesDisconnected.remove(pnode);
668                         delete pnode;
669                     }
670                 }
671             }
672         }
673         if (vNodes.size() != nPrevNodeCount)
674         {
675             nPrevNodeCount = vNodes.size();
676             uiInterface.NotifyNumConnectionsChanged(vNodes.size());
677         }
678
679
680         //
681         // Find which sockets have data to receive
682         //
683         struct timeval timeout;
684         timeout.tv_sec  = 0;
685         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
686
687         fd_set fdsetRecv;
688         fd_set fdsetSend;
689         fd_set fdsetError;
690         FD_ZERO(&fdsetRecv);
691         FD_ZERO(&fdsetSend);
692         FD_ZERO(&fdsetError);
693         SOCKET hSocketMax = 0;
694         bool have_fds = false;
695
696         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
697             FD_SET(hListenSocket, &fdsetRecv);
698             hSocketMax = max(hSocketMax, hListenSocket);
699             have_fds = true;
700         }
701         {
702             LOCK(cs_vNodes);
703             BOOST_FOREACH(CNode* pnode, vNodes)
704             {
705                 if (pnode->hSocket == INVALID_SOCKET)
706                     continue;
707                 FD_SET(pnode->hSocket, &fdsetRecv);
708                 FD_SET(pnode->hSocket, &fdsetError);
709                 hSocketMax = max(hSocketMax, pnode->hSocket);
710                 have_fds = true;
711                 {
712                     TRY_LOCK(pnode->cs_vSend, lockSend);
713                     if (lockSend && !pnode->vSend.empty())
714                         FD_SET(pnode->hSocket, &fdsetSend);
715                 }
716             }
717         }
718
719         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
720         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
721                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
722         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
723         if (fShutdown)
724             return;
725         if (nSelect == SOCKET_ERROR)
726         {
727             if (have_fds)
728             {
729                 int nErr = WSAGetLastError();
730                 printf("socket select error %d\n", nErr);
731                 for (unsigned int i = 0; i <= hSocketMax; i++)
732                     FD_SET(i, &fdsetRecv);
733             }
734             FD_ZERO(&fdsetSend);
735             FD_ZERO(&fdsetError);
736             Sleep(timeout.tv_usec/1000);
737         }
738
739
740         //
741         // Accept new connections
742         //
743         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
744         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
745         {
746 #ifdef USE_IPV6
747             struct sockaddr_storage sockaddr;
748 #else
749             struct sockaddr sockaddr;
750 #endif
751             socklen_t len = sizeof(sockaddr);
752             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
753             CAddress addr;
754             int nInbound = 0;
755
756             if (hSocket != INVALID_SOCKET)
757                 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
758                     printf("Warning: Unknown socket family\n");
759
760             {
761                 LOCK(cs_vNodes);
762                 BOOST_FOREACH(CNode* pnode, vNodes)
763                     if (pnode->fInbound)
764                         nInbound++;
765             }
766
767             if (hSocket == INVALID_SOCKET)
768             {
769                 int nErr = WSAGetLastError();
770                 if (nErr != WSAEWOULDBLOCK)
771                     printf("socket error accept failed: %d\n", nErr);
772             }
773             else if (nInbound >= GetArgInt("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
774             {
775                 {
776                     LOCK(cs_setservAddNodeAddresses);
777                     if (!setservAddNodeAddresses.count(addr))
778                         CloseSocket(hSocket);
779                 }
780             }
781             else if (CNode::IsBanned(addr))
782             {
783                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
784                 CloseSocket(hSocket);
785             }
786             else
787             {
788                 printf("accepted connection %s\n", addr.ToString().c_str());
789                 CNode* pnode = new CNode(hSocket, addr, "", true);
790                 pnode->AddRef();
791                 {
792                     LOCK(cs_vNodes);
793                     vNodes.push_back(pnode);
794                 }
795             }
796         }
797
798
799         //
800         // Service each socket
801         //
802         vector<CNode*> vNodesCopy;
803         {
804             LOCK(cs_vNodes);
805             vNodesCopy = vNodes;
806             BOOST_FOREACH(CNode* pnode, vNodesCopy)
807                 pnode->AddRef();
808         }
809         BOOST_FOREACH(CNode* pnode, vNodesCopy)
810         {
811             if (fShutdown)
812                 return;
813
814             //
815             // Receive
816             //
817             if (pnode->hSocket == INVALID_SOCKET)
818                 continue;
819             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
820             {
821                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
822                 if (lockRecv)
823                 {
824                     CDataStream& vRecv = pnode->vRecv;
825                     uint64_t nPos = vRecv.size();
826
827                     if (nPos > ReceiveBufferSize()) {
828                         if (!pnode->fDisconnect)
829                             printf("socket recv flood control disconnect (%" PRIszu " bytes)\n", vRecv.size());
830                         pnode->CloseSocketDisconnect();
831                     }
832                     else {
833                         // typical socket buffer is 8K-64K
834                         char pchBuf[0x10000];
835                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
836                         if (nBytes > 0)
837                         {
838                             vRecv.resize(nPos + nBytes);
839                             memcpy(&vRecv[nPos], pchBuf, nBytes);
840                             pnode->nLastRecv = GetTime();
841                             pnode->nRecvBytes += nBytes;
842                             pnode->RecordBytesRecv(nBytes);
843                         }
844                         else if (nBytes == 0)
845                         {
846                             // socket closed gracefully
847                             if (!pnode->fDisconnect)
848                                 printf("socket closed\n");
849                             pnode->CloseSocketDisconnect();
850                         }
851                         else if (nBytes < 0)
852                         {
853                             // error
854                             int nErr = WSAGetLastError();
855                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
856                             {
857                                 if (!pnode->fDisconnect)
858                                     printf("socket recv error %d\n", nErr);
859                                 pnode->CloseSocketDisconnect();
860                             }
861                         }
862                     }
863                 }
864             }
865
866             //
867             // Send
868             //
869             if (pnode->hSocket == INVALID_SOCKET)
870                 continue;
871             if (FD_ISSET(pnode->hSocket, &fdsetSend))
872             {
873                 TRY_LOCK(pnode->cs_vSend, lockSend);
874                 if (lockSend)
875                 {
876                     CDataStream& vSend = pnode->vSend;
877                     if (!vSend.empty())
878                     {
879                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
880                         if (nBytes > 0)
881                         {
882                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
883                             pnode->nLastSend = GetTime();
884                             pnode->nSendBytes += nBytes;
885                             pnode->RecordBytesSent(nBytes);
886                         }
887                         else if (nBytes < 0)
888                         {
889                             // error
890                             int nErr = WSAGetLastError();
891                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
892                             {
893                                 printf("socket send error %d\n", nErr);
894                                 pnode->CloseSocketDisconnect();
895                             }
896                         }
897                     }
898                 }
899             }
900
901             //
902             // Inactivity checking
903             //
904             if (pnode->vSend.empty())
905                 pnode->nLastSendEmpty = GetTime();
906             if (GetTime() - pnode->nTimeConnected > 60)
907             {
908                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
909                 {
910                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
911                     pnode->fDisconnect = true;
912                 }
913                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
914                 {
915                     printf("socket not sending\n");
916                     pnode->fDisconnect = true;
917                 }
918                 else if (GetTime() - pnode->nLastRecv > 90*60)
919                 {
920                     printf("socket inactivity timeout\n");
921                     pnode->fDisconnect = true;
922                 }
923             }
924         }
925         {
926             LOCK(cs_vNodes);
927             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
928         }
929
930         Sleep(10);
931     }
932 }
933
934 // DNS seeds
935 // Each pair gives a source name and a seed name.
936 // The first name is used as information source for addrman.
937 // The second name should resolve to a list of seed addresses.
938 static const char *strDNSSeed[][2] = {
939     {"novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro"},
940     {"novacoin.ru", "dnsseed.novacoin.ru"},
941     {"novacoin.ru", "testseed.novacoin.ru"},
942     {"novaco.in", "dnsseed.novaco.in"},
943 };
944
945 void ThreadDNSAddressSeed(void* parg)
946 {
947     // Make this thread recognisable as the DNS seeding thread
948     RenameThread("novacoin-dnsseed");
949
950     try
951     {
952         vnThreadsRunning[THREAD_DNSSEED]++;
953         ThreadDNSAddressSeed2(parg);
954         vnThreadsRunning[THREAD_DNSSEED]--;
955     }
956     catch (std::exception& e) {
957         vnThreadsRunning[THREAD_DNSSEED]--;
958         PrintException(&e, "ThreadDNSAddressSeed()");
959     } catch (...) {
960         vnThreadsRunning[THREAD_DNSSEED]--;
961         throw; // support pthread_cancel()
962     }
963     printf("ThreadDNSAddressSeed exited\n");
964 }
965
966 void ThreadDNSAddressSeed2(void* parg)
967 {
968     printf("ThreadDNSAddressSeed started\n");
969     int found = 0;
970
971     if (!fTestNet)
972     {
973         printf("Loading addresses from DNS seeds (could take a while)\n");
974
975         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
976             if (HaveNameProxy()) {
977                 AddOneShot(strDNSSeed[seed_idx][1]);
978             } else {
979                 vector<CNetAddr> vaddr;
980                 vector<CAddress> vAdd;
981                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
982                 {
983                     BOOST_FOREACH(CNetAddr& ip, vaddr)
984                     {
985                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
986                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
987                         vAdd.push_back(addr);
988                         found++;
989                     }
990                 }
991                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
992             }
993         }
994     }
995
996     printf("%d addresses found from DNS seeds\n", found);
997 }
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 uint32_t pnSeed[] =
1011 {
1012     0xa52bf0da, 0x30aa43d8, 0x614488d5, 0x517b6fd5, 0xd4bf62d4, 0xb7d638d4, 0xbc12bcd1, 0xa2501bc6,
1013     0xfde617c6, 0x3337b1c6, 0x1dcd71c3, 0x2c1544c1, 0xe05f6ac1, 0x852f63c0, 0x3e2363c0, 0x15f563c0,
1014     0x430d63c0, 0x50d6a9c0, 0xf0a679c0, 0xefdeedbf, 0x7aaee8bc, 0x3a3dbbbc, 0xef218abc, 0x0bef78bc,
1015     0x8baa3eb2, 0x2bf913b2, 0x24ed9fb2, 0xb42289b2, 0x718a09b0, 0xe9433eb0, 0x559425b0, 0xc97e1fb0,
1016     0x18e1d4b0, 0x8f6cc1b0, 0xac3838ae, 0x86c0ffad, 0x6b0272a7, 0xa463f8a2, 0x6f17f3a2, 0xb3d6f3a2,
1017     0x9cd8f997, 0xd513fb94, 0x39e64880, 0x3859dd6f, 0x0b08fe6d, 0xe601fe6d, 0xeb44a26d, 0xfe53186c,
1018     0x203c2e68, 0x1c542868, 0x0caa8368, 0xb8748368, 0xccca4762, 0xc637555f, 0x638a545f, 0x59b2205f,
1019     0x52568c5f, 0xba568c5f, 0x8a568c5f, 0x31b0f45e, 0x54a0f45e, 0x37d6f15e, 0xc520175e, 0x7620175e,
1020     0xc310175e, 0x8e33b45e, 0x7abb5f5d, 0xd3014c5d, 0xa1e1485d, 0x9947645d, 0xfab8ff5c, 0xa979e65b,
1021     0xa879e65b, 0x9f79e65b, 0x9fa3d25b, 0x112a925b, 0x7b92905b, 0x60647a5b, 0x1e389d5a, 0x851afa59,
1022     0x0185ef59, 0x26549b59, 0x1c9efe57, 0xc54c1256, 0x1ad51955, 0x19d21955, 0x73c41955, 0x3f74ee55,
1023     0x633eea55, 0x6883d655, 0xfb72c655, 0x5360a653, 0x17c1ea52, 0xc661c852, 0x1ecdc852, 0x006a9752,
1024     0xf72d9252, 0x82650551, 0x36f1c851, 0x33f1c851, 0xd5c1864f, 0xb6bf1b4e, 0x96da184e, 0x40d0234d,
1025     0x9a96ab4c, 0x8fc2a84c, 0xb5dbd048, 0xf4644447, 0x2d51af47, 0xa9625445, 0x83f05243, 0x89672941,
1026     0x3a8bad3e, 0xf0a05436, 0x6ab7c936, 0x49971d32, 0xadd4482e, 0xcffd212e, 0x6730bc2e, 0x839aa12e,
1027     0x68d9692e, 0xc7183b25, 0x6c47bb25, 0x2490bb25, 0xad651c1f, 0x048a861f, 0x6937811f, 0x064b2d05,
1028     0x4d226805,
1029 };
1030
1031 const char* pchTorSeed[] = 
1032 {
1033     "seedp4knqnoei57u.onion",
1034     "seedr3hhlepyi7fd.onion",
1035     "seed3uuomkclbiz4.onion",
1036     "seedeh7qck3ouff5.onion",
1037     "5rg3vq4jagckeckf.onion",
1038     "seedt3sraf53ajiy.onion",
1039     "seedg4qyccsg42oq.onion",
1040     "novaqrtoywpg7jly.onion",
1041     "seed3d5wolqbgrcb.onion",
1042     "seed24u5dwph3qw4.onion",
1043     "mj26ulzbs2oskgym.onion",
1044     "eqon4usunavt76m7.onion",
1045     "seedd3aldwpslzl3.onion"
1046 };
1047
1048 void DumpAddresses()
1049 {
1050     int64_t nStart = GetTimeMillis();
1051
1052     CAddrDB adb;
1053     adb.Write(addrman);
1054
1055     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1056            addrman.size(), GetTimeMillis() - nStart);
1057 }
1058
1059 void ThreadDumpAddress2(void* parg)
1060 {
1061     printf("ThreadDumpAddress started\n");
1062
1063     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1064     while (!fShutdown)
1065     {
1066         DumpAddresses();
1067         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1068         Sleep(600000);
1069         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1070     }
1071     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1072 }
1073
1074 void ThreadDumpAddress(void* parg)
1075 {
1076     // Make this thread recognisable as the address dumping thread
1077     RenameThread("novacoin-adrdump");
1078
1079     try
1080     {
1081         ThreadDumpAddress2(parg);
1082     }
1083     catch (std::exception& e) {
1084         PrintException(&e, "ThreadDumpAddress()");
1085     }
1086     printf("ThreadDumpAddress exited\n");
1087 }
1088
1089 void ThreadOpenConnections(void* parg)
1090 {
1091     // Make this thread recognisable as the connection opening thread
1092     RenameThread("novacoin-opencon");
1093
1094     try
1095     {
1096         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1097         ThreadOpenConnections2(parg);
1098         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1099     }
1100     catch (std::exception& e) {
1101         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1102         PrintException(&e, "ThreadOpenConnections()");
1103     } catch (...) {
1104         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1105         PrintException(NULL, "ThreadOpenConnections()");
1106     }
1107     printf("ThreadOpenConnections exited\n");
1108 }
1109
1110 void static ProcessOneShot()
1111 {
1112     string strDest;
1113     {
1114         LOCK(cs_vOneShots);
1115         if (vOneShots.empty())
1116             return;
1117         strDest = vOneShots.front();
1118         vOneShots.pop_front();
1119     }
1120     CAddress addr;
1121     CSemaphoreGrant grant(*semOutbound, true);
1122     if (grant) {
1123         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1124             AddOneShot(strDest);
1125     }
1126 }
1127
1128 void ThreadOpenConnections2(void* parg)
1129 {
1130     printf("ThreadOpenConnections started\n");
1131
1132     // Connect to specific addresses
1133     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1134     {
1135         for (int64_t nLoop = 0;; nLoop++)
1136         {
1137             ProcessOneShot();
1138             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1139             {
1140                 CAddress addr;
1141                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1142                 for (int i = 0; i < 10 && i < nLoop; i++)
1143                 {
1144                     Sleep(500);
1145                     if (fShutdown)
1146                         return;
1147                 }
1148             }
1149             Sleep(500);
1150         }
1151     }
1152
1153     // Initiate network connections
1154     int64_t nStart = GetTime();
1155     for ( ; ; )
1156     {
1157         ProcessOneShot();
1158
1159         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1160         Sleep(500);
1161         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1162         if (fShutdown)
1163             return;
1164
1165
1166         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1167         CSemaphoreGrant grant(*semOutbound);
1168         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1169         if (fShutdown)
1170             return;
1171
1172         // Add seed nodes if IRC isn't working
1173         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1174         {
1175             std::vector<CAddress> vAdd;
1176             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1177             {
1178                 // It'll only connect to one or two seed nodes because once it connects,
1179                 // it'll get a pile of addresses with newer timestamps.
1180                 // Seed nodes are given a random 'last seen time' of between one and two
1181                 // weeks ago.
1182                 struct in_addr ip;
1183                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1184                 CAddress addr(CService(ip, GetDefaultPort()));
1185                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1186                 vAdd.push_back(addr);
1187             }
1188             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1189         }
1190
1191         // Add Tor nodes if we have connection with onion router
1192         if (mapArgs.count("-tor"))
1193         {
1194             std::vector<CAddress> vAdd;
1195             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1196             {
1197                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1198                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1199                 vAdd.push_back(addr);
1200             }
1201             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1202         }
1203
1204         //
1205         // Choose an address to connect to based on most recently seen
1206         //
1207         CAddress addrConnect;
1208
1209         // Only connect out to one peer per network group (/16 for IPv4).
1210         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1211         int nOutbound = 0;
1212         set<vector<unsigned char> > setConnected;
1213         {
1214             LOCK(cs_vNodes);
1215             BOOST_FOREACH(CNode* pnode, vNodes) {
1216                 if (!pnode->fInbound) {
1217                     setConnected.insert(pnode->addr.GetGroup());
1218                     nOutbound++;
1219                 }
1220             }
1221         }
1222
1223         int64_t nANow = GetAdjustedTime();
1224
1225         int nTries = 0;
1226         for ( ; ; )
1227         {
1228             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1229             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1230
1231             // if we selected an invalid address, restart
1232             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1233                 break;
1234
1235             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1236             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1237             // already-connected network ranges, ...) before trying new addrman addresses.
1238             nTries++;
1239             if (nTries > 100)
1240                 break;
1241
1242             if (IsLimited(addr))
1243                 continue;
1244
1245             // only consider very recently tried nodes after 30 failed attempts
1246             if (nANow - addr.nLastTry < 600 && nTries < 30)
1247                 continue;
1248
1249             // do not allow non-default ports, unless after 50 invalid addresses selected already
1250             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1251                 continue;
1252
1253             addrConnect = addr;
1254             break;
1255         }
1256
1257         if (addrConnect.IsValid())
1258             OpenNetworkConnection(addrConnect, &grant);
1259     }
1260 }
1261
1262 void ThreadOpenAddedConnections(void* parg)
1263 {
1264     // Make this thread recognisable as the connection opening thread
1265     RenameThread("novacoin-opencon");
1266
1267     try
1268     {
1269         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1270         ThreadOpenAddedConnections2(parg);
1271         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1272     }
1273     catch (std::exception& e) {
1274         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1275         PrintException(&e, "ThreadOpenAddedConnections()");
1276     } catch (...) {
1277         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1278         PrintException(NULL, "ThreadOpenAddedConnections()");
1279     }
1280     printf("ThreadOpenAddedConnections exited\n");
1281 }
1282
1283 void ThreadOpenAddedConnections2(void* parg)
1284 {
1285     printf("ThreadOpenAddedConnections started\n");
1286
1287     {
1288         LOCK(cs_vAddedNodes);
1289         vAddedNodes = mapMultiArgs["-addnode"];
1290     }
1291
1292     if (HaveNameProxy()) {
1293         while(!fShutdown) {
1294             list<string> lAddresses(0);
1295             {
1296                 LOCK(cs_vAddedNodes);
1297                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1298                     lAddresses.push_back(strAddNode);
1299             }
1300             BOOST_FOREACH(string& strAddNode, lAddresses) {
1301                 CAddress addr;
1302                 CSemaphoreGrant grant(*semOutbound);
1303                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1304                 Sleep(500);
1305             }
1306             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1307             Sleep(120000); // Retry every 2 minutes
1308             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1309         }
1310         return;
1311     }
1312
1313     for (uint32_t i = 0; true; i++)
1314     {
1315         list<string> lAddresses(0);
1316         {
1317             LOCK(cs_vAddedNodes);
1318             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1319                 lAddresses.push_back(strAddNode);
1320         }
1321
1322         list<vector<CService> > lservAddressesToAdd(0);
1323         BOOST_FOREACH(string& strAddNode, lAddresses)
1324         {
1325             vector<CService> vservNode(0);
1326             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1327             {
1328                 lservAddressesToAdd.push_back(vservNode);
1329                 {
1330                     LOCK(cs_setservAddNodeAddresses);
1331                     BOOST_FOREACH(CService& serv, vservNode)
1332                         setservAddNodeAddresses.insert(serv);
1333                 }
1334             }
1335         }
1336         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1337         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1338         {
1339             LOCK(cs_vNodes);
1340             BOOST_FOREACH(CNode* pnode, vNodes)
1341                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1342                 {
1343                     BOOST_FOREACH(CService& addrNode, *(it))
1344                         if (pnode->addr == addrNode)
1345                         {
1346                             it = lservAddressesToAdd.erase(it);
1347                             if(it != lservAddressesToAdd.begin())
1348                                 it--;
1349                             break;
1350                         }
1351                     if (it == lservAddressesToAdd.end())
1352                         break;
1353                 }
1354         }
1355         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1356         {
1357             if (vserv.size() == 0)
1358                 continue;
1359             CSemaphoreGrant grant(*semOutbound);
1360             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1361             Sleep(500);
1362             if (fShutdown)
1363                 return;
1364         }
1365         if (fShutdown)
1366             return;
1367         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1368         Sleep(120000); // Retry every 2 minutes
1369         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1370         if (fShutdown)
1371             return;
1372     }
1373 }
1374
1375 // if successful, this moves the passed grant to the constructed node
1376 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1377 {
1378     //
1379     // Initiate outbound network connection
1380     //
1381     if (fShutdown)
1382         return false;
1383     if (!strDest)
1384         if (IsLocal(addrConnect) ||
1385             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1386             FindNode(addrConnect.ToStringIPPort().c_str()))
1387             return false;
1388     if (strDest && FindNode(strDest))
1389         return false;
1390
1391     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1392     CNode* pnode = ConnectNode(addrConnect, strDest);
1393     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1394     if (fShutdown)
1395         return false;
1396     if (!pnode)
1397         return false;
1398     if (grantOutbound)
1399         grantOutbound->MoveTo(pnode->grantOutbound);
1400     pnode->fNetworkNode = true;
1401     if (fOneShot)
1402         pnode->fOneShot = true;
1403
1404     return true;
1405 }
1406
1407 // for now, use a very simple selection metric: the node from which we received
1408 // most recently
1409 static int64_t NodeSyncScore(const CNode *pnode) {
1410     return pnode->nLastRecv;
1411 }
1412
1413 void static StartSync(const vector<CNode*> &vNodes) {
1414     CNode *pnodeNewSync = NULL;
1415     int64_t nBestScore = 0;
1416
1417     // Iterate over all nodes
1418     BOOST_FOREACH(CNode* pnode, vNodes) {
1419         // check preconditions for allowing a sync
1420         if (!pnode->fClient && !pnode->fOneShot &&
1421             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1422             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1423             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1424             // if ok, compare node's score with the best so far
1425             int64_t nScore = NodeSyncScore(pnode);
1426             if (pnodeNewSync == NULL || nScore > nBestScore) {
1427                 pnodeNewSync = pnode;
1428                 nBestScore = nScore;
1429             }
1430         }
1431     }
1432     // if a new sync candidate was found, start sync!
1433     if (pnodeNewSync) {
1434         pnodeNewSync->fStartSync = true;
1435         pnodeSync = pnodeNewSync;
1436     }
1437 }
1438
1439 void ThreadMessageHandler(void* parg)
1440 {
1441     // Make this thread recognisable as the message handling thread
1442     RenameThread("novacoin-msghand");
1443
1444     try
1445     {
1446         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1447         ThreadMessageHandler2(parg);
1448         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1449     }
1450     catch (std::exception& e) {
1451         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1452         PrintException(&e, "ThreadMessageHandler()");
1453     } catch (...) {
1454         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1455         PrintException(NULL, "ThreadMessageHandler()");
1456     }
1457     printf("ThreadMessageHandler exited\n");
1458 }
1459
1460 void ThreadMessageHandler2(void* parg)
1461 {
1462     printf("ThreadMessageHandler started\n");
1463     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1464     while (!fShutdown)
1465     {
1466         bool fHaveSyncNode = false;
1467         vector<CNode*> vNodesCopy;
1468         {
1469             LOCK(cs_vNodes);
1470             vNodesCopy = vNodes;
1471             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1472                 pnode->AddRef();
1473                 if (pnode == pnodeSync)
1474                     fHaveSyncNode = true;
1475             }
1476         }
1477
1478         if (!fHaveSyncNode)
1479             StartSync(vNodesCopy);
1480
1481         // Poll the connected nodes for messages
1482         CNode* pnodeTrickle = NULL;
1483         if (!vNodesCopy.empty())
1484             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1485         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1486         {
1487             // Receive messages
1488             {
1489                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1490                 if (lockRecv)
1491                     ProcessMessages(pnode);
1492             }
1493             if (fShutdown)
1494                 return;
1495
1496             // Send messages
1497             {
1498                 TRY_LOCK(pnode->cs_vSend, lockSend);
1499                 if (lockSend)
1500                     SendMessages(pnode, pnode == pnodeTrickle);
1501             }
1502             if (fShutdown)
1503                 return;
1504         }
1505
1506         {
1507             LOCK(cs_vNodes);
1508             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1509         }
1510
1511         // Wait and allow messages to bunch up.
1512         // Reduce vnThreadsRunning so StopNode has permission to exit while
1513         // we're sleeping, but we must always check fShutdown after doing this.
1514         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1515         Sleep(100);
1516         if (fRequestShutdown)
1517             StartShutdown();
1518         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1519         if (fShutdown)
1520             return;
1521     }
1522 }
1523
1524
1525
1526
1527
1528
1529 bool BindListenPort(const CService &addrBind, string& strError)
1530 {
1531     strError.clear();
1532     int nOne = 1;
1533
1534     // Create socket for listening for incoming connections
1535 #ifdef USE_IPV6
1536     struct sockaddr_storage sockaddr;
1537 #else
1538     struct sockaddr sockaddr;
1539 #endif
1540     socklen_t len = sizeof(sockaddr);
1541     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1542     {
1543         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1544         printf("%s\n", strError.c_str());
1545         return false;
1546     }
1547
1548     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1549     if (hListenSocket == INVALID_SOCKET)
1550     {
1551         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1552         printf("%s\n", strError.c_str());
1553         return false;
1554     }
1555
1556 #ifndef WIN32
1557 #ifdef SO_NOSIGPIPE
1558     // Different way of disabling SIGPIPE on BSD
1559     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1560 #endif
1561     // Allow binding if the port is still in TIME_WAIT state after
1562     // the program was closed and restarted. Not an issue on windows!
1563     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1564 #endif
1565
1566 #ifdef WIN32
1567     // Set to non-blocking, incoming connections will also inherit this
1568     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1569 #else
1570     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1571 #endif
1572     {
1573         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1574         printf("%s\n", strError.c_str());
1575         return false;
1576     }
1577
1578 #ifdef USE_IPV6
1579     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1580     // and enable it by default or not. Try to enable it, if possible.
1581     if (addrBind.IsIPv6()) {
1582 #ifdef IPV6_V6ONLY
1583 #ifdef WIN32
1584         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1585 #else
1586         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1587 #endif
1588 #endif
1589 #ifdef WIN32
1590         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1591         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1592 #endif
1593     }
1594 #endif
1595
1596     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1597     {
1598         int nErr = WSAGetLastError();
1599         if (nErr == WSAEADDRINUSE)
1600             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1601         else
1602             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1603         printf("%s\n", strError.c_str());
1604         CloseSocket(hListenSocket);
1605         return false;
1606     }
1607     printf("Bound to %s\n", addrBind.ToString().c_str());
1608
1609     // Listen for incoming connections
1610     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1611     {
1612         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1613         printf("%s\n", strError.c_str());
1614         CloseSocket(hListenSocket);
1615         return false;
1616     }
1617
1618     vhListenSocket.push_back(hListenSocket);
1619
1620     if (addrBind.IsRoutable() && fDiscover)
1621         AddLocal(addrBind, LOCAL_BIND);
1622
1623     return true;
1624 }
1625
1626 void static Discover()
1627 {
1628     if (!fDiscover)
1629         return;
1630
1631 #ifdef WIN32
1632     // Get local host IP
1633     char pszHostName[1000] = "";
1634     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1635     {
1636         vector<CNetAddr> vaddr;
1637         if (LookupHost(pszHostName, vaddr))
1638         {
1639             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1640             {
1641                 AddLocal(addr, LOCAL_IF);
1642             }
1643         }
1644     }
1645 #else
1646     // Get local host ip
1647     struct ifaddrs* myaddrs;
1648     if (getifaddrs(&myaddrs) == 0)
1649     {
1650         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1651         {
1652             if (ifa->ifa_addr == NULL) continue;
1653             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1654             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1655             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1656             if (ifa->ifa_addr->sa_family == AF_INET)
1657             {
1658                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1659                 CNetAddr addr(s4->sin_addr);
1660                 if (AddLocal(addr, LOCAL_IF))
1661                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1662             }
1663 #ifdef USE_IPV6
1664             else if (ifa->ifa_addr->sa_family == AF_INET6)
1665             {
1666                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1667                 CNetAddr addr(s6->sin6_addr);
1668                 if (AddLocal(addr, LOCAL_IF))
1669                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1670             }
1671 #endif
1672         }
1673         freeifaddrs(myaddrs);
1674     }
1675 #endif
1676
1677     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1678     if (!IsLimited(NET_IPV4))
1679         NewThread(ThreadGetMyExternalIP, NULL);
1680 }
1681
1682 void StartNode(void* parg)
1683 {
1684     // Make this thread recognisable as the startup thread
1685     RenameThread("novacoin-start");
1686
1687     if (semOutbound == NULL) {
1688         // initialize semaphore
1689         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1690         semOutbound = new CSemaphore(nMaxOutbound);
1691     }
1692
1693     if (pnodeLocalHost == NULL)
1694         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1695
1696     Discover();
1697
1698     //
1699     // Start threads
1700     //
1701
1702     if (!GetBoolArg("-dnsseed", true))
1703         printf("DNS seeding disabled\n");
1704     else
1705         if (!NewThread(ThreadDNSAddressSeed, NULL))
1706             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1707
1708     // Get addresses from IRC and advertise ours
1709     if (!GetBoolArg("-irc", true))
1710         printf("IRC seeding disabled\n");
1711     else
1712         if (!NewThread(ThreadIRCSeed, NULL))
1713             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1714
1715     // Send and receive from sockets, accept connections
1716     if (!NewThread(ThreadSocketHandler, NULL))
1717         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1718
1719     // Initiate outbound connections from -addnode
1720     if (!NewThread(ThreadOpenAddedConnections, NULL))
1721         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1722
1723     // Initiate outbound connections
1724     if (!NewThread(ThreadOpenConnections, NULL))
1725         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1726
1727     // Process messages
1728     if (!NewThread(ThreadMessageHandler, NULL))
1729         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1730
1731     // Dump network addresses
1732     if (!NewThread(ThreadDumpAddress, NULL))
1733         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1734
1735     // Mine proof-of-stake blocks in the background
1736     if (!NewThread(ThreadStakeMiner, pwalletMain))
1737         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1738
1739     // Trusted NTP server, it's localhost by default.
1740     strTrustedUpstream = GetArg("-ntp", "localhost");
1741
1742     // Start periodical NTP sampling thread
1743     NewThread(ThreadNtpSamples, NULL);
1744
1745 }
1746
1747 bool StopNode()
1748 {
1749     printf("StopNode()\n");
1750     fShutdown = true;
1751     nTransactionsUpdated++;
1752     int64_t nStart = GetTime();
1753     {
1754         LOCK(cs_main);
1755         ThreadScriptCheckQuit();
1756     }
1757     if (semOutbound)
1758         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1759             semOutbound->post();
1760     for ( ; ; )
1761     {
1762         int nThreadsRunning = 0;
1763         for (int n = 0; n < THREAD_MAX; n++)
1764             nThreadsRunning += vnThreadsRunning[n];
1765         if (nThreadsRunning == 0)
1766             break;
1767         if (GetTime() - nStart > 20)
1768             break;
1769         Sleep(20);
1770     };
1771     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1772     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1773     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1774     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1775     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1776     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1777     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1778     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1779     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1780     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1781     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1782         Sleep(20);
1783     Sleep(50);
1784     DumpAddresses();
1785
1786     return true;
1787 }
1788
1789 class CNetCleanup
1790 {
1791 public:
1792     CNetCleanup()
1793     {
1794     }
1795     ~CNetCleanup()
1796     {
1797         // Close sockets
1798         BOOST_FOREACH(CNode* pnode, vNodes)
1799             if (pnode->hSocket != INVALID_SOCKET)
1800                 CloseSocket(pnode->hSocket);
1801         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1802             if (hListenSocket != INVALID_SOCKET)
1803                 if (!CloseSocket(hListenSocket))
1804                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1805
1806         // clean up some globals (to help leak detection)
1807         BOOST_FOREACH(CNode *pnode, vNodes)
1808             delete pnode;
1809         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1810             delete pnode;
1811         vNodes.clear();
1812         vNodesDisconnected.clear();
1813         delete semOutbound;
1814         semOutbound = NULL;
1815         delete pnodeLocalHost;
1816         pnodeLocalHost = NULL;
1817
1818 #ifdef WIN32
1819         // Shutdown Windows Sockets
1820         WSACleanup();
1821 #endif
1822     }
1823 }
1824 instance_of_cnetcleanup;
1825
1826 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1827 {
1828     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1829     ss.reserve(10000);
1830     ss << tx;
1831     RelayTransaction(tx, hash, ss);
1832 }
1833
1834 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1835 {
1836     CInv inv(MSG_TX, hash);
1837     {
1838         LOCK(cs_mapRelay);
1839         // Expire old relay messages
1840         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1841         {
1842             mapRelay.erase(vRelayExpiration.front().second);
1843             vRelayExpiration.pop_front();
1844         }
1845
1846         // Save original serialized message so newer versions are preserved
1847         mapRelay.insert(std::make_pair(inv, ss));
1848         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1849     }
1850
1851     RelayInventory(inv);
1852 }
1853
1854 void CNode::RecordBytesRecv(uint64_t bytes)
1855 {
1856     LOCK(cs_totalBytesRecv);
1857     nTotalBytesRecv += bytes;
1858 }
1859
1860 void CNode::RecordBytesSent(uint64_t bytes)
1861 {
1862     LOCK(cs_totalBytesSent);
1863     nTotalBytesSent += bytes;
1864 }
1865
1866 uint64_t CNode::GetTotalBytesRecv()
1867 {
1868     LOCK(cs_totalBytesRecv);
1869     return nTotalBytesRecv;
1870 }
1871
1872 uint64_t CNode::GetTotalBytesSent()
1873 {
1874     LOCK(cs_totalBytesSent);
1875     return nTotalBytesSent;
1876 }