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.
9 #include <miniupnpc/miniwget.h>
10 #include <miniupnpc/miniupnpc.h>
11 #include <miniupnpc/upnpcommands.h>
12 #include <miniupnpc/upnperrors.h>
16 using namespace boost;
18 static const int MAX_OUTBOUND_CONNECTIONS = 8;
20 void ThreadMessageHandler2(void* parg);
21 void ThreadSocketHandler2(void* parg);
22 void ThreadOpenConnections2(void* parg);
24 void ThreadMapPort2(void* parg);
26 bool OpenNetworkConnection(const CAddress& addrConnect);
33 // Global state variables
36 bool fAllowDNS = false;
37 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
38 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
39 CNode* pnodeLocalHost = NULL;
40 uint64 nLocalHostNonce = 0;
41 array<int, 10> vnThreadsRunning;
42 SOCKET hListenSocket = INVALID_SOCKET;
44 vector<CNode*> vNodes;
45 CCriticalSection cs_vNodes;
46 map<vector<unsigned char>, CAddress> mapAddresses;
47 CCriticalSection cs_mapAddresses;
48 map<CInv, CDataStream> mapRelay;
49 deque<pair<int64, CInv> > vRelayExpiration;
50 CCriticalSection cs_mapRelay;
51 map<CInv, int64> mapAlreadyAskedFor;
54 int fUseProxy = false;
55 CAddress addrProxy("127.0.0.1",9050);
61 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
63 // Filter out duplicate requests
64 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
66 pindexLastGetBlocksBegin = pindexBegin;
67 hashLastGetBlocksEnd = hashEnd;
69 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
76 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
78 hSocketRet = INVALID_SOCKET;
80 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
81 if (hSocket == INVALID_SOCKET)
85 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
88 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
89 bool fProxy = (fUseProxy && fRoutable);
90 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
92 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
100 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
101 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
102 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
103 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
104 char* pszSocks4 = pszSocks4IP;
105 int nSize = sizeof(pszSocks4IP);
107 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
110 closesocket(hSocket);
111 return error("Error sending to proxy");
114 if (recv(hSocket, pchRet, 8, 0) != 8)
116 closesocket(hSocket);
117 return error("Error reading proxy response");
119 if (pchRet[1] != 0x5a)
121 closesocket(hSocket);
122 if (pchRet[1] != 0x5b)
123 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
126 printf("proxy connected %s\n", addrConnect.ToString().c_str());
129 hSocketRet = hSocket;
133 // portDefault is in host order
134 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
139 int port = portDefault;
142 strlcpy(psz, pszName, sizeof(psz));
145 char* pszColon = strrchr(psz+1,':');
146 char *pszPortEnd = NULL;
147 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
148 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
150 if (psz[0] == '[' && pszColon[-1] == ']')
152 // Future: enable IPv6 colon-notation inside []
159 if (port < 0 || port > USHRT_MAX)
164 unsigned int addrIP = inet_addr(pszHost);
165 if (addrIP != INADDR_NONE)
167 // valid IP address passed
168 vaddr.push_back(CAddress(addrIP, port, nServices));
175 struct hostent* phostent = gethostbyname(pszHost);
179 if (phostent->h_addrtype != AF_INET)
182 char** ppAddr = phostent->h_addr_list;
183 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
185 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
187 vaddr.push_back(addr);
191 return (vaddr.size() > 0);
194 // portDefault is in host order
195 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
197 vector<CAddress> vaddr;
198 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
204 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
207 if (!ConnectSocket(addrConnect, hSocket))
208 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
210 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
213 while (RecvLine(hSocket, strLine))
215 if (strLine.empty()) // HTTP response is separated from headers by blank line
219 if (!RecvLine(hSocket, strLine))
221 closesocket(hSocket);
224 if (pszKeyword == NULL)
226 if (strLine.find(pszKeyword) != -1)
228 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
232 closesocket(hSocket);
233 if (strLine.find("<") != -1)
234 strLine = strLine.substr(0, strLine.find("<"));
235 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
236 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
237 strLine.resize(strLine.size()-1);
238 CAddress addr(strLine,0,true);
239 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
240 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
246 closesocket(hSocket);
247 return error("GetMyExternalIP() : connection closed");
250 // We now get our external IP from the IRC server first and only use this as a backup
251 bool GetMyExternalIP(unsigned int& ipRet)
253 CAddress addrConnect;
255 const char* pszKeyword;
260 for (int nLookup = 0; nLookup <= 1; nLookup++)
261 for (int nHost = 1; nHost <= 2; nHost++)
263 // We should be phasing out our use of sites like these. If we need
264 // replacements, we should ask for volunteers to put this simple
265 // php file on their webserver that prints the client IP:
266 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
269 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
273 CAddress addrIP("checkip.dyndns.org", 80, true);
274 if (addrIP.IsValid())
275 addrConnect = addrIP;
278 pszGet = "GET / HTTP/1.1\r\n"
279 "Host: checkip.dyndns.org\r\n"
280 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
281 "Connection: close\r\n"
284 pszKeyword = "Address:";
288 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
292 CAddress addrIP("www.showmyip.com", 80, true);
293 if (addrIP.IsValid())
294 addrConnect = addrIP;
297 pszGet = "GET /simple/ HTTP/1.1\r\n"
298 "Host: www.showmyip.com\r\n"
299 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
300 "Connection: close\r\n"
303 pszKeyword = NULL; // Returns just IP address
306 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
313 void ThreadGetMyExternalIP(void* parg)
315 // Wait for IRC to get it first
316 if (!GetBoolArg("-noirc"))
318 for (int i = 0; i < 2 * 60; i++)
321 if (fGotExternalIP || fShutdown)
326 // Fallback in case IRC fails to get it
327 if (GetMyExternalIP(addrLocalHost.ip))
329 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
330 if (addrLocalHost.IsRoutable())
332 // If we already connected to a few before we had our IP, go back and addr them.
333 // setAddrKnown automatically filters any duplicate sends.
334 CAddress addr(addrLocalHost);
335 addr.nTime = GetAdjustedTime();
336 CRITICAL_BLOCK(cs_vNodes)
337 BOOST_FOREACH(CNode* pnode, vNodes)
338 pnode->PushAddress(addr);
347 bool AddAddress(CAddress addr, int64 nTimePenalty)
349 if (!addr.IsRoutable())
351 if (addr.ip == addrLocalHost.ip)
353 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
354 CRITICAL_BLOCK(cs_mapAddresses)
356 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
357 if (it == mapAddresses.end())
360 printf("AddAddress(%s)\n", addr.ToString().c_str());
361 mapAddresses.insert(make_pair(addr.GetKey(), addr));
362 CAddrDB().WriteAddress(addr);
367 bool fUpdated = false;
368 CAddress& addrFound = (*it).second;
369 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
371 // Services have been added
372 addrFound.nServices |= addr.nServices;
375 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
376 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
377 if (addrFound.nTime < addr.nTime - nUpdateInterval)
379 // Periodically update most recently seen time
380 addrFound.nTime = addr.nTime;
384 CAddrDB().WriteAddress(addrFound);
390 void AddressCurrentlyConnected(const CAddress& addr)
392 CRITICAL_BLOCK(cs_mapAddresses)
394 // Only if it's been published already
395 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
396 if (it != mapAddresses.end())
398 CAddress& addrFound = (*it).second;
399 int64 nUpdateInterval = 20 * 60;
400 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
402 // Periodically update most recently seen time
403 addrFound.nTime = GetAdjustedTime();
405 addrdb.WriteAddress(addrFound);
415 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
417 // If the dialog might get closed before the reply comes back,
418 // call this in the destructor so it doesn't get called after it's deleted.
419 CRITICAL_BLOCK(cs_vNodes)
421 BOOST_FOREACH(CNode* pnode, vNodes)
423 CRITICAL_BLOCK(pnode->cs_mapRequests)
425 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
427 CRequestTracker& tracker = (*mi).second;
428 if (tracker.fn == fn && tracker.param1 == param1)
429 pnode->mapRequests.erase(mi++);
445 // Subscription methods for the broadcast and subscription system.
446 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
448 // The subscription system uses a meet-in-the-middle strategy.
449 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
450 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
453 bool AnySubscribed(unsigned int nChannel)
455 if (pnodeLocalHost->IsSubscribed(nChannel))
457 CRITICAL_BLOCK(cs_vNodes)
458 BOOST_FOREACH(CNode* pnode, vNodes)
459 if (pnode->IsSubscribed(nChannel))
464 bool CNode::IsSubscribed(unsigned int nChannel)
466 if (nChannel >= vfSubscribe.size())
468 return vfSubscribe[nChannel];
471 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
473 if (nChannel >= vfSubscribe.size())
476 if (!AnySubscribed(nChannel))
479 CRITICAL_BLOCK(cs_vNodes)
480 BOOST_FOREACH(CNode* pnode, vNodes)
482 pnode->PushMessage("subscribe", nChannel, nHops);
485 vfSubscribe[nChannel] = true;
488 void CNode::CancelSubscribe(unsigned int nChannel)
490 if (nChannel >= vfSubscribe.size())
493 // Prevent from relaying cancel if wasn't subscribed
494 if (!vfSubscribe[nChannel])
496 vfSubscribe[nChannel] = false;
498 if (!AnySubscribed(nChannel))
500 // Relay subscription cancel
501 CRITICAL_BLOCK(cs_vNodes)
502 BOOST_FOREACH(CNode* pnode, vNodes)
504 pnode->PushMessage("sub-cancel", nChannel);
516 CNode* FindNode(unsigned int ip)
518 CRITICAL_BLOCK(cs_vNodes)
520 BOOST_FOREACH(CNode* pnode, vNodes)
521 if (pnode->addr.ip == ip)
527 CNode* FindNode(CAddress addr)
529 CRITICAL_BLOCK(cs_vNodes)
531 BOOST_FOREACH(CNode* pnode, vNodes)
532 if (pnode->addr == addr)
538 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
540 if (addrConnect.ip == addrLocalHost.ip)
543 // Look for an existing connection
544 CNode* pnode = FindNode(addrConnect.ip);
548 pnode->AddRef(nTimeout);
555 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
556 addrConnect.ToString().c_str(),
557 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
558 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
560 CRITICAL_BLOCK(cs_mapAddresses)
561 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
565 if (ConnectSocket(addrConnect, hSocket))
568 printf("connected %s\n", addrConnect.ToString().c_str());
570 // Set to nonblocking
573 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
574 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
576 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
577 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
581 CNode* pnode = new CNode(hSocket, addrConnect, false);
583 pnode->AddRef(nTimeout);
586 CRITICAL_BLOCK(cs_vNodes)
587 vNodes.push_back(pnode);
589 pnode->nTimeConnected = GetTime();
598 void CNode::CloseSocketDisconnect()
601 if (hSocket != INVALID_SOCKET)
604 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
605 printf("disconnecting node %s\n", addr.ToString().c_str());
606 closesocket(hSocket);
607 hSocket = INVALID_SOCKET;
611 void CNode::Cleanup()
613 // All of a nodes broadcasts and subscriptions are automatically torn down
614 // when it goes down, so a node has to stay up to keep its broadcast going.
616 // Cancel subscriptions
617 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
618 if (vfSubscribe[nChannel])
619 CancelSubscribe(nChannel);
634 void ThreadSocketHandler(void* parg)
636 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
639 vnThreadsRunning[0]++;
640 ThreadSocketHandler2(parg);
641 vnThreadsRunning[0]--;
643 catch (std::exception& e) {
644 vnThreadsRunning[0]--;
645 PrintException(&e, "ThreadSocketHandler()");
647 vnThreadsRunning[0]--;
648 throw; // support pthread_cancel()
650 printf("ThreadSocketHandler exiting\n");
653 void ThreadSocketHandler2(void* parg)
655 printf("ThreadSocketHandler started\n");
656 list<CNode*> vNodesDisconnected;
657 int nPrevNodeCount = 0;
664 CRITICAL_BLOCK(cs_vNodes)
666 // Disconnect unused nodes
667 vector<CNode*> vNodesCopy = vNodes;
668 BOOST_FOREACH(CNode* pnode, vNodesCopy)
670 if (pnode->fDisconnect ||
671 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
673 // remove from vNodes
674 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
676 // close socket and cleanup
677 pnode->CloseSocketDisconnect();
680 // hold in disconnected pool until all refs are released
681 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
682 if (pnode->fNetworkNode || pnode->fInbound)
684 vNodesDisconnected.push_back(pnode);
688 // Delete disconnected nodes
689 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
690 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
692 // wait until threads are done using it
693 if (pnode->GetRefCount() <= 0)
695 bool fDelete = false;
696 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
697 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
698 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
699 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
703 vNodesDisconnected.remove(pnode);
709 if (vNodes.size() != nPrevNodeCount)
711 nPrevNodeCount = vNodes.size();
717 // Find which sockets have data to receive
719 struct timeval timeout;
721 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
728 FD_ZERO(&fdsetError);
729 SOCKET hSocketMax = 0;
731 if(hListenSocket != INVALID_SOCKET)
732 FD_SET(hListenSocket, &fdsetRecv);
733 hSocketMax = max(hSocketMax, hListenSocket);
734 CRITICAL_BLOCK(cs_vNodes)
736 BOOST_FOREACH(CNode* pnode, vNodes)
738 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
740 FD_SET(pnode->hSocket, &fdsetRecv);
741 FD_SET(pnode->hSocket, &fdsetError);
742 hSocketMax = max(hSocketMax, pnode->hSocket);
743 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
744 if (!pnode->vSend.empty())
745 FD_SET(pnode->hSocket, &fdsetSend);
749 vnThreadsRunning[0]--;
750 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
751 vnThreadsRunning[0]++;
754 if (nSelect == SOCKET_ERROR)
756 int nErr = WSAGetLastError();
757 printf("socket select error %d\n", nErr);
758 for (int i = 0; i <= hSocketMax; i++)
759 FD_SET(i, &fdsetRecv);
761 FD_ZERO(&fdsetError);
762 Sleep(timeout.tv_usec/1000);
767 // Accept new connections
769 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
771 struct sockaddr_in sockaddr;
772 socklen_t len = sizeof(sockaddr);
773 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
774 CAddress addr(sockaddr);
777 CRITICAL_BLOCK(cs_vNodes)
778 BOOST_FOREACH(CNode* pnode, vNodes)
781 if (hSocket == INVALID_SOCKET)
783 if (WSAGetLastError() != WSAEWOULDBLOCK)
784 printf("socket error accept failed: %d\n", WSAGetLastError());
786 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
788 closesocket(hSocket);
792 printf("accepted connection %s\n", addr.ToString().c_str());
793 CNode* pnode = new CNode(hSocket, addr, true);
795 CRITICAL_BLOCK(cs_vNodes)
796 vNodes.push_back(pnode);
802 // Service each socket
804 vector<CNode*> vNodesCopy;
805 CRITICAL_BLOCK(cs_vNodes)
808 BOOST_FOREACH(CNode* pnode, vNodesCopy)
811 BOOST_FOREACH(CNode* pnode, vNodesCopy)
819 if (pnode->hSocket == INVALID_SOCKET)
821 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
823 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
825 CDataStream& vRecv = pnode->vRecv;
826 unsigned int nPos = vRecv.size();
828 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
829 if (!pnode->fDisconnect)
830 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
831 pnode->CloseSocketDisconnect();
834 // typical socket buffer is 8K-64K
835 char pchBuf[0x10000];
836 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
839 vRecv.resize(nPos + nBytes);
840 memcpy(&vRecv[nPos], pchBuf, nBytes);
841 pnode->nLastRecv = GetTime();
843 else if (nBytes == 0)
845 // socket closed gracefully
846 if (!pnode->fDisconnect)
847 printf("socket closed\n");
848 pnode->CloseSocketDisconnect();
853 int nErr = WSAGetLastError();
854 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
856 if (!pnode->fDisconnect)
857 printf("socket recv error %d\n", nErr);
858 pnode->CloseSocketDisconnect();
868 if (pnode->hSocket == INVALID_SOCKET)
870 if (FD_ISSET(pnode->hSocket, &fdsetSend))
872 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
874 CDataStream& vSend = pnode->vSend;
877 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
880 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
881 pnode->nLastSend = GetTime();
886 int nErr = WSAGetLastError();
887 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
889 printf("socket send error %d\n", nErr);
890 pnode->CloseSocketDisconnect();
893 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
894 if (!pnode->fDisconnect)
895 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
896 pnode->CloseSocketDisconnect();
903 // Inactivity checking
905 if (pnode->vSend.empty())
906 pnode->nLastSendEmpty = GetTime();
907 if (GetTime() - pnode->nTimeConnected > 60)
909 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
911 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
912 pnode->fDisconnect = true;
914 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
916 printf("socket not sending\n");
917 pnode->fDisconnect = true;
919 else if (GetTime() - pnode->nLastRecv > 90*60)
921 printf("socket inactivity timeout\n");
922 pnode->fDisconnect = true;
926 CRITICAL_BLOCK(cs_vNodes)
928 BOOST_FOREACH(CNode* pnode, vNodesCopy)
945 void ThreadMapPort(void* parg)
947 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
950 vnThreadsRunning[5]++;
951 ThreadMapPort2(parg);
952 vnThreadsRunning[5]--;
954 catch (std::exception& e) {
955 vnThreadsRunning[5]--;
956 PrintException(&e, "ThreadMapPort()");
958 vnThreadsRunning[5]--;
959 PrintException(NULL, "ThreadMapPort()");
961 printf("ThreadMapPort exiting\n");
964 void ThreadMapPort2(void* parg)
966 printf("ThreadMapPort started\n");
969 sprintf(port, "%d", GetDefaultPort());
971 const char * rootdescurl = 0;
972 const char * multicastif = 0;
973 const char * minissdpdpath = 0;
974 struct UPNPDev * devlist = 0;
977 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
979 struct UPNPUrls urls;
980 struct IGDdatas data;
983 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
990 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
991 port, port, lanaddr, 0, "TCP", 0);
993 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
994 port, port, lanaddr, 0, "TCP", 0, "0");
996 if(r!=UPNPCOMMAND_SUCCESS)
997 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
998 port, port, lanaddr, r, strupnperror(r));
1000 printf("UPnP Port Mapping successful.\n");
1002 if (fShutdown || !fUseUPnP)
1004 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1005 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1006 freeUPNPDevlist(devlist); devlist = 0;
1007 FreeUPNPUrls(&urls);
1013 printf("No valid UPnP IGDs found\n");
1014 freeUPNPDevlist(devlist); devlist = 0;
1016 FreeUPNPUrls(&urls);
1018 if (fShutdown || !fUseUPnP)
1025 void MapPort(bool fMapPort)
1027 if (fUseUPnP != fMapPort)
1029 fUseUPnP = fMapPort;
1030 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1032 if (fUseUPnP && vnThreadsRunning[5] < 1)
1034 if (!CreateThread(ThreadMapPort, NULL))
1035 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1049 static const char *strDNSSeed[] = {
1051 "bitseed.bitcoin.org.uk",
1054 void DNSAddressSeed()
1058 printf("Loading addresses from DNS seeds (could take a while)\n");
1060 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1061 vector<CAddress> vaddr;
1062 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1064 BOOST_FOREACH (CAddress& addr, vaddr)
1066 if (addr.GetByte(3) != 127)
1076 printf("%d addresses found from DNS seeds\n", found);
1081 unsigned int pnSeed[] =
1083 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1084 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1085 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1086 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1087 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1088 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1089 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1090 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1091 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1092 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1093 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1094 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1095 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1096 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1097 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1098 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1099 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1100 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1101 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1102 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1103 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1104 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1105 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1106 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1107 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1108 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1109 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1110 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1111 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1112 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1113 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1114 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1115 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1116 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1117 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1118 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1119 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1120 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1121 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1122 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1127 void ThreadOpenConnections(void* parg)
1129 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1132 vnThreadsRunning[1]++;
1133 ThreadOpenConnections2(parg);
1134 vnThreadsRunning[1]--;
1136 catch (std::exception& e) {
1137 vnThreadsRunning[1]--;
1138 PrintException(&e, "ThreadOpenConnections()");
1140 vnThreadsRunning[1]--;
1141 PrintException(NULL, "ThreadOpenConnections()");
1143 printf("ThreadOpenConnections exiting\n");
1146 void ThreadOpenConnections2(void* parg)
1148 printf("ThreadOpenConnections started\n");
1150 // Connect to specific addresses
1151 if (mapArgs.count("-connect"))
1153 for (int64 nLoop = 0;; nLoop++)
1155 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1157 CAddress addr(strAddr, fAllowDNS);
1159 OpenNetworkConnection(addr);
1160 for (int i = 0; i < 10 && i < nLoop; i++)
1170 // Connect to manually added nodes first
1171 if (mapArgs.count("-addnode"))
1173 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1175 CAddress addr(strAddr, fAllowDNS);
1178 OpenNetworkConnection(addr);
1186 // Initiate network connections
1187 int64 nStart = GetTime();
1190 // Limit outbound connections
1191 vnThreadsRunning[1]--;
1196 CRITICAL_BLOCK(cs_vNodes)
1197 BOOST_FOREACH(CNode* pnode, vNodes)
1198 if (!pnode->fInbound)
1200 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1201 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1202 if (nOutbound < nMaxOutboundConnections)
1208 vnThreadsRunning[1]++;
1212 CRITICAL_BLOCK(cs_mapAddresses)
1214 // Add seed nodes if IRC isn't working
1215 static bool fSeedUsed;
1216 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1217 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1219 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1221 // It'll only connect to one or two seed nodes because once it connects,
1222 // it'll get a pile of addresses with newer timestamps.
1224 addr.ip = pnSeed[i];
1231 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1233 // Disconnect seed nodes
1234 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1235 static int64 nSeedDisconnected;
1236 if (nSeedDisconnected == 0)
1238 nSeedDisconnected = GetTime();
1239 CRITICAL_BLOCK(cs_vNodes)
1240 BOOST_FOREACH(CNode* pnode, vNodes)
1241 if (setSeed.count(pnode->addr.ip))
1242 pnode->fDisconnect = true;
1245 // Keep setting timestamps to 0 so they won't reconnect
1246 if (GetTime() - nSeedDisconnected < 60 * 60)
1248 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1250 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1252 item.second.nTime = 0;
1253 CAddrDB().WriteAddress(item.second);
1262 // Choose an address to connect to based on most recently seen
1264 CAddress addrConnect;
1265 int64 nBest = INT64_MIN;
1267 // Only connect to one address per a.b.?.? range.
1268 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1269 set<unsigned int> setConnected;
1270 CRITICAL_BLOCK(cs_vNodes)
1271 BOOST_FOREACH(CNode* pnode, vNodes)
1272 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1274 CRITICAL_BLOCK(cs_mapAddresses)
1276 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1278 const CAddress& addr = item.second;
1279 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1281 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1282 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1284 // Randomize the order in a deterministic way, putting the standard port first
1285 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1286 if (addr.port != htons(GetDefaultPort()))
1287 nRandomizer += 2 * 60 * 60;
1289 // Last seen Base retry frequency
1298 // 365 days 93 hours
1299 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1301 // Fast reconnect for one hour after last seen
1302 if (nSinceLastSeen < 60 * 60)
1305 // Limit retry frequency
1306 if (nSinceLastTry < nDelay)
1309 // If we have IRC, we'll be notified when they first come online,
1310 // and again every 24 hours by the refresh broadcast.
1311 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1314 // Only try the old stuff if we don't have enough connections
1315 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1318 // If multiple addresses are ready, prioritize by time since
1319 // last seen and time since last tried.
1320 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1329 if (addrConnect.IsValid())
1330 OpenNetworkConnection(addrConnect);
1334 bool OpenNetworkConnection(const CAddress& addrConnect)
1337 // Initiate outbound network connection
1341 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1344 vnThreadsRunning[1]--;
1345 CNode* pnode = ConnectNode(addrConnect);
1346 vnThreadsRunning[1]++;
1351 pnode->fNetworkNode = true;
1363 void ThreadMessageHandler(void* parg)
1365 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1368 vnThreadsRunning[2]++;
1369 ThreadMessageHandler2(parg);
1370 vnThreadsRunning[2]--;
1372 catch (std::exception& e) {
1373 vnThreadsRunning[2]--;
1374 PrintException(&e, "ThreadMessageHandler()");
1376 vnThreadsRunning[2]--;
1377 PrintException(NULL, "ThreadMessageHandler()");
1379 printf("ThreadMessageHandler exiting\n");
1382 void ThreadMessageHandler2(void* parg)
1384 printf("ThreadMessageHandler started\n");
1385 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1388 vector<CNode*> vNodesCopy;
1389 CRITICAL_BLOCK(cs_vNodes)
1391 vNodesCopy = vNodes;
1392 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1396 // Poll the connected nodes for messages
1397 CNode* pnodeTrickle = NULL;
1398 if (!vNodesCopy.empty())
1399 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1400 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1403 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1404 ProcessMessages(pnode);
1409 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1410 SendMessages(pnode, pnode == pnodeTrickle);
1415 CRITICAL_BLOCK(cs_vNodes)
1417 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1421 // Wait and allow messages to bunch up.
1422 // Reduce vnThreadsRunning so StopNode has permission to exit while
1423 // we're sleeping, but we must always check fShutdown after doing this.
1424 vnThreadsRunning[2]--;
1426 if (fRequestShutdown)
1428 vnThreadsRunning[2]++;
1442 bool BindListenPort(string& strError)
1446 addrLocalHost.port = htons(GetDefaultPort());
1449 // Initialize Windows Sockets
1451 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1452 if (ret != NO_ERROR)
1454 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1455 printf("%s\n", strError.c_str());
1460 // Create socket for listening for incoming connections
1461 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1462 if (hListenSocket == INVALID_SOCKET)
1464 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1465 printf("%s\n", strError.c_str());
1470 // Different way of disabling SIGPIPE on BSD
1471 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1475 // Allow binding if the port is still in TIME_WAIT state after
1476 // the program was closed and restarted. Not an issue on windows.
1477 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1481 // Set to nonblocking, incoming connections will also inherit this
1482 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1484 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1487 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1488 printf("%s\n", strError.c_str());
1492 // The sockaddr_in structure specifies the address family,
1493 // IP address, and port for the socket that is being bound
1494 struct sockaddr_in sockaddr;
1495 memset(&sockaddr, 0, sizeof(sockaddr));
1496 sockaddr.sin_family = AF_INET;
1497 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1498 sockaddr.sin_port = htons(GetDefaultPort());
1499 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1501 int nErr = WSAGetLastError();
1502 if (nErr == WSAEADDRINUSE)
1503 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1505 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1506 printf("%s\n", strError.c_str());
1509 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1511 // Listen for incoming connections
1512 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1514 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1515 printf("%s\n", strError.c_str());
1522 void StartNode(void* parg)
1524 if (pnodeLocalHost == NULL)
1525 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1528 // Get local host ip
1529 char pszHostName[1000] = "";
1530 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1532 vector<CAddress> vaddr;
1533 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1534 BOOST_FOREACH (const CAddress &addr, vaddr)
1535 if (addr.GetByte(3) != 127)
1537 addrLocalHost = addr;
1542 // Get local host ip
1543 struct ifaddrs* myaddrs;
1544 if (getifaddrs(&myaddrs) == 0)
1546 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1548 if (ifa->ifa_addr == NULL) continue;
1549 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1550 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1551 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1553 if (ifa->ifa_addr->sa_family == AF_INET)
1555 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1556 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1557 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1559 // Take the first IP that isn't loopback 127.x.x.x
1560 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1561 if (addr.IsValid() && addr.GetByte(3) != 127)
1563 addrLocalHost = addr;
1567 else if (ifa->ifa_addr->sa_family == AF_INET6)
1569 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1570 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1571 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1574 freeifaddrs(myaddrs);
1577 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1579 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1581 // Proxies can't take incoming connections
1582 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1583 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1587 CreateThread(ThreadGetMyExternalIP, NULL);
1594 // Map ports with UPnP
1598 // Get addresses from IRC and advertise ours
1599 if (!CreateThread(ThreadIRCSeed, NULL))
1600 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1602 // Send and receive from sockets, accept connections
1603 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1605 // Initiate outbound connections
1606 if (!CreateThread(ThreadOpenConnections, NULL))
1607 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1610 if (!CreateThread(ThreadMessageHandler, NULL))
1611 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1613 // Generate coins in the background
1614 GenerateBitcoins(fGenerateBitcoins);
1619 printf("StopNode()\n");
1621 nTransactionsUpdated++;
1622 int64 nStart = GetTime();
1623 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1625 || vnThreadsRunning[5] > 0
1629 if (GetTime() - nStart > 20)
1633 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1634 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1635 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1636 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1637 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1638 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1639 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1655 BOOST_FOREACH(CNode* pnode, vNodes)
1656 if (pnode->hSocket != INVALID_SOCKET)
1657 closesocket(pnode->hSocket);
1658 if (hListenSocket != INVALID_SOCKET)
1659 if (closesocket(hListenSocket) == SOCKET_ERROR)
1660 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1663 // Shutdown Windows Sockets
1668 instance_of_cnetcleanup;