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