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