DNSNode: fix source name
[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     0xa52bf0da, 0x30aa43d8, 0x614488d5, 0x517b6fd5, 0xd4bf62d4, 0xb7d638d4, 0xbc12bcd1, 0xa2501bc6,
1051     0xfde617c6, 0x3337b1c6, 0x1dcd71c3, 0x2c1544c1, 0xe05f6ac1, 0x852f63c0, 0x3e2363c0, 0x15f563c0,
1052     0x430d63c0, 0x50d6a9c0, 0xf0a679c0, 0xefdeedbf, 0x7aaee8bc, 0x3a3dbbbc, 0xef218abc, 0x0bef78bc,
1053     0x8baa3eb2, 0x2bf913b2, 0x24ed9fb2, 0xb42289b2, 0x718a09b0, 0xe9433eb0, 0x559425b0, 0xc97e1fb0,
1054     0x18e1d4b0, 0x8f6cc1b0, 0xac3838ae, 0x86c0ffad, 0x6b0272a7, 0xa463f8a2, 0x6f17f3a2, 0xb3d6f3a2,
1055     0x9cd8f997, 0xd513fb94, 0x39e64880, 0x3859dd6f, 0x0b08fe6d, 0xe601fe6d, 0xeb44a26d, 0xfe53186c,
1056     0x203c2e68, 0x1c542868, 0x0caa8368, 0xb8748368, 0xccca4762, 0xc637555f, 0x638a545f, 0x59b2205f,
1057     0x52568c5f, 0xba568c5f, 0x8a568c5f, 0x31b0f45e, 0x54a0f45e, 0x37d6f15e, 0xc520175e, 0x7620175e,
1058     0xc310175e, 0x8e33b45e, 0x7abb5f5d, 0xd3014c5d, 0xa1e1485d, 0x9947645d, 0xfab8ff5c, 0xa979e65b,
1059     0xa879e65b, 0x9f79e65b, 0x9fa3d25b, 0x112a925b, 0x7b92905b, 0x60647a5b, 0x1e389d5a, 0x851afa59,
1060     0x0185ef59, 0x26549b59, 0x1c9efe57, 0xc54c1256, 0x1ad51955, 0x19d21955, 0x73c41955, 0x3f74ee55,
1061     0x633eea55, 0x6883d655, 0xfb72c655, 0x5360a653, 0x17c1ea52, 0xc661c852, 0x1ecdc852, 0x006a9752,
1062     0xf72d9252, 0x82650551, 0x36f1c851, 0x33f1c851, 0xd5c1864f, 0xb6bf1b4e, 0x96da184e, 0x40d0234d,
1063     0x9a96ab4c, 0x8fc2a84c, 0xb5dbd048, 0xf4644447, 0x2d51af47, 0xa9625445, 0x83f05243, 0x89672941,
1064     0x3a8bad3e, 0xf0a05436, 0x6ab7c936, 0x49971d32, 0xadd4482e, 0xcffd212e, 0x6730bc2e, 0x839aa12e,
1065     0x68d9692e, 0xc7183b25, 0x6c47bb25, 0x2490bb25, 0xad651c1f, 0x048a861f, 0x6937811f, 0x064b2d05,
1066     0x4d226805,
1067 };
1068
1069 const char* pchTorSeed[] = 
1070 {
1071     "seedp4knqnoei57u.onion",
1072     "seedr3hhlepyi7fd.onion",
1073     "seed3uuomkclbiz4.onion",
1074     "seedeh7qck3ouff5.onion",
1075     "5rg3vq4jagckeckf.onion",
1076     "seedt3sraf53ajiy.onion",
1077     "seedg4qyccsg42oq.onion",
1078     "novaqrtoywpg7jly.onion",
1079     "seed3d5wolqbgrcb.onion",
1080     "seed24u5dwph3qw4.onion",
1081     "mj26ulzbs2oskgym.onion",
1082     "eqon4usunavt76m7.onion",
1083     "seedd3aldwpslzl3.onion"
1084 };
1085
1086 void DumpAddresses()
1087 {
1088     int64_t nStart = GetTimeMillis();
1089
1090     CAddrDB adb;
1091     adb.Write(addrman);
1092
1093     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1094            addrman.size(), GetTimeMillis() - nStart);
1095 }
1096
1097 void ThreadDumpAddress2(void* parg)
1098 {
1099     printf("ThreadDumpAddress started\n");
1100
1101     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1102     while (!fShutdown)
1103     {
1104         DumpAddresses();
1105         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1106         Sleep(600000);
1107         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1108     }
1109     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1110 }
1111
1112 void ThreadDumpAddress(void* parg)
1113 {
1114     // Make this thread recognisable as the address dumping thread
1115     RenameThread("novacoin-adrdump");
1116
1117     try
1118     {
1119         ThreadDumpAddress2(parg);
1120     }
1121     catch (std::exception& e) {
1122         PrintException(&e, "ThreadDumpAddress()");
1123     }
1124     printf("ThreadDumpAddress exited\n");
1125 }
1126
1127 void ThreadOpenConnections(void* parg)
1128 {
1129     // Make this thread recognisable as the connection opening thread
1130     RenameThread("novacoin-opencon");
1131
1132     try
1133     {
1134         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1135         ThreadOpenConnections2(parg);
1136         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1137     }
1138     catch (std::exception& e) {
1139         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1140         PrintException(&e, "ThreadOpenConnections()");
1141     } catch (...) {
1142         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1143         PrintException(NULL, "ThreadOpenConnections()");
1144     }
1145     printf("ThreadOpenConnections exited\n");
1146 }
1147
1148 void static ProcessOneShot()
1149 {
1150     string strDest;
1151     {
1152         LOCK(cs_vOneShots);
1153         if (vOneShots.empty())
1154             return;
1155         strDest = vOneShots.front();
1156         vOneShots.pop_front();
1157     }
1158     CAddress addr;
1159     CSemaphoreGrant grant(*semOutbound, true);
1160     if (grant) {
1161         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1162             AddOneShot(strDest);
1163     }
1164 }
1165
1166 void ThreadOpenConnections2(void* parg)
1167 {
1168     printf("ThreadOpenConnections started\n");
1169
1170     // Connect to specific addresses
1171     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1172     {
1173         for (int64_t nLoop = 0;; nLoop++)
1174         {
1175             ProcessOneShot();
1176             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1177             {
1178                 CAddress addr;
1179                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1180                 for (int i = 0; i < 10 && i < nLoop; i++)
1181                 {
1182                     Sleep(500);
1183                     if (fShutdown)
1184                         return;
1185                 }
1186             }
1187             Sleep(500);
1188         }
1189     }
1190
1191     // Initiate network connections
1192     int64_t nStart = GetTime();
1193     for ( ; ; )
1194     {
1195         ProcessOneShot();
1196
1197         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1198         Sleep(500);
1199         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1200         if (fShutdown)
1201             return;
1202
1203
1204         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1205         CSemaphoreGrant grant(*semOutbound);
1206         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1207         if (fShutdown)
1208             return;
1209
1210         // Add seed nodes if IRC isn't working
1211         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1212         {
1213             std::vector<CAddress> vAdd;
1214             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1215             {
1216                 // It'll only connect to one or two seed nodes because once it connects,
1217                 // it'll get a pile of addresses with newer timestamps.
1218                 // Seed nodes are given a random 'last seen time' of between one and two
1219                 // weeks ago.
1220                 struct in_addr ip;
1221                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1222                 CAddress addr(CService(ip, GetDefaultPort()));
1223                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1224                 vAdd.push_back(addr);
1225             }
1226             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1227         }
1228
1229         // Add Tor nodes if we have connection with onion router
1230         if (mapArgs.count("-tor"))
1231         {
1232             std::vector<CAddress> vAdd;
1233             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1234             {
1235                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1236                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1237                 vAdd.push_back(addr);
1238             }
1239             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1240         }
1241
1242         //
1243         // Choose an address to connect to based on most recently seen
1244         //
1245         CAddress addrConnect;
1246
1247         // Only connect out to one peer per network group (/16 for IPv4).
1248         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1249         int nOutbound = 0;
1250         set<vector<unsigned char> > setConnected;
1251         {
1252             LOCK(cs_vNodes);
1253             BOOST_FOREACH(CNode* pnode, vNodes) {
1254                 if (!pnode->fInbound) {
1255                     setConnected.insert(pnode->addr.GetGroup());
1256                     nOutbound++;
1257                 }
1258             }
1259         }
1260
1261         int64_t nANow = GetAdjustedTime();
1262
1263         int nTries = 0;
1264         for ( ; ; )
1265         {
1266             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1267             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1268
1269             // if we selected an invalid address, restart
1270             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1271                 break;
1272
1273             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1274             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1275             // already-connected network ranges, ...) before trying new addrman addresses.
1276             nTries++;
1277             if (nTries > 100)
1278                 break;
1279
1280             if (IsLimited(addr))
1281                 continue;
1282
1283             // only consider very recently tried nodes after 30 failed attempts
1284             if (nANow - addr.nLastTry < 600 && nTries < 30)
1285                 continue;
1286
1287             // do not allow non-default ports, unless after 50 invalid addresses selected already
1288             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1289                 continue;
1290
1291             addrConnect = addr;
1292             break;
1293         }
1294
1295         if (addrConnect.IsValid())
1296             OpenNetworkConnection(addrConnect, &grant);
1297     }
1298 }
1299
1300 void ThreadOpenAddedConnections(void* parg)
1301 {
1302     // Make this thread recognisable as the connection opening thread
1303     RenameThread("novacoin-opencon");
1304
1305     try
1306     {
1307         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1308         ThreadOpenAddedConnections2(parg);
1309         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1310     }
1311     catch (std::exception& e) {
1312         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1313         PrintException(&e, "ThreadOpenAddedConnections()");
1314     } catch (...) {
1315         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1316         PrintException(NULL, "ThreadOpenAddedConnections()");
1317     }
1318     printf("ThreadOpenAddedConnections exited\n");
1319 }
1320
1321 void ThreadOpenAddedConnections2(void* parg)
1322 {
1323     printf("ThreadOpenAddedConnections started\n");
1324
1325     {
1326         LOCK(cs_vAddedNodes);
1327         vAddedNodes = mapMultiArgs["-addnode"];
1328     }
1329
1330     if (HaveNameProxy()) {
1331         while(!fShutdown) {
1332             list<string> lAddresses(0);
1333             {
1334                 LOCK(cs_vAddedNodes);
1335                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1336                     lAddresses.push_back(strAddNode);
1337             }
1338             BOOST_FOREACH(string& strAddNode, lAddresses) {
1339                 CAddress addr;
1340                 CSemaphoreGrant grant(*semOutbound);
1341                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1342                 Sleep(500);
1343             }
1344             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1345             Sleep(120000); // Retry every 2 minutes
1346             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1347         }
1348         return;
1349     }
1350
1351     for (uint32_t i = 0; true; i++)
1352     {
1353         list<string> lAddresses(0);
1354         {
1355             LOCK(cs_vAddedNodes);
1356             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1357                 lAddresses.push_back(strAddNode);
1358         }
1359
1360         list<vector<CService> > lservAddressesToAdd(0);
1361         BOOST_FOREACH(string& strAddNode, lAddresses)
1362         {
1363             vector<CService> vservNode(0);
1364             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1365             {
1366                 lservAddressesToAdd.push_back(vservNode);
1367                 {
1368                     LOCK(cs_setservAddNodeAddresses);
1369                     BOOST_FOREACH(CService& serv, vservNode)
1370                         setservAddNodeAddresses.insert(serv);
1371                 }
1372             }
1373         }
1374         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1375         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1376         {
1377             LOCK(cs_vNodes);
1378             BOOST_FOREACH(CNode* pnode, vNodes)
1379                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1380                 {
1381                     BOOST_FOREACH(CService& addrNode, *(it))
1382                         if (pnode->addr == addrNode)
1383                         {
1384                             it = lservAddressesToAdd.erase(it);
1385                             if(it != lservAddressesToAdd.begin())
1386                                 it--;
1387                             break;
1388                         }
1389                     if (it == lservAddressesToAdd.end())
1390                         break;
1391                 }
1392         }
1393         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1394         {
1395             if (vserv.size() == 0)
1396                 continue;
1397             CSemaphoreGrant grant(*semOutbound);
1398             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1399             Sleep(500);
1400             if (fShutdown)
1401                 return;
1402         }
1403         if (fShutdown)
1404             return;
1405         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1406         Sleep(120000); // Retry every 2 minutes
1407         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1408         if (fShutdown)
1409             return;
1410     }
1411 }
1412
1413 // if successful, this moves the passed grant to the constructed node
1414 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1415 {
1416     //
1417     // Initiate outbound network connection
1418     //
1419     if (fShutdown)
1420         return false;
1421     if (!strDest)
1422         if (IsLocal(addrConnect) ||
1423             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1424             FindNode(addrConnect.ToStringIPPort().c_str()))
1425             return false;
1426     if (strDest && FindNode(strDest))
1427         return false;
1428
1429     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1430     CNode* pnode = ConnectNode(addrConnect, strDest);
1431     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1432     if (fShutdown)
1433         return false;
1434     if (!pnode)
1435         return false;
1436     if (grantOutbound)
1437         grantOutbound->MoveTo(pnode->grantOutbound);
1438     pnode->fNetworkNode = true;
1439     if (fOneShot)
1440         pnode->fOneShot = true;
1441
1442     return true;
1443 }
1444
1445 // for now, use a very simple selection metric: the node from which we received
1446 // most recently
1447 static int64_t NodeSyncScore(const CNode *pnode) {
1448     return pnode->nLastRecv;
1449 }
1450
1451 void static StartSync(const vector<CNode*> &vNodes) {
1452     CNode *pnodeNewSync = NULL;
1453     int64_t nBestScore = 0;
1454
1455     // Iterate over all nodes
1456     BOOST_FOREACH(CNode* pnode, vNodes) {
1457         // check preconditions for allowing a sync
1458         if (!pnode->fClient && !pnode->fOneShot &&
1459             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1460             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1461             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1462             // if ok, compare node's score with the best so far
1463             int64_t nScore = NodeSyncScore(pnode);
1464             if (pnodeNewSync == NULL || nScore > nBestScore) {
1465                 pnodeNewSync = pnode;
1466                 nBestScore = nScore;
1467             }
1468         }
1469     }
1470     // if a new sync candidate was found, start sync!
1471     if (pnodeNewSync) {
1472         pnodeNewSync->fStartSync = true;
1473         pnodeSync = pnodeNewSync;
1474     }
1475 }
1476
1477 void ThreadMessageHandler(void* parg)
1478 {
1479     // Make this thread recognisable as the message handling thread
1480     RenameThread("novacoin-msghand");
1481
1482     try
1483     {
1484         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1485         ThreadMessageHandler2(parg);
1486         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1487     }
1488     catch (std::exception& e) {
1489         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1490         PrintException(&e, "ThreadMessageHandler()");
1491     } catch (...) {
1492         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1493         PrintException(NULL, "ThreadMessageHandler()");
1494     }
1495     printf("ThreadMessageHandler exited\n");
1496 }
1497
1498 void ThreadMessageHandler2(void* parg)
1499 {
1500     printf("ThreadMessageHandler started\n");
1501     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1502     while (!fShutdown)
1503     {
1504         bool fHaveSyncNode = false;
1505         vector<CNode*> vNodesCopy;
1506         {
1507             LOCK(cs_vNodes);
1508             vNodesCopy = vNodes;
1509             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1510                 pnode->AddRef();
1511                 if (pnode == pnodeSync)
1512                     fHaveSyncNode = true;
1513             }
1514         }
1515
1516         if (!fHaveSyncNode)
1517             StartSync(vNodesCopy);
1518
1519         // Poll the connected nodes for messages
1520         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1521         {
1522             // Receive messages
1523             {
1524                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1525                 if (lockRecv)
1526                     ProcessMessages(pnode);
1527             }
1528             if (fShutdown)
1529                 return;
1530
1531             // Send messages
1532             {
1533                 TRY_LOCK(pnode->cs_vSend, lockSend);
1534                 if (lockSend)
1535                     SendMessages(pnode);
1536             }
1537             if (fShutdown)
1538                 return;
1539         }
1540
1541         {
1542             LOCK(cs_vNodes);
1543             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1544         }
1545
1546         // Wait and allow messages to bunch up.
1547         // Reduce vnThreadsRunning so StopNode has permission to exit while
1548         // we're sleeping, but we must always check fShutdown after doing this.
1549         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1550         Sleep(100);
1551         if (fRequestShutdown)
1552             StartShutdown();
1553         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1554         if (fShutdown)
1555             return;
1556     }
1557 }
1558
1559
1560
1561
1562
1563
1564 bool BindListenPort(const CService &addrBind, string& strError)
1565 {
1566     strError.clear();
1567     int nOne = 1;
1568
1569     // Create socket for listening for incoming connections
1570 #ifdef USE_IPV6
1571     struct sockaddr_storage sockaddr;
1572 #else
1573     struct sockaddr sockaddr;
1574 #endif
1575     socklen_t len = sizeof(sockaddr);
1576     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1577     {
1578         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1579         printf("%s\n", strError.c_str());
1580         return false;
1581     }
1582
1583     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1584     if (hListenSocket == INVALID_SOCKET)
1585     {
1586         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1587         printf("%s\n", strError.c_str());
1588         return false;
1589     }
1590
1591 #ifndef WIN32
1592 #ifdef SO_NOSIGPIPE
1593     // Different way of disabling SIGPIPE on BSD
1594     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1595 #endif
1596     // Allow binding if the port is still in TIME_WAIT state after
1597     // the program was closed and restarted. Not an issue on windows!
1598     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1599 #endif
1600
1601 #ifdef WIN32
1602     // Set to non-blocking, incoming connections will also inherit this
1603     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1604 #else
1605     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1606 #endif
1607     {
1608         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1609         printf("%s\n", strError.c_str());
1610         return false;
1611     }
1612
1613 #ifdef USE_IPV6
1614     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1615     // and enable it by default or not. Try to enable it, if possible.
1616     if (addrBind.IsIPv6()) {
1617 #ifdef IPV6_V6ONLY
1618 #ifdef WIN32
1619         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1620 #else
1621         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1622 #endif
1623 #endif
1624 #ifdef WIN32
1625         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1626         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1627 #endif
1628     }
1629 #endif
1630
1631     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1632     {
1633         int nErr = WSAGetLastError();
1634         if (nErr == WSAEADDRINUSE)
1635             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1636         else
1637             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1638         printf("%s\n", strError.c_str());
1639         CloseSocket(hListenSocket);
1640         return false;
1641     }
1642     printf("Bound to %s\n", addrBind.ToString().c_str());
1643
1644     // Listen for incoming connections
1645     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1646     {
1647         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1648         printf("%s\n", strError.c_str());
1649         CloseSocket(hListenSocket);
1650         return false;
1651     }
1652
1653     vhListenSocket.push_back(hListenSocket);
1654
1655     if (addrBind.IsRoutable() && fDiscover)
1656         AddLocal(addrBind, LOCAL_BIND);
1657
1658     return true;
1659 }
1660
1661 void static Discover()
1662 {
1663     if (!fDiscover)
1664         return;
1665
1666 #ifdef WIN32
1667     // Get local host IP
1668     char pszHostName[1000] = "";
1669     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1670     {
1671         vector<CNetAddr> vaddr;
1672         if (LookupHost(pszHostName, vaddr))
1673         {
1674             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1675             {
1676                 AddLocal(addr, LOCAL_IF);
1677             }
1678         }
1679     }
1680 #else
1681     // Get local host ip
1682     struct ifaddrs* myaddrs;
1683     if (getifaddrs(&myaddrs) == 0)
1684     {
1685         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1686         {
1687             if (ifa->ifa_addr == NULL) continue;
1688             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1689             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1690             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1691             if (ifa->ifa_addr->sa_family == AF_INET)
1692             {
1693                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1694                 CNetAddr addr(s4->sin_addr);
1695                 if (AddLocal(addr, LOCAL_IF))
1696                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1697             }
1698 #ifdef USE_IPV6
1699             else if (ifa->ifa_addr->sa_family == AF_INET6)
1700             {
1701                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1702                 CNetAddr addr(s6->sin6_addr);
1703                 if (AddLocal(addr, LOCAL_IF))
1704                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1705             }
1706 #endif
1707         }
1708         freeifaddrs(myaddrs);
1709     }
1710 #endif
1711
1712     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1713     if (!IsLimited(NET_IPV4))
1714         NewThread(ThreadGetMyExternalIP, NULL);
1715 }
1716
1717 void StartNode(void* parg)
1718 {
1719     // Make this thread recognisable as the startup thread
1720     RenameThread("novacoin-start");
1721
1722     if (semOutbound == NULL) {
1723         // initialize semaphore
1724         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1725         semOutbound = new CSemaphore(nMaxOutbound);
1726     }
1727
1728     if (pnodeLocalHost == NULL)
1729         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1730
1731     Discover();
1732
1733     //
1734     // Start threads
1735     //
1736
1737     if (!GetBoolArg("-dnsseed", true))
1738         printf("DNS seeding disabled\n");
1739     else
1740         if (!NewThread(ThreadDNSAddressSeed, NULL))
1741             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1742
1743     // Get addresses from IRC and advertise ours
1744     if (!GetBoolArg("-irc", true))
1745         printf("IRC seeding disabled\n");
1746     else
1747         if (!NewThread(ThreadIRCSeed, NULL))
1748             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1749
1750     // Send and receive from sockets, accept connections
1751     if (!NewThread(ThreadSocketHandler, NULL))
1752         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1753
1754     // Initiate outbound connections from -addnode
1755     if (!NewThread(ThreadOpenAddedConnections, NULL))
1756         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1757
1758     // Initiate outbound connections
1759     if (!NewThread(ThreadOpenConnections, NULL))
1760         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1761
1762     // Process messages
1763     if (!NewThread(ThreadMessageHandler, NULL))
1764         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1765
1766     // Dump network addresses
1767     if (!NewThread(ThreadDumpAddress, NULL))
1768         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1769
1770     // Mine proof-of-stake blocks in the background
1771     if (!NewThread(ThreadStakeMiner, pwalletMain))
1772         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1773
1774     // Trusted NTP server, it's localhost by default.
1775     strTrustedUpstream = GetArg("-ntp", "localhost");
1776
1777     // Start periodical NTP sampling thread
1778     NewThread(ThreadNtpSamples, NULL);
1779
1780 }
1781
1782 bool StopNode()
1783 {
1784     printf("StopNode()\n");
1785     fShutdown = true;
1786     nTransactionsUpdated++;
1787     int64_t nStart = GetTime();
1788     {
1789         LOCK(cs_main);
1790         ThreadScriptCheckQuit();
1791     }
1792     if (semOutbound)
1793         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1794             semOutbound->post();
1795     for ( ; ; )
1796     {
1797         int nThreadsRunning = 0;
1798         for (int n = 0; n < THREAD_MAX; n++)
1799             nThreadsRunning += vnThreadsRunning[n];
1800         if (nThreadsRunning == 0)
1801             break;
1802         if (GetTime() - nStart > 20)
1803             break;
1804         Sleep(20);
1805     };
1806     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1807     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1808     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1809     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1810     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1811     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1812     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1813     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1814     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1815     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1816     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1817         Sleep(20);
1818     Sleep(50);
1819     DumpAddresses();
1820
1821     return true;
1822 }
1823
1824 class CNetCleanup
1825 {
1826 public:
1827     CNetCleanup()
1828     {
1829     }
1830     ~CNetCleanup()
1831     {
1832         // Close sockets
1833         BOOST_FOREACH(CNode* pnode, vNodes)
1834             if (pnode->hSocket != INVALID_SOCKET)
1835                 CloseSocket(pnode->hSocket);
1836         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1837             if (hListenSocket != INVALID_SOCKET)
1838                 if (!CloseSocket(hListenSocket))
1839                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1840
1841         // clean up some globals (to help leak detection)
1842         BOOST_FOREACH(CNode *pnode, vNodes)
1843             delete pnode;
1844         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1845             delete pnode;
1846         vNodes.clear();
1847         vNodesDisconnected.clear();
1848         delete semOutbound;
1849         semOutbound = NULL;
1850         delete pnodeLocalHost;
1851         pnodeLocalHost = NULL;
1852
1853 #ifdef WIN32
1854         // Shutdown Windows Sockets
1855         WSACleanup();
1856 #endif
1857     }
1858 }
1859 instance_of_cnetcleanup;
1860
1861 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1862 {
1863     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1864     ss.reserve(10000);
1865     ss << tx;
1866     RelayTransaction(tx, hash, ss);
1867 }
1868
1869 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1870 {
1871     CInv inv(MSG_TX, hash);
1872     {
1873         LOCK(cs_mapRelay);
1874         // Expire old relay messages
1875         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1876         {
1877             mapRelay.erase(vRelayExpiration.front().second);
1878             vRelayExpiration.pop_front();
1879         }
1880
1881         // Save original serialized message so newer versions are preserved
1882         mapRelay.insert(std::make_pair(inv, ss));
1883         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1884     }
1885
1886     RelayInventory(inv);
1887 }
1888
1889 void CNode::RecordBytesRecv(uint64_t bytes)
1890 {
1891     LOCK(cs_totalBytesRecv);
1892     nTotalBytesRecv += bytes;
1893 }
1894
1895 void CNode::RecordBytesSent(uint64_t bytes)
1896 {
1897     LOCK(cs_totalBytesSent);
1898     nTotalBytesSent += bytes;
1899 }
1900
1901 uint64_t CNode::GetTotalBytesRecv()
1902 {
1903     LOCK(cs_totalBytesRecv);
1904     return nTotalBytesRecv;
1905 }
1906
1907 uint64_t CNode::GetTotalBytesSent()
1908 {
1909     LOCK(cs_totalBytesSent);
1910     return nTotalBytesSent;
1911 }
1912 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
1913     return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
1914 }