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>
15 using namespace boost;
17 static const int MAX_OUTBOUND_CONNECTIONS = 8;
19 void ThreadMessageHandler2(void* parg);
20 void ThreadSocketHandler2(void* parg);
21 void ThreadOpenConnections2(void* parg);
23 void ThreadMapPort2(void* parg);
25 bool OpenNetworkConnection(const CAddress& addrConnect);
32 // Global state variables
35 bool fAllowDNS = false;
36 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
37 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
38 CNode* pnodeLocalHost = NULL;
39 uint64 nLocalHostNonce = 0;
40 array<int, 10> vnThreadsRunning;
41 SOCKET hListenSocket = INVALID_SOCKET;
43 vector<CNode*> vNodes;
44 CCriticalSection cs_vNodes;
45 map<vector<unsigned char>, CAddress> mapAddresses;
46 CCriticalSection cs_mapAddresses;
47 map<CInv, CDataStream> mapRelay;
48 deque<pair<int64, CInv> > vRelayExpiration;
49 CCriticalSection cs_mapRelay;
50 map<CInv, int64> mapAlreadyAskedFor;
53 int fUseProxy = false;
54 CAddress addrProxy("127.0.0.1",9050);
60 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
62 // Filter out duplicate requests
63 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
65 pindexLastGetBlocksBegin = pindexBegin;
66 hashLastGetBlocksEnd = hashEnd;
68 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
75 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
77 hSocketRet = INVALID_SOCKET;
79 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
80 if (hSocket == INVALID_SOCKET)
84 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
87 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
88 bool fProxy = (fUseProxy && fRoutable);
89 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
91 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
99 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
100 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
101 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
102 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
103 char* pszSocks4 = pszSocks4IP;
104 int nSize = sizeof(pszSocks4IP);
106 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
109 closesocket(hSocket);
110 return error("Error sending to proxy");
113 if (recv(hSocket, pchRet, 8, 0) != 8)
115 closesocket(hSocket);
116 return error("Error reading proxy response");
118 if (pchRet[1] != 0x5a)
120 closesocket(hSocket);
121 if (pchRet[1] != 0x5b)
122 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
125 printf("proxy connected %s\n", addrConnect.ToString().c_str());
128 hSocketRet = hSocket;
132 // portDefault is in host order
133 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
138 int port = portDefault;
141 strlcpy(psz, pszName, sizeof(psz));
144 char* pszColon = strrchr(psz+1,':');
145 char *pszPortEnd = NULL;
146 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
147 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
149 if (psz[0] == '[' && pszColon[-1] == ']')
151 // Future: enable IPv6 colon-notation inside []
158 if (port < 0 || port > USHRT_MAX)
163 unsigned int addrIP = inet_addr(pszHost);
164 if (addrIP != INADDR_NONE)
166 // valid IP address passed
167 vaddr.push_back(CAddress(addrIP, port, nServices));
174 struct hostent* phostent = gethostbyname(pszHost);
178 if (phostent->h_addrtype != AF_INET)
181 char** ppAddr = phostent->h_addr_list;
182 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
184 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
186 vaddr.push_back(addr);
190 return (vaddr.size() > 0);
193 // portDefault is in host order
194 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
196 vector<CAddress> vaddr;
197 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
203 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
206 if (!ConnectSocket(addrConnect, hSocket))
207 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
209 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
212 while (RecvLine(hSocket, strLine))
214 if (strLine.empty()) // HTTP response is separated from headers by blank line
218 if (!RecvLine(hSocket, strLine))
220 closesocket(hSocket);
223 if (pszKeyword == NULL)
225 if (strLine.find(pszKeyword) != -1)
227 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
231 closesocket(hSocket);
232 if (strLine.find("<") != -1)
233 strLine = strLine.substr(0, strLine.find("<"));
234 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
235 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
236 strLine.resize(strLine.size()-1);
237 CAddress addr(strLine,0,true);
238 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
239 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
245 closesocket(hSocket);
246 return error("GetMyExternalIP() : connection closed");
249 // We now get our external IP from the IRC server first and only use this as a backup
250 bool GetMyExternalIP(unsigned int& ipRet)
252 CAddress addrConnect;
254 const char* pszKeyword;
259 for (int nLookup = 0; nLookup <= 1; nLookup++)
260 for (int nHost = 1; nHost <= 2; nHost++)
262 // We should be phasing out our use of sites like these. If we need
263 // replacements, we should ask for volunteers to put this simple
264 // php file on their webserver that prints the client IP:
265 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
268 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
272 CAddress addrIP("checkip.dyndns.org", 80, true);
273 if (addrIP.IsValid())
274 addrConnect = addrIP;
277 pszGet = "GET / HTTP/1.1\r\n"
278 "Host: checkip.dyndns.org\r\n"
279 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
280 "Connection: close\r\n"
283 pszKeyword = "Address:";
287 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
291 CAddress addrIP("www.showmyip.com", 80, true);
292 if (addrIP.IsValid())
293 addrConnect = addrIP;
296 pszGet = "GET /simple/ HTTP/1.1\r\n"
297 "Host: www.showmyip.com\r\n"
298 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
299 "Connection: close\r\n"
302 pszKeyword = NULL; // Returns just IP address
305 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
312 void ThreadGetMyExternalIP(void* parg)
314 // Wait for IRC to get it first
315 if (!GetBoolArg("-noirc"))
317 for (int i = 0; i < 2 * 60; i++)
320 if (fGotExternalIP || fShutdown)
325 // Fallback in case IRC fails to get it
326 if (GetMyExternalIP(addrLocalHost.ip))
328 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
329 if (addrLocalHost.IsRoutable())
331 // If we already connected to a few before we had our IP, go back and addr them.
332 // setAddrKnown automatically filters any duplicate sends.
333 CAddress addr(addrLocalHost);
334 addr.nTime = GetAdjustedTime();
335 CRITICAL_BLOCK(cs_vNodes)
336 BOOST_FOREACH(CNode* pnode, vNodes)
337 pnode->PushAddress(addr);
346 bool AddAddress(CAddress addr, int64 nTimePenalty)
348 if (!addr.IsRoutable())
350 if (addr.ip == addrLocalHost.ip)
352 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
353 CRITICAL_BLOCK(cs_mapAddresses)
355 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
356 if (it == mapAddresses.end())
359 printf("AddAddress(%s)\n", addr.ToString().c_str());
360 mapAddresses.insert(make_pair(addr.GetKey(), addr));
361 CAddrDB().WriteAddress(addr);
366 bool fUpdated = false;
367 CAddress& addrFound = (*it).second;
368 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
370 // Services have been added
371 addrFound.nServices |= addr.nServices;
374 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
375 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
376 if (addrFound.nTime < addr.nTime - nUpdateInterval)
378 // Periodically update most recently seen time
379 addrFound.nTime = addr.nTime;
383 CAddrDB().WriteAddress(addrFound);
389 void AddressCurrentlyConnected(const CAddress& addr)
391 CRITICAL_BLOCK(cs_mapAddresses)
393 // Only if it's been published already
394 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
395 if (it != mapAddresses.end())
397 CAddress& addrFound = (*it).second;
398 int64 nUpdateInterval = 20 * 60;
399 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
401 // Periodically update most recently seen time
402 addrFound.nTime = GetAdjustedTime();
404 addrdb.WriteAddress(addrFound);
414 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
416 // If the dialog might get closed before the reply comes back,
417 // call this in the destructor so it doesn't get called after it's deleted.
418 CRITICAL_BLOCK(cs_vNodes)
420 BOOST_FOREACH(CNode* pnode, vNodes)
422 CRITICAL_BLOCK(pnode->cs_mapRequests)
424 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
426 CRequestTracker& tracker = (*mi).second;
427 if (tracker.fn == fn && tracker.param1 == param1)
428 pnode->mapRequests.erase(mi++);
444 // Subscription methods for the broadcast and subscription system.
445 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
447 // The subscription system uses a meet-in-the-middle strategy.
448 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
449 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
452 bool AnySubscribed(unsigned int nChannel)
454 if (pnodeLocalHost->IsSubscribed(nChannel))
456 CRITICAL_BLOCK(cs_vNodes)
457 BOOST_FOREACH(CNode* pnode, vNodes)
458 if (pnode->IsSubscribed(nChannel))
463 bool CNode::IsSubscribed(unsigned int nChannel)
465 if (nChannel >= vfSubscribe.size())
467 return vfSubscribe[nChannel];
470 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
472 if (nChannel >= vfSubscribe.size())
475 if (!AnySubscribed(nChannel))
478 CRITICAL_BLOCK(cs_vNodes)
479 BOOST_FOREACH(CNode* pnode, vNodes)
481 pnode->PushMessage("subscribe", nChannel, nHops);
484 vfSubscribe[nChannel] = true;
487 void CNode::CancelSubscribe(unsigned int nChannel)
489 if (nChannel >= vfSubscribe.size())
492 // Prevent from relaying cancel if wasn't subscribed
493 if (!vfSubscribe[nChannel])
495 vfSubscribe[nChannel] = false;
497 if (!AnySubscribed(nChannel))
499 // Relay subscription cancel
500 CRITICAL_BLOCK(cs_vNodes)
501 BOOST_FOREACH(CNode* pnode, vNodes)
503 pnode->PushMessage("sub-cancel", nChannel);
515 CNode* FindNode(unsigned int ip)
517 CRITICAL_BLOCK(cs_vNodes)
519 BOOST_FOREACH(CNode* pnode, vNodes)
520 if (pnode->addr.ip == ip)
526 CNode* FindNode(CAddress addr)
528 CRITICAL_BLOCK(cs_vNodes)
530 BOOST_FOREACH(CNode* pnode, vNodes)
531 if (pnode->addr == addr)
537 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
539 if (addrConnect.ip == addrLocalHost.ip)
542 // Look for an existing connection
543 CNode* pnode = FindNode(addrConnect.ip);
547 pnode->AddRef(nTimeout);
554 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
555 addrConnect.ToString().c_str(),
556 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
557 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
559 CRITICAL_BLOCK(cs_mapAddresses)
560 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
564 if (ConnectSocket(addrConnect, hSocket))
567 printf("connected %s\n", addrConnect.ToString().c_str());
569 // Set to nonblocking
572 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
573 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
575 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
576 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
580 CNode* pnode = new CNode(hSocket, addrConnect, false);
582 pnode->AddRef(nTimeout);
585 CRITICAL_BLOCK(cs_vNodes)
586 vNodes.push_back(pnode);
588 pnode->nTimeConnected = GetTime();
597 void CNode::CloseSocketDisconnect()
600 if (hSocket != INVALID_SOCKET)
603 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
604 printf("disconnecting node %s\n", addr.ToString().c_str());
605 closesocket(hSocket);
606 hSocket = INVALID_SOCKET;
610 void CNode::Cleanup()
612 // All of a nodes broadcasts and subscriptions are automatically torn down
613 // when it goes down, so a node has to stay up to keep its broadcast going.
615 // Cancel subscriptions
616 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
617 if (vfSubscribe[nChannel])
618 CancelSubscribe(nChannel);
633 void ThreadSocketHandler(void* parg)
635 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
638 vnThreadsRunning[0]++;
639 ThreadSocketHandler2(parg);
640 vnThreadsRunning[0]--;
642 catch (std::exception& e) {
643 vnThreadsRunning[0]--;
644 PrintException(&e, "ThreadSocketHandler()");
646 vnThreadsRunning[0]--;
647 throw; // support pthread_cancel()
649 printf("ThreadSocketHandler exiting\n");
652 void ThreadSocketHandler2(void* parg)
654 printf("ThreadSocketHandler started\n");
655 list<CNode*> vNodesDisconnected;
656 int nPrevNodeCount = 0;
663 CRITICAL_BLOCK(cs_vNodes)
665 // Disconnect unused nodes
666 vector<CNode*> vNodesCopy = vNodes;
667 BOOST_FOREACH(CNode* pnode, vNodesCopy)
669 if (pnode->fDisconnect ||
670 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
672 // remove from vNodes
673 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
675 // close socket and cleanup
676 pnode->CloseSocketDisconnect();
679 // hold in disconnected pool until all refs are released
680 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
681 if (pnode->fNetworkNode || pnode->fInbound)
683 vNodesDisconnected.push_back(pnode);
687 // Delete disconnected nodes
688 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
689 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
691 // wait until threads are done using it
692 if (pnode->GetRefCount() <= 0)
694 bool fDelete = false;
695 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
696 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
697 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
698 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
702 vNodesDisconnected.remove(pnode);
708 if (vNodes.size() != nPrevNodeCount)
710 nPrevNodeCount = vNodes.size();
716 // Find which sockets have data to receive
718 struct timeval timeout;
720 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
727 FD_ZERO(&fdsetError);
728 SOCKET hSocketMax = 0;
730 if(hListenSocket != INVALID_SOCKET)
731 FD_SET(hListenSocket, &fdsetRecv);
732 hSocketMax = max(hSocketMax, hListenSocket);
733 CRITICAL_BLOCK(cs_vNodes)
735 BOOST_FOREACH(CNode* pnode, vNodes)
737 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
739 FD_SET(pnode->hSocket, &fdsetRecv);
740 FD_SET(pnode->hSocket, &fdsetError);
741 hSocketMax = max(hSocketMax, pnode->hSocket);
742 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
743 if (!pnode->vSend.empty())
744 FD_SET(pnode->hSocket, &fdsetSend);
748 vnThreadsRunning[0]--;
749 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
750 vnThreadsRunning[0]++;
753 if (nSelect == SOCKET_ERROR)
755 int nErr = WSAGetLastError();
756 printf("socket select error %d\n", nErr);
757 for (int i = 0; i <= hSocketMax; i++)
758 FD_SET(i, &fdsetRecv);
760 FD_ZERO(&fdsetError);
761 Sleep(timeout.tv_usec/1000);
766 // Accept new connections
768 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
770 struct sockaddr_in sockaddr;
771 socklen_t len = sizeof(sockaddr);
772 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
773 CAddress addr(sockaddr);
776 CRITICAL_BLOCK(cs_vNodes)
777 BOOST_FOREACH(CNode* pnode, vNodes)
780 if (hSocket == INVALID_SOCKET)
782 if (WSAGetLastError() != WSAEWOULDBLOCK)
783 printf("socket error accept failed: %d\n", WSAGetLastError());
785 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
787 closesocket(hSocket);
791 printf("accepted connection %s\n", addr.ToString().c_str());
792 CNode* pnode = new CNode(hSocket, addr, true);
794 CRITICAL_BLOCK(cs_vNodes)
795 vNodes.push_back(pnode);
801 // Service each socket
803 vector<CNode*> vNodesCopy;
804 CRITICAL_BLOCK(cs_vNodes)
807 BOOST_FOREACH(CNode* pnode, vNodesCopy)
810 BOOST_FOREACH(CNode* pnode, vNodesCopy)
818 if (pnode->hSocket == INVALID_SOCKET)
820 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
822 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
824 CDataStream& vRecv = pnode->vRecv;
825 unsigned int nPos = vRecv.size();
827 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
828 if (!pnode->fDisconnect)
829 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
830 pnode->CloseSocketDisconnect();
833 // typical socket buffer is 8K-64K
834 char pchBuf[0x10000];
835 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
838 vRecv.resize(nPos + nBytes);
839 memcpy(&vRecv[nPos], pchBuf, nBytes);
840 pnode->nLastRecv = GetTime();
842 else if (nBytes == 0)
844 // socket closed gracefully
845 if (!pnode->fDisconnect)
846 printf("socket closed\n");
847 pnode->CloseSocketDisconnect();
852 int nErr = WSAGetLastError();
853 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
855 if (!pnode->fDisconnect)
856 printf("socket recv error %d\n", nErr);
857 pnode->CloseSocketDisconnect();
867 if (pnode->hSocket == INVALID_SOCKET)
869 if (FD_ISSET(pnode->hSocket, &fdsetSend))
871 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
873 CDataStream& vSend = pnode->vSend;
876 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
879 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
880 pnode->nLastSend = GetTime();
885 int nErr = WSAGetLastError();
886 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
888 printf("socket send error %d\n", nErr);
889 pnode->CloseSocketDisconnect();
892 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
893 if (!pnode->fDisconnect)
894 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
895 pnode->CloseSocketDisconnect();
902 // Inactivity checking
904 if (pnode->vSend.empty())
905 pnode->nLastSendEmpty = GetTime();
906 if (GetTime() - pnode->nTimeConnected > 60)
908 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
910 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
911 pnode->fDisconnect = true;
913 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
915 printf("socket not sending\n");
916 pnode->fDisconnect = true;
918 else if (GetTime() - pnode->nLastRecv > 90*60)
920 printf("socket inactivity timeout\n");
921 pnode->fDisconnect = true;
925 CRITICAL_BLOCK(cs_vNodes)
927 BOOST_FOREACH(CNode* pnode, vNodesCopy)
944 void ThreadMapPort(void* parg)
946 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
949 vnThreadsRunning[5]++;
950 ThreadMapPort2(parg);
951 vnThreadsRunning[5]--;
953 catch (std::exception& e) {
954 vnThreadsRunning[5]--;
955 PrintException(&e, "ThreadMapPort()");
957 vnThreadsRunning[5]--;
958 PrintException(NULL, "ThreadMapPort()");
960 printf("ThreadMapPort exiting\n");
963 void ThreadMapPort2(void* parg)
965 printf("ThreadMapPort started\n");
968 sprintf(port, "%d", GetDefaultPort());
970 const char * rootdescurl = 0;
971 const char * multicastif = 0;
972 const char * minissdpdpath = 0;
973 struct UPNPDev * devlist = 0;
976 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
978 struct UPNPUrls urls;
979 struct IGDdatas data;
982 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
989 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
990 port, port, lanaddr, 0, "TCP", 0);
992 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
993 port, port, lanaddr, 0, "TCP", 0, "0");
995 if(r!=UPNPCOMMAND_SUCCESS)
996 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
997 port, port, lanaddr, r, strupnperror(r));
999 printf("UPnP Port Mapping successful.\n");
1001 if (fShutdown || !fUseUPnP)
1003 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1004 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1005 freeUPNPDevlist(devlist); devlist = 0;
1006 FreeUPNPUrls(&urls);
1012 printf("No valid UPnP IGDs found\n");
1013 freeUPNPDevlist(devlist); devlist = 0;
1015 FreeUPNPUrls(&urls);
1017 if (fShutdown || !fUseUPnP)
1024 void MapPort(bool fMapPort)
1026 if (fUseUPnP != fMapPort)
1028 fUseUPnP = fMapPort;
1029 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1031 if (fUseUPnP && vnThreadsRunning[5] < 1)
1033 if (!CreateThread(ThreadMapPort, NULL))
1034 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1048 static const char *strDNSSeed[] = {
1050 "bitseed.bitcoin.org.uk",
1053 void DNSAddressSeed()
1057 printf("Loading addresses from DNS seeds (could take a while)\n");
1059 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1060 vector<CAddress> vaddr;
1061 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1063 BOOST_FOREACH (CAddress& addr, vaddr)
1065 if (addr.GetByte(3) != 127)
1075 printf("%d addresses found from DNS seeds\n", found);
1080 unsigned int pnSeed[] =
1082 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1083 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1084 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1085 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1086 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1087 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1088 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1089 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1090 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1091 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1092 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1093 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1094 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1095 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1096 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1097 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1098 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1099 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1100 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1101 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1102 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1103 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1104 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1105 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1106 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1107 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1108 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1109 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1110 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1111 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1112 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1113 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1114 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1115 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1116 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1117 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1118 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1119 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1120 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1121 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1126 void ThreadOpenConnections(void* parg)
1128 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1131 vnThreadsRunning[1]++;
1132 ThreadOpenConnections2(parg);
1133 vnThreadsRunning[1]--;
1135 catch (std::exception& e) {
1136 vnThreadsRunning[1]--;
1137 PrintException(&e, "ThreadOpenConnections()");
1139 vnThreadsRunning[1]--;
1140 PrintException(NULL, "ThreadOpenConnections()");
1142 printf("ThreadOpenConnections exiting\n");
1145 void ThreadOpenConnections2(void* parg)
1147 printf("ThreadOpenConnections started\n");
1149 // Connect to specific addresses
1150 if (mapArgs.count("-connect"))
1152 for (int64 nLoop = 0;; nLoop++)
1154 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1156 CAddress addr(strAddr, fAllowDNS);
1158 OpenNetworkConnection(addr);
1159 for (int i = 0; i < 10 && i < nLoop; i++)
1169 // Connect to manually added nodes first
1170 if (mapArgs.count("-addnode"))
1172 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1174 CAddress addr(strAddr, fAllowDNS);
1177 OpenNetworkConnection(addr);
1185 // Initiate network connections
1186 int64 nStart = GetTime();
1189 // Limit outbound connections
1190 vnThreadsRunning[1]--;
1195 CRITICAL_BLOCK(cs_vNodes)
1196 BOOST_FOREACH(CNode* pnode, vNodes)
1197 if (!pnode->fInbound)
1199 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1200 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1201 if (nOutbound < nMaxOutboundConnections)
1207 vnThreadsRunning[1]++;
1211 CRITICAL_BLOCK(cs_mapAddresses)
1213 // Add seed nodes if IRC isn't working
1214 static bool fSeedUsed;
1215 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1216 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1218 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1220 // It'll only connect to one or two seed nodes because once it connects,
1221 // it'll get a pile of addresses with newer timestamps.
1223 addr.ip = pnSeed[i];
1230 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1232 // Disconnect seed nodes
1233 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1234 static int64 nSeedDisconnected;
1235 if (nSeedDisconnected == 0)
1237 nSeedDisconnected = GetTime();
1238 CRITICAL_BLOCK(cs_vNodes)
1239 BOOST_FOREACH(CNode* pnode, vNodes)
1240 if (setSeed.count(pnode->addr.ip))
1241 pnode->fDisconnect = true;
1244 // Keep setting timestamps to 0 so they won't reconnect
1245 if (GetTime() - nSeedDisconnected < 60 * 60)
1247 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1249 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1251 item.second.nTime = 0;
1252 CAddrDB().WriteAddress(item.second);
1261 // Choose an address to connect to based on most recently seen
1263 CAddress addrConnect;
1264 int64 nBest = INT64_MIN;
1266 // Only connect to one address per a.b.?.? range.
1267 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1268 set<unsigned int> setConnected;
1269 CRITICAL_BLOCK(cs_vNodes)
1270 BOOST_FOREACH(CNode* pnode, vNodes)
1271 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1273 CRITICAL_BLOCK(cs_mapAddresses)
1275 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1277 const CAddress& addr = item.second;
1278 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1280 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1281 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1283 // Randomize the order in a deterministic way, putting the standard port first
1284 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1285 if (addr.port != htons(GetDefaultPort()))
1286 nRandomizer += 2 * 60 * 60;
1288 // Last seen Base retry frequency
1297 // 365 days 93 hours
1298 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1300 // Fast reconnect for one hour after last seen
1301 if (nSinceLastSeen < 60 * 60)
1304 // Limit retry frequency
1305 if (nSinceLastTry < nDelay)
1308 // If we have IRC, we'll be notified when they first come online,
1309 // and again every 24 hours by the refresh broadcast.
1310 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1313 // Only try the old stuff if we don't have enough connections
1314 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1317 // If multiple addresses are ready, prioritize by time since
1318 // last seen and time since last tried.
1319 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1328 if (addrConnect.IsValid())
1329 OpenNetworkConnection(addrConnect);
1333 bool OpenNetworkConnection(const CAddress& addrConnect)
1336 // Initiate outbound network connection
1340 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1343 vnThreadsRunning[1]--;
1344 CNode* pnode = ConnectNode(addrConnect);
1345 vnThreadsRunning[1]++;
1350 pnode->fNetworkNode = true;
1362 void ThreadMessageHandler(void* parg)
1364 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1367 vnThreadsRunning[2]++;
1368 ThreadMessageHandler2(parg);
1369 vnThreadsRunning[2]--;
1371 catch (std::exception& e) {
1372 vnThreadsRunning[2]--;
1373 PrintException(&e, "ThreadMessageHandler()");
1375 vnThreadsRunning[2]--;
1376 PrintException(NULL, "ThreadMessageHandler()");
1378 printf("ThreadMessageHandler exiting\n");
1381 void ThreadMessageHandler2(void* parg)
1383 printf("ThreadMessageHandler started\n");
1384 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1387 vector<CNode*> vNodesCopy;
1388 CRITICAL_BLOCK(cs_vNodes)
1390 vNodesCopy = vNodes;
1391 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1395 // Poll the connected nodes for messages
1396 CNode* pnodeTrickle = NULL;
1397 if (!vNodesCopy.empty())
1398 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1399 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1402 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1403 ProcessMessages(pnode);
1408 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1409 SendMessages(pnode, pnode == pnodeTrickle);
1414 CRITICAL_BLOCK(cs_vNodes)
1416 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1420 // Wait and allow messages to bunch up.
1421 // Reduce vnThreadsRunning so StopNode has permission to exit while
1422 // we're sleeping, but we must always check fShutdown after doing this.
1423 vnThreadsRunning[2]--;
1425 if (fRequestShutdown)
1427 vnThreadsRunning[2]++;
1441 bool BindListenPort(string& strError)
1445 addrLocalHost.port = htons(GetDefaultPort());
1448 // Initialize Windows Sockets
1450 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1451 if (ret != NO_ERROR)
1453 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1454 printf("%s\n", strError.c_str());
1459 // Create socket for listening for incoming connections
1460 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1461 if (hListenSocket == INVALID_SOCKET)
1463 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1464 printf("%s\n", strError.c_str());
1469 // Different way of disabling SIGPIPE on BSD
1470 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1474 // Allow binding if the port is still in TIME_WAIT state after
1475 // the program was closed and restarted. Not an issue on windows.
1476 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1480 // Set to nonblocking, incoming connections will also inherit this
1481 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1483 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1486 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1487 printf("%s\n", strError.c_str());
1491 // The sockaddr_in structure specifies the address family,
1492 // IP address, and port for the socket that is being bound
1493 struct sockaddr_in sockaddr;
1494 memset(&sockaddr, 0, sizeof(sockaddr));
1495 sockaddr.sin_family = AF_INET;
1496 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1497 sockaddr.sin_port = htons(GetDefaultPort());
1498 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1500 int nErr = WSAGetLastError();
1501 if (nErr == WSAEADDRINUSE)
1502 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1504 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1505 printf("%s\n", strError.c_str());
1508 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1510 // Listen for incoming connections
1511 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1513 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1514 printf("%s\n", strError.c_str());
1521 void StartNode(void* parg)
1523 if (pnodeLocalHost == NULL)
1524 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1527 // Get local host ip
1528 char pszHostName[1000] = "";
1529 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1531 vector<CAddress> vaddr;
1532 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1533 BOOST_FOREACH (const CAddress &addr, vaddr)
1534 if (addr.GetByte(3) != 127)
1536 addrLocalHost = addr;
1541 // Get local host ip
1542 struct ifaddrs* myaddrs;
1543 if (getifaddrs(&myaddrs) == 0)
1545 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1547 if (ifa->ifa_addr == NULL) continue;
1548 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1549 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1550 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1552 if (ifa->ifa_addr->sa_family == AF_INET)
1554 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1555 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1556 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1558 // Take the first IP that isn't loopback 127.x.x.x
1559 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1560 if (addr.IsValid() && addr.GetByte(3) != 127)
1562 addrLocalHost = addr;
1566 else if (ifa->ifa_addr->sa_family == AF_INET6)
1568 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1569 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1570 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1573 freeifaddrs(myaddrs);
1576 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1578 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1580 // Proxies can't take incoming connections
1581 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1582 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1586 CreateThread(ThreadGetMyExternalIP, NULL);
1593 // Map ports with UPnP
1597 // Get addresses from IRC and advertise ours
1598 if (!CreateThread(ThreadIRCSeed, NULL))
1599 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1601 // Send and receive from sockets, accept connections
1602 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1604 // Initiate outbound connections
1605 if (!CreateThread(ThreadOpenConnections, NULL))
1606 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1609 if (!CreateThread(ThreadMessageHandler, NULL))
1610 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1612 // Generate coins in the background
1613 GenerateBitcoins(fGenerateBitcoins);
1618 printf("StopNode()\n");
1620 nTransactionsUpdated++;
1621 int64 nStart = GetTime();
1622 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1624 || vnThreadsRunning[5] > 0
1628 if (GetTime() - nStart > 20)
1632 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1633 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1634 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1635 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1636 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1637 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1638 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1654 BOOST_FOREACH(CNode* pnode, vNodes)
1655 if (pnode->hSocket != INVALID_SOCKET)
1656 closesocket(pnode->hSocket);
1657 if (hListenSocket != INVALID_SOCKET)
1658 if (closesocket(hListenSocket) == SOCKET_ERROR)
1659 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1662 // Shutdown Windows Sockets
1667 instance_of_cnetcleanup;