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)
133 int port = portDefault;
136 strlcpy(psz, pszName, sizeof(psz));
139 char* pszColon = strrchr(psz+1,':');
140 char *pszPortEnd = NULL;
141 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
142 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
144 if (psz[0] == '[' && pszColon[-1] == ']')
146 // Future: enable IPv6 colon-notation inside []
153 if (port < 0 || port > USHRT_MAX)
158 struct in_addr addrIP;
159 if (inet_aton(pszHost, &addrIP))
161 // valid IP address passed
162 vaddr.push_back(CAddress(addrIP.s_addr, port, nServices));
169 struct hostent* phostent = gethostbyname(pszHost);
173 if (phostent->h_addrtype != AF_INET)
176 char** ppAddr = phostent->h_addr_list;
177 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
179 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
181 vaddr.push_back(addr);
185 return (vaddr.size() > 0);
188 // portDefault is in host order
189 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
191 vector<CAddress> vaddr;
192 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
198 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
201 if (!ConnectSocket(addrConnect, hSocket))
202 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
204 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
207 while (RecvLine(hSocket, strLine))
209 if (strLine.empty()) // HTTP response is separated from headers by blank line
213 if (!RecvLine(hSocket, strLine))
215 closesocket(hSocket);
218 if (pszKeyword == NULL)
220 if (strLine.find(pszKeyword) != -1)
222 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
226 closesocket(hSocket);
227 if (strLine.find("<") != -1)
228 strLine = strLine.substr(0, strLine.find("<"));
229 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
230 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
231 strLine.resize(strLine.size()-1);
232 CAddress addr(strLine,0,true);
233 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
234 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
240 closesocket(hSocket);
241 return error("GetMyExternalIP() : connection closed");
244 // We now get our external IP from the IRC server first and only use this as a backup
245 bool GetMyExternalIP(unsigned int& ipRet)
247 CAddress addrConnect;
249 const char* pszKeyword;
254 for (int nLookup = 0; nLookup <= 1; nLookup++)
255 for (int nHost = 1; nHost <= 2; nHost++)
257 // We should be phasing out our use of sites like these. If we need
258 // replacements, we should ask for volunteers to put this simple
259 // php file on their webserver that prints the client IP:
260 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
263 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
267 CAddress addrIP("checkip.dyndns.org", 80, true);
268 if (addrIP.IsValid())
269 addrConnect = addrIP;
272 pszGet = "GET / HTTP/1.1\r\n"
273 "Host: checkip.dyndns.org\r\n"
274 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
275 "Connection: close\r\n"
278 pszKeyword = "Address:";
282 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
286 CAddress addrIP("www.showmyip.com", 80, true);
287 if (addrIP.IsValid())
288 addrConnect = addrIP;
291 pszGet = "GET /simple/ HTTP/1.1\r\n"
292 "Host: www.showmyip.com\r\n"
293 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
294 "Connection: close\r\n"
297 pszKeyword = NULL; // Returns just IP address
300 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
307 void ThreadGetMyExternalIP(void* parg)
309 // Wait for IRC to get it first
310 if (!GetBoolArg("-noirc"))
312 for (int i = 0; i < 2 * 60; i++)
315 if (fGotExternalIP || fShutdown)
320 // Fallback in case IRC fails to get it
321 if (GetMyExternalIP(addrLocalHost.ip))
323 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
324 if (addrLocalHost.IsRoutable())
326 // If we already connected to a few before we had our IP, go back and addr them.
327 // setAddrKnown automatically filters any duplicate sends.
328 CAddress addr(addrLocalHost);
329 addr.nTime = GetAdjustedTime();
330 CRITICAL_BLOCK(cs_vNodes)
331 foreach(CNode* pnode, vNodes)
332 pnode->PushAddress(addr);
341 bool AddAddress(CAddress addr, int64 nTimePenalty)
343 if (!addr.IsRoutable())
345 if (addr.ip == addrLocalHost.ip)
347 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
348 CRITICAL_BLOCK(cs_mapAddresses)
350 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
351 if (it == mapAddresses.end())
354 printf("AddAddress(%s)\n", addr.ToString().c_str());
355 mapAddresses.insert(make_pair(addr.GetKey(), addr));
356 CAddrDB().WriteAddress(addr);
361 bool fUpdated = false;
362 CAddress& addrFound = (*it).second;
363 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
365 // Services have been added
366 addrFound.nServices |= addr.nServices;
369 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
370 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
371 if (addrFound.nTime < addr.nTime - nUpdateInterval)
373 // Periodically update most recently seen time
374 addrFound.nTime = addr.nTime;
378 CAddrDB().WriteAddress(addrFound);
384 void AddressCurrentlyConnected(const CAddress& addr)
386 CRITICAL_BLOCK(cs_mapAddresses)
388 // Only if it's been published already
389 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
390 if (it != mapAddresses.end())
392 CAddress& addrFound = (*it).second;
393 int64 nUpdateInterval = 20 * 60;
394 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
396 // Periodically update most recently seen time
397 addrFound.nTime = GetAdjustedTime();
399 addrdb.WriteAddress(addrFound);
409 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
411 // If the dialog might get closed before the reply comes back,
412 // call this in the destructor so it doesn't get called after it's deleted.
413 CRITICAL_BLOCK(cs_vNodes)
415 foreach(CNode* pnode, vNodes)
417 CRITICAL_BLOCK(pnode->cs_mapRequests)
419 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
421 CRequestTracker& tracker = (*mi).second;
422 if (tracker.fn == fn && tracker.param1 == param1)
423 pnode->mapRequests.erase(mi++);
439 // Subscription methods for the broadcast and subscription system.
440 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
442 // The subscription system uses a meet-in-the-middle strategy.
443 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
444 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
447 bool AnySubscribed(unsigned int nChannel)
449 if (pnodeLocalHost->IsSubscribed(nChannel))
451 CRITICAL_BLOCK(cs_vNodes)
452 foreach(CNode* pnode, vNodes)
453 if (pnode->IsSubscribed(nChannel))
458 bool CNode::IsSubscribed(unsigned int nChannel)
460 if (nChannel >= vfSubscribe.size())
462 return vfSubscribe[nChannel];
465 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
467 if (nChannel >= vfSubscribe.size())
470 if (!AnySubscribed(nChannel))
473 CRITICAL_BLOCK(cs_vNodes)
474 foreach(CNode* pnode, vNodes)
476 pnode->PushMessage("subscribe", nChannel, nHops);
479 vfSubscribe[nChannel] = true;
482 void CNode::CancelSubscribe(unsigned int nChannel)
484 if (nChannel >= vfSubscribe.size())
487 // Prevent from relaying cancel if wasn't subscribed
488 if (!vfSubscribe[nChannel])
490 vfSubscribe[nChannel] = false;
492 if (!AnySubscribed(nChannel))
494 // Relay subscription cancel
495 CRITICAL_BLOCK(cs_vNodes)
496 foreach(CNode* pnode, vNodes)
498 pnode->PushMessage("sub-cancel", nChannel);
510 CNode* FindNode(unsigned int ip)
512 CRITICAL_BLOCK(cs_vNodes)
514 foreach(CNode* pnode, vNodes)
515 if (pnode->addr.ip == ip)
521 CNode* FindNode(CAddress addr)
523 CRITICAL_BLOCK(cs_vNodes)
525 foreach(CNode* pnode, vNodes)
526 if (pnode->addr == addr)
532 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
534 if (addrConnect.ip == addrLocalHost.ip)
537 // Look for an existing connection
538 CNode* pnode = FindNode(addrConnect.ip);
542 pnode->AddRef(nTimeout);
549 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
550 addrConnect.ToString().c_str(),
551 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
552 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
554 CRITICAL_BLOCK(cs_mapAddresses)
555 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
559 if (ConnectSocket(addrConnect, hSocket))
562 printf("connected %s\n", addrConnect.ToString().c_str());
564 // Set to nonblocking
567 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
568 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
570 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
571 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
575 CNode* pnode = new CNode(hSocket, addrConnect, false);
577 pnode->AddRef(nTimeout);
580 CRITICAL_BLOCK(cs_vNodes)
581 vNodes.push_back(pnode);
583 pnode->nTimeConnected = GetTime();
592 void CNode::CloseSocketDisconnect()
595 if (hSocket != INVALID_SOCKET)
598 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
599 printf("disconnecting node %s\n", addr.ToString().c_str());
600 closesocket(hSocket);
601 hSocket = INVALID_SOCKET;
605 void CNode::Cleanup()
607 // All of a nodes broadcasts and subscriptions are automatically torn down
608 // when it goes down, so a node has to stay up to keep its broadcast going.
610 // Cancel subscriptions
611 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
612 if (vfSubscribe[nChannel])
613 CancelSubscribe(nChannel);
628 void ThreadSocketHandler(void* parg)
630 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
633 vnThreadsRunning[0]++;
634 ThreadSocketHandler2(parg);
635 vnThreadsRunning[0]--;
637 catch (std::exception& e) {
638 vnThreadsRunning[0]--;
639 PrintException(&e, "ThreadSocketHandler()");
641 vnThreadsRunning[0]--;
642 throw; // support pthread_cancel()
644 printf("ThreadSocketHandler exiting\n");
647 void ThreadSocketHandler2(void* parg)
649 printf("ThreadSocketHandler started\n");
650 list<CNode*> vNodesDisconnected;
651 int nPrevNodeCount = 0;
658 CRITICAL_BLOCK(cs_vNodes)
660 // Disconnect unused nodes
661 vector<CNode*> vNodesCopy = vNodes;
662 foreach(CNode* pnode, vNodesCopy)
664 if (pnode->fDisconnect ||
665 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
667 // remove from vNodes
668 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
670 // close socket and cleanup
671 pnode->CloseSocketDisconnect();
674 // hold in disconnected pool until all refs are released
675 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
676 if (pnode->fNetworkNode || pnode->fInbound)
678 vNodesDisconnected.push_back(pnode);
682 // Delete disconnected nodes
683 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
684 foreach(CNode* pnode, vNodesDisconnectedCopy)
686 // wait until threads are done using it
687 if (pnode->GetRefCount() <= 0)
689 bool fDelete = false;
690 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
691 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
692 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
693 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
697 vNodesDisconnected.remove(pnode);
703 if (vNodes.size() != nPrevNodeCount)
705 nPrevNodeCount = vNodes.size();
711 // Find which sockets have data to receive
713 struct timeval timeout;
715 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
722 FD_ZERO(&fdsetError);
723 SOCKET hSocketMax = 0;
725 if(hListenSocket != INVALID_SOCKET)
726 FD_SET(hListenSocket, &fdsetRecv);
727 hSocketMax = max(hSocketMax, hListenSocket);
728 CRITICAL_BLOCK(cs_vNodes)
730 foreach(CNode* pnode, vNodes)
732 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
734 FD_SET(pnode->hSocket, &fdsetRecv);
735 FD_SET(pnode->hSocket, &fdsetError);
736 hSocketMax = max(hSocketMax, pnode->hSocket);
737 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
738 if (!pnode->vSend.empty())
739 FD_SET(pnode->hSocket, &fdsetSend);
743 vnThreadsRunning[0]--;
744 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
745 vnThreadsRunning[0]++;
748 if (nSelect == SOCKET_ERROR)
750 int nErr = WSAGetLastError();
751 printf("socket select error %d\n", nErr);
752 for (int i = 0; i <= hSocketMax; i++)
753 FD_SET(i, &fdsetRecv);
755 FD_ZERO(&fdsetError);
756 Sleep(timeout.tv_usec/1000);
761 // Accept new connections
763 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
765 struct sockaddr_in sockaddr;
766 socklen_t len = sizeof(sockaddr);
767 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
768 CAddress addr(sockaddr);
771 CRITICAL_BLOCK(cs_vNodes)
772 foreach(CNode* pnode, vNodes)
775 if (hSocket == INVALID_SOCKET)
777 if (WSAGetLastError() != WSAEWOULDBLOCK)
778 printf("socket error accept failed: %d\n", WSAGetLastError());
780 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
782 closesocket(hSocket);
786 printf("accepted connection %s\n", addr.ToString().c_str());
787 CNode* pnode = new CNode(hSocket, addr, true);
789 CRITICAL_BLOCK(cs_vNodes)
790 vNodes.push_back(pnode);
796 // Service each socket
798 vector<CNode*> vNodesCopy;
799 CRITICAL_BLOCK(cs_vNodes)
802 foreach(CNode* pnode, vNodesCopy)
805 foreach(CNode* pnode, vNodesCopy)
813 if (pnode->hSocket == INVALID_SOCKET)
815 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
817 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
819 CDataStream& vRecv = pnode->vRecv;
820 unsigned int nPos = vRecv.size();
822 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
823 if (!pnode->fDisconnect)
824 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
825 pnode->CloseSocketDisconnect();
828 // typical socket buffer is 8K-64K
829 char pchBuf[0x10000];
830 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
833 vRecv.resize(nPos + nBytes);
834 memcpy(&vRecv[nPos], pchBuf, nBytes);
835 pnode->nLastRecv = GetTime();
837 else if (nBytes == 0)
839 // socket closed gracefully
840 if (!pnode->fDisconnect)
841 printf("socket closed\n");
842 pnode->CloseSocketDisconnect();
847 int nErr = WSAGetLastError();
848 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
850 if (!pnode->fDisconnect)
851 printf("socket recv error %d\n", nErr);
852 pnode->CloseSocketDisconnect();
862 if (pnode->hSocket == INVALID_SOCKET)
864 if (FD_ISSET(pnode->hSocket, &fdsetSend))
866 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
868 CDataStream& vSend = pnode->vSend;
871 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
874 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
875 pnode->nLastSend = GetTime();
880 int nErr = WSAGetLastError();
881 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
883 printf("socket send error %d\n", nErr);
884 pnode->CloseSocketDisconnect();
887 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
888 if (!pnode->fDisconnect)
889 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
890 pnode->CloseSocketDisconnect();
897 // Inactivity checking
899 if (pnode->vSend.empty())
900 pnode->nLastSendEmpty = GetTime();
901 if (GetTime() - pnode->nTimeConnected > 60)
903 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
905 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
906 pnode->fDisconnect = true;
908 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
910 printf("socket not sending\n");
911 pnode->fDisconnect = true;
913 else if (GetTime() - pnode->nLastRecv > 90*60)
915 printf("socket inactivity timeout\n");
916 pnode->fDisconnect = true;
920 CRITICAL_BLOCK(cs_vNodes)
922 foreach(CNode* pnode, vNodesCopy)
939 void ThreadMapPort(void* parg)
941 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
944 vnThreadsRunning[5]++;
945 ThreadMapPort2(parg);
946 vnThreadsRunning[5]--;
948 catch (std::exception& e) {
949 vnThreadsRunning[5]--;
950 PrintException(&e, "ThreadMapPort()");
952 vnThreadsRunning[5]--;
953 PrintException(NULL, "ThreadMapPort()");
955 printf("ThreadMapPort exiting\n");
958 void ThreadMapPort2(void* parg)
960 printf("ThreadMapPort started\n");
963 sprintf(port, "%d", GetDefaultPort());
965 const char * rootdescurl = 0;
966 const char * multicastif = 0;
967 const char * minissdpdpath = 0;
968 struct UPNPDev * devlist = 0;
971 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
973 struct UPNPUrls urls;
974 struct IGDdatas data;
977 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
984 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
985 port, port, lanaddr, 0, "TCP", 0);
987 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
988 port, port, lanaddr, 0, "TCP", 0, "0");
990 if(r!=UPNPCOMMAND_SUCCESS)
991 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
992 port, port, lanaddr, r, strupnperror(r));
994 printf("UPnP Port Mapping successful.\n");
996 if (fShutdown || !fUseUPnP)
998 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
999 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1000 freeUPNPDevlist(devlist); devlist = 0;
1001 FreeUPNPUrls(&urls);
1007 printf("No valid UPnP IGDs found\n");
1008 freeUPNPDevlist(devlist); devlist = 0;
1010 FreeUPNPUrls(&urls);
1012 if (fShutdown || !fUseUPnP)
1019 void MapPort(bool fMapPort)
1021 if (fUseUPnP != fMapPort)
1023 fUseUPnP = fMapPort;
1024 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1026 if (fUseUPnP && vnThreadsRunning[5] < 1)
1028 if (!CreateThread(ThreadMapPort, NULL))
1029 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1043 static const char *strDNSSeed[] = {
1045 "bitseed.bitcoin.org.uk",
1048 void DNSAddressSeed()
1052 printf("Loading addresses from DNS seeds (could take a while)\n");
1054 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1055 vector<CAddress> vaddr;
1056 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1058 foreach (CAddress& addr, vaddr)
1060 if (addr.GetByte(3) != 127)
1070 printf("%d addresses found from DNS seeds\n", found);
1075 unsigned int pnSeed[] =
1077 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1078 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1079 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1080 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1081 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1082 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1083 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1084 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1085 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1086 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1087 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1088 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1089 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1090 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1091 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1092 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1093 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1094 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1095 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1096 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1097 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1098 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1099 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1100 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1101 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1102 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1103 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1104 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1105 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1106 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1107 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1108 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1109 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1110 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1111 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1112 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1113 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1114 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1115 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1116 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1121 void ThreadOpenConnections(void* parg)
1123 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1126 vnThreadsRunning[1]++;
1127 ThreadOpenConnections2(parg);
1128 vnThreadsRunning[1]--;
1130 catch (std::exception& e) {
1131 vnThreadsRunning[1]--;
1132 PrintException(&e, "ThreadOpenConnections()");
1134 vnThreadsRunning[1]--;
1135 PrintException(NULL, "ThreadOpenConnections()");
1137 printf("ThreadOpenConnections exiting\n");
1140 void ThreadOpenConnections2(void* parg)
1142 printf("ThreadOpenConnections started\n");
1144 // Connect to specific addresses
1145 if (mapArgs.count("-connect"))
1147 for (int64 nLoop = 0;; nLoop++)
1149 foreach(string strAddr, mapMultiArgs["-connect"])
1151 CAddress addr(strAddr, fAllowDNS);
1153 OpenNetworkConnection(addr);
1154 for (int i = 0; i < 10 && i < nLoop; i++)
1164 // Connect to manually added nodes first
1165 if (mapArgs.count("-addnode"))
1167 foreach(string strAddr, mapMultiArgs["-addnode"])
1169 CAddress addr(strAddr, fAllowDNS);
1172 OpenNetworkConnection(addr);
1180 // Initiate network connections
1181 int64 nStart = GetTime();
1184 // Limit outbound connections
1185 vnThreadsRunning[1]--;
1190 CRITICAL_BLOCK(cs_vNodes)
1191 foreach(CNode* pnode, vNodes)
1192 if (!pnode->fInbound)
1194 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1195 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1196 if (nOutbound < nMaxOutboundConnections)
1202 vnThreadsRunning[1]++;
1206 CRITICAL_BLOCK(cs_mapAddresses)
1208 // Add seed nodes if IRC isn't working
1209 static bool fSeedUsed;
1210 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1211 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1213 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1215 // It'll only connect to one or two seed nodes because once it connects,
1216 // it'll get a pile of addresses with newer timestamps.
1218 addr.ip = pnSeed[i];
1225 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1227 // Disconnect seed nodes
1228 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1229 static int64 nSeedDisconnected;
1230 if (nSeedDisconnected == 0)
1232 nSeedDisconnected = GetTime();
1233 CRITICAL_BLOCK(cs_vNodes)
1234 foreach(CNode* pnode, vNodes)
1235 if (setSeed.count(pnode->addr.ip))
1236 pnode->fDisconnect = true;
1239 // Keep setting timestamps to 0 so they won't reconnect
1240 if (GetTime() - nSeedDisconnected < 60 * 60)
1242 foreach(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1244 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1246 item.second.nTime = 0;
1247 CAddrDB().WriteAddress(item.second);
1256 // Choose an address to connect to based on most recently seen
1258 CAddress addrConnect;
1259 int64 nBest = INT64_MIN;
1261 // Only connect to one address per a.b.?.? range.
1262 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1263 set<unsigned int> setConnected;
1264 CRITICAL_BLOCK(cs_vNodes)
1265 foreach(CNode* pnode, vNodes)
1266 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1268 CRITICAL_BLOCK(cs_mapAddresses)
1270 foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1272 const CAddress& addr = item.second;
1273 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1275 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1276 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1278 // Randomize the order in a deterministic way, putting the standard port first
1279 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1280 if (addr.port != htons(GetDefaultPort()))
1281 nRandomizer += 2 * 60 * 60;
1283 // Last seen Base retry frequency
1292 // 365 days 93 hours
1293 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1295 // Fast reconnect for one hour after last seen
1296 if (nSinceLastSeen < 60 * 60)
1299 // Limit retry frequency
1300 if (nSinceLastTry < nDelay)
1303 // If we have IRC, we'll be notified when they first come online,
1304 // and again every 24 hours by the refresh broadcast.
1305 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1308 // Only try the old stuff if we don't have enough connections
1309 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1312 // If multiple addresses are ready, prioritize by time since
1313 // last seen and time since last tried.
1314 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1323 if (addrConnect.IsValid())
1324 OpenNetworkConnection(addrConnect);
1328 bool OpenNetworkConnection(const CAddress& addrConnect)
1331 // Initiate outbound network connection
1335 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1338 vnThreadsRunning[1]--;
1339 CNode* pnode = ConnectNode(addrConnect);
1340 vnThreadsRunning[1]++;
1345 pnode->fNetworkNode = true;
1357 void ThreadMessageHandler(void* parg)
1359 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1362 vnThreadsRunning[2]++;
1363 ThreadMessageHandler2(parg);
1364 vnThreadsRunning[2]--;
1366 catch (std::exception& e) {
1367 vnThreadsRunning[2]--;
1368 PrintException(&e, "ThreadMessageHandler()");
1370 vnThreadsRunning[2]--;
1371 PrintException(NULL, "ThreadMessageHandler()");
1373 printf("ThreadMessageHandler exiting\n");
1376 void ThreadMessageHandler2(void* parg)
1378 printf("ThreadMessageHandler started\n");
1379 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1382 vector<CNode*> vNodesCopy;
1383 CRITICAL_BLOCK(cs_vNodes)
1385 vNodesCopy = vNodes;
1386 foreach(CNode* pnode, vNodesCopy)
1390 // Poll the connected nodes for messages
1391 CNode* pnodeTrickle = NULL;
1392 if (!vNodesCopy.empty())
1393 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1394 foreach(CNode* pnode, vNodesCopy)
1397 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1398 ProcessMessages(pnode);
1403 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1404 SendMessages(pnode, pnode == pnodeTrickle);
1409 CRITICAL_BLOCK(cs_vNodes)
1411 foreach(CNode* pnode, vNodesCopy)
1415 // Wait and allow messages to bunch up.
1416 // Reduce vnThreadsRunning so StopNode has permission to exit while
1417 // we're sleeping, but we must always check fShutdown after doing this.
1418 vnThreadsRunning[2]--;
1420 if (fRequestShutdown)
1422 vnThreadsRunning[2]++;
1436 bool BindListenPort(string& strError)
1440 addrLocalHost.port = htons(GetDefaultPort());
1443 // Initialize Windows Sockets
1445 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1446 if (ret != NO_ERROR)
1448 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1449 printf("%s\n", strError.c_str());
1454 // Create socket for listening for incoming connections
1455 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1456 if (hListenSocket == INVALID_SOCKET)
1458 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1459 printf("%s\n", strError.c_str());
1464 // Different way of disabling SIGPIPE on BSD
1465 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1469 // Allow binding if the port is still in TIME_WAIT state after
1470 // the program was closed and restarted. Not an issue on windows.
1471 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1475 // Set to nonblocking, incoming connections will also inherit this
1476 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1478 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1481 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1482 printf("%s\n", strError.c_str());
1486 // The sockaddr_in structure specifies the address family,
1487 // IP address, and port for the socket that is being bound
1488 struct sockaddr_in sockaddr;
1489 memset(&sockaddr, 0, sizeof(sockaddr));
1490 sockaddr.sin_family = AF_INET;
1491 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1492 sockaddr.sin_port = htons(GetDefaultPort());
1493 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1495 int nErr = WSAGetLastError();
1496 if (nErr == WSAEADDRINUSE)
1497 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1499 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1500 printf("%s\n", strError.c_str());
1503 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1505 // Listen for incoming connections
1506 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1508 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1509 printf("%s\n", strError.c_str());
1516 void StartNode(void* parg)
1518 if (pnodeLocalHost == NULL)
1519 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1522 // Get local host ip
1523 char pszHostName[1000] = "";
1524 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1526 vector<CAddress> vaddr;
1527 if (NameLookup(pszHostName, vaddr, nLocalServices))
1528 foreach (const CAddress &addr, vaddr)
1529 if (addr.GetByte(3) != 127)
1531 addrLocalHost = addr;
1536 // Get local host ip
1537 struct ifaddrs* myaddrs;
1538 if (getifaddrs(&myaddrs) == 0)
1540 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1542 if (ifa->ifa_addr == NULL) continue;
1543 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1544 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1545 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1547 if (ifa->ifa_addr->sa_family == AF_INET)
1549 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1550 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1551 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1553 // Take the first IP that isn't loopback 127.x.x.x
1554 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1555 if (addr.IsValid() && addr.GetByte(3) != 127)
1557 addrLocalHost = addr;
1561 else if (ifa->ifa_addr->sa_family == AF_INET6)
1563 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1564 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1565 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1568 freeifaddrs(myaddrs);
1571 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1573 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1575 // Proxies can't take incoming connections
1576 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1577 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1581 CreateThread(ThreadGetMyExternalIP, NULL);
1588 // Map ports with UPnP
1592 // Get addresses from IRC and advertise ours
1593 if (!CreateThread(ThreadIRCSeed, NULL))
1594 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1596 // Send and receive from sockets, accept connections
1597 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1599 // Initiate outbound connections
1600 if (!CreateThread(ThreadOpenConnections, NULL))
1601 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1604 if (!CreateThread(ThreadMessageHandler, NULL))
1605 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1607 // Generate coins in the background
1608 GenerateBitcoins(fGenerateBitcoins);
1613 printf("StopNode()\n");
1615 nTransactionsUpdated++;
1616 int64 nStart = GetTime();
1617 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1619 || vnThreadsRunning[5] > 0
1623 if (GetTime() - nStart > 20)
1627 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1628 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1629 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1630 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1631 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1632 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1633 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1649 foreach(CNode* pnode, vNodes)
1650 if (pnode->hSocket != INVALID_SOCKET)
1651 closesocket(pnode->hSocket);
1652 if (hListenSocket != INVALID_SOCKET)
1653 if (closesocket(hListenSocket) == SOCKET_ERROR)
1654 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1657 // Shutdown Windows Sockets
1662 instance_of_cnetcleanup;