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.
11 #include <miniupnpc/miniwget.h>
12 #include <miniupnpc/miniupnpc.h>
13 #include <miniupnpc/upnpcommands.h>
14 #include <miniupnpc/upnperrors.h>
18 using namespace boost;
20 static const int MAX_OUTBOUND_CONNECTIONS = 8;
22 void ThreadMessageHandler2(void* parg);
23 void ThreadSocketHandler2(void* parg);
24 void ThreadOpenConnections2(void* parg);
26 void ThreadMapPort2(void* parg);
28 bool OpenNetworkConnection(const CAddress& addrConnect);
35 // Global state variables
38 bool fAllowDNS = false;
39 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
40 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
41 CNode* pnodeLocalHost = NULL;
42 uint64 nLocalHostNonce = 0;
43 array<int, 10> vnThreadsRunning;
44 SOCKET hListenSocket = INVALID_SOCKET;
46 vector<CNode*> vNodes;
47 CCriticalSection cs_vNodes;
48 map<vector<unsigned char>, CAddress> mapAddresses;
49 CCriticalSection cs_mapAddresses;
50 map<CInv, CDataStream> mapRelay;
51 deque<pair<int64, CInv> > vRelayExpiration;
52 CCriticalSection cs_mapRelay;
53 map<CInv, int64> mapAlreadyAskedFor;
56 int fUseProxy = false;
57 CAddress addrProxy("127.0.0.1",9050);
63 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
65 // Filter out duplicate requests
66 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
68 pindexLastGetBlocksBegin = pindexBegin;
69 hashLastGetBlocksEnd = hashEnd;
71 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
78 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
80 hSocketRet = INVALID_SOCKET;
82 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
83 if (hSocket == INVALID_SOCKET)
87 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
90 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
91 bool fProxy = (fUseProxy && fRoutable);
92 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
94 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
102 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
103 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
104 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
105 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
106 char* pszSocks4 = pszSocks4IP;
107 int nSize = sizeof(pszSocks4IP);
109 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
112 closesocket(hSocket);
113 return error("Error sending to proxy");
116 if (recv(hSocket, pchRet, 8, 0) != 8)
118 closesocket(hSocket);
119 return error("Error reading proxy response");
121 if (pchRet[1] != 0x5a)
123 closesocket(hSocket);
124 if (pchRet[1] != 0x5b)
125 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
128 printf("proxy connected %s\n", addrConnect.ToString().c_str());
131 hSocketRet = hSocket;
135 // portDefault is in host order
136 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
141 int port = portDefault;
144 strlcpy(psz, pszName, sizeof(psz));
147 char* pszColon = strrchr(psz+1,':');
148 char *pszPortEnd = NULL;
149 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
150 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
152 if (psz[0] == '[' && pszColon[-1] == ']')
154 // Future: enable IPv6 colon-notation inside []
161 if (port < 0 || port > USHRT_MAX)
166 unsigned int addrIP = inet_addr(pszHost);
167 if (addrIP != INADDR_NONE)
169 // valid IP address passed
170 vaddr.push_back(CAddress(addrIP, port, nServices));
177 struct hostent* phostent = gethostbyname(pszHost);
181 if (phostent->h_addrtype != AF_INET)
184 char** ppAddr = phostent->h_addr_list;
185 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
187 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
189 vaddr.push_back(addr);
193 return (vaddr.size() > 0);
196 // portDefault is in host order
197 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
199 vector<CAddress> vaddr;
200 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
206 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
209 if (!ConnectSocket(addrConnect, hSocket))
210 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
212 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
215 while (RecvLine(hSocket, strLine))
217 if (strLine.empty()) // HTTP response is separated from headers by blank line
221 if (!RecvLine(hSocket, strLine))
223 closesocket(hSocket);
226 if (pszKeyword == NULL)
228 if (strLine.find(pszKeyword) != -1)
230 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
234 closesocket(hSocket);
235 if (strLine.find("<") != -1)
236 strLine = strLine.substr(0, strLine.find("<"));
237 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
238 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
239 strLine.resize(strLine.size()-1);
240 CAddress addr(strLine,0,true);
241 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
242 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
248 closesocket(hSocket);
249 return error("GetMyExternalIP() : connection closed");
252 // We now get our external IP from the IRC server first and only use this as a backup
253 bool GetMyExternalIP(unsigned int& ipRet)
255 CAddress addrConnect;
257 const char* pszKeyword;
262 for (int nLookup = 0; nLookup <= 1; nLookup++)
263 for (int nHost = 1; nHost <= 2; nHost++)
265 // We should be phasing out our use of sites like these. If we need
266 // replacements, we should ask for volunteers to put this simple
267 // php file on their webserver that prints the client IP:
268 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
271 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
275 CAddress addrIP("checkip.dyndns.org", 80, true);
276 if (addrIP.IsValid())
277 addrConnect = addrIP;
280 pszGet = "GET / HTTP/1.1\r\n"
281 "Host: checkip.dyndns.org\r\n"
282 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
283 "Connection: close\r\n"
286 pszKeyword = "Address:";
290 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
294 CAddress addrIP("www.showmyip.com", 80, true);
295 if (addrIP.IsValid())
296 addrConnect = addrIP;
299 pszGet = "GET /simple/ HTTP/1.1\r\n"
300 "Host: www.showmyip.com\r\n"
301 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
302 "Connection: close\r\n"
305 pszKeyword = NULL; // Returns just IP address
308 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
315 void ThreadGetMyExternalIP(void* parg)
317 // Wait for IRC to get it first
318 if (!GetBoolArg("-noirc"))
320 for (int i = 0; i < 2 * 60; i++)
323 if (fGotExternalIP || fShutdown)
328 // Fallback in case IRC fails to get it
329 if (GetMyExternalIP(addrLocalHost.ip))
331 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
332 if (addrLocalHost.IsRoutable())
334 // If we already connected to a few before we had our IP, go back and addr them.
335 // setAddrKnown automatically filters any duplicate sends.
336 CAddress addr(addrLocalHost);
337 addr.nTime = GetAdjustedTime();
338 CRITICAL_BLOCK(cs_vNodes)
339 BOOST_FOREACH(CNode* pnode, vNodes)
340 pnode->PushAddress(addr);
349 bool AddAddress(CAddress addr, int64 nTimePenalty)
351 if (!addr.IsRoutable())
353 if (addr.ip == addrLocalHost.ip)
355 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
356 CRITICAL_BLOCK(cs_mapAddresses)
358 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
359 if (it == mapAddresses.end())
362 printf("AddAddress(%s)\n", addr.ToString().c_str());
363 mapAddresses.insert(make_pair(addr.GetKey(), addr));
364 CAddrDB().WriteAddress(addr);
369 bool fUpdated = false;
370 CAddress& addrFound = (*it).second;
371 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
373 // Services have been added
374 addrFound.nServices |= addr.nServices;
377 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
378 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
379 if (addrFound.nTime < addr.nTime - nUpdateInterval)
381 // Periodically update most recently seen time
382 addrFound.nTime = addr.nTime;
386 CAddrDB().WriteAddress(addrFound);
392 void AddressCurrentlyConnected(const CAddress& addr)
394 CRITICAL_BLOCK(cs_mapAddresses)
396 // Only if it's been published already
397 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
398 if (it != mapAddresses.end())
400 CAddress& addrFound = (*it).second;
401 int64 nUpdateInterval = 20 * 60;
402 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
404 // Periodically update most recently seen time
405 addrFound.nTime = GetAdjustedTime();
407 addrdb.WriteAddress(addrFound);
417 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
419 // If the dialog might get closed before the reply comes back,
420 // call this in the destructor so it doesn't get called after it's deleted.
421 CRITICAL_BLOCK(cs_vNodes)
423 BOOST_FOREACH(CNode* pnode, vNodes)
425 CRITICAL_BLOCK(pnode->cs_mapRequests)
427 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
429 CRequestTracker& tracker = (*mi).second;
430 if (tracker.fn == fn && tracker.param1 == param1)
431 pnode->mapRequests.erase(mi++);
447 // Subscription methods for the broadcast and subscription system.
448 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
450 // The subscription system uses a meet-in-the-middle strategy.
451 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
452 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
455 bool AnySubscribed(unsigned int nChannel)
457 if (pnodeLocalHost->IsSubscribed(nChannel))
459 CRITICAL_BLOCK(cs_vNodes)
460 BOOST_FOREACH(CNode* pnode, vNodes)
461 if (pnode->IsSubscribed(nChannel))
466 bool CNode::IsSubscribed(unsigned int nChannel)
468 if (nChannel >= vfSubscribe.size())
470 return vfSubscribe[nChannel];
473 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
475 if (nChannel >= vfSubscribe.size())
478 if (!AnySubscribed(nChannel))
481 CRITICAL_BLOCK(cs_vNodes)
482 BOOST_FOREACH(CNode* pnode, vNodes)
484 pnode->PushMessage("subscribe", nChannel, nHops);
487 vfSubscribe[nChannel] = true;
490 void CNode::CancelSubscribe(unsigned int nChannel)
492 if (nChannel >= vfSubscribe.size())
495 // Prevent from relaying cancel if wasn't subscribed
496 if (!vfSubscribe[nChannel])
498 vfSubscribe[nChannel] = false;
500 if (!AnySubscribed(nChannel))
502 // Relay subscription cancel
503 CRITICAL_BLOCK(cs_vNodes)
504 BOOST_FOREACH(CNode* pnode, vNodes)
506 pnode->PushMessage("sub-cancel", nChannel);
518 CNode* FindNode(unsigned int ip)
520 CRITICAL_BLOCK(cs_vNodes)
522 BOOST_FOREACH(CNode* pnode, vNodes)
523 if (pnode->addr.ip == ip)
529 CNode* FindNode(CAddress addr)
531 CRITICAL_BLOCK(cs_vNodes)
533 BOOST_FOREACH(CNode* pnode, vNodes)
534 if (pnode->addr == addr)
540 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
542 if (addrConnect.ip == addrLocalHost.ip)
545 // Look for an existing connection
546 CNode* pnode = FindNode(addrConnect.ip);
550 pnode->AddRef(nTimeout);
557 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
558 addrConnect.ToString().c_str(),
559 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
560 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
562 CRITICAL_BLOCK(cs_mapAddresses)
563 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
567 if (ConnectSocket(addrConnect, hSocket))
570 printf("connected %s\n", addrConnect.ToString().c_str());
572 // Set to nonblocking
575 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
576 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
578 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
579 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
583 CNode* pnode = new CNode(hSocket, addrConnect, false);
585 pnode->AddRef(nTimeout);
588 CRITICAL_BLOCK(cs_vNodes)
589 vNodes.push_back(pnode);
591 pnode->nTimeConnected = GetTime();
600 void CNode::CloseSocketDisconnect()
603 if (hSocket != INVALID_SOCKET)
606 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
607 printf("disconnecting node %s\n", addr.ToString().c_str());
608 closesocket(hSocket);
609 hSocket = INVALID_SOCKET;
613 void CNode::Cleanup()
615 // All of a nodes broadcasts and subscriptions are automatically torn down
616 // when it goes down, so a node has to stay up to keep its broadcast going.
618 // Cancel subscriptions
619 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
620 if (vfSubscribe[nChannel])
621 CancelSubscribe(nChannel);
636 void ThreadSocketHandler(void* parg)
638 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
641 vnThreadsRunning[0]++;
642 ThreadSocketHandler2(parg);
643 vnThreadsRunning[0]--;
645 catch (std::exception& e) {
646 vnThreadsRunning[0]--;
647 PrintException(&e, "ThreadSocketHandler()");
649 vnThreadsRunning[0]--;
650 throw; // support pthread_cancel()
652 printf("ThreadSocketHandler exiting\n");
655 void ThreadSocketHandler2(void* parg)
657 printf("ThreadSocketHandler started\n");
658 list<CNode*> vNodesDisconnected;
659 int nPrevNodeCount = 0;
666 CRITICAL_BLOCK(cs_vNodes)
668 // Disconnect unused nodes
669 vector<CNode*> vNodesCopy = vNodes;
670 BOOST_FOREACH(CNode* pnode, vNodesCopy)
672 if (pnode->fDisconnect ||
673 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
675 // remove from vNodes
676 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
678 // close socket and cleanup
679 pnode->CloseSocketDisconnect();
682 // hold in disconnected pool until all refs are released
683 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
684 if (pnode->fNetworkNode || pnode->fInbound)
686 vNodesDisconnected.push_back(pnode);
690 // Delete disconnected nodes
691 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
692 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
694 // wait until threads are done using it
695 if (pnode->GetRefCount() <= 0)
697 bool fDelete = false;
698 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
699 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
700 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
701 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
705 vNodesDisconnected.remove(pnode);
711 if (vNodes.size() != nPrevNodeCount)
713 nPrevNodeCount = vNodes.size();
719 // Find which sockets have data to receive
721 struct timeval timeout;
723 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
730 FD_ZERO(&fdsetError);
731 SOCKET hSocketMax = 0;
733 if(hListenSocket != INVALID_SOCKET)
734 FD_SET(hListenSocket, &fdsetRecv);
735 hSocketMax = max(hSocketMax, hListenSocket);
736 CRITICAL_BLOCK(cs_vNodes)
738 BOOST_FOREACH(CNode* pnode, vNodes)
740 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
742 FD_SET(pnode->hSocket, &fdsetRecv);
743 FD_SET(pnode->hSocket, &fdsetError);
744 hSocketMax = max(hSocketMax, pnode->hSocket);
745 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
746 if (!pnode->vSend.empty())
747 FD_SET(pnode->hSocket, &fdsetSend);
751 vnThreadsRunning[0]--;
752 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
753 vnThreadsRunning[0]++;
756 if (nSelect == SOCKET_ERROR)
758 int nErr = WSAGetLastError();
759 printf("socket select error %d\n", nErr);
760 for (int i = 0; i <= hSocketMax; i++)
761 FD_SET(i, &fdsetRecv);
763 FD_ZERO(&fdsetError);
764 Sleep(timeout.tv_usec/1000);
769 // Accept new connections
771 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
773 struct sockaddr_in sockaddr;
774 socklen_t len = sizeof(sockaddr);
775 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
776 CAddress addr(sockaddr);
779 CRITICAL_BLOCK(cs_vNodes)
780 BOOST_FOREACH(CNode* pnode, vNodes)
783 if (hSocket == INVALID_SOCKET)
785 if (WSAGetLastError() != WSAEWOULDBLOCK)
786 printf("socket error accept failed: %d\n", WSAGetLastError());
788 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
790 closesocket(hSocket);
794 printf("accepted connection %s\n", addr.ToString().c_str());
795 CNode* pnode = new CNode(hSocket, addr, true);
797 CRITICAL_BLOCK(cs_vNodes)
798 vNodes.push_back(pnode);
804 // Service each socket
806 vector<CNode*> vNodesCopy;
807 CRITICAL_BLOCK(cs_vNodes)
810 BOOST_FOREACH(CNode* pnode, vNodesCopy)
813 BOOST_FOREACH(CNode* pnode, vNodesCopy)
821 if (pnode->hSocket == INVALID_SOCKET)
823 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
825 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
827 CDataStream& vRecv = pnode->vRecv;
828 unsigned int nPos = vRecv.size();
830 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
831 if (!pnode->fDisconnect)
832 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
833 pnode->CloseSocketDisconnect();
836 // typical socket buffer is 8K-64K
837 char pchBuf[0x10000];
838 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
841 vRecv.resize(nPos + nBytes);
842 memcpy(&vRecv[nPos], pchBuf, nBytes);
843 pnode->nLastRecv = GetTime();
845 else if (nBytes == 0)
847 // socket closed gracefully
848 if (!pnode->fDisconnect)
849 printf("socket closed\n");
850 pnode->CloseSocketDisconnect();
855 int nErr = WSAGetLastError();
856 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
858 if (!pnode->fDisconnect)
859 printf("socket recv error %d\n", nErr);
860 pnode->CloseSocketDisconnect();
870 if (pnode->hSocket == INVALID_SOCKET)
872 if (FD_ISSET(pnode->hSocket, &fdsetSend))
874 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
876 CDataStream& vSend = pnode->vSend;
879 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
882 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
883 pnode->nLastSend = GetTime();
888 int nErr = WSAGetLastError();
889 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
891 printf("socket send error %d\n", nErr);
892 pnode->CloseSocketDisconnect();
895 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
896 if (!pnode->fDisconnect)
897 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
898 pnode->CloseSocketDisconnect();
905 // Inactivity checking
907 if (pnode->vSend.empty())
908 pnode->nLastSendEmpty = GetTime();
909 if (GetTime() - pnode->nTimeConnected > 60)
911 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
913 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
914 pnode->fDisconnect = true;
916 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
918 printf("socket not sending\n");
919 pnode->fDisconnect = true;
921 else if (GetTime() - pnode->nLastRecv > 90*60)
923 printf("socket inactivity timeout\n");
924 pnode->fDisconnect = true;
928 CRITICAL_BLOCK(cs_vNodes)
930 BOOST_FOREACH(CNode* pnode, vNodesCopy)
947 void ThreadMapPort(void* parg)
949 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
952 vnThreadsRunning[5]++;
953 ThreadMapPort2(parg);
954 vnThreadsRunning[5]--;
956 catch (std::exception& e) {
957 vnThreadsRunning[5]--;
958 PrintException(&e, "ThreadMapPort()");
960 vnThreadsRunning[5]--;
961 PrintException(NULL, "ThreadMapPort()");
963 printf("ThreadMapPort exiting\n");
966 void ThreadMapPort2(void* parg)
968 printf("ThreadMapPort started\n");
971 sprintf(port, "%d", GetDefaultPort());
973 const char * rootdescurl = 0;
974 const char * multicastif = 0;
975 const char * minissdpdpath = 0;
976 struct UPNPDev * devlist = 0;
979 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
981 struct UPNPUrls urls;
982 struct IGDdatas data;
985 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
992 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
993 port, port, lanaddr, 0, "TCP", 0);
995 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
996 port, port, lanaddr, 0, "TCP", 0, "0");
998 if(r!=UPNPCOMMAND_SUCCESS)
999 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1000 port, port, lanaddr, r, strupnperror(r));
1002 printf("UPnP Port Mapping successful.\n");
1004 if (fShutdown || !fUseUPnP)
1006 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1007 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1008 freeUPNPDevlist(devlist); devlist = 0;
1009 FreeUPNPUrls(&urls);
1015 printf("No valid UPnP IGDs found\n");
1016 freeUPNPDevlist(devlist); devlist = 0;
1018 FreeUPNPUrls(&urls);
1020 if (fShutdown || !fUseUPnP)
1027 void MapPort(bool fMapPort)
1029 if (fUseUPnP != fMapPort)
1031 fUseUPnP = fMapPort;
1032 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1034 if (fUseUPnP && vnThreadsRunning[5] < 1)
1036 if (!CreateThread(ThreadMapPort, NULL))
1037 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1051 static const char *strDNSSeed[] = {
1053 "bitseed.bitcoin.org.uk",
1056 void DNSAddressSeed()
1060 printf("Loading addresses from DNS seeds (could take a while)\n");
1062 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1063 vector<CAddress> vaddr;
1064 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1066 BOOST_FOREACH (CAddress& addr, vaddr)
1068 if (addr.GetByte(3) != 127)
1078 printf("%d addresses found from DNS seeds\n", found);
1083 unsigned int pnSeed[] =
1085 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1086 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1087 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1088 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1089 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1090 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1091 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1092 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1093 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1094 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1095 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1096 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1097 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1098 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1099 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1100 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1101 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1102 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1103 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1104 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1105 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1106 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1107 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1108 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1109 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1110 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1111 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1112 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1113 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1114 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1115 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1116 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1117 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1118 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1119 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1120 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1121 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1122 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1123 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1124 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1129 void ThreadOpenConnections(void* parg)
1131 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1134 vnThreadsRunning[1]++;
1135 ThreadOpenConnections2(parg);
1136 vnThreadsRunning[1]--;
1138 catch (std::exception& e) {
1139 vnThreadsRunning[1]--;
1140 PrintException(&e, "ThreadOpenConnections()");
1142 vnThreadsRunning[1]--;
1143 PrintException(NULL, "ThreadOpenConnections()");
1145 printf("ThreadOpenConnections exiting\n");
1148 void ThreadOpenConnections2(void* parg)
1150 printf("ThreadOpenConnections started\n");
1152 // Connect to specific addresses
1153 if (mapArgs.count("-connect"))
1155 for (int64 nLoop = 0;; nLoop++)
1157 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1159 CAddress addr(strAddr, fAllowDNS);
1161 OpenNetworkConnection(addr);
1162 for (int i = 0; i < 10 && i < nLoop; i++)
1172 // Connect to manually added nodes first
1173 if (mapArgs.count("-addnode"))
1175 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1177 CAddress addr(strAddr, fAllowDNS);
1180 OpenNetworkConnection(addr);
1188 // Initiate network connections
1189 int64 nStart = GetTime();
1192 // Limit outbound connections
1193 vnThreadsRunning[1]--;
1198 CRITICAL_BLOCK(cs_vNodes)
1199 BOOST_FOREACH(CNode* pnode, vNodes)
1200 if (!pnode->fInbound)
1202 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1203 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1204 if (nOutbound < nMaxOutboundConnections)
1210 vnThreadsRunning[1]++;
1214 CRITICAL_BLOCK(cs_mapAddresses)
1216 // Add seed nodes if IRC isn't working
1217 static bool fSeedUsed;
1218 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1219 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1221 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1223 // It'll only connect to one or two seed nodes because once it connects,
1224 // it'll get a pile of addresses with newer timestamps.
1226 addr.ip = pnSeed[i];
1233 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1235 // Disconnect seed nodes
1236 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1237 static int64 nSeedDisconnected;
1238 if (nSeedDisconnected == 0)
1240 nSeedDisconnected = GetTime();
1241 CRITICAL_BLOCK(cs_vNodes)
1242 BOOST_FOREACH(CNode* pnode, vNodes)
1243 if (setSeed.count(pnode->addr.ip))
1244 pnode->fDisconnect = true;
1247 // Keep setting timestamps to 0 so they won't reconnect
1248 if (GetTime() - nSeedDisconnected < 60 * 60)
1250 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1252 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1254 item.second.nTime = 0;
1255 CAddrDB().WriteAddress(item.second);
1264 // Choose an address to connect to based on most recently seen
1266 CAddress addrConnect;
1267 int64 nBest = INT64_MIN;
1269 // Only connect to one address per a.b.?.? range.
1270 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1271 set<unsigned int> setConnected;
1272 CRITICAL_BLOCK(cs_vNodes)
1273 BOOST_FOREACH(CNode* pnode, vNodes)
1274 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1276 CRITICAL_BLOCK(cs_mapAddresses)
1278 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1280 const CAddress& addr = item.second;
1281 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1283 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1284 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1286 // Randomize the order in a deterministic way, putting the standard port first
1287 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1288 if (addr.port != htons(GetDefaultPort()))
1289 nRandomizer += 2 * 60 * 60;
1291 // Last seen Base retry frequency
1300 // 365 days 93 hours
1301 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1303 // Fast reconnect for one hour after last seen
1304 if (nSinceLastSeen < 60 * 60)
1307 // Limit retry frequency
1308 if (nSinceLastTry < nDelay)
1311 // If we have IRC, we'll be notified when they first come online,
1312 // and again every 24 hours by the refresh broadcast.
1313 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1316 // Only try the old stuff if we don't have enough connections
1317 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1320 // If multiple addresses are ready, prioritize by time since
1321 // last seen and time since last tried.
1322 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1331 if (addrConnect.IsValid())
1332 OpenNetworkConnection(addrConnect);
1336 bool OpenNetworkConnection(const CAddress& addrConnect)
1339 // Initiate outbound network connection
1343 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1346 vnThreadsRunning[1]--;
1347 CNode* pnode = ConnectNode(addrConnect);
1348 vnThreadsRunning[1]++;
1353 pnode->fNetworkNode = true;
1365 void ThreadMessageHandler(void* parg)
1367 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1370 vnThreadsRunning[2]++;
1371 ThreadMessageHandler2(parg);
1372 vnThreadsRunning[2]--;
1374 catch (std::exception& e) {
1375 vnThreadsRunning[2]--;
1376 PrintException(&e, "ThreadMessageHandler()");
1378 vnThreadsRunning[2]--;
1379 PrintException(NULL, "ThreadMessageHandler()");
1381 printf("ThreadMessageHandler exiting\n");
1384 void ThreadMessageHandler2(void* parg)
1386 printf("ThreadMessageHandler started\n");
1387 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1390 vector<CNode*> vNodesCopy;
1391 CRITICAL_BLOCK(cs_vNodes)
1393 vNodesCopy = vNodes;
1394 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1398 // Poll the connected nodes for messages
1399 CNode* pnodeTrickle = NULL;
1400 if (!vNodesCopy.empty())
1401 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1402 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1405 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1406 ProcessMessages(pnode);
1411 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1412 SendMessages(pnode, pnode == pnodeTrickle);
1417 CRITICAL_BLOCK(cs_vNodes)
1419 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1423 // Wait and allow messages to bunch up.
1424 // Reduce vnThreadsRunning so StopNode has permission to exit while
1425 // we're sleeping, but we must always check fShutdown after doing this.
1426 vnThreadsRunning[2]--;
1428 if (fRequestShutdown)
1430 vnThreadsRunning[2]++;
1444 bool BindListenPort(string& strError)
1448 addrLocalHost.port = htons(GetDefaultPort());
1451 // Initialize Windows Sockets
1453 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1454 if (ret != NO_ERROR)
1456 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1457 printf("%s\n", strError.c_str());
1462 // Create socket for listening for incoming connections
1463 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1464 if (hListenSocket == INVALID_SOCKET)
1466 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1467 printf("%s\n", strError.c_str());
1472 // Different way of disabling SIGPIPE on BSD
1473 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1477 // Allow binding if the port is still in TIME_WAIT state after
1478 // the program was closed and restarted. Not an issue on windows.
1479 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1483 // Set to nonblocking, incoming connections will also inherit this
1484 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1486 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1489 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1490 printf("%s\n", strError.c_str());
1494 // The sockaddr_in structure specifies the address family,
1495 // IP address, and port for the socket that is being bound
1496 struct sockaddr_in sockaddr;
1497 memset(&sockaddr, 0, sizeof(sockaddr));
1498 sockaddr.sin_family = AF_INET;
1499 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1500 sockaddr.sin_port = htons(GetDefaultPort());
1501 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1503 int nErr = WSAGetLastError();
1504 if (nErr == WSAEADDRINUSE)
1505 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1507 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1508 printf("%s\n", strError.c_str());
1511 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1513 // Listen for incoming connections
1514 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1516 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1517 printf("%s\n", strError.c_str());
1524 void StartNode(void* parg)
1526 if (pnodeLocalHost == NULL)
1527 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1530 // Get local host ip
1531 char pszHostName[1000] = "";
1532 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1534 vector<CAddress> vaddr;
1535 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1536 BOOST_FOREACH (const CAddress &addr, vaddr)
1537 if (addr.GetByte(3) != 127)
1539 addrLocalHost = addr;
1544 // Get local host ip
1545 struct ifaddrs* myaddrs;
1546 if (getifaddrs(&myaddrs) == 0)
1548 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1550 if (ifa->ifa_addr == NULL) continue;
1551 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1552 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1553 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1555 if (ifa->ifa_addr->sa_family == AF_INET)
1557 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1558 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1559 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1561 // Take the first IP that isn't loopback 127.x.x.x
1562 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1563 if (addr.IsValid() && addr.GetByte(3) != 127)
1565 addrLocalHost = addr;
1569 else if (ifa->ifa_addr->sa_family == AF_INET6)
1571 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1572 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1573 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1576 freeifaddrs(myaddrs);
1579 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1581 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1583 // Proxies can't take incoming connections
1584 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1585 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1589 CreateThread(ThreadGetMyExternalIP, NULL);
1596 // Map ports with UPnP
1600 // Get addresses from IRC and advertise ours
1601 if (!CreateThread(ThreadIRCSeed, NULL))
1602 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1604 // Send and receive from sockets, accept connections
1605 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1607 // Initiate outbound connections
1608 if (!CreateThread(ThreadOpenConnections, NULL))
1609 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1612 if (!CreateThread(ThreadMessageHandler, NULL))
1613 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1615 // Generate coins in the background
1616 GenerateBitcoins(fGenerateBitcoins);
1621 printf("StopNode()\n");
1623 nTransactionsUpdated++;
1624 int64 nStart = GetTime();
1625 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1627 || vnThreadsRunning[5] > 0
1631 if (GetTime() - nStart > 20)
1635 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1636 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1637 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1638 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1639 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1640 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1641 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1657 BOOST_FOREACH(CNode* pnode, vNodes)
1658 if (pnode->hSocket != INVALID_SOCKET)
1659 closesocket(pnode->hSocket);
1660 if (hListenSocket != INVALID_SOCKET)
1661 if (closesocket(hListenSocket) == SOCKET_ERROR)
1662 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1665 // Shutdown Windows Sockets
1670 instance_of_cnetcleanup;