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.
13 #include <miniupnpc/miniwget.h>
14 #include <miniupnpc/miniupnpc.h>
15 #include <miniupnpc/upnpcommands.h>
16 #include <miniupnpc/upnperrors.h>
20 using namespace boost;
22 static const int MAX_OUTBOUND_CONNECTIONS = 8;
24 void ThreadMessageHandler2(void* parg);
25 void ThreadSocketHandler2(void* parg);
26 void ThreadOpenConnections2(void* parg);
28 void ThreadMapPort2(void* parg);
30 bool OpenNetworkConnection(const CAddress& addrConnect);
37 // Global state variables
40 bool fAllowDNS = false;
41 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
42 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
43 CNode* pnodeLocalHost = NULL;
44 uint64 nLocalHostNonce = 0;
45 array<int, 10> vnThreadsRunning;
46 SOCKET hListenSocket = INVALID_SOCKET;
48 vector<CNode*> vNodes;
49 CCriticalSection cs_vNodes;
50 map<vector<unsigned char>, CAddress> mapAddresses;
51 CCriticalSection cs_mapAddresses;
52 map<CInv, CDataStream> mapRelay;
53 deque<pair<int64, CInv> > vRelayExpiration;
54 CCriticalSection cs_mapRelay;
55 map<CInv, int64> mapAlreadyAskedFor;
58 int fUseProxy = false;
59 CAddress addrProxy("127.0.0.1",9050);
65 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
67 // Filter out duplicate requests
68 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
70 pindexLastGetBlocksBegin = pindexBegin;
71 hashLastGetBlocksEnd = hashEnd;
73 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
80 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
82 hSocketRet = INVALID_SOCKET;
84 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
85 if (hSocket == INVALID_SOCKET)
89 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
92 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
93 bool fProxy = (fUseProxy && fRoutable);
94 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
96 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
104 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
105 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
106 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
107 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
108 char* pszSocks4 = pszSocks4IP;
109 int nSize = sizeof(pszSocks4IP);
111 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
114 closesocket(hSocket);
115 return error("Error sending to proxy");
118 if (recv(hSocket, pchRet, 8, 0) != 8)
120 closesocket(hSocket);
121 return error("Error reading proxy response");
123 if (pchRet[1] != 0x5a)
125 closesocket(hSocket);
126 if (pchRet[1] != 0x5b)
127 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
130 printf("proxy connected %s\n", addrConnect.ToString().c_str());
133 hSocketRet = hSocket;
137 // portDefault is in host order
138 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
143 int port = portDefault;
146 strlcpy(psz, pszName, sizeof(psz));
149 char* pszColon = strrchr(psz+1,':');
150 char *pszPortEnd = NULL;
151 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
152 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
154 if (psz[0] == '[' && pszColon[-1] == ']')
156 // Future: enable IPv6 colon-notation inside []
163 if (port < 0 || port > USHRT_MAX)
168 unsigned int addrIP = inet_addr(pszHost);
169 if (addrIP != INADDR_NONE)
171 // valid IP address passed
172 vaddr.push_back(CAddress(addrIP, port, nServices));
179 struct hostent* phostent = gethostbyname(pszHost);
183 if (phostent->h_addrtype != AF_INET)
186 char** ppAddr = phostent->h_addr_list;
187 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
189 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
191 vaddr.push_back(addr);
195 return (vaddr.size() > 0);
198 // portDefault is in host order
199 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
201 vector<CAddress> vaddr;
202 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
208 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
211 if (!ConnectSocket(addrConnect, hSocket))
212 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
214 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
217 while (RecvLine(hSocket, strLine))
219 if (strLine.empty()) // HTTP response is separated from headers by blank line
223 if (!RecvLine(hSocket, strLine))
225 closesocket(hSocket);
228 if (pszKeyword == NULL)
230 if (strLine.find(pszKeyword) != -1)
232 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
236 closesocket(hSocket);
237 if (strLine.find("<") != -1)
238 strLine = strLine.substr(0, strLine.find("<"));
239 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
240 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
241 strLine.resize(strLine.size()-1);
242 CAddress addr(strLine,0,true);
243 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
244 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
250 closesocket(hSocket);
251 return error("GetMyExternalIP() : connection closed");
254 // We now get our external IP from the IRC server first and only use this as a backup
255 bool GetMyExternalIP(unsigned int& ipRet)
257 CAddress addrConnect;
259 const char* pszKeyword;
264 for (int nLookup = 0; nLookup <= 1; nLookup++)
265 for (int nHost = 1; nHost <= 2; nHost++)
267 // We should be phasing out our use of sites like these. If we need
268 // replacements, we should ask for volunteers to put this simple
269 // php file on their webserver that prints the client IP:
270 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
273 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
277 CAddress addrIP("checkip.dyndns.org", 80, true);
278 if (addrIP.IsValid())
279 addrConnect = addrIP;
282 pszGet = "GET / HTTP/1.1\r\n"
283 "Host: checkip.dyndns.org\r\n"
284 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
285 "Connection: close\r\n"
288 pszKeyword = "Address:";
292 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
296 CAddress addrIP("www.showmyip.com", 80, true);
297 if (addrIP.IsValid())
298 addrConnect = addrIP;
301 pszGet = "GET /simple/ HTTP/1.1\r\n"
302 "Host: www.showmyip.com\r\n"
303 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
304 "Connection: close\r\n"
307 pszKeyword = NULL; // Returns just IP address
310 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
317 void ThreadGetMyExternalIP(void* parg)
319 // Wait for IRC to get it first
320 if (!GetBoolArg("-noirc"))
322 for (int i = 0; i < 2 * 60; i++)
325 if (fGotExternalIP || fShutdown)
330 // Fallback in case IRC fails to get it
331 if (GetMyExternalIP(addrLocalHost.ip))
333 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
334 if (addrLocalHost.IsRoutable())
336 // If we already connected to a few before we had our IP, go back and addr them.
337 // setAddrKnown automatically filters any duplicate sends.
338 CAddress addr(addrLocalHost);
339 addr.nTime = GetAdjustedTime();
340 CRITICAL_BLOCK(cs_vNodes)
341 BOOST_FOREACH(CNode* pnode, vNodes)
342 pnode->PushAddress(addr);
351 bool AddAddress(CAddress addr, int64 nTimePenalty)
353 if (!addr.IsRoutable())
355 if (addr.ip == addrLocalHost.ip)
357 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
358 CRITICAL_BLOCK(cs_mapAddresses)
360 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
361 if (it == mapAddresses.end())
364 printf("AddAddress(%s)\n", addr.ToString().c_str());
365 mapAddresses.insert(make_pair(addr.GetKey(), addr));
366 CAddrDB().WriteAddress(addr);
371 bool fUpdated = false;
372 CAddress& addrFound = (*it).second;
373 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
375 // Services have been added
376 addrFound.nServices |= addr.nServices;
379 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
380 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
381 if (addrFound.nTime < addr.nTime - nUpdateInterval)
383 // Periodically update most recently seen time
384 addrFound.nTime = addr.nTime;
388 CAddrDB().WriteAddress(addrFound);
394 void AddressCurrentlyConnected(const CAddress& addr)
396 CRITICAL_BLOCK(cs_mapAddresses)
398 // Only if it's been published already
399 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
400 if (it != mapAddresses.end())
402 CAddress& addrFound = (*it).second;
403 int64 nUpdateInterval = 20 * 60;
404 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
406 // Periodically update most recently seen time
407 addrFound.nTime = GetAdjustedTime();
409 addrdb.WriteAddress(addrFound);
419 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
421 // If the dialog might get closed before the reply comes back,
422 // call this in the destructor so it doesn't get called after it's deleted.
423 CRITICAL_BLOCK(cs_vNodes)
425 BOOST_FOREACH(CNode* pnode, vNodes)
427 CRITICAL_BLOCK(pnode->cs_mapRequests)
429 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
431 CRequestTracker& tracker = (*mi).second;
432 if (tracker.fn == fn && tracker.param1 == param1)
433 pnode->mapRequests.erase(mi++);
449 // Subscription methods for the broadcast and subscription system.
450 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
452 // The subscription system uses a meet-in-the-middle strategy.
453 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
454 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
457 bool AnySubscribed(unsigned int nChannel)
459 if (pnodeLocalHost->IsSubscribed(nChannel))
461 CRITICAL_BLOCK(cs_vNodes)
462 BOOST_FOREACH(CNode* pnode, vNodes)
463 if (pnode->IsSubscribed(nChannel))
468 bool CNode::IsSubscribed(unsigned int nChannel)
470 if (nChannel >= vfSubscribe.size())
472 return vfSubscribe[nChannel];
475 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
477 if (nChannel >= vfSubscribe.size())
480 if (!AnySubscribed(nChannel))
483 CRITICAL_BLOCK(cs_vNodes)
484 BOOST_FOREACH(CNode* pnode, vNodes)
486 pnode->PushMessage("subscribe", nChannel, nHops);
489 vfSubscribe[nChannel] = true;
492 void CNode::CancelSubscribe(unsigned int nChannel)
494 if (nChannel >= vfSubscribe.size())
497 // Prevent from relaying cancel if wasn't subscribed
498 if (!vfSubscribe[nChannel])
500 vfSubscribe[nChannel] = false;
502 if (!AnySubscribed(nChannel))
504 // Relay subscription cancel
505 CRITICAL_BLOCK(cs_vNodes)
506 BOOST_FOREACH(CNode* pnode, vNodes)
508 pnode->PushMessage("sub-cancel", nChannel);
520 CNode* FindNode(unsigned int ip)
522 CRITICAL_BLOCK(cs_vNodes)
524 BOOST_FOREACH(CNode* pnode, vNodes)
525 if (pnode->addr.ip == ip)
531 CNode* FindNode(CAddress addr)
533 CRITICAL_BLOCK(cs_vNodes)
535 BOOST_FOREACH(CNode* pnode, vNodes)
536 if (pnode->addr == addr)
542 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
544 if (addrConnect.ip == addrLocalHost.ip)
547 // Look for an existing connection
548 CNode* pnode = FindNode(addrConnect.ip);
552 pnode->AddRef(nTimeout);
559 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
560 addrConnect.ToString().c_str(),
561 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
562 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
564 CRITICAL_BLOCK(cs_mapAddresses)
565 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
569 if (ConnectSocket(addrConnect, hSocket))
572 printf("connected %s\n", addrConnect.ToString().c_str());
574 // Set to nonblocking
577 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
578 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
580 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
581 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
585 CNode* pnode = new CNode(hSocket, addrConnect, false);
587 pnode->AddRef(nTimeout);
590 CRITICAL_BLOCK(cs_vNodes)
591 vNodes.push_back(pnode);
593 pnode->nTimeConnected = GetTime();
602 void CNode::CloseSocketDisconnect()
605 if (hSocket != INVALID_SOCKET)
608 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
609 printf("disconnecting node %s\n", addr.ToString().c_str());
610 closesocket(hSocket);
611 hSocket = INVALID_SOCKET;
615 void CNode::Cleanup()
617 // All of a nodes broadcasts and subscriptions are automatically torn down
618 // when it goes down, so a node has to stay up to keep its broadcast going.
620 // Cancel subscriptions
621 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
622 if (vfSubscribe[nChannel])
623 CancelSubscribe(nChannel);
638 void ThreadSocketHandler(void* parg)
640 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
643 vnThreadsRunning[0]++;
644 ThreadSocketHandler2(parg);
645 vnThreadsRunning[0]--;
647 catch (std::exception& e) {
648 vnThreadsRunning[0]--;
649 PrintException(&e, "ThreadSocketHandler()");
651 vnThreadsRunning[0]--;
652 throw; // support pthread_cancel()
654 printf("ThreadSocketHandler exiting\n");
657 void ThreadSocketHandler2(void* parg)
659 printf("ThreadSocketHandler started\n");
660 list<CNode*> vNodesDisconnected;
661 int nPrevNodeCount = 0;
668 CRITICAL_BLOCK(cs_vNodes)
670 // Disconnect unused nodes
671 vector<CNode*> vNodesCopy = vNodes;
672 BOOST_FOREACH(CNode* pnode, vNodesCopy)
674 if (pnode->fDisconnect ||
675 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
677 // remove from vNodes
678 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
680 // close socket and cleanup
681 pnode->CloseSocketDisconnect();
684 // hold in disconnected pool until all refs are released
685 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
686 if (pnode->fNetworkNode || pnode->fInbound)
688 vNodesDisconnected.push_back(pnode);
692 // Delete disconnected nodes
693 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
694 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
696 // wait until threads are done using it
697 if (pnode->GetRefCount() <= 0)
699 bool fDelete = false;
700 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
701 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
702 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
703 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
707 vNodesDisconnected.remove(pnode);
713 if (vNodes.size() != nPrevNodeCount)
715 nPrevNodeCount = vNodes.size();
721 // Find which sockets have data to receive
723 struct timeval timeout;
725 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
732 FD_ZERO(&fdsetError);
733 SOCKET hSocketMax = 0;
735 if(hListenSocket != INVALID_SOCKET)
736 FD_SET(hListenSocket, &fdsetRecv);
737 hSocketMax = max(hSocketMax, hListenSocket);
738 CRITICAL_BLOCK(cs_vNodes)
740 BOOST_FOREACH(CNode* pnode, vNodes)
742 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
744 FD_SET(pnode->hSocket, &fdsetRecv);
745 FD_SET(pnode->hSocket, &fdsetError);
746 hSocketMax = max(hSocketMax, pnode->hSocket);
747 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
748 if (!pnode->vSend.empty())
749 FD_SET(pnode->hSocket, &fdsetSend);
753 vnThreadsRunning[0]--;
754 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
755 vnThreadsRunning[0]++;
758 if (nSelect == SOCKET_ERROR)
760 int nErr = WSAGetLastError();
761 printf("socket select error %d\n", nErr);
762 for (int i = 0; i <= hSocketMax; i++)
763 FD_SET(i, &fdsetRecv);
765 FD_ZERO(&fdsetError);
766 Sleep(timeout.tv_usec/1000);
771 // Accept new connections
773 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
775 struct sockaddr_in sockaddr;
776 socklen_t len = sizeof(sockaddr);
777 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
778 CAddress addr(sockaddr);
781 CRITICAL_BLOCK(cs_vNodes)
782 BOOST_FOREACH(CNode* pnode, vNodes)
785 if (hSocket == INVALID_SOCKET)
787 if (WSAGetLastError() != WSAEWOULDBLOCK)
788 printf("socket error accept failed: %d\n", WSAGetLastError());
790 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
792 closesocket(hSocket);
796 printf("accepted connection %s\n", addr.ToString().c_str());
797 CNode* pnode = new CNode(hSocket, addr, true);
799 CRITICAL_BLOCK(cs_vNodes)
800 vNodes.push_back(pnode);
806 // Service each socket
808 vector<CNode*> vNodesCopy;
809 CRITICAL_BLOCK(cs_vNodes)
812 BOOST_FOREACH(CNode* pnode, vNodesCopy)
815 BOOST_FOREACH(CNode* pnode, vNodesCopy)
823 if (pnode->hSocket == INVALID_SOCKET)
825 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
827 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
829 CDataStream& vRecv = pnode->vRecv;
830 unsigned int nPos = vRecv.size();
832 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
833 if (!pnode->fDisconnect)
834 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
835 pnode->CloseSocketDisconnect();
838 // typical socket buffer is 8K-64K
839 char pchBuf[0x10000];
840 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
843 vRecv.resize(nPos + nBytes);
844 memcpy(&vRecv[nPos], pchBuf, nBytes);
845 pnode->nLastRecv = GetTime();
847 else if (nBytes == 0)
849 // socket closed gracefully
850 if (!pnode->fDisconnect)
851 printf("socket closed\n");
852 pnode->CloseSocketDisconnect();
857 int nErr = WSAGetLastError();
858 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
860 if (!pnode->fDisconnect)
861 printf("socket recv error %d\n", nErr);
862 pnode->CloseSocketDisconnect();
872 if (pnode->hSocket == INVALID_SOCKET)
874 if (FD_ISSET(pnode->hSocket, &fdsetSend))
876 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
878 CDataStream& vSend = pnode->vSend;
881 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
884 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
885 pnode->nLastSend = GetTime();
890 int nErr = WSAGetLastError();
891 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
893 printf("socket send error %d\n", nErr);
894 pnode->CloseSocketDisconnect();
897 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
898 if (!pnode->fDisconnect)
899 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
900 pnode->CloseSocketDisconnect();
907 // Inactivity checking
909 if (pnode->vSend.empty())
910 pnode->nLastSendEmpty = GetTime();
911 if (GetTime() - pnode->nTimeConnected > 60)
913 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
915 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
916 pnode->fDisconnect = true;
918 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
920 printf("socket not sending\n");
921 pnode->fDisconnect = true;
923 else if (GetTime() - pnode->nLastRecv > 90*60)
925 printf("socket inactivity timeout\n");
926 pnode->fDisconnect = true;
930 CRITICAL_BLOCK(cs_vNodes)
932 BOOST_FOREACH(CNode* pnode, vNodesCopy)
949 void ThreadMapPort(void* parg)
951 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
954 vnThreadsRunning[5]++;
955 ThreadMapPort2(parg);
956 vnThreadsRunning[5]--;
958 catch (std::exception& e) {
959 vnThreadsRunning[5]--;
960 PrintException(&e, "ThreadMapPort()");
962 vnThreadsRunning[5]--;
963 PrintException(NULL, "ThreadMapPort()");
965 printf("ThreadMapPort exiting\n");
968 void ThreadMapPort2(void* parg)
970 printf("ThreadMapPort started\n");
973 sprintf(port, "%d", GetDefaultPort());
975 const char * rootdescurl = 0;
976 const char * multicastif = 0;
977 const char * minissdpdpath = 0;
978 struct UPNPDev * devlist = 0;
981 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
983 struct UPNPUrls urls;
984 struct IGDdatas data;
987 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
994 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
995 port, port, lanaddr, 0, "TCP", 0);
997 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
998 port, port, lanaddr, 0, "TCP", 0, "0");
1000 if(r!=UPNPCOMMAND_SUCCESS)
1001 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1002 port, port, lanaddr, r, strupnperror(r));
1004 printf("UPnP Port Mapping successful.\n");
1006 if (fShutdown || !fUseUPnP)
1008 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1009 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1010 freeUPNPDevlist(devlist); devlist = 0;
1011 FreeUPNPUrls(&urls);
1017 printf("No valid UPnP IGDs found\n");
1018 freeUPNPDevlist(devlist); devlist = 0;
1020 FreeUPNPUrls(&urls);
1022 if (fShutdown || !fUseUPnP)
1029 void MapPort(bool fMapPort)
1031 if (fUseUPnP != fMapPort)
1033 fUseUPnP = fMapPort;
1034 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1036 if (fUseUPnP && vnThreadsRunning[5] < 1)
1038 if (!CreateThread(ThreadMapPort, NULL))
1039 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1053 static const char *strDNSSeed[] = {
1055 "bitseed.bitcoin.org.uk",
1058 void DNSAddressSeed()
1062 printf("Loading addresses from DNS seeds (could take a while)\n");
1064 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1065 vector<CAddress> vaddr;
1066 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1068 BOOST_FOREACH (CAddress& addr, vaddr)
1070 if (addr.GetByte(3) != 127)
1080 printf("%d addresses found from DNS seeds\n", found);
1085 unsigned int pnSeed[] =
1087 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1088 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1089 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1090 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1091 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1092 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1093 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1094 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1095 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1096 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1097 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1098 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1099 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1100 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1101 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1102 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1103 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1104 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1105 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1106 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1107 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1108 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1109 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1110 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1111 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1112 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1113 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1114 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1115 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1116 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1117 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1118 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1119 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1120 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1121 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1122 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1123 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1124 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1125 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1126 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1131 void ThreadOpenConnections(void* parg)
1133 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1136 vnThreadsRunning[1]++;
1137 ThreadOpenConnections2(parg);
1138 vnThreadsRunning[1]--;
1140 catch (std::exception& e) {
1141 vnThreadsRunning[1]--;
1142 PrintException(&e, "ThreadOpenConnections()");
1144 vnThreadsRunning[1]--;
1145 PrintException(NULL, "ThreadOpenConnections()");
1147 printf("ThreadOpenConnections exiting\n");
1150 void ThreadOpenConnections2(void* parg)
1152 printf("ThreadOpenConnections started\n");
1154 // Connect to specific addresses
1155 if (mapArgs.count("-connect"))
1157 for (int64 nLoop = 0;; nLoop++)
1159 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1161 CAddress addr(strAddr, fAllowDNS);
1163 OpenNetworkConnection(addr);
1164 for (int i = 0; i < 10 && i < nLoop; i++)
1174 // Connect to manually added nodes first
1175 if (mapArgs.count("-addnode"))
1177 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1179 CAddress addr(strAddr, fAllowDNS);
1182 OpenNetworkConnection(addr);
1190 // Initiate network connections
1191 int64 nStart = GetTime();
1194 // Limit outbound connections
1195 vnThreadsRunning[1]--;
1200 CRITICAL_BLOCK(cs_vNodes)
1201 BOOST_FOREACH(CNode* pnode, vNodes)
1202 if (!pnode->fInbound)
1204 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1205 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1206 if (nOutbound < nMaxOutboundConnections)
1212 vnThreadsRunning[1]++;
1216 CRITICAL_BLOCK(cs_mapAddresses)
1218 // Add seed nodes if IRC isn't working
1219 static bool fSeedUsed;
1220 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1221 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1223 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1225 // It'll only connect to one or two seed nodes because once it connects,
1226 // it'll get a pile of addresses with newer timestamps.
1228 addr.ip = pnSeed[i];
1235 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1237 // Disconnect seed nodes
1238 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1239 static int64 nSeedDisconnected;
1240 if (nSeedDisconnected == 0)
1242 nSeedDisconnected = GetTime();
1243 CRITICAL_BLOCK(cs_vNodes)
1244 BOOST_FOREACH(CNode* pnode, vNodes)
1245 if (setSeed.count(pnode->addr.ip))
1246 pnode->fDisconnect = true;
1249 // Keep setting timestamps to 0 so they won't reconnect
1250 if (GetTime() - nSeedDisconnected < 60 * 60)
1252 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1254 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1256 item.second.nTime = 0;
1257 CAddrDB().WriteAddress(item.second);
1266 // Choose an address to connect to based on most recently seen
1268 CAddress addrConnect;
1269 int64 nBest = INT64_MIN;
1271 // Only connect to one address per a.b.?.? range.
1272 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1273 set<unsigned int> setConnected;
1274 CRITICAL_BLOCK(cs_vNodes)
1275 BOOST_FOREACH(CNode* pnode, vNodes)
1276 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1278 CRITICAL_BLOCK(cs_mapAddresses)
1280 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1282 const CAddress& addr = item.second;
1283 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1285 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1286 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1288 // Randomize the order in a deterministic way, putting the standard port first
1289 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1290 if (addr.port != htons(GetDefaultPort()))
1291 nRandomizer += 2 * 60 * 60;
1293 // Last seen Base retry frequency
1302 // 365 days 93 hours
1303 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1305 // Fast reconnect for one hour after last seen
1306 if (nSinceLastSeen < 60 * 60)
1309 // Limit retry frequency
1310 if (nSinceLastTry < nDelay)
1313 // If we have IRC, we'll be notified when they first come online,
1314 // and again every 24 hours by the refresh broadcast.
1315 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1318 // Only try the old stuff if we don't have enough connections
1319 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1322 // If multiple addresses are ready, prioritize by time since
1323 // last seen and time since last tried.
1324 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1333 if (addrConnect.IsValid())
1334 OpenNetworkConnection(addrConnect);
1338 bool OpenNetworkConnection(const CAddress& addrConnect)
1341 // Initiate outbound network connection
1345 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1348 vnThreadsRunning[1]--;
1349 CNode* pnode = ConnectNode(addrConnect);
1350 vnThreadsRunning[1]++;
1355 pnode->fNetworkNode = true;
1367 void ThreadMessageHandler(void* parg)
1369 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1372 vnThreadsRunning[2]++;
1373 ThreadMessageHandler2(parg);
1374 vnThreadsRunning[2]--;
1376 catch (std::exception& e) {
1377 vnThreadsRunning[2]--;
1378 PrintException(&e, "ThreadMessageHandler()");
1380 vnThreadsRunning[2]--;
1381 PrintException(NULL, "ThreadMessageHandler()");
1383 printf("ThreadMessageHandler exiting\n");
1386 void ThreadMessageHandler2(void* parg)
1388 printf("ThreadMessageHandler started\n");
1389 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1392 vector<CNode*> vNodesCopy;
1393 CRITICAL_BLOCK(cs_vNodes)
1395 vNodesCopy = vNodes;
1396 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1400 // Poll the connected nodes for messages
1401 CNode* pnodeTrickle = NULL;
1402 if (!vNodesCopy.empty())
1403 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1404 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1407 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1408 ProcessMessages(pnode);
1413 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1414 SendMessages(pnode, pnode == pnodeTrickle);
1419 CRITICAL_BLOCK(cs_vNodes)
1421 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1425 // Wait and allow messages to bunch up.
1426 // Reduce vnThreadsRunning so StopNode has permission to exit while
1427 // we're sleeping, but we must always check fShutdown after doing this.
1428 vnThreadsRunning[2]--;
1430 if (fRequestShutdown)
1432 vnThreadsRunning[2]++;
1446 bool BindListenPort(string& strError)
1450 addrLocalHost.port = htons(GetDefaultPort());
1453 // Initialize Windows Sockets
1455 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1456 if (ret != NO_ERROR)
1458 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1459 printf("%s\n", strError.c_str());
1464 // Create socket for listening for incoming connections
1465 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1466 if (hListenSocket == INVALID_SOCKET)
1468 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1469 printf("%s\n", strError.c_str());
1474 // Different way of disabling SIGPIPE on BSD
1475 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1479 // Allow binding if the port is still in TIME_WAIT state after
1480 // the program was closed and restarted. Not an issue on windows.
1481 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1485 // Set to nonblocking, incoming connections will also inherit this
1486 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1488 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1491 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1492 printf("%s\n", strError.c_str());
1496 // The sockaddr_in structure specifies the address family,
1497 // IP address, and port for the socket that is being bound
1498 struct sockaddr_in sockaddr;
1499 memset(&sockaddr, 0, sizeof(sockaddr));
1500 sockaddr.sin_family = AF_INET;
1501 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1502 sockaddr.sin_port = htons(GetDefaultPort());
1503 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1505 int nErr = WSAGetLastError();
1506 if (nErr == WSAEADDRINUSE)
1507 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1509 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1510 printf("%s\n", strError.c_str());
1513 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1515 // Listen for incoming connections
1516 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1518 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1519 printf("%s\n", strError.c_str());
1526 void StartNode(void* parg)
1528 if (pnodeLocalHost == NULL)
1529 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1532 // Get local host ip
1533 char pszHostName[1000] = "";
1534 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1536 vector<CAddress> vaddr;
1537 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1538 BOOST_FOREACH (const CAddress &addr, vaddr)
1539 if (addr.GetByte(3) != 127)
1541 addrLocalHost = addr;
1546 // Get local host ip
1547 struct ifaddrs* myaddrs;
1548 if (getifaddrs(&myaddrs) == 0)
1550 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1552 if (ifa->ifa_addr == NULL) continue;
1553 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1554 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1555 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1557 if (ifa->ifa_addr->sa_family == AF_INET)
1559 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1560 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1561 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1563 // Take the first IP that isn't loopback 127.x.x.x
1564 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1565 if (addr.IsValid() && addr.GetByte(3) != 127)
1567 addrLocalHost = addr;
1571 else if (ifa->ifa_addr->sa_family == AF_INET6)
1573 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1574 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1575 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1578 freeifaddrs(myaddrs);
1581 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1583 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1585 // Proxies can't take incoming connections
1586 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1587 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1591 CreateThread(ThreadGetMyExternalIP, NULL);
1598 // Map ports with UPnP
1602 // Get addresses from IRC and advertise ours
1603 if (!CreateThread(ThreadIRCSeed, NULL))
1604 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1606 // Send and receive from sockets, accept connections
1607 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1609 // Initiate outbound connections
1610 if (!CreateThread(ThreadOpenConnections, NULL))
1611 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1614 if (!CreateThread(ThreadMessageHandler, NULL))
1615 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1617 // Generate coins in the background
1618 GenerateBitcoins(fGenerateBitcoins);
1623 printf("StopNode()\n");
1625 nTransactionsUpdated++;
1626 int64 nStart = GetTime();
1627 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1629 || vnThreadsRunning[5] > 0
1633 if (GetTime() - nStart > 20)
1637 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1638 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1639 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1640 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1641 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1642 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1643 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1659 BOOST_FOREACH(CNode* pnode, vNodes)
1660 if (pnode->hSocket != INVALID_SOCKET)
1661 closesocket(pnode->hSocket);
1662 if (hListenSocket != INVALID_SOCKET)
1663 if (closesocket(hListenSocket) == SOCKET_ERROR)
1664 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1667 // Shutdown Windows Sockets
1672 instance_of_cnetcleanup;