Update Bugreport Links
[bitcoinplatinum.git] / src / net.cpp
blob651f4a974c4313452462198cb711d27c74abbc8d
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 + (fAlready ? 1 : 0);
237 info.nPort = addr.GetPort();
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 web server 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 non-blocking
501 #ifdef WIN32
502 u_long nOne = 1;
503 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
504 printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
505 #else
506 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
507 printf("ConnectSocket() : fcntl non-blocking 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 (delta: %d)!\n", addrName.c_str(), howmuch);
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
600 printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
602 LOCK(cs_setBanned);
603 if (setBanned[addr] < banTime)
604 setBanned[addr] = banTime;
606 CloseSocketDisconnect();
607 return true;
608 } else
609 printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
610 return false;
613 #undef X
614 #define X(name) stats.name = name
615 void CNode::copyStats(CNodeStats &stats)
617 X(nServices);
618 X(nLastSend);
619 X(nLastRecv);
620 X(nTimeConnected);
621 X(addrName);
622 X(nVersion);
623 X(strSubVer);
624 X(fInbound);
625 X(nReleaseTime);
626 X(nStartingHeight);
627 X(nMisbehavior);
629 #undef X
640 void ThreadSocketHandler(void* parg)
642 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
644 // Make this thread recognisable as the networking thread
645 RenameThread("bitcoin-net");
649 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
650 ThreadSocketHandler2(parg);
651 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
653 catch (std::exception& e) {
654 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
655 PrintException(&e, "ThreadSocketHandler()");
656 } catch (...) {
657 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
658 throw; // support pthread_cancel()
660 printf("ThreadSocketHandler exited\n");
663 void ThreadSocketHandler2(void* parg)
665 printf("ThreadSocketHandler started\n");
666 list<CNode*> vNodesDisconnected;
667 unsigned int nPrevNodeCount = 0;
669 loop
672 // Disconnect nodes
675 LOCK(cs_vNodes);
676 // Disconnect unused nodes
677 vector<CNode*> vNodesCopy = vNodes;
678 BOOST_FOREACH(CNode* pnode, vNodesCopy)
680 if (pnode->fDisconnect ||
681 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
683 // remove from vNodes
684 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
686 // release outbound grant (if any)
687 pnode->grantOutbound.Release();
689 // close socket and cleanup
690 pnode->CloseSocketDisconnect();
691 pnode->Cleanup();
693 // hold in disconnected pool until all refs are released
694 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
695 if (pnode->fNetworkNode || pnode->fInbound)
696 pnode->Release();
697 vNodesDisconnected.push_back(pnode);
701 // Delete disconnected nodes
702 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
703 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
705 // wait until threads are done using it
706 if (pnode->GetRefCount() <= 0)
708 bool fDelete = false;
710 TRY_LOCK(pnode->cs_vSend, lockSend);
711 if (lockSend)
713 TRY_LOCK(pnode->cs_vRecv, lockRecv);
714 if (lockRecv)
716 TRY_LOCK(pnode->cs_mapRequests, lockReq);
717 if (lockReq)
719 TRY_LOCK(pnode->cs_inventory, lockInv);
720 if (lockInv)
721 fDelete = true;
726 if (fDelete)
728 vNodesDisconnected.remove(pnode);
729 delete pnode;
734 if (vNodes.size() != nPrevNodeCount)
736 nPrevNodeCount = vNodes.size();
737 uiInterface.NotifyNumConnectionsChanged(vNodes.size());
742 // Find which sockets have data to receive
744 struct timeval timeout;
745 timeout.tv_sec = 0;
746 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
748 fd_set fdsetRecv;
749 fd_set fdsetSend;
750 fd_set fdsetError;
751 FD_ZERO(&fdsetRecv);
752 FD_ZERO(&fdsetSend);
753 FD_ZERO(&fdsetError);
754 SOCKET hSocketMax = 0;
755 bool have_fds = false;
757 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
758 FD_SET(hListenSocket, &fdsetRecv);
759 hSocketMax = max(hSocketMax, hListenSocket);
760 have_fds = true;
763 LOCK(cs_vNodes);
764 BOOST_FOREACH(CNode* pnode, vNodes)
766 if (pnode->hSocket == INVALID_SOCKET)
767 continue;
768 FD_SET(pnode->hSocket, &fdsetRecv);
769 FD_SET(pnode->hSocket, &fdsetError);
770 hSocketMax = max(hSocketMax, pnode->hSocket);
771 have_fds = true;
773 TRY_LOCK(pnode->cs_vSend, lockSend);
774 if (lockSend && !pnode->vSend.empty())
775 FD_SET(pnode->hSocket, &fdsetSend);
780 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
781 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
782 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
783 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
784 if (fShutdown)
785 return;
786 if (nSelect == SOCKET_ERROR)
788 if (have_fds)
790 int nErr = WSAGetLastError();
791 printf("socket select error %d\n", nErr);
792 for (unsigned int i = 0; i <= hSocketMax; i++)
793 FD_SET(i, &fdsetRecv);
795 FD_ZERO(&fdsetSend);
796 FD_ZERO(&fdsetError);
797 Sleep(timeout.tv_usec/1000);
802 // Accept new connections
804 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
805 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
807 #ifdef USE_IPV6
808 struct sockaddr_storage sockaddr;
809 #else
810 struct sockaddr sockaddr;
811 #endif
812 socklen_t len = sizeof(sockaddr);
813 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
814 CAddress addr;
815 int nInbound = 0;
817 if (hSocket != INVALID_SOCKET)
818 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
819 printf("Warning: Unknown socket family\n");
822 LOCK(cs_vNodes);
823 BOOST_FOREACH(CNode* pnode, vNodes)
824 if (pnode->fInbound)
825 nInbound++;
828 if (hSocket == INVALID_SOCKET)
830 int nErr = WSAGetLastError();
831 if (nErr != WSAEWOULDBLOCK)
832 printf("socket error accept failed: %d\n", nErr);
834 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
837 LOCK(cs_setservAddNodeAddresses);
838 if (!setservAddNodeAddresses.count(addr))
839 closesocket(hSocket);
842 else if (CNode::IsBanned(addr))
844 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
845 closesocket(hSocket);
847 else
849 printf("accepted connection %s\n", addr.ToString().c_str());
850 CNode* pnode = new CNode(hSocket, addr, "", true);
851 pnode->AddRef();
853 LOCK(cs_vNodes);
854 vNodes.push_back(pnode);
861 // Service each socket
863 vector<CNode*> vNodesCopy;
865 LOCK(cs_vNodes);
866 vNodesCopy = vNodes;
867 BOOST_FOREACH(CNode* pnode, vNodesCopy)
868 pnode->AddRef();
870 BOOST_FOREACH(CNode* pnode, vNodesCopy)
872 if (fShutdown)
873 return;
876 // Receive
878 if (pnode->hSocket == INVALID_SOCKET)
879 continue;
880 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
882 TRY_LOCK(pnode->cs_vRecv, lockRecv);
883 if (lockRecv)
885 CDataStream& vRecv = pnode->vRecv;
886 unsigned int nPos = vRecv.size();
888 if (nPos > ReceiveBufferSize()) {
889 if (!pnode->fDisconnect)
890 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
891 pnode->CloseSocketDisconnect();
893 else {
894 // typical socket buffer is 8K-64K
895 char pchBuf[0x10000];
896 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
897 if (nBytes > 0)
899 vRecv.resize(nPos + nBytes);
900 memcpy(&vRecv[nPos], pchBuf, nBytes);
901 pnode->nLastRecv = GetTime();
903 else if (nBytes == 0)
905 // socket closed gracefully
906 if (!pnode->fDisconnect)
907 printf("socket closed\n");
908 pnode->CloseSocketDisconnect();
910 else if (nBytes < 0)
912 // error
913 int nErr = WSAGetLastError();
914 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
916 if (!pnode->fDisconnect)
917 printf("socket recv error %d\n", nErr);
918 pnode->CloseSocketDisconnect();
926 // Send
928 if (pnode->hSocket == INVALID_SOCKET)
929 continue;
930 if (FD_ISSET(pnode->hSocket, &fdsetSend))
932 TRY_LOCK(pnode->cs_vSend, lockSend);
933 if (lockSend)
935 CDataStream& vSend = pnode->vSend;
936 if (!vSend.empty())
938 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
939 if (nBytes > 0)
941 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
942 pnode->nLastSend = GetTime();
944 else if (nBytes < 0)
946 // error
947 int nErr = WSAGetLastError();
948 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
950 printf("socket send error %d\n", nErr);
951 pnode->CloseSocketDisconnect();
959 // Inactivity checking
961 if (pnode->vSend.empty())
962 pnode->nLastSendEmpty = GetTime();
963 if (GetTime() - pnode->nTimeConnected > 60)
965 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
967 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
968 pnode->fDisconnect = true;
970 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
972 printf("socket not sending\n");
973 pnode->fDisconnect = true;
975 else if (GetTime() - pnode->nLastRecv > 90*60)
977 printf("socket inactivity timeout\n");
978 pnode->fDisconnect = true;
983 LOCK(cs_vNodes);
984 BOOST_FOREACH(CNode* pnode, vNodesCopy)
985 pnode->Release();
988 Sleep(10);
1000 #ifdef USE_UPNP
1001 void ThreadMapPort(void* parg)
1003 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1005 // Make this thread recognisable as the UPnP thread
1006 RenameThread("bitcoin-UPnP");
1010 vnThreadsRunning[THREAD_UPNP]++;
1011 ThreadMapPort2(parg);
1012 vnThreadsRunning[THREAD_UPNP]--;
1014 catch (std::exception& e) {
1015 vnThreadsRunning[THREAD_UPNP]--;
1016 PrintException(&e, "ThreadMapPort()");
1017 } catch (...) {
1018 vnThreadsRunning[THREAD_UPNP]--;
1019 PrintException(NULL, "ThreadMapPort()");
1021 printf("ThreadMapPort exited\n");
1024 void ThreadMapPort2(void* parg)
1026 printf("ThreadMapPort started\n");
1028 std::string port = strprintf("%u", GetListenPort());
1029 const char * multicastif = 0;
1030 const char * minissdpdpath = 0;
1031 struct UPNPDev * devlist = 0;
1032 char lanaddr[64];
1034 #ifndef UPNPDISCOVER_SUCCESS
1035 /* miniupnpc 1.5 */
1036 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1037 #else
1038 /* miniupnpc 1.6 */
1039 int error = 0;
1040 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1041 #endif
1043 struct UPNPUrls urls;
1044 struct IGDdatas data;
1045 int r;
1047 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1048 if (r == 1)
1050 if (fDiscover) {
1051 char externalIPAddress[40];
1052 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1053 if(r != UPNPCOMMAND_SUCCESS)
1054 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1055 else
1057 if(externalIPAddress[0])
1059 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1060 AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1062 else
1063 printf("UPnP: GetExternalIPAddress failed.\n");
1067 string strDesc = "Bitcoin " + FormatFullVersion();
1068 #ifndef UPNPDISCOVER_SUCCESS
1069 /* miniupnpc 1.5 */
1070 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1071 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1072 #else
1073 /* miniupnpc 1.6 */
1074 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1075 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1076 #endif
1078 if(r!=UPNPCOMMAND_SUCCESS)
1079 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1080 port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
1081 else
1082 printf("UPnP Port Mapping successful.\n");
1083 int i = 1;
1084 loop {
1085 if (fShutdown || !fUseUPnP)
1087 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1088 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1089 freeUPNPDevlist(devlist); devlist = 0;
1090 FreeUPNPUrls(&urls);
1091 return;
1093 if (i % 600 == 0) // Refresh every 20 minutes
1095 #ifndef UPNPDISCOVER_SUCCESS
1096 /* miniupnpc 1.5 */
1097 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1098 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1099 #else
1100 /* miniupnpc 1.6 */
1101 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1102 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1103 #endif
1105 if(r!=UPNPCOMMAND_SUCCESS)
1106 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1107 port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
1108 else
1109 printf("UPnP Port Mapping successful.\n");;
1111 Sleep(2000);
1112 i++;
1114 } else {
1115 printf("No valid UPnP IGDs found\n");
1116 freeUPNPDevlist(devlist); devlist = 0;
1117 if (r != 0)
1118 FreeUPNPUrls(&urls);
1119 loop {
1120 if (fShutdown || !fUseUPnP)
1121 return;
1122 Sleep(2000);
1127 void MapPort()
1129 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1131 if (!NewThread(ThreadMapPort, NULL))
1132 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1135 #else
1136 void MapPort()
1138 // Intentionally left blank.
1140 #endif
1150 // DNS seeds
1151 // Each pair gives a source name and a seed name.
1152 // The first name is used as information source for addrman.
1153 // The second name should resolve to a list of seed addresses.
1154 static const char *strDNSSeed[][2] = {
1155 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1156 {"bluematt.me", "dnsseed.bluematt.me"},
1157 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1158 {"xf2.org", "bitseed.xf2.org"},
1161 void ThreadDNSAddressSeed(void* parg)
1163 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1165 // Make this thread recognisable as the DNS seeding thread
1166 RenameThread("bitcoin-dnsseed");
1170 vnThreadsRunning[THREAD_DNSSEED]++;
1171 ThreadDNSAddressSeed2(parg);
1172 vnThreadsRunning[THREAD_DNSSEED]--;
1174 catch (std::exception& e) {
1175 vnThreadsRunning[THREAD_DNSSEED]--;
1176 PrintException(&e, "ThreadDNSAddressSeed()");
1177 } catch (...) {
1178 vnThreadsRunning[THREAD_DNSSEED]--;
1179 throw; // support pthread_cancel()
1181 printf("ThreadDNSAddressSeed exited\n");
1184 void ThreadDNSAddressSeed2(void* parg)
1186 printf("ThreadDNSAddressSeed started\n");
1187 int found = 0;
1189 if (!fTestNet)
1191 printf("Loading addresses from DNS seeds (could take a while)\n");
1193 for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1194 if (GetNameProxy()) {
1195 AddOneShot(strDNSSeed[seed_idx][1]);
1196 } else {
1197 vector<CNetAddr> vaddr;
1198 vector<CAddress> vAdd;
1199 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1201 BOOST_FOREACH(CNetAddr& ip, vaddr)
1203 int nOneDay = 24*3600;
1204 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1205 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1206 vAdd.push_back(addr);
1207 found++;
1210 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1215 printf("%d addresses found from DNS seeds\n", found);
1229 unsigned int pnSeed[] =
1231 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1232 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1233 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1234 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1235 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1236 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1237 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1238 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1239 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1240 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1241 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1242 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1243 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1244 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1245 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1246 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1247 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1248 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1249 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1250 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1251 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1252 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1253 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1254 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1255 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1256 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1257 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1258 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1259 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1260 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1261 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1262 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1263 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1264 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1265 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1266 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1267 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1268 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1269 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1270 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1271 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1272 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1273 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1274 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1275 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1276 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1277 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1278 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1279 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1280 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1281 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1282 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1283 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1284 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1285 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1286 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1287 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1288 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1289 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1290 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1291 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1292 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1293 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1294 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1295 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1296 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1297 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1298 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1299 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1300 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1301 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1302 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1303 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1304 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1305 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1306 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1307 0xc461d84a, 0xb2dbe247,
1310 void DumpAddresses()
1312 int64 nStart = GetTimeMillis();
1314 CAddrDB adb;
1315 adb.Write(addrman);
1317 printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
1318 addrman.size(), GetTimeMillis() - nStart);
1321 void ThreadDumpAddress2(void* parg)
1323 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1324 while (!fShutdown)
1326 DumpAddresses();
1327 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1328 Sleep(100000);
1329 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1331 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1334 void ThreadDumpAddress(void* parg)
1336 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1338 // Make this thread recognisable as the address dumping thread
1339 RenameThread("bitcoin-adrdump");
1343 ThreadDumpAddress2(parg);
1345 catch (std::exception& e) {
1346 PrintException(&e, "ThreadDumpAddress()");
1348 printf("ThreadDumpAddress exited\n");
1351 void ThreadOpenConnections(void* parg)
1353 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1355 // Make this thread recognisable as the connection opening thread
1356 RenameThread("bitcoin-opencon");
1360 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1361 ThreadOpenConnections2(parg);
1362 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1364 catch (std::exception& e) {
1365 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1366 PrintException(&e, "ThreadOpenConnections()");
1367 } catch (...) {
1368 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1369 PrintException(NULL, "ThreadOpenConnections()");
1371 printf("ThreadOpenConnections exited\n");
1374 void static ProcessOneShot()
1376 string strDest;
1378 LOCK(cs_vOneShots);
1379 if (vOneShots.empty())
1380 return;
1381 strDest = vOneShots.front();
1382 vOneShots.pop_front();
1384 CAddress addr;
1385 CSemaphoreGrant grant(*semOutbound, true);
1386 if (grant) {
1387 if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1388 AddOneShot(strDest);
1392 void ThreadOpenConnections2(void* parg)
1394 printf("ThreadOpenConnections started\n");
1396 // Connect to specific addresses
1397 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1399 for (int64 nLoop = 0;; nLoop++)
1401 ProcessOneShot();
1402 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1404 CAddress addr;
1405 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1406 for (int i = 0; i < 10 && i < nLoop; i++)
1408 Sleep(500);
1409 if (fShutdown)
1410 return;
1413 Sleep(500);
1417 // Initiate network connections
1418 int64 nStart = GetTime();
1419 loop
1421 ProcessOneShot();
1423 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1424 Sleep(500);
1425 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1426 if (fShutdown)
1427 return;
1430 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1431 CSemaphoreGrant grant(*semOutbound);
1432 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1433 if (fShutdown)
1434 return;
1436 // Add seed nodes if IRC isn't working
1437 if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1439 std::vector<CAddress> vAdd;
1440 for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1442 // It'll only connect to one or two seed nodes because once it connects,
1443 // it'll get a pile of addresses with newer timestamps.
1444 // Seed nodes are given a random 'last seen time' of between one and two
1445 // weeks ago.
1446 const int64 nOneWeek = 7*24*60*60;
1447 struct in_addr ip;
1448 memcpy(&ip, &pnSeed[i], sizeof(ip));
1449 CAddress addr(CService(ip, GetDefaultPort()));
1450 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1451 vAdd.push_back(addr);
1453 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1457 // Choose an address to connect to based on most recently seen
1459 CAddress addrConnect;
1461 // Only connect out to one peer per network group (/16 for IPv4).
1462 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1463 int nOutbound = 0;
1464 set<vector<unsigned char> > setConnected;
1466 LOCK(cs_vNodes);
1467 BOOST_FOREACH(CNode* pnode, vNodes) {
1468 if (!pnode->fInbound) {
1469 setConnected.insert(pnode->addr.GetGroup());
1470 nOutbound++;
1475 int64 nANow = GetAdjustedTime();
1477 int nTries = 0;
1478 loop
1480 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1481 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1483 // if we selected an invalid address, restart
1484 if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1485 break;
1487 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1488 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1489 // already-connected network ranges, ...) before trying new addrman addresses.
1490 nTries++;
1491 if (nTries > 100)
1492 break;
1494 if (IsLimited(addr))
1495 continue;
1497 // only consider very recently tried nodes after 30 failed attempts
1498 if (nANow - addr.nLastTry < 600 && nTries < 30)
1499 continue;
1501 // do not allow non-default ports, unless after 50 invalid addresses selected already
1502 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1503 continue;
1505 addrConnect = addr;
1506 break;
1509 if (addrConnect.IsValid())
1510 OpenNetworkConnection(addrConnect, &grant);
1514 void ThreadOpenAddedConnections(void* parg)
1516 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1518 // Make this thread recognisable as the connection opening thread
1519 RenameThread("bitcoin-opencon");
1523 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1524 ThreadOpenAddedConnections2(parg);
1525 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1527 catch (std::exception& e) {
1528 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1529 PrintException(&e, "ThreadOpenAddedConnections()");
1530 } catch (...) {
1531 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1532 PrintException(NULL, "ThreadOpenAddedConnections()");
1534 printf("ThreadOpenAddedConnections exited\n");
1537 void ThreadOpenAddedConnections2(void* parg)
1539 printf("ThreadOpenAddedConnections started\n");
1541 if (mapArgs.count("-addnode") == 0)
1542 return;
1544 if (GetNameProxy()) {
1545 while(!fShutdown) {
1546 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
1547 CAddress addr;
1548 CSemaphoreGrant grant(*semOutbound);
1549 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1550 Sleep(500);
1552 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1553 Sleep(120000); // Retry every 2 minutes
1554 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1556 return;
1559 vector<vector<CService> > vservAddressesToAdd(0);
1560 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1562 vector<CService> vservNode(0);
1563 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1565 vservAddressesToAdd.push_back(vservNode);
1567 LOCK(cs_setservAddNodeAddresses);
1568 BOOST_FOREACH(CService& serv, vservNode)
1569 setservAddNodeAddresses.insert(serv);
1573 loop
1575 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1576 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1577 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1579 LOCK(cs_vNodes);
1580 BOOST_FOREACH(CNode* pnode, vNodes)
1581 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1582 BOOST_FOREACH(CService& addrNode, *(it))
1583 if (pnode->addr == addrNode)
1585 it = vservConnectAddresses.erase(it);
1586 it--;
1587 break;
1590 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1592 CSemaphoreGrant grant(*semOutbound);
1593 OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
1594 Sleep(500);
1595 if (fShutdown)
1596 return;
1598 if (fShutdown)
1599 return;
1600 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1601 Sleep(120000); // Retry every 2 minutes
1602 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1603 if (fShutdown)
1604 return;
1608 // if successful, this moves the passed grant to the constructed node
1609 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1612 // Initiate outbound network connection
1614 if (fShutdown)
1615 return false;
1616 if (!strDest)
1617 if (IsLocal(addrConnect) ||
1618 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1619 FindNode(addrConnect.ToStringIPPort().c_str()))
1620 return false;
1621 if (strDest && FindNode(strDest))
1622 return false;
1624 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1625 CNode* pnode = ConnectNode(addrConnect, strDest);
1626 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1627 if (fShutdown)
1628 return false;
1629 if (!pnode)
1630 return false;
1631 if (grantOutbound)
1632 grantOutbound->MoveTo(pnode->grantOutbound);
1633 pnode->fNetworkNode = true;
1634 if (fOneShot)
1635 pnode->fOneShot = true;
1637 return true;
1647 void ThreadMessageHandler(void* parg)
1649 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1651 // Make this thread recognisable as the message handling thread
1652 RenameThread("bitcoin-msghand");
1656 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1657 ThreadMessageHandler2(parg);
1658 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1660 catch (std::exception& e) {
1661 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1662 PrintException(&e, "ThreadMessageHandler()");
1663 } catch (...) {
1664 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1665 PrintException(NULL, "ThreadMessageHandler()");
1667 printf("ThreadMessageHandler exited\n");
1670 void ThreadMessageHandler2(void* parg)
1672 printf("ThreadMessageHandler started\n");
1673 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1674 while (!fShutdown)
1676 vector<CNode*> vNodesCopy;
1678 LOCK(cs_vNodes);
1679 vNodesCopy = vNodes;
1680 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1681 pnode->AddRef();
1684 // Poll the connected nodes for messages
1685 CNode* pnodeTrickle = NULL;
1686 if (!vNodesCopy.empty())
1687 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1688 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1690 // Receive messages
1692 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1693 if (lockRecv)
1694 ProcessMessages(pnode);
1696 if (fShutdown)
1697 return;
1699 // Send messages
1701 TRY_LOCK(pnode->cs_vSend, lockSend);
1702 if (lockSend)
1703 SendMessages(pnode, pnode == pnodeTrickle);
1705 if (fShutdown)
1706 return;
1710 LOCK(cs_vNodes);
1711 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1712 pnode->Release();
1715 // Wait and allow messages to bunch up.
1716 // Reduce vnThreadsRunning so StopNode has permission to exit while
1717 // we're sleeping, but we must always check fShutdown after doing this.
1718 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1719 Sleep(100);
1720 if (fRequestShutdown)
1721 StartShutdown();
1722 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1723 if (fShutdown)
1724 return;
1733 bool BindListenPort(const CService &addrBind, string& strError)
1735 strError = "";
1736 int nOne = 1;
1738 #ifdef WIN32
1739 // Initialize Windows Sockets
1740 WSADATA wsadata;
1741 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1742 if (ret != NO_ERROR)
1744 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1745 printf("%s\n", strError.c_str());
1746 return false;
1748 #endif
1750 // Create socket for listening for incoming connections
1751 #ifdef USE_IPV6
1752 struct sockaddr_storage sockaddr;
1753 #else
1754 struct sockaddr sockaddr;
1755 #endif
1756 socklen_t len = sizeof(sockaddr);
1757 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1759 strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1760 printf("%s\n", strError.c_str());
1761 return false;
1764 SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1765 if (hListenSocket == INVALID_SOCKET)
1767 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1768 printf("%s\n", strError.c_str());
1769 return false;
1772 #ifdef SO_NOSIGPIPE
1773 // Different way of disabling SIGPIPE on BSD
1774 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1775 #endif
1777 #ifndef WIN32
1778 // Allow binding if the port is still in TIME_WAIT state after
1779 // the program was closed and restarted. Not an issue on windows.
1780 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1781 #endif
1784 #ifdef WIN32
1785 // Set to non-blocking, incoming connections will also inherit this
1786 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1787 #else
1788 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1789 #endif
1791 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1792 printf("%s\n", strError.c_str());
1793 return false;
1796 #ifdef USE_IPV6
1797 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1798 // and enable it by default or not. Try to enable it, if possible.
1799 if (addrBind.IsIPv6()) {
1800 #ifdef IPV6_V6ONLY
1801 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1802 #endif
1803 #ifdef WIN32
1804 int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1805 int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1806 // this call is allowed to fail
1807 setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1808 #endif
1810 #endif
1812 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1814 int nErr = WSAGetLastError();
1815 if (nErr == WSAEADDRINUSE)
1816 strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
1817 else
1818 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1819 printf("%s\n", strError.c_str());
1820 return false;
1822 printf("Bound to %s\n", addrBind.ToString().c_str());
1824 // Listen for incoming connections
1825 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1827 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1828 printf("%s\n", strError.c_str());
1829 return false;
1832 vhListenSocket.push_back(hListenSocket);
1834 if (addrBind.IsRoutable() && fDiscover)
1835 AddLocal(addrBind, LOCAL_BIND);
1837 return true;
1840 void static Discover()
1842 if (!fDiscover)
1843 return;
1845 #ifdef WIN32
1846 // Get local host IP
1847 char pszHostName[1000] = "";
1848 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1850 vector<CNetAddr> vaddr;
1851 if (LookupHost(pszHostName, vaddr))
1853 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1855 AddLocal(addr, LOCAL_IF);
1859 #else
1860 // Get local host ip
1861 struct ifaddrs* myaddrs;
1862 if (getifaddrs(&myaddrs) == 0)
1864 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1866 if (ifa->ifa_addr == NULL) continue;
1867 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1868 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1869 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1870 if (ifa->ifa_addr->sa_family == AF_INET)
1872 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1873 CNetAddr addr(s4->sin_addr);
1874 if (AddLocal(addr, LOCAL_IF))
1875 printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1877 #ifdef USE_IPV6
1878 else if (ifa->ifa_addr->sa_family == AF_INET6)
1880 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1881 CNetAddr addr(s6->sin6_addr);
1882 if (AddLocal(addr, LOCAL_IF))
1883 printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1885 #endif
1887 freeifaddrs(myaddrs);
1889 #endif
1891 // Don't use external IPv4 discovery, when -onlynet="IPv6"
1892 if (!IsLimited(NET_IPV4))
1893 NewThread(ThreadGetMyExternalIP, NULL);
1896 void StartNode(void* parg)
1898 // Make this thread recognisable as the startup thread
1899 RenameThread("bitcoin-start");
1901 if (semOutbound == NULL) {
1902 // initialize semaphore
1903 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1904 semOutbound = new CSemaphore(nMaxOutbound);
1907 if (pnodeLocalHost == NULL)
1908 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1910 Discover();
1913 // Start threads
1916 if (!GetBoolArg("-dnsseed", true))
1917 printf("DNS seeding disabled\n");
1918 else
1919 if (!NewThread(ThreadDNSAddressSeed, NULL))
1920 printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1922 // Map ports with UPnP
1923 if (fUseUPnP)
1924 MapPort();
1926 // Get addresses from IRC and advertise ours
1927 if (!NewThread(ThreadIRCSeed, NULL))
1928 printf("Error: NewThread(ThreadIRCSeed) failed\n");
1930 // Send and receive from sockets, accept connections
1931 if (!NewThread(ThreadSocketHandler, NULL))
1932 printf("Error: NewThread(ThreadSocketHandler) failed\n");
1934 // Initiate outbound connections from -addnode
1935 if (!NewThread(ThreadOpenAddedConnections, NULL))
1936 printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1938 // Initiate outbound connections
1939 if (!NewThread(ThreadOpenConnections, NULL))
1940 printf("Error: NewThread(ThreadOpenConnections) failed\n");
1942 // Process messages
1943 if (!NewThread(ThreadMessageHandler, NULL))
1944 printf("Error: NewThread(ThreadMessageHandler) failed\n");
1946 // Dump network addresses
1947 if (!NewThread(ThreadDumpAddress, NULL))
1948 printf("Error; NewThread(ThreadDumpAddress) failed\n");
1950 // Generate coins in the background
1951 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1954 bool StopNode()
1956 printf("StopNode()\n");
1957 fShutdown = true;
1958 nTransactionsUpdated++;
1959 int64 nStart = GetTime();
1960 if (semOutbound)
1961 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1962 semOutbound->post();
1965 int nThreadsRunning = 0;
1966 for (int n = 0; n < THREAD_MAX; n++)
1967 nThreadsRunning += vnThreadsRunning[n];
1968 if (nThreadsRunning == 0)
1969 break;
1970 if (GetTime() - nStart > 20)
1971 break;
1972 Sleep(20);
1973 } while(true);
1974 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1975 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1976 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1977 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1978 if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1979 if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1980 #ifdef USE_UPNP
1981 if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1982 #endif
1983 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1984 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1985 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1986 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
1987 Sleep(20);
1988 Sleep(50);
1989 DumpAddresses();
1990 return true;
1993 class CNetCleanup
1995 public:
1996 CNetCleanup()
1999 ~CNetCleanup()
2001 // Close sockets
2002 BOOST_FOREACH(CNode* pnode, vNodes)
2003 if (pnode->hSocket != INVALID_SOCKET)
2004 closesocket(pnode->hSocket);
2005 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
2006 if (hListenSocket != INVALID_SOCKET)
2007 if (closesocket(hListenSocket) == SOCKET_ERROR)
2008 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
2010 #ifdef WIN32
2011 // Shutdown Windows Sockets
2012 WSACleanup();
2013 #endif
2016 instance_of_cnetcleanup;