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 bool fAllowDNS = false;
33 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
34 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
35 CNode* pnodeLocalHost = NULL;
36 uint64 nLocalHostNonce = 0;
37 array<int, 10> vnThreadsRunning;
38 SOCKET hListenSocket = INVALID_SOCKET;
40 vector<CNode*> vNodes;
41 CCriticalSection cs_vNodes;
42 map<vector<unsigned char>, CAddress> mapAddresses;
43 CCriticalSection cs_mapAddresses;
44 map<CInv, CDataStream> mapRelay;
45 deque<pair<int64, CInv> > vRelayExpiration;
46 CCriticalSection cs_mapRelay;
47 map<CInv, int64> mapAlreadyAskedFor;
50 int fUseProxy = false;
51 CAddress addrProxy("127.0.0.1",9050);
57 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
59 // Filter out duplicate requests
60 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
62 pindexLastGetBlocksBegin = pindexBegin;
63 hashLastGetBlocksEnd = hashEnd;
65 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
72 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
74 hSocketRet = INVALID_SOCKET;
76 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
77 if (hSocket == INVALID_SOCKET)
81 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
84 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
85 bool fProxy = (fUseProxy && fRoutable);
86 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
88 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
96 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
97 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
98 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
99 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
100 char* pszSocks4 = pszSocks4IP;
101 int nSize = sizeof(pszSocks4IP);
103 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
106 closesocket(hSocket);
107 return error("Error sending to proxy");
110 if (recv(hSocket, pchRet, 8, 0) != 8)
112 closesocket(hSocket);
113 return error("Error reading proxy response");
115 if (pchRet[1] != 0x5a)
117 closesocket(hSocket);
118 if (pchRet[1] != 0x5b)
119 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
122 printf("proxy connected %s\n", addrConnect.ToString().c_str());
125 hSocketRet = hSocket;
129 // portDefault is in host order
130 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
135 int port = portDefault;
138 strlcpy(psz, pszName, sizeof(psz));
141 char* pszColon = strrchr(psz+1,':');
142 char *pszPortEnd = NULL;
143 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
144 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
146 if (psz[0] == '[' && pszColon[-1] == ']')
148 // Future: enable IPv6 colon-notation inside []
155 if (port < 0 || port > USHRT_MAX)
160 unsigned int addrIP = inet_addr(pszHost);
161 if (addrIP != INADDR_NONE)
163 // valid IP address passed
164 vaddr.push_back(CAddress(addrIP, port, nServices));
171 struct hostent* phostent = gethostbyname(pszHost);
175 if (phostent->h_addrtype != AF_INET)
178 char** ppAddr = phostent->h_addr_list;
179 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
181 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
183 vaddr.push_back(addr);
187 return (vaddr.size() > 0);
190 // portDefault is in host order
191 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
193 vector<CAddress> vaddr;
194 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
200 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
203 if (!ConnectSocket(addrConnect, hSocket))
204 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
206 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
209 while (RecvLine(hSocket, strLine))
211 if (strLine.empty()) // HTTP response is separated from headers by blank line
215 if (!RecvLine(hSocket, strLine))
217 closesocket(hSocket);
220 if (pszKeyword == NULL)
222 if (strLine.find(pszKeyword) != -1)
224 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
228 closesocket(hSocket);
229 if (strLine.find("<") != -1)
230 strLine = strLine.substr(0, strLine.find("<"));
231 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
232 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
233 strLine.resize(strLine.size()-1);
234 CAddress addr(strLine,0,true);
235 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
236 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
242 closesocket(hSocket);
243 return error("GetMyExternalIP() : connection closed");
246 // We now get our external IP from the IRC server first and only use this as a backup
247 bool GetMyExternalIP(unsigned int& ipRet)
249 CAddress addrConnect;
251 const char* pszKeyword;
256 for (int nLookup = 0; nLookup <= 1; nLookup++)
257 for (int nHost = 1; nHost <= 2; nHost++)
259 // We should be phasing out our use of sites like these. If we need
260 // replacements, we should ask for volunteers to put this simple
261 // php file on their webserver that prints the client IP:
262 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
265 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
269 CAddress addrIP("checkip.dyndns.org", 80, true);
270 if (addrIP.IsValid())
271 addrConnect = addrIP;
274 pszGet = "GET / HTTP/1.1\r\n"
275 "Host: checkip.dyndns.org\r\n"
276 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
277 "Connection: close\r\n"
280 pszKeyword = "Address:";
284 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
288 CAddress addrIP("www.showmyip.com", 80, true);
289 if (addrIP.IsValid())
290 addrConnect = addrIP;
293 pszGet = "GET /simple/ HTTP/1.1\r\n"
294 "Host: www.showmyip.com\r\n"
295 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
296 "Connection: close\r\n"
299 pszKeyword = NULL; // Returns just IP address
302 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
309 void ThreadGetMyExternalIP(void* parg)
311 // Wait for IRC to get it first
312 if (!GetBoolArg("-noirc"))
314 for (int i = 0; i < 2 * 60; i++)
317 if (fGotExternalIP || fShutdown)
322 // Fallback in case IRC fails to get it
323 if (GetMyExternalIP(addrLocalHost.ip))
325 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
326 if (addrLocalHost.IsRoutable())
328 // If we already connected to a few before we had our IP, go back and addr them.
329 // setAddrKnown automatically filters any duplicate sends.
330 CAddress addr(addrLocalHost);
331 addr.nTime = GetAdjustedTime();
332 CRITICAL_BLOCK(cs_vNodes)
333 foreach(CNode* pnode, vNodes)
334 pnode->PushAddress(addr);
343 bool AddAddress(CAddress addr, int64 nTimePenalty)
345 if (!addr.IsRoutable())
347 if (addr.ip == addrLocalHost.ip)
349 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
350 CRITICAL_BLOCK(cs_mapAddresses)
352 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
353 if (it == mapAddresses.end())
356 printf("AddAddress(%s)\n", addr.ToString().c_str());
357 mapAddresses.insert(make_pair(addr.GetKey(), addr));
358 CAddrDB().WriteAddress(addr);
363 bool fUpdated = false;
364 CAddress& addrFound = (*it).second;
365 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
367 // Services have been added
368 addrFound.nServices |= addr.nServices;
371 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
372 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
373 if (addrFound.nTime < addr.nTime - nUpdateInterval)
375 // Periodically update most recently seen time
376 addrFound.nTime = addr.nTime;
380 CAddrDB().WriteAddress(addrFound);
386 void AddressCurrentlyConnected(const CAddress& addr)
388 CRITICAL_BLOCK(cs_mapAddresses)
390 // Only if it's been published already
391 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
392 if (it != mapAddresses.end())
394 CAddress& addrFound = (*it).second;
395 int64 nUpdateInterval = 20 * 60;
396 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
398 // Periodically update most recently seen time
399 addrFound.nTime = GetAdjustedTime();
401 addrdb.WriteAddress(addrFound);
411 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
413 // If the dialog might get closed before the reply comes back,
414 // call this in the destructor so it doesn't get called after it's deleted.
415 CRITICAL_BLOCK(cs_vNodes)
417 foreach(CNode* pnode, vNodes)
419 CRITICAL_BLOCK(pnode->cs_mapRequests)
421 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
423 CRequestTracker& tracker = (*mi).second;
424 if (tracker.fn == fn && tracker.param1 == param1)
425 pnode->mapRequests.erase(mi++);
441 // Subscription methods for the broadcast and subscription system.
442 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
444 // The subscription system uses a meet-in-the-middle strategy.
445 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
446 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
449 bool AnySubscribed(unsigned int nChannel)
451 if (pnodeLocalHost->IsSubscribed(nChannel))
453 CRITICAL_BLOCK(cs_vNodes)
454 foreach(CNode* pnode, vNodes)
455 if (pnode->IsSubscribed(nChannel))
460 bool CNode::IsSubscribed(unsigned int nChannel)
462 if (nChannel >= vfSubscribe.size())
464 return vfSubscribe[nChannel];
467 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
469 if (nChannel >= vfSubscribe.size())
472 if (!AnySubscribed(nChannel))
475 CRITICAL_BLOCK(cs_vNodes)
476 foreach(CNode* pnode, vNodes)
478 pnode->PushMessage("subscribe", nChannel, nHops);
481 vfSubscribe[nChannel] = true;
484 void CNode::CancelSubscribe(unsigned int nChannel)
486 if (nChannel >= vfSubscribe.size())
489 // Prevent from relaying cancel if wasn't subscribed
490 if (!vfSubscribe[nChannel])
492 vfSubscribe[nChannel] = false;
494 if (!AnySubscribed(nChannel))
496 // Relay subscription cancel
497 CRITICAL_BLOCK(cs_vNodes)
498 foreach(CNode* pnode, vNodes)
500 pnode->PushMessage("sub-cancel", nChannel);
512 CNode* FindNode(unsigned int ip)
514 CRITICAL_BLOCK(cs_vNodes)
516 foreach(CNode* pnode, vNodes)
517 if (pnode->addr.ip == ip)
523 CNode* FindNode(CAddress addr)
525 CRITICAL_BLOCK(cs_vNodes)
527 foreach(CNode* pnode, vNodes)
528 if (pnode->addr == addr)
534 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
536 if (addrConnect.ip == addrLocalHost.ip)
539 // Look for an existing connection
540 CNode* pnode = FindNode(addrConnect.ip);
544 pnode->AddRef(nTimeout);
551 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
552 addrConnect.ToString().c_str(),
553 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
554 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
556 CRITICAL_BLOCK(cs_mapAddresses)
557 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
561 if (ConnectSocket(addrConnect, hSocket))
564 printf("connected %s\n", addrConnect.ToString().c_str());
566 // Set to nonblocking
569 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
570 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
572 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
573 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
577 CNode* pnode = new CNode(hSocket, addrConnect, false);
579 pnode->AddRef(nTimeout);
582 CRITICAL_BLOCK(cs_vNodes)
583 vNodes.push_back(pnode);
585 pnode->nTimeConnected = GetTime();
594 void CNode::CloseSocketDisconnect()
597 if (hSocket != INVALID_SOCKET)
600 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
601 printf("disconnecting node %s\n", addr.ToString().c_str());
602 closesocket(hSocket);
603 hSocket = INVALID_SOCKET;
607 void CNode::Cleanup()
609 // All of a nodes broadcasts and subscriptions are automatically torn down
610 // when it goes down, so a node has to stay up to keep its broadcast going.
612 // Cancel subscriptions
613 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
614 if (vfSubscribe[nChannel])
615 CancelSubscribe(nChannel);
630 void ThreadSocketHandler(void* parg)
632 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
635 vnThreadsRunning[0]++;
636 ThreadSocketHandler2(parg);
637 vnThreadsRunning[0]--;
639 catch (std::exception& e) {
640 vnThreadsRunning[0]--;
641 PrintException(&e, "ThreadSocketHandler()");
643 vnThreadsRunning[0]--;
644 throw; // support pthread_cancel()
646 printf("ThreadSocketHandler exiting\n");
649 void ThreadSocketHandler2(void* parg)
651 printf("ThreadSocketHandler started\n");
652 list<CNode*> vNodesDisconnected;
653 int nPrevNodeCount = 0;
660 CRITICAL_BLOCK(cs_vNodes)
662 // Disconnect unused nodes
663 vector<CNode*> vNodesCopy = vNodes;
664 foreach(CNode* pnode, vNodesCopy)
666 if (pnode->fDisconnect ||
667 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
669 // remove from vNodes
670 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
672 // close socket and cleanup
673 pnode->CloseSocketDisconnect();
676 // hold in disconnected pool until all refs are released
677 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
678 if (pnode->fNetworkNode || pnode->fInbound)
680 vNodesDisconnected.push_back(pnode);
684 // Delete disconnected nodes
685 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
686 foreach(CNode* pnode, vNodesDisconnectedCopy)
688 // wait until threads are done using it
689 if (pnode->GetRefCount() <= 0)
691 bool fDelete = false;
692 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
693 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
694 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
695 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
699 vNodesDisconnected.remove(pnode);
705 if (vNodes.size() != nPrevNodeCount)
707 nPrevNodeCount = vNodes.size();
713 // Find which sockets have data to receive
715 struct timeval timeout;
717 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
724 FD_ZERO(&fdsetError);
725 SOCKET hSocketMax = 0;
727 if(hListenSocket != INVALID_SOCKET)
728 FD_SET(hListenSocket, &fdsetRecv);
729 hSocketMax = max(hSocketMax, hListenSocket);
730 CRITICAL_BLOCK(cs_vNodes)
732 foreach(CNode* pnode, vNodes)
734 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
736 FD_SET(pnode->hSocket, &fdsetRecv);
737 FD_SET(pnode->hSocket, &fdsetError);
738 hSocketMax = max(hSocketMax, pnode->hSocket);
739 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
740 if (!pnode->vSend.empty())
741 FD_SET(pnode->hSocket, &fdsetSend);
745 vnThreadsRunning[0]--;
746 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
747 vnThreadsRunning[0]++;
750 if (nSelect == SOCKET_ERROR)
752 int nErr = WSAGetLastError();
753 printf("socket select error %d\n", nErr);
754 for (int i = 0; i <= hSocketMax; i++)
755 FD_SET(i, &fdsetRecv);
757 FD_ZERO(&fdsetError);
758 Sleep(timeout.tv_usec/1000);
763 // Accept new connections
765 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
767 struct sockaddr_in sockaddr;
768 socklen_t len = sizeof(sockaddr);
769 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
770 CAddress addr(sockaddr);
773 CRITICAL_BLOCK(cs_vNodes)
774 foreach(CNode* pnode, vNodes)
777 if (hSocket == INVALID_SOCKET)
779 if (WSAGetLastError() != WSAEWOULDBLOCK)
780 printf("socket error accept failed: %d\n", WSAGetLastError());
782 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
784 closesocket(hSocket);
788 printf("accepted connection %s\n", addr.ToString().c_str());
789 CNode* pnode = new CNode(hSocket, addr, true);
791 CRITICAL_BLOCK(cs_vNodes)
792 vNodes.push_back(pnode);
798 // Service each socket
800 vector<CNode*> vNodesCopy;
801 CRITICAL_BLOCK(cs_vNodes)
804 foreach(CNode* pnode, vNodesCopy)
807 foreach(CNode* pnode, vNodesCopy)
815 if (pnode->hSocket == INVALID_SOCKET)
817 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
819 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
821 CDataStream& vRecv = pnode->vRecv;
822 unsigned int nPos = vRecv.size();
824 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
825 if (!pnode->fDisconnect)
826 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
827 pnode->CloseSocketDisconnect();
830 // typical socket buffer is 8K-64K
831 char pchBuf[0x10000];
832 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
835 vRecv.resize(nPos + nBytes);
836 memcpy(&vRecv[nPos], pchBuf, nBytes);
837 pnode->nLastRecv = GetTime();
839 else if (nBytes == 0)
841 // socket closed gracefully
842 if (!pnode->fDisconnect)
843 printf("socket closed\n");
844 pnode->CloseSocketDisconnect();
849 int nErr = WSAGetLastError();
850 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
852 if (!pnode->fDisconnect)
853 printf("socket recv error %d\n", nErr);
854 pnode->CloseSocketDisconnect();
864 if (pnode->hSocket == INVALID_SOCKET)
866 if (FD_ISSET(pnode->hSocket, &fdsetSend))
868 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
870 CDataStream& vSend = pnode->vSend;
873 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
876 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
877 pnode->nLastSend = GetTime();
882 int nErr = WSAGetLastError();
883 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
885 printf("socket send error %d\n", nErr);
886 pnode->CloseSocketDisconnect();
889 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
890 if (!pnode->fDisconnect)
891 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
892 pnode->CloseSocketDisconnect();
899 // Inactivity checking
901 if (pnode->vSend.empty())
902 pnode->nLastSendEmpty = GetTime();
903 if (GetTime() - pnode->nTimeConnected > 60)
905 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
907 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
908 pnode->fDisconnect = true;
910 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
912 printf("socket not sending\n");
913 pnode->fDisconnect = true;
915 else if (GetTime() - pnode->nLastRecv > 90*60)
917 printf("socket inactivity timeout\n");
918 pnode->fDisconnect = true;
922 CRITICAL_BLOCK(cs_vNodes)
924 foreach(CNode* pnode, vNodesCopy)
941 void ThreadMapPort(void* parg)
943 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
946 vnThreadsRunning[5]++;
947 ThreadMapPort2(parg);
948 vnThreadsRunning[5]--;
950 catch (std::exception& e) {
951 vnThreadsRunning[5]--;
952 PrintException(&e, "ThreadMapPort()");
954 vnThreadsRunning[5]--;
955 PrintException(NULL, "ThreadMapPort()");
957 printf("ThreadMapPort exiting\n");
960 void ThreadMapPort2(void* parg)
962 printf("ThreadMapPort started\n");
965 sprintf(port, "%d", GetDefaultPort());
967 const char * rootdescurl = 0;
968 const char * multicastif = 0;
969 const char * minissdpdpath = 0;
970 struct UPNPDev * devlist = 0;
973 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
975 struct UPNPUrls urls;
976 struct IGDdatas data;
979 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
986 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
987 port, port, lanaddr, 0, "TCP", 0);
989 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
990 port, port, lanaddr, 0, "TCP", 0, "0");
992 if(r!=UPNPCOMMAND_SUCCESS)
993 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
994 port, port, lanaddr, r, strupnperror(r));
996 printf("UPnP Port Mapping successful.\n");
998 if (fShutdown || !fUseUPnP)
1000 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1001 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1002 freeUPNPDevlist(devlist); devlist = 0;
1003 FreeUPNPUrls(&urls);
1009 printf("No valid UPnP IGDs found\n");
1010 freeUPNPDevlist(devlist); devlist = 0;
1012 FreeUPNPUrls(&urls);
1014 if (fShutdown || !fUseUPnP)
1021 void MapPort(bool fMapPort)
1023 if (fUseUPnP != fMapPort)
1025 fUseUPnP = fMapPort;
1026 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1028 if (fUseUPnP && vnThreadsRunning[5] < 1)
1030 if (!CreateThread(ThreadMapPort, NULL))
1031 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1045 static const char *strDNSSeed[] = {
1047 "bitseed.bitcoin.org.uk",
1050 void DNSAddressSeed()
1054 printf("Loading addresses from DNS seeds (could take a while)\n");
1056 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1057 vector<CAddress> vaddr;
1058 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1060 foreach (CAddress& addr, vaddr)
1062 if (addr.GetByte(3) != 127)
1072 printf("%d addresses found from DNS seeds\n", found);
1077 unsigned int pnSeed[] =
1079 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1080 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1081 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1082 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1083 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1084 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1085 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1086 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1087 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1088 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1089 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1090 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1091 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1092 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1093 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1094 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1095 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1096 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1097 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1098 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1099 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1100 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1101 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1102 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1103 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1104 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1105 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1106 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1107 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1108 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1109 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1110 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1111 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1112 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1113 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1114 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1115 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1116 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1117 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1118 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1123 void ThreadOpenConnections(void* parg)
1125 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1128 vnThreadsRunning[1]++;
1129 ThreadOpenConnections2(parg);
1130 vnThreadsRunning[1]--;
1132 catch (std::exception& e) {
1133 vnThreadsRunning[1]--;
1134 PrintException(&e, "ThreadOpenConnections()");
1136 vnThreadsRunning[1]--;
1137 PrintException(NULL, "ThreadOpenConnections()");
1139 printf("ThreadOpenConnections exiting\n");
1142 void ThreadOpenConnections2(void* parg)
1144 printf("ThreadOpenConnections started\n");
1146 // Connect to specific addresses
1147 if (mapArgs.count("-connect"))
1149 for (int64 nLoop = 0;; nLoop++)
1151 foreach(string strAddr, mapMultiArgs["-connect"])
1153 CAddress addr(strAddr, fAllowDNS);
1155 OpenNetworkConnection(addr);
1156 for (int i = 0; i < 10 && i < nLoop; i++)
1166 // Connect to manually added nodes first
1167 if (mapArgs.count("-addnode"))
1169 foreach(string strAddr, mapMultiArgs["-addnode"])
1171 CAddress addr(strAddr, fAllowDNS);
1174 OpenNetworkConnection(addr);
1182 // Initiate network connections
1183 int64 nStart = GetTime();
1186 // Limit outbound connections
1187 vnThreadsRunning[1]--;
1192 CRITICAL_BLOCK(cs_vNodes)
1193 foreach(CNode* pnode, vNodes)
1194 if (!pnode->fInbound)
1196 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1197 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1198 if (nOutbound < nMaxOutboundConnections)
1204 vnThreadsRunning[1]++;
1208 CRITICAL_BLOCK(cs_mapAddresses)
1210 // Add seed nodes if IRC isn't working
1211 static bool fSeedUsed;
1212 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1213 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1215 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1217 // It'll only connect to one or two seed nodes because once it connects,
1218 // it'll get a pile of addresses with newer timestamps.
1220 addr.ip = pnSeed[i];
1227 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1229 // Disconnect seed nodes
1230 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1231 static int64 nSeedDisconnected;
1232 if (nSeedDisconnected == 0)
1234 nSeedDisconnected = GetTime();
1235 CRITICAL_BLOCK(cs_vNodes)
1236 foreach(CNode* pnode, vNodes)
1237 if (setSeed.count(pnode->addr.ip))
1238 pnode->fDisconnect = true;
1241 // Keep setting timestamps to 0 so they won't reconnect
1242 if (GetTime() - nSeedDisconnected < 60 * 60)
1244 foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1246 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1248 item.second.nTime = 0;
1249 CAddrDB().WriteAddress(item.second);
1258 // Choose an address to connect to based on most recently seen
1260 CAddress addrConnect;
1261 int64 nBest = INT64_MIN;
1263 // Only connect to one address per a.b.?.? range.
1264 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1265 set<unsigned int> setConnected;
1266 CRITICAL_BLOCK(cs_vNodes)
1267 foreach(CNode* pnode, vNodes)
1268 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1270 CRITICAL_BLOCK(cs_mapAddresses)
1272 foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1274 const CAddress& addr = item.second;
1275 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1277 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1278 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1280 // Randomize the order in a deterministic way, putting the standard port first
1281 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1282 if (addr.port != htons(GetDefaultPort()))
1283 nRandomizer += 2 * 60 * 60;
1285 // Last seen Base retry frequency
1294 // 365 days 93 hours
1295 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1297 // Fast reconnect for one hour after last seen
1298 if (nSinceLastSeen < 60 * 60)
1301 // Limit retry frequency
1302 if (nSinceLastTry < nDelay)
1305 // If we have IRC, we'll be notified when they first come online,
1306 // and again every 24 hours by the refresh broadcast.
1307 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1310 // Only try the old stuff if we don't have enough connections
1311 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1314 // If multiple addresses are ready, prioritize by time since
1315 // last seen and time since last tried.
1316 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1325 if (addrConnect.IsValid())
1326 OpenNetworkConnection(addrConnect);
1330 bool OpenNetworkConnection(const CAddress& addrConnect)
1333 // Initiate outbound network connection
1337 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1340 vnThreadsRunning[1]--;
1341 CNode* pnode = ConnectNode(addrConnect);
1342 vnThreadsRunning[1]++;
1347 pnode->fNetworkNode = true;
1359 void ThreadMessageHandler(void* parg)
1361 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1364 vnThreadsRunning[2]++;
1365 ThreadMessageHandler2(parg);
1366 vnThreadsRunning[2]--;
1368 catch (std::exception& e) {
1369 vnThreadsRunning[2]--;
1370 PrintException(&e, "ThreadMessageHandler()");
1372 vnThreadsRunning[2]--;
1373 PrintException(NULL, "ThreadMessageHandler()");
1375 printf("ThreadMessageHandler exiting\n");
1378 void ThreadMessageHandler2(void* parg)
1380 printf("ThreadMessageHandler started\n");
1381 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1384 vector<CNode*> vNodesCopy;
1385 CRITICAL_BLOCK(cs_vNodes)
1387 vNodesCopy = vNodes;
1388 foreach(CNode* pnode, vNodesCopy)
1392 // Poll the connected nodes for messages
1393 CNode* pnodeTrickle = NULL;
1394 if (!vNodesCopy.empty())
1395 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1396 foreach(CNode* pnode, vNodesCopy)
1399 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1400 ProcessMessages(pnode);
1405 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1406 SendMessages(pnode, pnode == pnodeTrickle);
1411 CRITICAL_BLOCK(cs_vNodes)
1413 foreach(CNode* pnode, vNodesCopy)
1417 // Wait and allow messages to bunch up.
1418 // Reduce vnThreadsRunning so StopNode has permission to exit while
1419 // we're sleeping, but we must always check fShutdown after doing this.
1420 vnThreadsRunning[2]--;
1422 if (fRequestShutdown)
1424 vnThreadsRunning[2]++;
1438 bool BindListenPort(string& strError)
1442 addrLocalHost.port = htons(GetDefaultPort());
1445 // Initialize Windows Sockets
1447 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1448 if (ret != NO_ERROR)
1450 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1451 printf("%s\n", strError.c_str());
1456 // Create socket for listening for incoming connections
1457 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1458 if (hListenSocket == INVALID_SOCKET)
1460 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1461 printf("%s\n", strError.c_str());
1466 // Different way of disabling SIGPIPE on BSD
1467 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1471 // Allow binding if the port is still in TIME_WAIT state after
1472 // the program was closed and restarted. Not an issue on windows.
1473 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1477 // Set to nonblocking, incoming connections will also inherit this
1478 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1480 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1483 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1484 printf("%s\n", strError.c_str());
1488 // The sockaddr_in structure specifies the address family,
1489 // IP address, and port for the socket that is being bound
1490 struct sockaddr_in sockaddr;
1491 memset(&sockaddr, 0, sizeof(sockaddr));
1492 sockaddr.sin_family = AF_INET;
1493 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1494 sockaddr.sin_port = htons(GetDefaultPort());
1495 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1497 int nErr = WSAGetLastError();
1498 if (nErr == WSAEADDRINUSE)
1499 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1501 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1502 printf("%s\n", strError.c_str());
1505 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1507 // Listen for incoming connections
1508 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1510 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1511 printf("%s\n", strError.c_str());
1518 void StartNode(void* parg)
1520 if (pnodeLocalHost == NULL)
1521 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1524 // Get local host ip
1525 char pszHostName[1000] = "";
1526 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1528 vector<CAddress> vaddr;
1529 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1530 foreach (const CAddress &addr, vaddr)
1531 if (addr.GetByte(3) != 127)
1533 addrLocalHost = addr;
1538 // Get local host ip
1539 struct ifaddrs* myaddrs;
1540 if (getifaddrs(&myaddrs) == 0)
1542 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1544 if (ifa->ifa_addr == NULL) continue;
1545 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1546 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1547 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1549 if (ifa->ifa_addr->sa_family == AF_INET)
1551 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1552 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1553 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1555 // Take the first IP that isn't loopback 127.x.x.x
1556 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1557 if (addr.IsValid() && addr.GetByte(3) != 127)
1559 addrLocalHost = addr;
1563 else if (ifa->ifa_addr->sa_family == AF_INET6)
1565 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1566 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1567 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1570 freeifaddrs(myaddrs);
1573 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1575 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1577 // Proxies can't take incoming connections
1578 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1579 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1583 CreateThread(ThreadGetMyExternalIP, NULL);
1590 // Map ports with UPnP
1594 // Get addresses from IRC and advertise ours
1595 if (!CreateThread(ThreadIRCSeed, NULL))
1596 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1598 // Send and receive from sockets, accept connections
1599 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1601 // Initiate outbound connections
1602 if (!CreateThread(ThreadOpenConnections, NULL))
1603 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1606 if (!CreateThread(ThreadMessageHandler, NULL))
1607 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1609 // Generate coins in the background
1610 GenerateBitcoins(fGenerateBitcoins);
1615 printf("StopNode()\n");
1617 nTransactionsUpdated++;
1618 int64 nStart = GetTime();
1619 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1621 || vnThreadsRunning[5] > 0
1625 if (GetTime() - nStart > 20)
1629 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1630 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1631 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1632 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1633 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1634 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1635 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1651 foreach(CNode* pnode, vNodes)
1652 if (pnode->hSocket != INVALID_SOCKET)
1653 closesocket(pnode->hSocket);
1654 if (hListenSocket != INVALID_SOCKET)
1655 if (closesocket(hListenSocket) == SOCKET_ERROR)
1656 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1659 // Shutdown Windows Sockets
1664 instance_of_cnetcleanup;