Docs Tidy up
[bitcoinplatinum.git] / src / net.cpp
blobf3c255c30836df268138f9684468a974ef6b7d13
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.
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"
14 #ifdef WIN32
15 #include <string.h>
16 #endif
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
25 using namespace std;
26 using namespace boost;
28 static const int MAX_OUTBOUND_CONNECTIONS = 8;
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);
41 struct LocalServiceInfo {
42 int nScore;
43 int nPort;
47 // Global state variables
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 uint64 nLocalHostNonce = 0;
59 array<int, THREAD_MAX> vnThreadsRunning;
60 static std::vector<SOCKET> vhListenSocket;
61 CAddrMan addrman;
63 vector<CNode*> vNodes;
64 CCriticalSection cs_vNodes;
65 map<CInv, CDataStream> mapRelay;
66 deque<pair<int64, CInv> > vRelayExpiration;
67 CCriticalSection cs_mapRelay;
68 map<CInv, int64> mapAlreadyAskedFor;
70 static deque<string> vOneShots;
71 CCriticalSection cs_vOneShots;
73 set<CNetAddr> setservAddNodeAddresses;
74 CCriticalSection cs_setservAddNodeAddresses;
76 static CSemaphore *semOutbound = NULL;
78 void AddOneShot(string strDest)
80 LOCK(cs_vOneShots);
81 vOneShots.push_back(strDest);
84 unsigned short GetListenPort()
86 return (unsigned short)(GetArg("-port", GetDefaultPort()));
89 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
91 // Filter out duplicate requests
92 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
93 return;
94 pindexLastGetBlocksBegin = pindexBegin;
95 hashLastGetBlocksEnd = hashEnd;
97 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
100 // find 'best' local address for a particular peer
101 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
103 if (fNoListen)
104 return false;
106 int nBestScore = -1;
107 int nBestReachability = -1;
109 LOCK(cs_mapLocalHost);
110 for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
112 int nScore = (*it).second.nScore;
113 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
114 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
116 addr = CService((*it).first, (*it).second.nPort);
117 nBestReachability = nReachability;
118 nBestScore = nScore;
122 return nBestScore >= 0;
125 // get best local address for a particular peer as a CAddress
126 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
128 CAddress ret(CService("0.0.0.0",0),0);
129 CService addr;
130 if (GetLocal(addr, paddrPeer))
132 ret = CAddress(addr);
133 ret.nServices = nLocalServices;
134 ret.nTime = GetAdjustedTime();
136 return ret;
139 bool RecvLine(SOCKET hSocket, string& strLine)
141 strLine = "";
142 loop
144 char c;
145 int nBytes = recv(hSocket, &c, 1, 0);
146 if (nBytes > 0)
148 if (c == '\n')
149 continue;
150 if (c == '\r')
151 return true;
152 strLine += c;
153 if (strLine.size() >= 9000)
154 return true;
156 else if (nBytes <= 0)
158 if (fShutdown)
159 return false;
160 if (nBytes < 0)
162 int nErr = WSAGetLastError();
163 if (nErr == WSAEMSGSIZE)
164 continue;
165 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
167 Sleep(10);
168 continue;
171 if (!strLine.empty())
172 return true;
173 if (nBytes == 0)
175 // socket closed
176 printf("socket closed\n");
177 return false;
179 else
181 // socket error
182 int nErr = WSAGetLastError();
183 printf("recv failed: %d\n", nErr);
184 return false;
190 // used when scores of local addresses may have changed
191 // pushes better local address to peers
192 void static AdvertizeLocal()
194 LOCK(cs_vNodes);
195 BOOST_FOREACH(CNode* pnode, vNodes)
197 if (pnode->fSuccessfullyConnected)
199 CAddress addrLocal = GetLocalAddress(&pnode->addr);
200 if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
202 pnode->PushAddress(addrLocal);
203 pnode->addrLocal = addrLocal;
209 void SetReachable(enum Network net, bool fFlag)
211 LOCK(cs_mapLocalHost);
212 vfReachable[net] = fFlag;
213 if (net == NET_IPV6 && fFlag)
214 vfReachable[NET_IPV4] = true;
217 // learn a new local address
218 bool AddLocal(const CService& addr, int nScore)
220 if (!addr.IsRoutable())
221 return false;
223 if (!fDiscover && nScore < LOCAL_MANUAL)
224 return false;
226 if (IsLimited(addr))
227 return false;
229 printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
232 LOCK(cs_mapLocalHost);
233 bool fAlready = mapLocalHost.count(addr) > 0;
234 LocalServiceInfo &info = mapLocalHost[addr];
235 if (!fAlready || nScore >= info.nScore) {
236 info.nScore = nScore;
237 info.nPort = addr.GetPort() + (fAlready ? 1 : 0);
239 SetReachable(addr.GetNetwork());
242 AdvertizeLocal();
244 return true;
247 bool AddLocal(const CNetAddr &addr, int nScore)
249 return AddLocal(CService(addr, GetListenPort()), nScore);
252 /** Make a particular network entirely off-limits (no automatic connects to it) */
253 void SetLimited(enum Network net, bool fLimited)
255 if (net == NET_UNROUTABLE)
256 return;
257 LOCK(cs_mapLocalHost);
258 vfLimited[net] = fLimited;
261 bool IsLimited(enum Network net)
263 LOCK(cs_mapLocalHost);
264 return vfLimited[net];
267 bool IsLimited(const CNetAddr &addr)
269 return IsLimited(addr.GetNetwork());
272 /** vote for a local address */
273 bool SeenLocal(const CService& addr)
276 LOCK(cs_mapLocalHost);
277 if (mapLocalHost.count(addr) == 0)
278 return false;
279 mapLocalHost[addr].nScore++;
282 AdvertizeLocal();
284 return true;
287 /** check whether a given address is potentially local */
288 bool IsLocal(const CService& addr)
290 LOCK(cs_mapLocalHost);
291 return mapLocalHost.count(addr) > 0;
294 /** check whether a given address is in a network we can probably connect to */
295 bool IsReachable(const CNetAddr& addr)
297 LOCK(cs_mapLocalHost);
298 enum Network net = addr.GetNetwork();
299 return vfReachable[net] && !vfLimited[net];
302 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
304 SOCKET hSocket;
305 if (!ConnectSocket(addrConnect, hSocket))
306 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
308 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
310 string strLine;
311 while (RecvLine(hSocket, strLine))
313 if (strLine.empty()) // HTTP response is separated from headers by blank line
315 loop
317 if (!RecvLine(hSocket, strLine))
319 closesocket(hSocket);
320 return false;
322 if (pszKeyword == NULL)
323 break;
324 if (strLine.find(pszKeyword) != string::npos)
326 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
327 break;
330 closesocket(hSocket);
331 if (strLine.find("<") != string::npos)
332 strLine = strLine.substr(0, strLine.find("<"));
333 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
334 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
335 strLine.resize(strLine.size()-1);
336 CService addr(strLine,0,true);
337 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
338 if (!addr.IsValid() || !addr.IsRoutable())
339 return false;
340 ipRet.SetIP(addr);
341 return true;
344 closesocket(hSocket);
345 return error("GetMyExternalIP() : connection closed");
348 // We now get our external IP from the IRC server first and only use this as a backup
349 bool GetMyExternalIP(CNetAddr& ipRet)
351 CService addrConnect;
352 const char* pszGet;
353 const char* pszKeyword;
355 for (int nLookup = 0; nLookup <= 1; nLookup++)
356 for (int nHost = 1; nHost <= 2; nHost++)
358 // We should be phasing out our use of sites like these. If we need
359 // replacements, we should ask for volunteers to put this simple
360 // php file on their webserver that prints the client IP:
361 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
362 if (nHost == 1)
364 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
366 if (nLookup == 1)
368 CService addrIP("checkip.dyndns.org", 80, true);
369 if (addrIP.IsValid())
370 addrConnect = addrIP;
373 pszGet = "GET / HTTP/1.1\r\n"
374 "Host: checkip.dyndns.org\r\n"
375 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
376 "Connection: close\r\n"
377 "\r\n";
379 pszKeyword = "Address:";
381 else if (nHost == 2)
383 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
385 if (nLookup == 1)
387 CService addrIP("www.showmyip.com", 80, true);
388 if (addrIP.IsValid())
389 addrConnect = addrIP;
392 pszGet = "GET /simple/ HTTP/1.1\r\n"
393 "Host: www.showmyip.com\r\n"
394 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
395 "Connection: close\r\n"
396 "\r\n";
398 pszKeyword = NULL; // Returns just IP address
401 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
402 return true;
405 return false;
408 void ThreadGetMyExternalIP(void* parg)
410 // Make this thread recognisable as the external IP detection thread
411 RenameThread("bitcoin-ext-ip");
413 CNetAddr addrLocalHost;
414 if (GetMyExternalIP(addrLocalHost))
416 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
417 AddLocal(addrLocalHost, LOCAL_HTTP);
425 void AddressCurrentlyConnected(const CService& addr)
427 addrman.Connected(addr);
436 CNode* FindNode(const CNetAddr& ip)
439 LOCK(cs_vNodes);
440 BOOST_FOREACH(CNode* pnode, vNodes)
441 if ((CNetAddr)pnode->addr == ip)
442 return (pnode);
444 return NULL;
447 CNode* FindNode(std::string addrName)
449 LOCK(cs_vNodes);
450 BOOST_FOREACH(CNode* pnode, vNodes)
451 if (pnode->addrName == addrName)
452 return (pnode);
453 return NULL;
456 CNode* FindNode(const CService& addr)
459 LOCK(cs_vNodes);
460 BOOST_FOREACH(CNode* pnode, vNodes)
461 if ((CService)pnode->addr == addr)
462 return (pnode);
464 return NULL;
467 CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout)
469 if (pszDest == NULL) {
470 if (IsLocal(addrConnect))
471 return NULL;
473 // Look for an existing connection
474 CNode* pnode = FindNode((CService)addrConnect);
475 if (pnode)
477 if (nTimeout != 0)
478 pnode->AddRef(nTimeout);
479 else
480 pnode->AddRef();
481 return pnode;
486 /// debug print
487 printf("trying connection %s lastseen=%.1fhrs\n",
488 pszDest ? pszDest : addrConnect.ToString().c_str(),
489 pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
491 // Connect
492 SOCKET hSocket;
493 if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
495 addrman.Attempt(addrConnect);
497 /// debug print
498 printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
500 // Set to nonblocking
501 #ifdef WIN32
502 u_long nOne = 1;
503 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
504 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
505 #else
506 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
507 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
508 #endif
510 // Add node
511 CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
512 if (nTimeout != 0)
513 pnode->AddRef(nTimeout);
514 else
515 pnode->AddRef();
518 LOCK(cs_vNodes);
519 vNodes.push_back(pnode);
522 pnode->nTimeConnected = GetTime();
523 return pnode;
525 else
527 return NULL;
531 void CNode::CloseSocketDisconnect()
533 fDisconnect = true;
534 if (hSocket != INVALID_SOCKET)
536 printf("disconnecting node %s\n", addrName.c_str());
537 closesocket(hSocket);
538 hSocket = INVALID_SOCKET;
539 vRecv.clear();
543 void CNode::Cleanup()
548 void CNode::PushVersion()
550 /// when NTP implemented, change to just nTime = GetAdjustedTime()
551 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
552 CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
553 CAddress addrMe = GetLocalAddress(&addr);
554 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
555 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());
556 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
557 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
564 std::map<CNetAddr, int64> CNode::setBanned;
565 CCriticalSection CNode::cs_setBanned;
567 void CNode::ClearBanned()
569 setBanned.clear();
572 bool CNode::IsBanned(CNetAddr ip)
574 bool fResult = false;
576 LOCK(cs_setBanned);
577 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
578 if (i != setBanned.end())
580 int64 t = (*i).second;
581 if (GetTime() < t)
582 fResult = true;
585 return fResult;
588 bool CNode::Misbehaving(int howmuch)
590 if (addr.IsLocal())
592 printf("Warning: local node %s misbehaving\n", addrName.c_str());
593 return false;
596 nMisbehavior += howmuch;
597 if (nMisbehavior >= GetArg("-banscore", 100))
599 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
601 LOCK(cs_setBanned);
602 if (setBanned[addr] < banTime)
603 setBanned[addr] = banTime;
605 CloseSocketDisconnect();
606 printf("Disconnected %s for misbehavior (score=%d)\n", addrName.c_str(), nMisbehavior);
607 return true;
609 return false;
612 #undef X
613 #define X(name) stats.name = name
614 void CNode::copyStats(CNodeStats &stats)
616 X(nServices);
617 X(nLastSend);
618 X(nLastRecv);
619 X(nTimeConnected);
620 X(addrName);
621 X(nVersion);
622 X(strSubVer);
623 X(fInbound);
624 X(nReleaseTime);
625 X(nStartingHeight);
626 X(nMisbehavior);
628 #undef X
639 void ThreadSocketHandler(void* parg)
641 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
643 // Make this thread recognisable as the networking thread
644 RenameThread("bitcoin-net");
648 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
649 ThreadSocketHandler2(parg);
650 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
652 catch (std::exception& e) {
653 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
654 PrintException(&e, "ThreadSocketHandler()");
655 } catch (...) {
656 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
657 throw; // support pthread_cancel()
659 printf("ThreadSocketHandler exited\n");
662 void ThreadSocketHandler2(void* parg)
664 printf("ThreadSocketHandler started\n");
665 list<CNode*> vNodesDisconnected;
666 unsigned int nPrevNodeCount = 0;
668 loop
671 // Disconnect nodes
674 LOCK(cs_vNodes);
675 // Disconnect unused nodes
676 vector<CNode*> vNodesCopy = vNodes;
677 BOOST_FOREACH(CNode* pnode, vNodesCopy)
679 if (pnode->fDisconnect ||
680 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
682 // remove from vNodes
683 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
685 // release outbound grant (if any)
686 pnode->grantOutbound.Release();
688 // close socket and cleanup
689 pnode->CloseSocketDisconnect();
690 pnode->Cleanup();
692 // hold in disconnected pool until all refs are released
693 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
694 if (pnode->fNetworkNode || pnode->fInbound)
695 pnode->Release();
696 vNodesDisconnected.push_back(pnode);
700 // Delete disconnected nodes
701 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
702 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
704 // wait until threads are done using it
705 if (pnode->GetRefCount() <= 0)
707 bool fDelete = false;
709 TRY_LOCK(pnode->cs_vSend, lockSend);
710 if (lockSend)
712 TRY_LOCK(pnode->cs_vRecv, lockRecv);
713 if (lockRecv)
715 TRY_LOCK(pnode->cs_mapRequests, lockReq);
716 if (lockReq)
718 TRY_LOCK(pnode->cs_inventory, lockInv);
719 if (lockInv)
720 fDelete = true;
725 if (fDelete)
727 vNodesDisconnected.remove(pnode);
728 delete pnode;
733 if (vNodes.size() != nPrevNodeCount)
735 nPrevNodeCount = vNodes.size();
736 uiInterface.NotifyNumConnectionsChanged(vNodes.size());
741 // Find which sockets have data to receive
743 struct timeval timeout;
744 timeout.tv_sec = 0;
745 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
747 fd_set fdsetRecv;
748 fd_set fdsetSend;
749 fd_set fdsetError;
750 FD_ZERO(&fdsetRecv);
751 FD_ZERO(&fdsetSend);
752 FD_ZERO(&fdsetError);
753 SOCKET hSocketMax = 0;
755 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
756 FD_SET(hListenSocket, &fdsetRecv);
757 hSocketMax = max(hSocketMax, hListenSocket);
760 LOCK(cs_vNodes);
761 BOOST_FOREACH(CNode* pnode, vNodes)
763 if (pnode->hSocket == INVALID_SOCKET)
764 continue;
765 FD_SET(pnode->hSocket, &fdsetRecv);
766 FD_SET(pnode->hSocket, &fdsetError);
767 hSocketMax = max(hSocketMax, pnode->hSocket);
769 TRY_LOCK(pnode->cs_vSend, lockSend);
770 if (lockSend && !pnode->vSend.empty())
771 FD_SET(pnode->hSocket, &fdsetSend);
776 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
777 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
778 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
779 if (fShutdown)
780 return;
781 if (nSelect == SOCKET_ERROR)
783 int nErr = WSAGetLastError();
784 if (hSocketMax != INVALID_SOCKET)
786 printf("socket select error %d\n", nErr);
787 for (unsigned int i = 0; i <= hSocketMax; i++)
788 FD_SET(i, &fdsetRecv);
790 FD_ZERO(&fdsetSend);
791 FD_ZERO(&fdsetError);
792 Sleep(timeout.tv_usec/1000);
797 // Accept new connections
799 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
800 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
802 #ifdef USE_IPV6
803 struct sockaddr_storage sockaddr;
804 #else
805 struct sockaddr sockaddr;
806 #endif
807 socklen_t len = sizeof(sockaddr);
808 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
809 CAddress addr;
810 int nInbound = 0;
812 if (hSocket != INVALID_SOCKET)
813 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
814 printf("warning: unknown socket family\n");
817 LOCK(cs_vNodes);
818 BOOST_FOREACH(CNode* pnode, vNodes)
819 if (pnode->fInbound)
820 nInbound++;
823 if (hSocket == INVALID_SOCKET)
825 if (WSAGetLastError() != WSAEWOULDBLOCK)
826 printf("socket error accept failed: %d\n", WSAGetLastError());
828 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
831 LOCK(cs_setservAddNodeAddresses);
832 if (!setservAddNodeAddresses.count(addr))
833 closesocket(hSocket);
836 else if (CNode::IsBanned(addr))
838 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
839 closesocket(hSocket);
841 else
843 printf("accepted connection %s\n", addr.ToString().c_str());
844 CNode* pnode = new CNode(hSocket, addr, "", true);
845 pnode->AddRef();
847 LOCK(cs_vNodes);
848 vNodes.push_back(pnode);
855 // Service each socket
857 vector<CNode*> vNodesCopy;
859 LOCK(cs_vNodes);
860 vNodesCopy = vNodes;
861 BOOST_FOREACH(CNode* pnode, vNodesCopy)
862 pnode->AddRef();
864 BOOST_FOREACH(CNode* pnode, vNodesCopy)
866 if (fShutdown)
867 return;
870 // Receive
872 if (pnode->hSocket == INVALID_SOCKET)
873 continue;
874 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
876 TRY_LOCK(pnode->cs_vRecv, lockRecv);
877 if (lockRecv)
879 CDataStream& vRecv = pnode->vRecv;
880 unsigned int nPos = vRecv.size();
882 if (nPos > ReceiveBufferSize()) {
883 if (!pnode->fDisconnect)
884 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
885 pnode->CloseSocketDisconnect();
887 else {
888 // typical socket buffer is 8K-64K
889 char pchBuf[0x10000];
890 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
891 if (nBytes > 0)
893 vRecv.resize(nPos + nBytes);
894 memcpy(&vRecv[nPos], pchBuf, nBytes);
895 pnode->nLastRecv = GetTime();
897 else if (nBytes == 0)
899 // socket closed gracefully
900 if (!pnode->fDisconnect)
901 printf("socket closed\n");
902 pnode->CloseSocketDisconnect();
904 else if (nBytes < 0)
906 // error
907 int nErr = WSAGetLastError();
908 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
910 if (!pnode->fDisconnect)
911 printf("socket recv error %d\n", nErr);
912 pnode->CloseSocketDisconnect();
920 // Send
922 if (pnode->hSocket == INVALID_SOCKET)
923 continue;
924 if (FD_ISSET(pnode->hSocket, &fdsetSend))
926 TRY_LOCK(pnode->cs_vSend, lockSend);
927 if (lockSend)
929 CDataStream& vSend = pnode->vSend;
930 if (!vSend.empty())
932 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
933 if (nBytes > 0)
935 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
936 pnode->nLastSend = GetTime();
938 else if (nBytes < 0)
940 // error
941 int nErr = WSAGetLastError();
942 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
944 printf("socket send error %d\n", nErr);
945 pnode->CloseSocketDisconnect();
953 // Inactivity checking
955 if (pnode->vSend.empty())
956 pnode->nLastSendEmpty = GetTime();
957 if (GetTime() - pnode->nTimeConnected > 60)
959 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
961 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
962 pnode->fDisconnect = true;
964 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
966 printf("socket not sending\n");
967 pnode->fDisconnect = true;
969 else if (GetTime() - pnode->nLastRecv > 90*60)
971 printf("socket inactivity timeout\n");
972 pnode->fDisconnect = true;
977 LOCK(cs_vNodes);
978 BOOST_FOREACH(CNode* pnode, vNodesCopy)
979 pnode->Release();
982 Sleep(10);
994 #ifdef USE_UPNP
995 void ThreadMapPort(void* parg)
997 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
999 // Make this thread recognisable as the UPnP thread
1000 RenameThread("bitcoin-UPnP");
1004 vnThreadsRunning[THREAD_UPNP]++;
1005 ThreadMapPort2(parg);
1006 vnThreadsRunning[THREAD_UPNP]--;
1008 catch (std::exception& e) {
1009 vnThreadsRunning[THREAD_UPNP]--;
1010 PrintException(&e, "ThreadMapPort()");
1011 } catch (...) {
1012 vnThreadsRunning[THREAD_UPNP]--;
1013 PrintException(NULL, "ThreadMapPort()");
1015 printf("ThreadMapPort exited\n");
1018 void ThreadMapPort2(void* parg)
1020 printf("ThreadMapPort started\n");
1022 char port[6];
1023 sprintf(port, "%d", GetListenPort());
1025 const char * multicastif = 0;
1026 const char * minissdpdpath = 0;
1027 struct UPNPDev * devlist = 0;
1028 char lanaddr[64];
1030 #ifndef UPNPDISCOVER_SUCCESS
1031 /* miniupnpc 1.5 */
1032 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1033 #else
1034 /* miniupnpc 1.6 */
1035 int error = 0;
1036 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1037 #endif
1039 struct UPNPUrls urls;
1040 struct IGDdatas data;
1041 int r;
1043 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1044 if (r == 1)
1046 if (fDiscover) {
1047 char externalIPAddress[40];
1048 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1049 if(r != UPNPCOMMAND_SUCCESS)
1050 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1051 else
1053 if(externalIPAddress[0])
1055 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1056 AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1058 else
1059 printf("UPnP: GetExternalIPAddress failed.\n");
1063 string strDesc = "Bitcoin " + FormatFullVersion();
1064 #ifndef UPNPDISCOVER_SUCCESS
1065 /* miniupnpc 1.5 */
1066 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1067 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1068 #else
1069 /* miniupnpc 1.6 */
1070 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1071 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1072 #endif
1074 if(r!=UPNPCOMMAND_SUCCESS)
1075 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1076 port, port, lanaddr, r, strupnperror(r));
1077 else
1078 printf("UPnP Port Mapping successful.\n");
1079 int i = 1;
1080 loop {
1081 if (fShutdown || !fUseUPnP)
1083 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1084 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1085 freeUPNPDevlist(devlist); devlist = 0;
1086 FreeUPNPUrls(&urls);
1087 return;
1089 if (i % 600 == 0) // Refresh every 20 minutes
1091 #ifndef UPNPDISCOVER_SUCCESS
1092 /* miniupnpc 1.5 */
1093 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1094 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1095 #else
1096 /* miniupnpc 1.6 */
1097 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1098 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1099 #endif
1101 if(r!=UPNPCOMMAND_SUCCESS)
1102 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1103 port, port, lanaddr, r, strupnperror(r));
1104 else
1105 printf("UPnP Port Mapping successful.\n");;
1107 Sleep(2000);
1108 i++;
1110 } else {
1111 printf("No valid UPnP IGDs found\n");
1112 freeUPNPDevlist(devlist); devlist = 0;
1113 if (r != 0)
1114 FreeUPNPUrls(&urls);
1115 loop {
1116 if (fShutdown || !fUseUPnP)
1117 return;
1118 Sleep(2000);
1123 void MapPort()
1125 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1127 if (!CreateThread(ThreadMapPort, NULL))
1128 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1131 #else
1132 void MapPort()
1134 // Intentionally left blank.
1136 #endif
1146 // DNS seeds
1147 // Each pair gives a source name and a seed name.
1148 // The first name is used as information source for addrman.
1149 // The second name should resolve to a list of seed addresses.
1150 static const char *strDNSSeed[][2] = {
1151 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1152 {"bluematt.me", "dnsseed.bluematt.me"},
1153 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1154 {"xf2.org", "bitseed.xf2.org"},
1157 void ThreadDNSAddressSeed(void* parg)
1159 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1161 // Make this thread recognisable as the DNS seeding thread
1162 RenameThread("bitcoin-dnsseed");
1166 vnThreadsRunning[THREAD_DNSSEED]++;
1167 ThreadDNSAddressSeed2(parg);
1168 vnThreadsRunning[THREAD_DNSSEED]--;
1170 catch (std::exception& e) {
1171 vnThreadsRunning[THREAD_DNSSEED]--;
1172 PrintException(&e, "ThreadDNSAddressSeed()");
1173 } catch (...) {
1174 vnThreadsRunning[THREAD_DNSSEED]--;
1175 throw; // support pthread_cancel()
1177 printf("ThreadDNSAddressSeed exited\n");
1180 void ThreadDNSAddressSeed2(void* parg)
1182 printf("ThreadDNSAddressSeed started\n");
1183 int found = 0;
1185 if (!fTestNet)
1187 printf("Loading addresses from DNS seeds (could take a while)\n");
1189 for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1190 if (GetNameProxy()) {
1191 AddOneShot(strDNSSeed[seed_idx][1]);
1192 } else {
1193 vector<CNetAddr> vaddr;
1194 vector<CAddress> vAdd;
1195 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1197 BOOST_FOREACH(CNetAddr& ip, vaddr)
1199 int nOneDay = 24*3600;
1200 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1201 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1202 vAdd.push_back(addr);
1203 found++;
1206 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1211 printf("%d addresses found from DNS seeds\n", found);
1225 unsigned int pnSeed[] =
1227 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1228 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1229 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1230 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1231 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1232 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1233 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1234 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1235 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1236 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1237 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1238 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1239 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1240 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1241 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1242 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1243 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1244 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1245 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1246 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1247 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1248 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1249 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1250 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1251 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1252 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1253 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1254 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1255 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1256 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1257 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1258 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1259 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1260 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1261 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1262 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1263 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1264 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1265 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1266 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1267 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1268 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1269 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1270 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1271 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1272 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1273 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1274 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1275 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1276 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1277 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1278 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1279 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1280 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1281 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1282 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1283 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1284 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1285 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1286 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1287 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1288 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1289 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1290 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1291 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1292 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1293 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1294 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1295 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1296 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1297 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1298 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1299 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1300 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1301 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1302 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1303 0xc461d84a, 0xb2dbe247,
1306 void DumpAddresses()
1308 int64 nStart = GetTimeMillis();
1310 CAddrDB adb;
1311 adb.Write(addrman);
1313 printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
1314 addrman.size(), GetTimeMillis() - nStart);
1317 void ThreadDumpAddress2(void* parg)
1319 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1320 while (!fShutdown)
1322 DumpAddresses();
1323 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1324 Sleep(100000);
1325 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1327 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1330 void ThreadDumpAddress(void* parg)
1332 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1334 // Make this thread recognisable as the address dumping thread
1335 RenameThread("bitcoin-adrdump");
1339 ThreadDumpAddress2(parg);
1341 catch (std::exception& e) {
1342 PrintException(&e, "ThreadDumpAddress()");
1344 printf("ThreadDumpAddress exited\n");
1347 void ThreadOpenConnections(void* parg)
1349 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1351 // Make this thread recognisable as the connection opening thread
1352 RenameThread("bitcoin-opencon");
1356 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1357 ThreadOpenConnections2(parg);
1358 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1360 catch (std::exception& e) {
1361 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1362 PrintException(&e, "ThreadOpenConnections()");
1363 } catch (...) {
1364 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1365 PrintException(NULL, "ThreadOpenConnections()");
1367 printf("ThreadOpenConnections exited\n");
1370 void static ProcessOneShot()
1372 string strDest;
1374 LOCK(cs_vOneShots);
1375 if (vOneShots.empty())
1376 return;
1377 strDest = vOneShots.front();
1378 vOneShots.pop_front();
1380 CAddress addr;
1381 CSemaphoreGrant grant(*semOutbound, true);
1382 if (grant) {
1383 if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1384 AddOneShot(strDest);
1388 void ThreadOpenConnections2(void* parg)
1390 printf("ThreadOpenConnections started\n");
1392 // Connect to specific addresses
1393 if (mapArgs.count("-connect"))
1395 for (int64 nLoop = 0;; nLoop++)
1397 ProcessOneShot();
1398 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1400 CAddress addr;
1401 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1402 for (int i = 0; i < 10 && i < nLoop; i++)
1404 Sleep(500);
1405 if (fShutdown)
1406 return;
1412 // Initiate network connections
1413 int64 nStart = GetTime();
1414 loop
1416 ProcessOneShot();
1418 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1419 Sleep(500);
1420 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1421 if (fShutdown)
1422 return;
1425 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1426 CSemaphoreGrant grant(*semOutbound);
1427 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1428 if (fShutdown)
1429 return;
1431 // Add seed nodes if IRC isn't working
1432 if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1434 std::vector<CAddress> vAdd;
1435 for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1437 // It'll only connect to one or two seed nodes because once it connects,
1438 // it'll get a pile of addresses with newer timestamps.
1439 // Seed nodes are given a random 'last seen time' of between one and two
1440 // weeks ago.
1441 const int64 nOneWeek = 7*24*60*60;
1442 struct in_addr ip;
1443 memcpy(&ip, &pnSeed[i], sizeof(ip));
1444 CAddress addr(CService(ip, GetDefaultPort()));
1445 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1446 vAdd.push_back(addr);
1448 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1452 // Choose an address to connect to based on most recently seen
1454 CAddress addrConnect;
1456 // Only connect out to one peer per network group (/16 for IPv4).
1457 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1458 int nOutbound = 0;
1459 set<vector<unsigned char> > setConnected;
1461 LOCK(cs_vNodes);
1462 BOOST_FOREACH(CNode* pnode, vNodes) {
1463 if (!pnode->fInbound) {
1464 setConnected.insert(pnode->addr.GetGroup());
1465 nOutbound++;
1470 int64 nANow = GetAdjustedTime();
1472 int nTries = 0;
1473 loop
1475 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1476 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1478 // if we selected an invalid address, restart
1479 if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1480 break;
1482 nTries++;
1484 if (IsLimited(addr))
1485 continue;
1487 // only consider very recently tried nodes after 30 failed attempts
1488 if (nANow - addr.nLastTry < 600 && nTries < 30)
1489 continue;
1491 // do not allow non-default ports, unless after 50 invalid addresses selected already
1492 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1493 continue;
1495 addrConnect = addr;
1496 break;
1499 if (addrConnect.IsValid())
1500 OpenNetworkConnection(addrConnect, &grant);
1504 void ThreadOpenAddedConnections(void* parg)
1506 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1508 // Make this thread recognisable as the connection opening thread
1509 RenameThread("bitcoin-opencon");
1513 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1514 ThreadOpenAddedConnections2(parg);
1515 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1517 catch (std::exception& e) {
1518 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1519 PrintException(&e, "ThreadOpenAddedConnections()");
1520 } catch (...) {
1521 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1522 PrintException(NULL, "ThreadOpenAddedConnections()");
1524 printf("ThreadOpenAddedConnections exited\n");
1527 void ThreadOpenAddedConnections2(void* parg)
1529 printf("ThreadOpenAddedConnections started\n");
1531 if (mapArgs.count("-addnode") == 0)
1532 return;
1534 if (GetNameProxy()) {
1535 while(!fShutdown) {
1536 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
1537 CAddress addr;
1538 CSemaphoreGrant grant(*semOutbound);
1539 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1540 Sleep(500);
1542 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1543 Sleep(120000); // Retry every 2 minutes
1544 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1546 return;
1549 vector<vector<CService> > vservAddressesToAdd(0);
1550 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1552 vector<CService> vservNode(0);
1553 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1555 vservAddressesToAdd.push_back(vservNode);
1557 LOCK(cs_setservAddNodeAddresses);
1558 BOOST_FOREACH(CService& serv, vservNode)
1559 setservAddNodeAddresses.insert(serv);
1563 loop
1565 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1566 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1567 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1569 LOCK(cs_vNodes);
1570 BOOST_FOREACH(CNode* pnode, vNodes)
1571 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1572 BOOST_FOREACH(CService& addrNode, *(it))
1573 if (pnode->addr == addrNode)
1575 it = vservConnectAddresses.erase(it);
1576 it--;
1577 break;
1580 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1582 CSemaphoreGrant grant(*semOutbound);
1583 OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
1584 Sleep(500);
1585 if (fShutdown)
1586 return;
1588 if (fShutdown)
1589 return;
1590 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1591 Sleep(120000); // Retry every 2 minutes
1592 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1593 if (fShutdown)
1594 return;
1598 // if succesful, this moves the passed grant to the constructed node
1599 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1602 // Initiate outbound network connection
1604 if (fShutdown)
1605 return false;
1606 if (!strDest)
1607 if (IsLocal(addrConnect) ||
1608 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1609 FindNode(addrConnect.ToStringIPPort().c_str()))
1610 return false;
1611 if (strDest && FindNode(strDest))
1612 return false;
1614 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1615 CNode* pnode = ConnectNode(addrConnect, strDest);
1616 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1617 if (fShutdown)
1618 return false;
1619 if (!pnode)
1620 return false;
1621 if (grantOutbound)
1622 grantOutbound->MoveTo(pnode->grantOutbound);
1623 pnode->fNetworkNode = true;
1624 if (fOneShot)
1625 pnode->fOneShot = true;
1627 return true;
1637 void ThreadMessageHandler(void* parg)
1639 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1641 // Make this thread recognisable as the message handling thread
1642 RenameThread("bitcoin-msghand");
1646 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1647 ThreadMessageHandler2(parg);
1648 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1650 catch (std::exception& e) {
1651 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1652 PrintException(&e, "ThreadMessageHandler()");
1653 } catch (...) {
1654 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1655 PrintException(NULL, "ThreadMessageHandler()");
1657 printf("ThreadMessageHandler exited\n");
1660 void ThreadMessageHandler2(void* parg)
1662 printf("ThreadMessageHandler started\n");
1663 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1664 while (!fShutdown)
1666 vector<CNode*> vNodesCopy;
1668 LOCK(cs_vNodes);
1669 vNodesCopy = vNodes;
1670 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1671 pnode->AddRef();
1674 // Poll the connected nodes for messages
1675 CNode* pnodeTrickle = NULL;
1676 if (!vNodesCopy.empty())
1677 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1678 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1680 // Receive messages
1682 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1683 if (lockRecv)
1684 ProcessMessages(pnode);
1686 if (fShutdown)
1687 return;
1689 // Send messages
1691 TRY_LOCK(pnode->cs_vSend, lockSend);
1692 if (lockSend)
1693 SendMessages(pnode, pnode == pnodeTrickle);
1695 if (fShutdown)
1696 return;
1700 LOCK(cs_vNodes);
1701 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1702 pnode->Release();
1705 // Wait and allow messages to bunch up.
1706 // Reduce vnThreadsRunning so StopNode has permission to exit while
1707 // we're sleeping, but we must always check fShutdown after doing this.
1708 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1709 Sleep(100);
1710 if (fRequestShutdown)
1711 StartShutdown();
1712 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1713 if (fShutdown)
1714 return;
1723 bool BindListenPort(const CService &addrBind, string& strError)
1725 strError = "";
1726 int nOne = 1;
1728 #ifdef WIN32
1729 // Initialize Windows Sockets
1730 WSADATA wsadata;
1731 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1732 if (ret != NO_ERROR)
1734 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1735 printf("%s\n", strError.c_str());
1736 return false;
1738 #endif
1740 // Create socket for listening for incoming connections
1741 #ifdef USE_IPV6
1742 struct sockaddr_storage sockaddr;
1743 #else
1744 struct sockaddr sockaddr;
1745 #endif
1746 socklen_t len = sizeof(sockaddr);
1747 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1749 strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1750 printf("%s\n", strError.c_str());
1751 return false;
1754 SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1755 if (hListenSocket == INVALID_SOCKET)
1757 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1758 printf("%s\n", strError.c_str());
1759 return false;
1762 #ifdef SO_NOSIGPIPE
1763 // Different way of disabling SIGPIPE on BSD
1764 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1765 #endif
1767 #ifndef WIN32
1768 // Allow binding if the port is still in TIME_WAIT state after
1769 // the program was closed and restarted. Not an issue on windows.
1770 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1771 #endif
1774 #ifdef WIN32
1775 // Set to nonblocking, incoming connections will also inherit this
1776 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1777 #else
1778 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1779 #endif
1781 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1782 printf("%s\n", strError.c_str());
1783 return false;
1786 #ifdef USE_IPV6
1787 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1788 // and enable it by default or not. Try to enable it, if possible.
1789 if (addrBind.IsIPv6()) {
1790 #ifdef IPV6_V6ONLY
1791 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1792 #endif
1793 #ifdef WIN32
1794 int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1795 int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1796 // this call is allowed to fail
1797 setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1798 #endif
1800 #endif
1802 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1804 int nErr = WSAGetLastError();
1805 if (nErr == WSAEADDRINUSE)
1806 strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
1807 else
1808 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1809 printf("%s\n", strError.c_str());
1810 return false;
1812 printf("Bound to %s\n", addrBind.ToString().c_str());
1814 // Listen for incoming connections
1815 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1817 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1818 printf("%s\n", strError.c_str());
1819 return false;
1822 vhListenSocket.push_back(hListenSocket);
1824 if (addrBind.IsRoutable() && fDiscover)
1825 AddLocal(addrBind, LOCAL_BIND);
1827 return true;
1830 void static Discover()
1832 if (!fDiscover)
1833 return;
1835 #ifdef WIN32
1836 // Get local host ip
1837 char pszHostName[1000] = "";
1838 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1840 vector<CNetAddr> vaddr;
1841 if (LookupHost(pszHostName, vaddr))
1843 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1845 AddLocal(addr, LOCAL_IF);
1849 #else
1850 // Get local host ip
1851 struct ifaddrs* myaddrs;
1852 if (getifaddrs(&myaddrs) == 0)
1854 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1856 if (ifa->ifa_addr == NULL) continue;
1857 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1858 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1859 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1860 if (ifa->ifa_addr->sa_family == AF_INET)
1862 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1863 CNetAddr addr(s4->sin_addr);
1864 if (AddLocal(addr, LOCAL_IF))
1865 printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1867 #ifdef USE_IPV6
1868 else if (ifa->ifa_addr->sa_family == AF_INET6)
1870 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1871 CNetAddr addr(s6->sin6_addr);
1872 if (AddLocal(addr, LOCAL_IF))
1873 printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1875 #endif
1877 freeifaddrs(myaddrs);
1879 #endif
1881 CreateThread(ThreadGetMyExternalIP, NULL);
1884 void StartNode(void* parg)
1886 // Make this thread recognisable as the startup thread
1887 RenameThread("bitcoin-start");
1889 if (semOutbound == NULL) {
1890 // initialize semaphore
1891 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1892 semOutbound = new CSemaphore(nMaxOutbound);
1895 if (pnodeLocalHost == NULL)
1896 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1898 Discover();
1901 // Start threads
1904 if (!GetBoolArg("-dnsseed", true))
1905 printf("DNS seeding disabled\n");
1906 else
1907 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1908 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1910 // Map ports with UPnP
1911 if (fUseUPnP)
1912 MapPort();
1914 // Get addresses from IRC and advertise ours
1915 if (!CreateThread(ThreadIRCSeed, NULL))
1916 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1918 // Send and receive from sockets, accept connections
1919 if (!CreateThread(ThreadSocketHandler, NULL))
1920 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1922 // Initiate outbound connections from -addnode
1923 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1924 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1926 // Initiate outbound connections
1927 if (!CreateThread(ThreadOpenConnections, NULL))
1928 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1930 // Process messages
1931 if (!CreateThread(ThreadMessageHandler, NULL))
1932 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1934 // Dump network addresses
1935 if (!CreateThread(ThreadDumpAddress, NULL))
1936 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1938 // Generate coins in the background
1939 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1942 bool StopNode()
1944 printf("StopNode()\n");
1945 fShutdown = true;
1946 nTransactionsUpdated++;
1947 int64 nStart = GetTime();
1948 if (semOutbound)
1949 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1950 semOutbound->post();
1953 int nThreadsRunning = 0;
1954 for (int n = 0; n < THREAD_MAX; n++)
1955 nThreadsRunning += vnThreadsRunning[n];
1956 if (nThreadsRunning == 0)
1957 break;
1958 if (GetTime() - nStart > 20)
1959 break;
1960 Sleep(20);
1961 } while(true);
1962 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1963 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1964 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1965 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1966 if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1967 if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1968 #ifdef USE_UPNP
1969 if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1970 #endif
1971 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1972 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1973 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1974 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
1975 Sleep(20);
1976 Sleep(50);
1977 DumpAddresses();
1978 return true;
1981 class CNetCleanup
1983 public:
1984 CNetCleanup()
1987 ~CNetCleanup()
1989 // Close sockets
1990 BOOST_FOREACH(CNode* pnode, vNodes)
1991 if (pnode->hSocket != INVALID_SOCKET)
1992 closesocket(pnode->hSocket);
1993 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1994 if (hListenSocket != INVALID_SOCKET)
1995 if (closesocket(hListenSocket) == SOCKET_ERROR)
1996 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1998 #ifdef WIN32
1999 // Shutdown Windows Sockets
2000 WSACleanup();
2001 #endif
2004 instance_of_cnetcleanup;