1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Copyright (c) 2011 The PPCoin developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
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);
34 void ThreadMapPort2(void* parg);
36 void ThreadDNSAddressSeed2(void* parg);
37 bool OpenNetworkConnection(const CAddress& addrConnect);
44 // Global state variables
47 bool fAllowDNS = false;
48 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
49 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
50 static CNode* pnodeLocalHost = NULL;
51 uint64 nLocalHostNonce = 0;
52 array<int, 10> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
55 vector<CNode*> vNodes;
56 CCriticalSection cs_vNodes;
57 map<vector<unsigned char>, CAddress> mapAddresses;
58 CCriticalSection cs_mapAddresses;
59 map<CInv, CDataStream> mapRelay;
60 deque<pair<int64, CInv> > vRelayExpiration;
61 CCriticalSection cs_mapRelay;
62 map<CInv, int64> mapAlreadyAskedFor;
65 int fUseProxy = false;
66 int nConnectTimeout = 5000;
67 CAddress addrProxy("127.0.0.1",9050);
72 unsigned short GetListenPort()
74 return (unsigned short)(GetArg("-port", GetDefaultPort()));
77 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
79 // Filter out duplicate requests
80 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
82 pindexLastGetBlocksBegin = pindexBegin;
83 hashLastGetBlocksEnd = hashEnd;
85 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
92 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
94 hSocketRet = INVALID_SOCKET;
96 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
97 if (hSocket == INVALID_SOCKET)
101 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
104 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
105 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
108 u_long fNonblock = 1;
109 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
111 int fFlags = fcntl(hSocket, F_GETFL, 0);
112 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
115 closesocket(hSocket);
120 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
122 // WSAEINVAL is here because some legacy version of winsock uses it
123 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
125 struct timeval timeout;
126 timeout.tv_sec = nTimeout / 1000;
127 timeout.tv_usec = (nTimeout % 1000) * 1000;
131 FD_SET(hSocket, &fdset);
132 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
135 printf("connection timeout\n");
136 closesocket(hSocket);
139 if (nRet == SOCKET_ERROR)
141 printf("select() for connection failed: %i\n",WSAGetLastError());
142 closesocket(hSocket);
145 socklen_t nRetSize = sizeof(nRet);
147 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
149 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
152 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
153 closesocket(hSocket);
158 printf("connect() failed after select(): %s\n",strerror(nRet));
159 closesocket(hSocket);
164 else if (WSAGetLastError() != WSAEISCONN)
169 printf("connect() failed: %i\n",WSAGetLastError());
170 closesocket(hSocket);
176 this isn't even strictly necessary
177 CNode::ConnectNode immediately turns the socket back to non-blocking
178 but we'll turn it back to blocking just in case
182 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
184 fFlags = fcntl(hSocket, F_GETFL, 0);
185 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
188 closesocket(hSocket);
194 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
195 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
196 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
197 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
198 char* pszSocks4 = pszSocks4IP;
199 int nSize = sizeof(pszSocks4IP);
201 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
204 closesocket(hSocket);
205 return error("Error sending to proxy");
208 if (recv(hSocket, pchRet, 8, 0) != 8)
210 closesocket(hSocket);
211 return error("Error reading proxy response");
213 if (pchRet[1] != 0x5a)
215 closesocket(hSocket);
216 if (pchRet[1] != 0x5b)
217 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
220 printf("proxy connected %s\n", addrConnect.ToString().c_str());
223 hSocketRet = hSocket;
227 // portDefault is in host order
228 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
233 int port = portDefault;
236 strlcpy(psz, pszName, sizeof(psz));
239 char* pszColon = strrchr(psz+1,':');
240 char *pszPortEnd = NULL;
241 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
242 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
244 if (psz[0] == '[' && pszColon[-1] == ']')
246 // Future: enable IPv6 colon-notation inside []
253 if (port < 0 || port > USHRT_MAX)
258 unsigned int addrIP = inet_addr(pszHost);
259 if (addrIP != INADDR_NONE)
261 // valid IP address passed
262 vaddr.push_back(CAddress(addrIP, port, nServices));
269 struct hostent* phostent = gethostbyname(pszHost);
273 if (phostent->h_addrtype != AF_INET)
276 char** ppAddr = phostent->h_addr_list;
277 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
279 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
281 vaddr.push_back(addr);
285 return (vaddr.size() > 0);
288 // portDefault is in host order
289 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
291 vector<CAddress> vaddr;
292 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
298 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
301 if (!ConnectSocket(addrConnect, hSocket))
302 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
304 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
307 while (RecvLine(hSocket, strLine))
309 if (strLine.empty()) // HTTP response is separated from headers by blank line
313 if (!RecvLine(hSocket, strLine))
315 closesocket(hSocket);
318 if (pszKeyword == NULL)
320 if (strLine.find(pszKeyword) != -1)
322 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
326 closesocket(hSocket);
327 if (strLine.find("<") != -1)
328 strLine = strLine.substr(0, strLine.find("<"));
329 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
330 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
331 strLine.resize(strLine.size()-1);
332 CAddress addr(strLine,0,true);
333 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
334 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
340 closesocket(hSocket);
341 return error("GetMyExternalIP() : connection closed");
344 // We now get our external IP from the IRC server first and only use this as a backup
345 bool GetMyExternalIP(unsigned int& ipRet)
347 CAddress addrConnect;
349 const char* pszKeyword;
354 for (int nLookup = 0; nLookup <= 1; nLookup++)
355 for (int nHost = 1; nHost <= 2; nHost++)
357 // We should be phasing out our use of sites like these. If we need
358 // replacements, we should ask for volunteers to put this simple
359 // php file on their webserver that prints the client IP:
360 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
363 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
367 CAddress addrIP("checkip.dyndns.org", 80, true);
368 if (addrIP.IsValid())
369 addrConnect = addrIP;
372 pszGet = "GET / HTTP/1.1\r\n"
373 "Host: checkip.dyndns.org\r\n"
374 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
375 "Connection: close\r\n"
378 pszKeyword = "Address:";
382 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
386 CAddress addrIP("www.showmyip.com", 80, true);
387 if (addrIP.IsValid())
388 addrConnect = addrIP;
391 pszGet = "GET /simple/ HTTP/1.1\r\n"
392 "Host: www.showmyip.com\r\n"
393 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
394 "Connection: close\r\n"
397 pszKeyword = NULL; // Returns just IP address
400 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
407 void ThreadGetMyExternalIP(void* parg)
409 // Wait for IRC to get it first - disabled with ppcoin
410 if (false && !GetBoolArg("-noirc"))
412 for (int i = 0; i < 2 * 60; i++)
415 if (fGotExternalIP || fShutdown)
420 // Fallback in case IRC fails to get it
421 if (GetMyExternalIP(addrLocalHost.ip))
423 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
424 if (addrLocalHost.IsRoutable())
426 // If we already connected to a few before we had our IP, go back and addr them.
427 // setAddrKnown automatically filters any duplicate sends.
428 CAddress addr(addrLocalHost);
429 addr.nTime = GetAdjustedTime();
430 CRITICAL_BLOCK(cs_vNodes)
431 BOOST_FOREACH(CNode* pnode, vNodes)
432 pnode->PushAddress(addr);
441 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
443 if (!addr.IsRoutable())
445 if (addr.ip == addrLocalHost.ip)
447 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
448 bool fUpdated = false;
450 CAddress addrFound = addr;
452 CRITICAL_BLOCK(cs_mapAddresses)
454 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
455 if (it == mapAddresses.end())
458 printf("AddAddress(%s)\n", addr.ToString().c_str());
459 mapAddresses.insert(make_pair(addr.GetKey(), addr));
465 addrFound = (*it).second;
466 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
468 // Services have been added
469 addrFound.nServices |= addr.nServices;
472 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
473 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
474 if (addrFound.nTime < addr.nTime - nUpdateInterval)
476 // Periodically update most recently seen time
477 addrFound.nTime = addr.nTime;
482 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
484 // Thread 1: begin db transaction (locks inside-db-mutex)
485 // then AddAddress (locks cs_mapAddresses)
486 // Thread 2: AddAddress (locks cs_mapAddresses)
487 // ... then db operation hangs waiting for inside-db-mutex
491 pAddrDB->WriteAddress(addrFound);
493 CAddrDB().WriteAddress(addrFound);
498 void AddressCurrentlyConnected(const CAddress& addr)
500 CRITICAL_BLOCK(cs_mapAddresses)
502 // Only if it's been published already
503 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
504 if (it != mapAddresses.end())
506 CAddress& addrFound = (*it).second;
507 int64 nUpdateInterval = 20 * 60;
508 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
510 // Periodically update most recently seen time
511 addrFound.nTime = GetAdjustedTime();
513 addrdb.WriteAddress(addrFound);
523 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
525 // If the dialog might get closed before the reply comes back,
526 // call this in the destructor so it doesn't get called after it's deleted.
527 CRITICAL_BLOCK(cs_vNodes)
529 BOOST_FOREACH(CNode* pnode, vNodes)
531 CRITICAL_BLOCK(pnode->cs_mapRequests)
533 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
535 CRequestTracker& tracker = (*mi).second;
536 if (tracker.fn == fn && tracker.param1 == param1)
537 pnode->mapRequests.erase(mi++);
553 // Subscription methods for the broadcast and subscription system.
554 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
556 // The subscription system uses a meet-in-the-middle strategy.
557 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
558 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
561 bool AnySubscribed(unsigned int nChannel)
563 if (pnodeLocalHost->IsSubscribed(nChannel))
565 CRITICAL_BLOCK(cs_vNodes)
566 BOOST_FOREACH(CNode* pnode, vNodes)
567 if (pnode->IsSubscribed(nChannel))
572 bool CNode::IsSubscribed(unsigned int nChannel)
574 if (nChannel >= vfSubscribe.size())
576 return vfSubscribe[nChannel];
579 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
581 if (nChannel >= vfSubscribe.size())
584 if (!AnySubscribed(nChannel))
587 CRITICAL_BLOCK(cs_vNodes)
588 BOOST_FOREACH(CNode* pnode, vNodes)
590 pnode->PushMessage("subscribe", nChannel, nHops);
593 vfSubscribe[nChannel] = true;
596 void CNode::CancelSubscribe(unsigned int nChannel)
598 if (nChannel >= vfSubscribe.size())
601 // Prevent from relaying cancel if wasn't subscribed
602 if (!vfSubscribe[nChannel])
604 vfSubscribe[nChannel] = false;
606 if (!AnySubscribed(nChannel))
608 // Relay subscription cancel
609 CRITICAL_BLOCK(cs_vNodes)
610 BOOST_FOREACH(CNode* pnode, vNodes)
612 pnode->PushMessage("sub-cancel", nChannel);
624 CNode* FindNode(unsigned int ip)
626 CRITICAL_BLOCK(cs_vNodes)
628 BOOST_FOREACH(CNode* pnode, vNodes)
629 if (pnode->addr.ip == ip)
635 CNode* FindNode(CAddress addr)
637 CRITICAL_BLOCK(cs_vNodes)
639 BOOST_FOREACH(CNode* pnode, vNodes)
640 if (pnode->addr == addr)
646 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
648 if (addrConnect.ip == addrLocalHost.ip)
651 // Look for an existing connection
652 CNode* pnode = FindNode(addrConnect.ip);
656 pnode->AddRef(nTimeout);
663 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
664 addrConnect.ToString().c_str(),
665 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
666 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
668 CRITICAL_BLOCK(cs_mapAddresses)
669 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
673 if (ConnectSocket(addrConnect, hSocket))
676 printf("connected %s\n", addrConnect.ToString().c_str());
678 // Set to nonblocking
681 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
682 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
684 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
685 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
689 CNode* pnode = new CNode(hSocket, addrConnect, false);
691 pnode->AddRef(nTimeout);
694 CRITICAL_BLOCK(cs_vNodes)
695 vNodes.push_back(pnode);
697 pnode->nTimeConnected = GetTime();
706 void CNode::CloseSocketDisconnect()
709 if (hSocket != INVALID_SOCKET)
712 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
713 printf("disconnecting node %s\n", addr.ToString().c_str());
714 closesocket(hSocket);
715 hSocket = INVALID_SOCKET;
719 void CNode::Cleanup()
721 // All of a nodes broadcasts and subscriptions are automatically torn down
722 // when it goes down, so a node has to stay up to keep its broadcast going.
724 // Cancel subscriptions
725 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
726 if (vfSubscribe[nChannel])
727 CancelSubscribe(nChannel);
731 std::map<unsigned int, int64> CNode::setBanned;
732 CCriticalSection CNode::cs_setBanned;
734 void CNode::ClearBanned()
739 bool CNode::IsBanned(unsigned int ip)
741 bool fResult = false;
742 CRITICAL_BLOCK(cs_setBanned)
744 std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
745 if (i != setBanned.end())
747 int64 t = (*i).second;
755 bool CNode::Misbehaving(int howmuch)
759 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
763 nMisbehavior += howmuch;
764 if (nMisbehavior >= GetArg("-banscore", 100))
766 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
767 CRITICAL_BLOCK(cs_setBanned)
768 if (setBanned[addr.ip] < banTime)
769 setBanned[addr.ip] = banTime;
770 CloseSocketDisconnect();
771 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
788 void ThreadSocketHandler(void* parg)
790 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
793 vnThreadsRunning[0]++;
794 ThreadSocketHandler2(parg);
795 vnThreadsRunning[0]--;
797 catch (std::exception& e) {
798 vnThreadsRunning[0]--;
799 PrintException(&e, "ThreadSocketHandler()");
801 vnThreadsRunning[0]--;
802 throw; // support pthread_cancel()
804 printf("ThreadSocketHandler exiting\n");
807 void ThreadSocketHandler2(void* parg)
809 printf("ThreadSocketHandler started\n");
810 list<CNode*> vNodesDisconnected;
811 int nPrevNodeCount = 0;
818 CRITICAL_BLOCK(cs_vNodes)
820 // Disconnect unused nodes
821 vector<CNode*> vNodesCopy = vNodes;
822 BOOST_FOREACH(CNode* pnode, vNodesCopy)
824 if (pnode->fDisconnect ||
825 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
827 // remove from vNodes
828 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
830 // close socket and cleanup
831 pnode->CloseSocketDisconnect();
834 // hold in disconnected pool until all refs are released
835 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
836 if (pnode->fNetworkNode || pnode->fInbound)
838 vNodesDisconnected.push_back(pnode);
842 // Delete disconnected nodes
843 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
844 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
846 // wait until threads are done using it
847 if (pnode->GetRefCount() <= 0)
849 bool fDelete = false;
850 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
851 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
852 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
853 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
857 vNodesDisconnected.remove(pnode);
863 if (vNodes.size() != nPrevNodeCount)
865 nPrevNodeCount = vNodes.size();
871 // Find which sockets have data to receive
873 struct timeval timeout;
875 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
882 FD_ZERO(&fdsetError);
883 SOCKET hSocketMax = 0;
885 if(hListenSocket != INVALID_SOCKET)
886 FD_SET(hListenSocket, &fdsetRecv);
887 hSocketMax = max(hSocketMax, hListenSocket);
888 CRITICAL_BLOCK(cs_vNodes)
890 BOOST_FOREACH(CNode* pnode, vNodes)
892 if (pnode->hSocket == INVALID_SOCKET)
894 FD_SET(pnode->hSocket, &fdsetRecv);
895 FD_SET(pnode->hSocket, &fdsetError);
896 hSocketMax = max(hSocketMax, pnode->hSocket);
897 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
898 if (!pnode->vSend.empty())
899 FD_SET(pnode->hSocket, &fdsetSend);
903 vnThreadsRunning[0]--;
904 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
905 vnThreadsRunning[0]++;
908 if (nSelect == SOCKET_ERROR)
910 int nErr = WSAGetLastError();
913 printf("socket select error %d\n", nErr);
914 for (int i = 0; i <= hSocketMax; i++)
915 FD_SET(i, &fdsetRecv);
918 FD_ZERO(&fdsetError);
919 Sleep(timeout.tv_usec/1000);
924 // Accept new connections
926 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
928 struct sockaddr_in sockaddr;
929 socklen_t len = sizeof(sockaddr);
930 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
931 CAddress addr(sockaddr);
934 CRITICAL_BLOCK(cs_vNodes)
935 BOOST_FOREACH(CNode* pnode, vNodes)
938 if (hSocket == INVALID_SOCKET)
940 if (WSAGetLastError() != WSAEWOULDBLOCK)
941 printf("socket error accept failed: %d\n", WSAGetLastError());
943 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
945 closesocket(hSocket);
947 else if (CNode::IsBanned(addr.ip))
949 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
950 closesocket(hSocket);
954 printf("accepted connection %s\n", addr.ToString().c_str());
955 CNode* pnode = new CNode(hSocket, addr, true);
957 CRITICAL_BLOCK(cs_vNodes)
958 vNodes.push_back(pnode);
964 // Service each socket
966 vector<CNode*> vNodesCopy;
967 CRITICAL_BLOCK(cs_vNodes)
970 BOOST_FOREACH(CNode* pnode, vNodesCopy)
973 BOOST_FOREACH(CNode* pnode, vNodesCopy)
981 if (pnode->hSocket == INVALID_SOCKET)
983 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
985 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
987 CDataStream& vRecv = pnode->vRecv;
988 unsigned int nPos = vRecv.size();
990 if (nPos > ReceiveBufferSize()) {
991 if (!pnode->fDisconnect)
992 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
993 pnode->CloseSocketDisconnect();
996 // typical socket buffer is 8K-64K
997 char pchBuf[0x10000];
998 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1001 vRecv.resize(nPos + nBytes);
1002 memcpy(&vRecv[nPos], pchBuf, nBytes);
1003 pnode->nLastRecv = GetTime();
1005 else if (nBytes == 0)
1007 // socket closed gracefully
1008 if (!pnode->fDisconnect)
1009 printf("socket closed\n");
1010 pnode->CloseSocketDisconnect();
1012 else if (nBytes < 0)
1015 int nErr = WSAGetLastError();
1016 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1018 if (!pnode->fDisconnect)
1019 printf("socket recv error %d\n", nErr);
1020 pnode->CloseSocketDisconnect();
1030 if (pnode->hSocket == INVALID_SOCKET)
1032 if (FD_ISSET(pnode->hSocket, &fdsetSend))
1034 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1036 CDataStream& vSend = pnode->vSend;
1039 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
1042 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1043 pnode->nLastSend = GetTime();
1045 else if (nBytes < 0)
1048 int nErr = WSAGetLastError();
1049 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1051 printf("socket send error %d\n", nErr);
1052 pnode->CloseSocketDisconnect();
1055 if (vSend.size() > SendBufferSize()) {
1056 if (!pnode->fDisconnect)
1057 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1058 pnode->CloseSocketDisconnect();
1065 // Inactivity checking
1067 if (pnode->vSend.empty())
1068 pnode->nLastSendEmpty = GetTime();
1069 if (GetTime() - pnode->nTimeConnected > 60)
1071 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1073 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1074 pnode->fDisconnect = true;
1076 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1078 printf("socket not sending\n");
1079 pnode->fDisconnect = true;
1081 else if (GetTime() - pnode->nLastRecv > 90*60)
1083 printf("socket inactivity timeout\n");
1084 pnode->fDisconnect = true;
1088 CRITICAL_BLOCK(cs_vNodes)
1090 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1107 void ThreadMapPort(void* parg)
1109 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1112 vnThreadsRunning[5]++;
1113 ThreadMapPort2(parg);
1114 vnThreadsRunning[5]--;
1116 catch (std::exception& e) {
1117 vnThreadsRunning[5]--;
1118 PrintException(&e, "ThreadMapPort()");
1120 vnThreadsRunning[5]--;
1121 PrintException(NULL, "ThreadMapPort()");
1123 printf("ThreadMapPort exiting\n");
1126 void ThreadMapPort2(void* parg)
1128 printf("ThreadMapPort started\n");
1131 sprintf(port, "%d", GetListenPort());
1133 const char * rootdescurl = 0;
1134 const char * multicastif = 0;
1135 const char * minissdpdpath = 0;
1136 struct UPNPDev * devlist = 0;
1139 #ifndef UPNPDISCOVER_SUCCESS
1141 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1145 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1148 struct UPNPUrls urls;
1149 struct IGDdatas data;
1152 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1157 string strDesc = "Bitcoin " + FormatFullVersion();
1158 #ifndef UPNPDISCOVER_SUCCESS
1160 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1161 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1164 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1165 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1168 if(r!=UPNPCOMMAND_SUCCESS)
1169 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1170 port, port, lanaddr, r, strupnperror(r));
1172 printf("UPnP Port Mapping successful.\n");
1174 if (fShutdown || !fUseUPnP)
1176 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1177 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1178 freeUPNPDevlist(devlist); devlist = 0;
1179 FreeUPNPUrls(&urls);
1185 printf("No valid UPnP IGDs found\n");
1186 freeUPNPDevlist(devlist); devlist = 0;
1188 FreeUPNPUrls(&urls);
1190 if (fShutdown || !fUseUPnP)
1197 void MapPort(bool fMapPort)
1199 if (fUseUPnP != fMapPort)
1201 fUseUPnP = fMapPort;
1202 WriteSetting("fUseUPnP", fUseUPnP);
1204 if (fUseUPnP && vnThreadsRunning[5] < 1)
1206 if (!CreateThread(ThreadMapPort, NULL))
1207 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1211 void MapPort(bool /* unused fMapPort */)
1213 // Intentionally left blank.
1225 // testnet dns seed begins with 't', all else are ppcoin dns seeds.
1226 static const char *strDNSSeed[] = {
1227 "ppcseed.zapto.org",
1231 void ThreadDNSAddressSeed(void* parg)
1233 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1236 vnThreadsRunning[6]++;
1237 ThreadDNSAddressSeed2(parg);
1238 vnThreadsRunning[6]--;
1240 catch (std::exception& e) {
1241 vnThreadsRunning[6]--;
1242 PrintException(&e, "ThreadDNSAddressSeed()");
1244 vnThreadsRunning[6]--;
1245 throw; // support pthread_cancel()
1247 printf("ThreadDNSAddressSeed exiting\n");
1250 void ThreadDNSAddressSeed2(void* parg)
1252 printf("ThreadDNSAddressSeed started\n");
1255 if (true /*!fTestNet*/) // ppcoin enables dns seeding with testnet too
1257 printf("Loading addresses from DNS seeds (could take a while)\n");
1261 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1262 if (fTestNet && strDNSSeed[seed_idx][0] != 't') continue;
1263 if ((!fTestNet) && strDNSSeed[seed_idx][0] == 't') continue;
1265 vector<CAddress> vaddr;
1266 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1268 BOOST_FOREACH (CAddress& addr, vaddr)
1270 if (addr.GetByte(3) != 127)
1273 AddAddress(addr, 0, &addrDB);
1280 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1283 printf("%d addresses found from DNS seeds\n", found);
1297 unsigned int pnSeed[] =
1304 void ThreadOpenConnections(void* parg)
1306 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1309 vnThreadsRunning[1]++;
1310 ThreadOpenConnections2(parg);
1311 vnThreadsRunning[1]--;
1313 catch (std::exception& e) {
1314 vnThreadsRunning[1]--;
1315 PrintException(&e, "ThreadOpenConnections()");
1317 vnThreadsRunning[1]--;
1318 PrintException(NULL, "ThreadOpenConnections()");
1320 printf("ThreadOpenConnections exiting\n");
1323 void ThreadOpenConnections2(void* parg)
1325 printf("ThreadOpenConnections started\n");
1327 // Connect to specific addresses
1328 if (mapArgs.count("-connect"))
1330 for (int64 nLoop = 0;; nLoop++)
1332 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1334 CAddress addr(strAddr, fAllowDNS);
1336 OpenNetworkConnection(addr);
1337 for (int i = 0; i < 10 && i < nLoop; i++)
1347 // Connect to manually added nodes first
1348 if (mapArgs.count("-addnode"))
1350 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1352 CAddress addr(strAddr, fAllowDNS);
1355 OpenNetworkConnection(addr);
1363 // Initiate network connections
1364 int64 nStart = GetTime();
1367 // Limit outbound connections
1368 vnThreadsRunning[1]--;
1373 CRITICAL_BLOCK(cs_vNodes)
1374 BOOST_FOREACH(CNode* pnode, vNodes)
1375 if (!pnode->fInbound)
1377 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1378 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1379 if (nOutbound < nMaxOutboundConnections)
1385 vnThreadsRunning[1]++;
1389 CRITICAL_BLOCK(cs_mapAddresses)
1391 // Add seed nodes if IRC isn't working
1392 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1393 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1395 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1397 // It'll only connect to one or two seed nodes because once it connects,
1398 // it'll get a pile of addresses with newer timestamps.
1399 // Seed nodes are given a random 'last seen time' of between one and two
1401 const int64 nOneWeek = 7*24*60*60;
1403 addr.ip = pnSeed[i];
1404 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1412 // Choose an address to connect to based on most recently seen
1414 CAddress addrConnect;
1415 int64 nBest = INT64_MIN;
1417 // Only connect to one address per a.b.?.? range.
1418 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1419 set<unsigned int> setConnected;
1420 CRITICAL_BLOCK(cs_vNodes)
1421 BOOST_FOREACH(CNode* pnode, vNodes)
1422 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1424 int64 nANow = GetAdjustedTime();
1426 CRITICAL_BLOCK(cs_mapAddresses)
1428 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1430 const CAddress& addr = item.second;
1431 if (addr.ip == addrLocalHost.ip || !addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1433 int64 nSinceLastSeen = nANow - addr.nTime;
1434 int64 nSinceLastTry = nANow - addr.nLastTry;
1436 // Randomize the order in a deterministic way, putting the standard port first
1437 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1438 if (addr.port != htons(GetDefaultPort()))
1439 nRandomizer += 2 * 60 * 60;
1441 // Last seen Base retry frequency
1450 // 365 days 93 hours
1451 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1453 // Fast reconnect for one hour after last seen
1454 if (nSinceLastSeen < 60 * 60)
1457 // Limit retry frequency
1458 if (nSinceLastTry < nDelay)
1461 // If we have IRC, we'll be notified when they first come online,
1462 // and again every 24 hours by the refresh broadcast.
1463 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1466 // Only try the old stuff if we don't have enough connections
1467 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1470 // If multiple addresses are ready, prioritize by time since
1471 // last seen and time since last tried.
1472 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1481 if (addrConnect.IsValid())
1482 OpenNetworkConnection(addrConnect);
1486 bool OpenNetworkConnection(const CAddress& addrConnect)
1489 // Initiate outbound network connection
1493 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1494 FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1497 vnThreadsRunning[1]--;
1498 CNode* pnode = ConnectNode(addrConnect);
1499 vnThreadsRunning[1]++;
1504 pnode->fNetworkNode = true;
1516 void ThreadMessageHandler(void* parg)
1518 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1521 vnThreadsRunning[2]++;
1522 ThreadMessageHandler2(parg);
1523 vnThreadsRunning[2]--;
1525 catch (std::exception& e) {
1526 vnThreadsRunning[2]--;
1527 PrintException(&e, "ThreadMessageHandler()");
1529 vnThreadsRunning[2]--;
1530 PrintException(NULL, "ThreadMessageHandler()");
1532 printf("ThreadMessageHandler exiting\n");
1535 void ThreadMessageHandler2(void* parg)
1537 printf("ThreadMessageHandler started\n");
1538 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1541 vector<CNode*> vNodesCopy;
1542 CRITICAL_BLOCK(cs_vNodes)
1544 vNodesCopy = vNodes;
1545 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1549 // Poll the connected nodes for messages
1550 CNode* pnodeTrickle = NULL;
1551 if (!vNodesCopy.empty())
1552 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1553 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1556 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1557 ProcessMessages(pnode);
1562 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1563 SendMessages(pnode, pnode == pnodeTrickle);
1568 CRITICAL_BLOCK(cs_vNodes)
1570 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1574 // Wait and allow messages to bunch up.
1575 // Reduce vnThreadsRunning so StopNode has permission to exit while
1576 // we're sleeping, but we must always check fShutdown after doing this.
1577 vnThreadsRunning[2]--;
1579 if (fRequestShutdown)
1581 vnThreadsRunning[2]++;
1592 bool BindListenPort(string& strError)
1596 addrLocalHost.port = htons(GetListenPort());
1599 // Initialize Windows Sockets
1601 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1602 if (ret != NO_ERROR)
1604 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1605 printf("%s\n", strError.c_str());
1610 // Create socket for listening for incoming connections
1611 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1612 if (hListenSocket == INVALID_SOCKET)
1614 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1615 printf("%s\n", strError.c_str());
1620 // Different way of disabling SIGPIPE on BSD
1621 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1625 // Allow binding if the port is still in TIME_WAIT state after
1626 // the program was closed and restarted. Not an issue on windows.
1627 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1631 // Set to nonblocking, incoming connections will also inherit this
1632 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1634 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1637 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1638 printf("%s\n", strError.c_str());
1642 // The sockaddr_in structure specifies the address family,
1643 // IP address, and port for the socket that is being bound
1644 struct sockaddr_in sockaddr;
1645 memset(&sockaddr, 0, sizeof(sockaddr));
1646 sockaddr.sin_family = AF_INET;
1647 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1648 sockaddr.sin_port = htons(GetListenPort());
1649 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1651 int nErr = WSAGetLastError();
1652 if (nErr == WSAEADDRINUSE)
1653 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1655 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1656 printf("%s\n", strError.c_str());
1659 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1661 // Listen for incoming connections
1662 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1664 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1665 printf("%s\n", strError.c_str());
1672 void StartNode(void* parg)
1674 if (pnodeLocalHost == NULL)
1675 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1678 // Get local host ip
1679 char pszHostName[1000] = "";
1680 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1682 vector<CAddress> vaddr;
1683 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1684 BOOST_FOREACH (const CAddress &addr, vaddr)
1685 if (addr.GetByte(3) != 127)
1687 addrLocalHost = addr;
1692 // Get local host ip
1693 struct ifaddrs* myaddrs;
1694 if (getifaddrs(&myaddrs) == 0)
1696 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1698 if (ifa->ifa_addr == NULL) continue;
1699 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1700 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1701 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1703 if (ifa->ifa_addr->sa_family == AF_INET)
1705 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1706 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1707 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1709 // Take the first IP that isn't loopback 127.x.x.x
1710 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1711 if (addr.IsValid() && addr.GetByte(3) != 127)
1713 addrLocalHost = addr;
1717 else if (ifa->ifa_addr->sa_family == AF_INET6)
1719 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1720 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1721 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1724 freeifaddrs(myaddrs);
1727 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1729 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1731 // Proxies can't take incoming connections
1732 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1733 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1737 CreateThread(ThreadGetMyExternalIP, NULL);
1744 if (GetBoolArg("-nodnsseed"))
1745 printf("DNS seeding disabled\n");
1747 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1748 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1750 // Map ports with UPnP
1754 // Get addresses from IRC and advertise ours
1755 // if (!CreateThread(ThreadIRCSeed, NULL))
1756 // printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1757 // IRC disabled with ppcoin
1758 printf("IRC seeding/communication disabled\n");
1760 // Send and receive from sockets, accept connections
1761 if (!CreateThread(ThreadSocketHandler, NULL))
1762 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1764 // Initiate outbound connections
1765 if (!CreateThread(ThreadOpenConnections, NULL))
1766 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1769 if (!CreateThread(ThreadMessageHandler, NULL))
1770 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1772 // Generate coins in the background
1773 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1778 printf("StopNode()\n");
1780 nTransactionsUpdated++;
1781 int64 nStart = GetTime();
1782 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1784 || vnThreadsRunning[5] > 0
1788 if (GetTime() - nStart > 20)
1792 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1793 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1794 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1795 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1796 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1797 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1798 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1799 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1815 BOOST_FOREACH(CNode* pnode, vNodes)
1816 if (pnode->hSocket != INVALID_SOCKET)
1817 closesocket(pnode->hSocket);
1818 if (hListenSocket != INVALID_SOCKET)
1819 if (closesocket(hListenSocket) == SOCKET_ERROR)
1820 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1823 // Shutdown Windows Sockets
1828 instance_of_cnetcleanup;