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 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
916 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
917 port, port, lanaddr, 0, "TCP", 0);
919 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
920 port, port, lanaddr, 0, "TCP", 0, "0");
922 if(r!=UPNPCOMMAND_SUCCESS)
923 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
924 port, port, lanaddr, r, strupnperror(r));
926 printf("UPnP Port Mapping successful.\n");
928 if (fShutdown || !fUseUPnP)
930 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
931 printf("UPNP_DeletePortMapping() returned : %d\n", r);
932 freeUPNPDevlist(devlist); devlist = 0;
939 printf("No valid UPnP IGDs found\n");
940 freeUPNPDevlist(devlist); devlist = 0;
944 if (fShutdown || !fUseUPnP)
951 void MapPort(bool fMapPort)
953 if (fUseUPnP != fMapPort)
956 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
958 if (fUseUPnP && vnThreadsRunning[5] < 1)
960 if (!CreateThread(ThreadMapPort, NULL))
961 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
975 static const char *strDNSSeed[] = {
977 "bitseed.bitcoin.org.uk",
980 void DNSAddressSeed()
984 printf("Loading addresses from DNS seeds (could take a while)\n");
986 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
987 struct hostent* phostent = gethostbyname(strDNSSeed[seed_idx]);
991 for (int host = 0; phostent->h_addr_list[host] != NULL; host++) {
992 CAddress addr(*(unsigned int*)phostent->h_addr_list[host],
993 GetDefaultPort(), NODE_NETWORK);
995 if (addr.IsValid() && addr.GetByte(3) != 127) {
1002 printf("%d addresses found from DNS seeds\n", found);
1007 unsigned int pnSeed[] =
1009 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1010 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1011 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1012 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1013 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1014 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1015 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1016 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1017 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1018 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1019 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1020 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1021 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1022 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1023 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1024 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1025 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1026 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1027 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1028 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1029 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1030 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1031 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1032 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1033 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1034 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1035 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1036 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1037 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1038 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1039 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1040 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1041 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1042 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1043 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1044 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1045 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1046 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1047 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1048 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1053 void ThreadOpenConnections(void* parg)
1055 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1058 vnThreadsRunning[1]++;
1059 ThreadOpenConnections2(parg);
1060 vnThreadsRunning[1]--;
1062 catch (std::exception& e) {
1063 vnThreadsRunning[1]--;
1064 PrintException(&e, "ThreadOpenConnections()");
1066 vnThreadsRunning[1]--;
1067 PrintException(NULL, "ThreadOpenConnections()");
1069 printf("ThreadOpenConnections exiting\n");
1072 void ThreadOpenConnections2(void* parg)
1074 printf("ThreadOpenConnections started\n");
1076 // Connect to specific addresses
1077 if (mapArgs.count("-connect"))
1079 for (int64 nLoop = 0;; nLoop++)
1081 foreach(string strAddr, mapMultiArgs["-connect"])
1083 CAddress addr(strAddr, NODE_NETWORK);
1085 OpenNetworkConnection(addr);
1086 for (int i = 0; i < 10 && i < nLoop; i++)
1096 // Connect to manually added nodes first
1097 if (mapArgs.count("-addnode"))
1099 foreach(string strAddr, mapMultiArgs["-addnode"])
1101 CAddress addr(strAddr, NODE_NETWORK);
1104 OpenNetworkConnection(addr);
1112 // Initiate network connections
1113 int64 nStart = GetTime();
1116 // Limit outbound connections
1117 vnThreadsRunning[1]--;
1122 CRITICAL_BLOCK(cs_vNodes)
1123 foreach(CNode* pnode, vNodes)
1124 if (!pnode->fInbound)
1126 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1127 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1128 if (nOutbound < nMaxOutboundConnections)
1134 vnThreadsRunning[1]++;
1138 CRITICAL_BLOCK(cs_mapAddresses)
1140 // Add seed nodes if IRC isn't working
1141 static bool fSeedUsed;
1142 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1143 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1145 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1147 // It'll only connect to one or two seed nodes because once it connects,
1148 // it'll get a pile of addresses with newer timestamps.
1150 addr.ip = pnSeed[i];
1157 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1159 // Disconnect seed nodes
1160 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1161 static int64 nSeedDisconnected;
1162 if (nSeedDisconnected == 0)
1164 nSeedDisconnected = GetTime();
1165 CRITICAL_BLOCK(cs_vNodes)
1166 foreach(CNode* pnode, vNodes)
1167 if (setSeed.count(pnode->addr.ip))
1168 pnode->fDisconnect = true;
1171 // Keep setting timestamps to 0 so they won't reconnect
1172 if (GetTime() - nSeedDisconnected < 60 * 60)
1174 foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1176 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1178 item.second.nTime = 0;
1179 CAddrDB().WriteAddress(item.second);
1188 // Choose an address to connect to based on most recently seen
1190 CAddress addrConnect;
1191 int64 nBest = INT64_MIN;
1193 // Only connect to one address per a.b.?.? range.
1194 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1195 set<unsigned int> setConnected;
1196 CRITICAL_BLOCK(cs_vNodes)
1197 foreach(CNode* pnode, vNodes)
1198 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1200 CRITICAL_BLOCK(cs_mapAddresses)
1202 foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1204 const CAddress& addr = item.second;
1205 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1207 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1208 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1210 // Randomize the order in a deterministic way, putting the standard port first
1211 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1212 if (addr.port != GetDefaultPort())
1213 nRandomizer += 2 * 60 * 60;
1215 // Last seen Base retry frequency
1224 // 365 days 93 hours
1225 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1227 // Fast reconnect for one hour after last seen
1228 if (nSinceLastSeen < 60 * 60)
1231 // Limit retry frequency
1232 if (nSinceLastTry < nDelay)
1235 // If we have IRC, we'll be notified when they first come online,
1236 // and again every 24 hours by the refresh broadcast.
1237 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1240 // Only try the old stuff if we don't have enough connections
1241 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1244 // If multiple addresses are ready, prioritize by time since
1245 // last seen and time since last tried.
1246 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1255 if (addrConnect.IsValid())
1256 OpenNetworkConnection(addrConnect);
1260 bool OpenNetworkConnection(const CAddress& addrConnect)
1263 // Initiate outbound network connection
1267 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1270 vnThreadsRunning[1]--;
1271 CNode* pnode = ConnectNode(addrConnect);
1272 vnThreadsRunning[1]++;
1277 pnode->fNetworkNode = true;
1289 void ThreadMessageHandler(void* parg)
1291 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1294 vnThreadsRunning[2]++;
1295 ThreadMessageHandler2(parg);
1296 vnThreadsRunning[2]--;
1298 catch (std::exception& e) {
1299 vnThreadsRunning[2]--;
1300 PrintException(&e, "ThreadMessageHandler()");
1302 vnThreadsRunning[2]--;
1303 PrintException(NULL, "ThreadMessageHandler()");
1305 printf("ThreadMessageHandler exiting\n");
1308 void ThreadMessageHandler2(void* parg)
1310 printf("ThreadMessageHandler started\n");
1311 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1314 vector<CNode*> vNodesCopy;
1315 CRITICAL_BLOCK(cs_vNodes)
1317 vNodesCopy = vNodes;
1318 foreach(CNode* pnode, vNodesCopy)
1322 // Poll the connected nodes for messages
1323 CNode* pnodeTrickle = NULL;
1324 if (!vNodesCopy.empty())
1325 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1326 foreach(CNode* pnode, vNodesCopy)
1329 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1330 ProcessMessages(pnode);
1335 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1336 SendMessages(pnode, pnode == pnodeTrickle);
1341 CRITICAL_BLOCK(cs_vNodes)
1343 foreach(CNode* pnode, vNodesCopy)
1347 // Wait and allow messages to bunch up.
1348 // Reduce vnThreadsRunning so StopNode has permission to exit while
1349 // we're sleeping, but we must always check fShutdown after doing this.
1350 vnThreadsRunning[2]--;
1352 if (fRequestShutdown)
1354 vnThreadsRunning[2]++;
1368 bool BindListenPort(string& strError)
1372 addrLocalHost.port = GetDefaultPort();
1375 // Initialize Windows Sockets
1377 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1378 if (ret != NO_ERROR)
1380 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1381 printf("%s\n", strError.c_str());
1386 // Create socket for listening for incoming connections
1387 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1388 if (hListenSocket == INVALID_SOCKET)
1390 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1391 printf("%s\n", strError.c_str());
1396 // Different way of disabling SIGPIPE on BSD
1397 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1401 // Allow binding if the port is still in TIME_WAIT state after
1402 // the program was closed and restarted. Not an issue on windows.
1403 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1407 // Set to nonblocking, incoming connections will also inherit this
1408 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1410 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1413 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1414 printf("%s\n", strError.c_str());
1418 // The sockaddr_in structure specifies the address family,
1419 // IP address, and port for the socket that is being bound
1420 struct sockaddr_in sockaddr;
1421 memset(&sockaddr, 0, sizeof(sockaddr));
1422 sockaddr.sin_family = AF_INET;
1423 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1424 sockaddr.sin_port = GetDefaultPort();
1425 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1427 int nErr = WSAGetLastError();
1428 if (nErr == WSAEADDRINUSE)
1429 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1431 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1432 printf("%s\n", strError.c_str());
1435 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1437 // Listen for incoming connections
1438 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1440 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1441 printf("%s\n", strError.c_str());
1448 void StartNode(void* parg)
1450 if (pnodeLocalHost == NULL)
1451 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
1454 // Get local host ip
1455 char pszHostName[1000] = "";
1456 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1458 struct hostent* phostent = gethostbyname(pszHostName);
1461 // Take the first IP that isn't loopback 127.x.x.x
1462 for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1463 printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
1464 for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
1466 CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
1467 if (addr.IsValid() && addr.GetByte(3) != 127)
1469 addrLocalHost = addr;
1476 // Get local host ip
1477 struct ifaddrs* myaddrs;
1478 if (getifaddrs(&myaddrs) == 0)
1480 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1482 if (ifa->ifa_addr == NULL) continue;
1483 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1484 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1485 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1487 if (ifa->ifa_addr->sa_family == AF_INET)
1489 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1490 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1491 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1493 // Take the first IP that isn't loopback 127.x.x.x
1494 CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
1495 if (addr.IsValid() && addr.GetByte(3) != 127)
1497 addrLocalHost = addr;
1501 else if (ifa->ifa_addr->sa_family == AF_INET6)
1503 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1504 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1505 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1508 freeifaddrs(myaddrs);
1511 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1513 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1515 // Proxies can't take incoming connections
1516 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1517 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1521 CreateThread(ThreadGetMyExternalIP, NULL);
1528 // Map ports with UPnP
1532 // Get addresses from IRC and advertise ours
1533 if (!CreateThread(ThreadIRCSeed, NULL))
1534 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1536 // Send and receive from sockets, accept connections
1537 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1539 // Initiate outbound connections
1540 if (!CreateThread(ThreadOpenConnections, NULL))
1541 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1544 if (!CreateThread(ThreadMessageHandler, NULL))
1545 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1547 // Generate coins in the background
1548 GenerateBitcoins(fGenerateBitcoins);
1553 printf("StopNode()\n");
1555 nTransactionsUpdated++;
1556 int64 nStart = GetTime();
1557 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1559 || vnThreadsRunning[5] > 0
1563 if (GetTime() - nStart > 20)
1567 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1568 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1569 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1570 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1571 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1572 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1573 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1589 foreach(CNode* pnode, vNodes)
1590 if (pnode->hSocket != INVALID_SOCKET)
1591 closesocket(pnode->hSocket);
1592 if (hListenSocket != INVALID_SOCKET)
1593 if (closesocket(hListenSocket) == SOCKET_ERROR)
1594 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1597 // Shutdown Windows Sockets
1602 instance_of_cnetcleanup;