1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
8 #include <miniupnpc/miniwget.h>
9 #include <miniupnpc/miniupnpc.h>
10 #include <miniupnpc/upnpcommands.h>
11 #include <miniupnpc/upnperrors.h>
14 static const int MAX_OUTBOUND_CONNECTIONS = 8;
16 void ThreadMessageHandler2(void* parg);
17 void ThreadSocketHandler2(void* parg);
18 void ThreadOpenConnections2(void* parg);
20 void ThreadMapPort2(void* parg);
22 bool OpenNetworkConnection(const CAddress& addrConnect);
29 // Global state variables
32 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
33 CAddress addrLocalHost(0, 0, nLocalServices);
34 CNode* pnodeLocalHost = NULL;
35 uint64 nLocalHostNonce = 0;
36 array<int, 10> vnThreadsRunning;
37 SOCKET hListenSocket = INVALID_SOCKET;
39 vector<CNode*> vNodes;
40 CCriticalSection cs_vNodes;
41 map<vector<unsigned char>, CAddress> mapAddresses;
42 CCriticalSection cs_mapAddresses;
43 map<CInv, CDataStream> mapRelay;
44 deque<pair<int64, CInv> > vRelayExpiration;
45 CCriticalSection cs_mapRelay;
46 map<CInv, int64> mapAlreadyAskedFor;
49 int fUseProxy = false;
50 CAddress addrProxy("127.0.0.1:9050");
56 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
58 // Filter out duplicate requests
59 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
61 pindexLastGetBlocksBegin = pindexBegin;
62 hashLastGetBlocksEnd = hashEnd;
64 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
71 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
73 hSocketRet = INVALID_SOCKET;
75 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
76 if (hSocket == INVALID_SOCKET)
80 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
83 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
84 bool fProxy = (fUseProxy && fRoutable);
85 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
87 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
95 printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str());
96 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
97 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
98 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
99 char* pszSocks4 = pszSocks4IP;
100 int nSize = sizeof(pszSocks4IP);
102 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
105 closesocket(hSocket);
106 return error("Error sending to proxy");
109 if (recv(hSocket, pchRet, 8, 0) != 8)
111 closesocket(hSocket);
112 return error("Error reading proxy response");
114 if (pchRet[1] != 0x5a)
116 closesocket(hSocket);
117 if (pchRet[1] != 0x5b)
118 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
121 printf("proxy connected %s\n", addrConnect.ToStringLog().c_str());
124 hSocketRet = hSocket;
130 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
133 if (!ConnectSocket(addrConnect, hSocket))
134 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
136 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
139 while (RecvLine(hSocket, strLine))
141 if (strLine.empty()) // HTTP response is separated from headers by blank line
145 if (!RecvLine(hSocket, strLine))
147 closesocket(hSocket);
150 if (pszKeyword == NULL)
152 if (strLine.find(pszKeyword) != -1)
154 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
158 closesocket(hSocket);
159 if (strLine.find("<") != -1)
160 strLine = strLine.substr(0, strLine.find("<"));
161 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
162 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
163 strLine.resize(strLine.size()-1);
164 CAddress addr(strLine.c_str());
165 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
166 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
172 closesocket(hSocket);
173 return error("GetMyExternalIP() : connection closed");
176 // We now get our external IP from the IRC server first and only use this as a backup
177 bool GetMyExternalIP(unsigned int& ipRet)
179 CAddress addrConnect;
181 const char* pszKeyword;
186 for (int nLookup = 0; nLookup <= 1; nLookup++)
187 for (int nHost = 1; nHost <= 2; nHost++)
189 // We should be phasing out our use of sites like these. If we need
190 // replacements, we should ask for volunteers to put this simple
191 // php file on their webserver that prints the client IP:
192 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
195 addrConnect = CAddress("91.198.22.70:80"); // checkip.dyndns.org
199 struct hostent* phostent = gethostbyname("checkip.dyndns.org");
200 if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
201 addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
204 pszGet = "GET / HTTP/1.1\r\n"
205 "Host: checkip.dyndns.org\r\n"
206 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
207 "Connection: close\r\n"
210 pszKeyword = "Address:";
214 addrConnect = CAddress("74.208.43.192:80"); // www.showmyip.com
218 struct hostent* phostent = gethostbyname("www.showmyip.com");
219 if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
220 addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
223 pszGet = "GET /simple/ HTTP/1.1\r\n"
224 "Host: www.showmyip.com\r\n"
225 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
226 "Connection: close\r\n"
229 pszKeyword = NULL; // Returns just IP address
232 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
239 void ThreadGetMyExternalIP(void* parg)
241 // Wait for IRC to get it first
242 if (!GetBoolArg("-noirc"))
244 for (int i = 0; i < 2 * 60; i++)
247 if (fGotExternalIP || fShutdown)
252 // Fallback in case IRC fails to get it
253 if (GetMyExternalIP(addrLocalHost.ip))
255 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
256 if (addrLocalHost.IsRoutable())
258 // If we already connected to a few before we had our IP, go back and addr them.
259 // setAddrKnown automatically filters any duplicate sends.
260 CAddress addr(addrLocalHost);
261 addr.nTime = GetAdjustedTime();
262 CRITICAL_BLOCK(cs_vNodes)
263 foreach(CNode* pnode, vNodes)
264 pnode->PushAddress(addr);
273 bool AddAddress(CAddress addr, int64 nTimePenalty)
275 if (!addr.IsRoutable())
277 if (addr.ip == addrLocalHost.ip)
279 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
280 CRITICAL_BLOCK(cs_mapAddresses)
282 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
283 if (it == mapAddresses.end())
286 printf("AddAddress(%s)\n", addr.ToStringLog().c_str());
287 mapAddresses.insert(make_pair(addr.GetKey(), addr));
288 CAddrDB().WriteAddress(addr);
293 bool fUpdated = false;
294 CAddress& addrFound = (*it).second;
295 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
297 // Services have been added
298 addrFound.nServices |= addr.nServices;
301 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
302 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
303 if (addrFound.nTime < addr.nTime - nUpdateInterval)
305 // Periodically update most recently seen time
306 addrFound.nTime = addr.nTime;
310 CAddrDB().WriteAddress(addrFound);
316 void AddressCurrentlyConnected(const CAddress& addr)
318 CRITICAL_BLOCK(cs_mapAddresses)
320 // Only if it's been published already
321 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
322 if (it != mapAddresses.end())
324 CAddress& addrFound = (*it).second;
325 int64 nUpdateInterval = 20 * 60;
326 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
328 // Periodically update most recently seen time
329 addrFound.nTime = GetAdjustedTime();
331 addrdb.WriteAddress(addrFound);
341 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
343 // If the dialog might get closed before the reply comes back,
344 // call this in the destructor so it doesn't get called after it's deleted.
345 CRITICAL_BLOCK(cs_vNodes)
347 foreach(CNode* pnode, vNodes)
349 CRITICAL_BLOCK(pnode->cs_mapRequests)
351 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
353 CRequestTracker& tracker = (*mi).second;
354 if (tracker.fn == fn && tracker.param1 == param1)
355 pnode->mapRequests.erase(mi++);
371 // Subscription methods for the broadcast and subscription system.
372 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
374 // The subscription system uses a meet-in-the-middle strategy.
375 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
376 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
379 bool AnySubscribed(unsigned int nChannel)
381 if (pnodeLocalHost->IsSubscribed(nChannel))
383 CRITICAL_BLOCK(cs_vNodes)
384 foreach(CNode* pnode, vNodes)
385 if (pnode->IsSubscribed(nChannel))
390 bool CNode::IsSubscribed(unsigned int nChannel)
392 if (nChannel >= vfSubscribe.size())
394 return vfSubscribe[nChannel];
397 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
399 if (nChannel >= vfSubscribe.size())
402 if (!AnySubscribed(nChannel))
405 CRITICAL_BLOCK(cs_vNodes)
406 foreach(CNode* pnode, vNodes)
408 pnode->PushMessage("subscribe", nChannel, nHops);
411 vfSubscribe[nChannel] = true;
414 void CNode::CancelSubscribe(unsigned int nChannel)
416 if (nChannel >= vfSubscribe.size())
419 // Prevent from relaying cancel if wasn't subscribed
420 if (!vfSubscribe[nChannel])
422 vfSubscribe[nChannel] = false;
424 if (!AnySubscribed(nChannel))
426 // Relay subscription cancel
427 CRITICAL_BLOCK(cs_vNodes)
428 foreach(CNode* pnode, vNodes)
430 pnode->PushMessage("sub-cancel", nChannel);
442 CNode* FindNode(unsigned int ip)
444 CRITICAL_BLOCK(cs_vNodes)
446 foreach(CNode* pnode, vNodes)
447 if (pnode->addr.ip == ip)
453 CNode* FindNode(CAddress addr)
455 CRITICAL_BLOCK(cs_vNodes)
457 foreach(CNode* pnode, vNodes)
458 if (pnode->addr == addr)
464 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
466 if (addrConnect.ip == addrLocalHost.ip)
469 // Look for an existing connection
470 CNode* pnode = FindNode(addrConnect.ip);
474 pnode->AddRef(nTimeout);
481 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
482 addrConnect.ToStringLog().c_str(),
483 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
484 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
486 CRITICAL_BLOCK(cs_mapAddresses)
487 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
491 if (ConnectSocket(addrConnect, hSocket))
494 printf("connected %s\n", addrConnect.ToStringLog().c_str());
496 // Set to nonblocking
499 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
500 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
502 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
503 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
507 CNode* pnode = new CNode(hSocket, addrConnect, false);
509 pnode->AddRef(nTimeout);
512 CRITICAL_BLOCK(cs_vNodes)
513 vNodes.push_back(pnode);
515 pnode->nTimeConnected = GetTime();
524 void CNode::CloseSocketDisconnect()
527 if (hSocket != INVALID_SOCKET)
530 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
531 printf("disconnecting node %s\n", addr.ToStringLog().c_str());
532 closesocket(hSocket);
533 hSocket = INVALID_SOCKET;
537 void CNode::Cleanup()
539 // All of a nodes broadcasts and subscriptions are automatically torn down
540 // when it goes down, so a node has to stay up to keep its broadcast going.
542 // Cancel subscriptions
543 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
544 if (vfSubscribe[nChannel])
545 CancelSubscribe(nChannel);
560 void ThreadSocketHandler(void* parg)
562 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
565 vnThreadsRunning[0]++;
566 ThreadSocketHandler2(parg);
567 vnThreadsRunning[0]--;
569 catch (std::exception& e) {
570 vnThreadsRunning[0]--;
571 PrintException(&e, "ThreadSocketHandler()");
573 vnThreadsRunning[0]--;
574 throw; // support pthread_cancel()
576 printf("ThreadSocketHandler exiting\n");
579 void ThreadSocketHandler2(void* parg)
581 printf("ThreadSocketHandler started\n");
582 list<CNode*> vNodesDisconnected;
583 int nPrevNodeCount = 0;
590 CRITICAL_BLOCK(cs_vNodes)
592 // Disconnect unused nodes
593 vector<CNode*> vNodesCopy = vNodes;
594 foreach(CNode* pnode, vNodesCopy)
596 if (pnode->fDisconnect ||
597 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
599 // remove from vNodes
600 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
602 // close socket and cleanup
603 pnode->CloseSocketDisconnect();
606 // hold in disconnected pool until all refs are released
607 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
608 if (pnode->fNetworkNode || pnode->fInbound)
610 vNodesDisconnected.push_back(pnode);
614 // Delete disconnected nodes
615 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
616 foreach(CNode* pnode, vNodesDisconnectedCopy)
618 // wait until threads are done using it
619 if (pnode->GetRefCount() <= 0)
621 bool fDelete = false;
622 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
623 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
624 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
625 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
629 vNodesDisconnected.remove(pnode);
635 if (vNodes.size() != nPrevNodeCount)
637 nPrevNodeCount = vNodes.size();
643 // Find which sockets have data to receive
645 struct timeval timeout;
647 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
654 FD_ZERO(&fdsetError);
655 SOCKET hSocketMax = 0;
657 if(hListenSocket != INVALID_SOCKET)
658 FD_SET(hListenSocket, &fdsetRecv);
659 hSocketMax = max(hSocketMax, hListenSocket);
660 CRITICAL_BLOCK(cs_vNodes)
662 foreach(CNode* pnode, vNodes)
664 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
666 FD_SET(pnode->hSocket, &fdsetRecv);
667 FD_SET(pnode->hSocket, &fdsetError);
668 hSocketMax = max(hSocketMax, pnode->hSocket);
669 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
670 if (!pnode->vSend.empty())
671 FD_SET(pnode->hSocket, &fdsetSend);
675 vnThreadsRunning[0]--;
676 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
677 vnThreadsRunning[0]++;
680 if (nSelect == SOCKET_ERROR)
682 int nErr = WSAGetLastError();
683 printf("socket select error %d\n", nErr);
684 for (int i = 0; i <= hSocketMax; i++)
685 FD_SET(i, &fdsetRecv);
687 FD_ZERO(&fdsetError);
688 Sleep(timeout.tv_usec/1000);
693 // Accept new connections
695 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
697 struct sockaddr_in sockaddr;
698 socklen_t len = sizeof(sockaddr);
699 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
700 CAddress addr(sockaddr);
703 CRITICAL_BLOCK(cs_vNodes)
704 foreach(CNode* pnode, vNodes)
707 if (hSocket == INVALID_SOCKET)
709 if (WSAGetLastError() != WSAEWOULDBLOCK)
710 printf("socket error accept failed: %d\n", WSAGetLastError());
712 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
714 closesocket(hSocket);
718 printf("accepted connection %s\n", addr.ToStringLog().c_str());
719 CNode* pnode = new CNode(hSocket, addr, true);
721 CRITICAL_BLOCK(cs_vNodes)
722 vNodes.push_back(pnode);
728 // Service each socket
730 vector<CNode*> vNodesCopy;
731 CRITICAL_BLOCK(cs_vNodes)
734 foreach(CNode* pnode, vNodesCopy)
737 foreach(CNode* pnode, vNodesCopy)
745 if (pnode->hSocket == INVALID_SOCKET)
747 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
749 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
751 CDataStream& vRecv = pnode->vRecv;
752 unsigned int nPos = vRecv.size();
754 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
755 if (!pnode->fDisconnect)
756 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
757 pnode->CloseSocketDisconnect();
760 // typical socket buffer is 8K-64K
761 char pchBuf[0x10000];
762 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
765 vRecv.resize(nPos + nBytes);
766 memcpy(&vRecv[nPos], pchBuf, nBytes);
767 pnode->nLastRecv = GetTime();
769 else if (nBytes == 0)
771 // socket closed gracefully
772 if (!pnode->fDisconnect)
773 printf("socket closed\n");
774 pnode->CloseSocketDisconnect();
779 int nErr = WSAGetLastError();
780 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
782 if (!pnode->fDisconnect)
783 printf("socket recv error %d\n", nErr);
784 pnode->CloseSocketDisconnect();
794 if (pnode->hSocket == INVALID_SOCKET)
796 if (FD_ISSET(pnode->hSocket, &fdsetSend))
798 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
800 CDataStream& vSend = pnode->vSend;
803 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
806 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
807 pnode->nLastSend = GetTime();
812 int nErr = WSAGetLastError();
813 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
815 printf("socket send error %d\n", nErr);
816 pnode->CloseSocketDisconnect();
819 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
820 if (!pnode->fDisconnect)
821 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
822 pnode->CloseSocketDisconnect();
829 // Inactivity checking
831 if (pnode->vSend.empty())
832 pnode->nLastSendEmpty = GetTime();
833 if (GetTime() - pnode->nTimeConnected > 60)
835 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
837 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
838 pnode->fDisconnect = true;
840 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
842 printf("socket not sending\n");
843 pnode->fDisconnect = true;
845 else if (GetTime() - pnode->nLastRecv > 90*60)
847 printf("socket inactivity timeout\n");
848 pnode->fDisconnect = true;
852 CRITICAL_BLOCK(cs_vNodes)
854 foreach(CNode* pnode, vNodesCopy)
871 void ThreadMapPort(void* parg)
873 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
876 vnThreadsRunning[5]++;
877 ThreadMapPort2(parg);
878 vnThreadsRunning[5]--;
880 catch (std::exception& e) {
881 vnThreadsRunning[5]--;
882 PrintException(&e, "ThreadMapPort()");
884 vnThreadsRunning[5]--;
885 PrintException(NULL, "ThreadMapPort()");
887 printf("ThreadMapPort exiting\n");
890 void ThreadMapPort2(void* parg)
892 printf("ThreadMapPort started\n");
895 sprintf(port, "%d", ntohs(GetDefaultPort()));
897 const char * rootdescurl = 0;
898 const char * multicastif = 0;
899 const char * minissdpdpath = 0;
900 struct UPNPDev * devlist = 0;
903 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
905 struct UPNPUrls urls;
906 struct IGDdatas data;
909 if (UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)) == 1)
915 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
916 port, port, lanaddr, 0, "TCP", 0);
918 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
919 port, port, lanaddr, 0, "TCP", 0, "0");
921 if(r!=UPNPCOMMAND_SUCCESS)
922 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
923 port, port, lanaddr, r, strupnperror(r));
925 printf("UPnP Port Mapping successful.\n");
927 if (fShutdown || !fUseUPnP)
929 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
930 printf("UPNP_DeletePortMapping() returned : %d\n", r);
931 freeUPNPDevlist(devlist); devlist = 0;
938 printf("No valid UPnP IGDs found\n");
939 freeUPNPDevlist(devlist); devlist = 0;
949 void MapPort(bool fMapPort)
951 if (fUseUPnP != fMapPort)
954 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
956 if (fUseUPnP && vnThreadsRunning[5] < 1)
958 if (!CreateThread(ThreadMapPort, NULL))
959 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
973 static const char *strDNSSeed[] = {
975 "bitseed.bitcoin.org.uk",
978 void DNSAddressSeed()
982 printf("Loading addresses from DNS seeds (could take a while)\n");
984 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
985 struct hostent* phostent = gethostbyname(strDNSSeed[seed_idx]);
989 for (int host = 0; phostent->h_addr_list[host] != NULL; host++) {
990 CAddress addr(*(unsigned int*)phostent->h_addr_list[host],
991 GetDefaultPort(), NODE_NETWORK);
993 if (addr.IsValid() && addr.GetByte(3) != 127) {
1000 printf("%d addresses found from DNS seeds\n", found);
1005 unsigned int pnSeed[] =
1007 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1008 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1009 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1010 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1011 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1012 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1013 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1014 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1015 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1016 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1017 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1018 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1019 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1020 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1021 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1022 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1023 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1024 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1025 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1026 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1027 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1028 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1029 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1030 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1031 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1032 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1033 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1034 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1035 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1036 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1037 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1038 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1039 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1040 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1041 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1042 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1043 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1044 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1045 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1046 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1051 void ThreadOpenConnections(void* parg)
1053 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1056 vnThreadsRunning[1]++;
1057 ThreadOpenConnections2(parg);
1058 vnThreadsRunning[1]--;
1060 catch (std::exception& e) {
1061 vnThreadsRunning[1]--;
1062 PrintException(&e, "ThreadOpenConnections()");
1064 vnThreadsRunning[1]--;
1065 PrintException(NULL, "ThreadOpenConnections()");
1067 printf("ThreadOpenConnections exiting\n");
1070 void ThreadOpenConnections2(void* parg)
1072 printf("ThreadOpenConnections started\n");
1074 // Connect to specific addresses
1075 if (mapArgs.count("-connect"))
1077 for (int64 nLoop = 0;; nLoop++)
1079 foreach(string strAddr, mapMultiArgs["-connect"])
1081 CAddress addr(strAddr, NODE_NETWORK);
1083 OpenNetworkConnection(addr);
1084 for (int i = 0; i < 10 && i < nLoop; i++)
1094 // Connect to manually added nodes first
1095 if (mapArgs.count("-addnode"))
1097 foreach(string strAddr, mapMultiArgs["-addnode"])
1099 CAddress addr(strAddr, NODE_NETWORK);
1102 OpenNetworkConnection(addr);
1110 // Initiate network connections
1111 int64 nStart = GetTime();
1114 // Limit outbound connections
1115 vnThreadsRunning[1]--;
1120 CRITICAL_BLOCK(cs_vNodes)
1121 foreach(CNode* pnode, vNodes)
1122 if (!pnode->fInbound)
1124 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1125 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1126 if (nOutbound < nMaxOutboundConnections)
1132 vnThreadsRunning[1]++;
1136 CRITICAL_BLOCK(cs_mapAddresses)
1138 // Add seed nodes if IRC isn't working
1139 static bool fSeedUsed;
1140 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1141 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1143 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1145 // It'll only connect to one or two seed nodes because once it connects,
1146 // it'll get a pile of addresses with newer timestamps.
1148 addr.ip = pnSeed[i];
1155 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1157 // Disconnect seed nodes
1158 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1159 static int64 nSeedDisconnected;
1160 if (nSeedDisconnected == 0)
1162 nSeedDisconnected = GetTime();
1163 CRITICAL_BLOCK(cs_vNodes)
1164 foreach(CNode* pnode, vNodes)
1165 if (setSeed.count(pnode->addr.ip))
1166 pnode->fDisconnect = true;
1169 // Keep setting timestamps to 0 so they won't reconnect
1170 if (GetTime() - nSeedDisconnected < 60 * 60)
1172 foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1174 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1176 item.second.nTime = 0;
1177 CAddrDB().WriteAddress(item.second);
1186 // Choose an address to connect to based on most recently seen
1188 CAddress addrConnect;
1189 int64 nBest = INT64_MIN;
1191 // Only connect to one address per a.b.?.? range.
1192 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1193 set<unsigned int> setConnected;
1194 CRITICAL_BLOCK(cs_vNodes)
1195 foreach(CNode* pnode, vNodes)
1196 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1198 CRITICAL_BLOCK(cs_mapAddresses)
1200 foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1202 const CAddress& addr = item.second;
1203 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1205 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1206 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1208 // Randomize the order in a deterministic way, putting the standard port first
1209 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1210 if (addr.port != GetDefaultPort())
1211 nRandomizer += 2 * 60 * 60;
1213 // Last seen Base retry frequency
1222 // 365 days 93 hours
1223 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1225 // Fast reconnect for one hour after last seen
1226 if (nSinceLastSeen < 60 * 60)
1229 // Limit retry frequency
1230 if (nSinceLastTry < nDelay)
1233 // If we have IRC, we'll be notified when they first come online,
1234 // and again every 24 hours by the refresh broadcast.
1235 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1238 // Only try the old stuff if we don't have enough connections
1239 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1242 // If multiple addresses are ready, prioritize by time since
1243 // last seen and time since last tried.
1244 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1253 if (addrConnect.IsValid())
1254 OpenNetworkConnection(addrConnect);
1258 bool OpenNetworkConnection(const CAddress& addrConnect)
1261 // Initiate outbound network connection
1265 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1268 vnThreadsRunning[1]--;
1269 CNode* pnode = ConnectNode(addrConnect);
1270 vnThreadsRunning[1]++;
1275 pnode->fNetworkNode = true;
1287 void ThreadMessageHandler(void* parg)
1289 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1292 vnThreadsRunning[2]++;
1293 ThreadMessageHandler2(parg);
1294 vnThreadsRunning[2]--;
1296 catch (std::exception& e) {
1297 vnThreadsRunning[2]--;
1298 PrintException(&e, "ThreadMessageHandler()");
1300 vnThreadsRunning[2]--;
1301 PrintException(NULL, "ThreadMessageHandler()");
1303 printf("ThreadMessageHandler exiting\n");
1306 void ThreadMessageHandler2(void* parg)
1308 printf("ThreadMessageHandler started\n");
1309 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1312 vector<CNode*> vNodesCopy;
1313 CRITICAL_BLOCK(cs_vNodes)
1315 vNodesCopy = vNodes;
1316 foreach(CNode* pnode, vNodesCopy)
1320 // Poll the connected nodes for messages
1321 CNode* pnodeTrickle = NULL;
1322 if (!vNodesCopy.empty())
1323 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1324 foreach(CNode* pnode, vNodesCopy)
1327 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1328 ProcessMessages(pnode);
1333 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1334 SendMessages(pnode, pnode == pnodeTrickle);
1339 CRITICAL_BLOCK(cs_vNodes)
1341 foreach(CNode* pnode, vNodesCopy)
1345 // Wait and allow messages to bunch up.
1346 // Reduce vnThreadsRunning so StopNode has permission to exit while
1347 // we're sleeping, but we must always check fShutdown after doing this.
1348 vnThreadsRunning[2]--;
1350 if (fRequestShutdown)
1352 vnThreadsRunning[2]++;
1366 bool BindListenPort(string& strError)
1370 addrLocalHost.port = GetDefaultPort();
1373 // Initialize Windows Sockets
1375 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1376 if (ret != NO_ERROR)
1378 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1379 printf("%s\n", strError.c_str());
1384 // Create socket for listening for incoming connections
1385 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1386 if (hListenSocket == INVALID_SOCKET)
1388 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1389 printf("%s\n", strError.c_str());
1394 // Different way of disabling SIGPIPE on BSD
1395 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1399 // Allow binding if the port is still in TIME_WAIT state after
1400 // the program was closed and restarted. Not an issue on windows.
1401 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1405 // Set to nonblocking, incoming connections will also inherit this
1406 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1408 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1411 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1412 printf("%s\n", strError.c_str());
1416 // The sockaddr_in structure specifies the address family,
1417 // IP address, and port for the socket that is being bound
1418 struct sockaddr_in sockaddr;
1419 memset(&sockaddr, 0, sizeof(sockaddr));
1420 sockaddr.sin_family = AF_INET;
1421 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1422 sockaddr.sin_port = GetDefaultPort();
1423 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1425 int nErr = WSAGetLastError();
1426 if (nErr == WSAEADDRINUSE)
1427 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1429 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1430 printf("%s\n", strError.c_str());
1433 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1435 // Listen for incoming connections
1436 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1438 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1439 printf("%s\n", strError.c_str());
1446 void StartNode(void* parg)
1448 if (pnodeLocalHost == NULL)
1449 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
1452 // Get local host ip
1453 char pszHostName[1000] = "";
1454 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1456 struct hostent* phostent = gethostbyname(pszHostName);
1459 // Take the first IP that isn't loopback 127.x.x.x
1460 for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1461 printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
1462 for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1464 CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
1465 if (addr.IsValid() && addr.GetByte(3) != 127)
1467 addrLocalHost = addr;
1474 // Get local host ip
1475 struct ifaddrs* myaddrs;
1476 if (getifaddrs(&myaddrs) == 0)
1478 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1480 if (ifa->ifa_addr == NULL) continue;
1481 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1482 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1483 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1485 if (ifa->ifa_addr->sa_family == AF_INET)
1487 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1488 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1489 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1491 // Take the first IP that isn't loopback 127.x.x.x
1492 CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
1493 if (addr.IsValid() && addr.GetByte(3) != 127)
1495 addrLocalHost = addr;
1499 else if (ifa->ifa_addr->sa_family == AF_INET6)
1501 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1502 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1503 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1506 freeifaddrs(myaddrs);
1509 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1511 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1513 // Proxies can't take incoming connections
1514 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1515 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1519 CreateThread(ThreadGetMyExternalIP, NULL);
1526 // Map ports with UPnP
1530 // Get addresses from IRC and advertise ours
1531 if (!CreateThread(ThreadIRCSeed, NULL))
1532 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1534 // Send and receive from sockets, accept connections
1535 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1537 // Initiate outbound connections
1538 if (!CreateThread(ThreadOpenConnections, NULL))
1539 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1542 if (!CreateThread(ThreadMessageHandler, NULL))
1543 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1545 // Generate coins in the background
1546 GenerateBitcoins(fGenerateBitcoins);
1551 printf("StopNode()\n");
1553 nTransactionsUpdated++;
1554 int64 nStart = GetTime();
1555 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1557 || vnThreadsRunning[5] > 0
1561 if (GetTime() - nStart > 20)
1565 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1566 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1567 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1568 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1569 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1570 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1571 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1587 foreach(CNode* pnode, vNodes)
1588 if (pnode->hSocket != INVALID_SOCKET)
1589 closesocket(pnode->hSocket);
1590 if (hListenSocket != INVALID_SOCKET)
1591 if (closesocket(hListenSocket) == SOCKET_ERROR)
1592 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1595 // Shutdown Windows Sockets
1600 instance_of_cnetcleanup;