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.
10 #include <miniupnpc/miniwget.h>
11 #include <miniupnpc/miniupnpc.h>
12 #include <miniupnpc/upnpcommands.h>
13 #include <miniupnpc/upnperrors.h>
17 using namespace boost;
19 static const int MAX_OUTBOUND_CONNECTIONS = 8;
21 void ThreadMessageHandler2(void* parg);
22 void ThreadSocketHandler2(void* parg);
23 void ThreadOpenConnections2(void* parg);
25 void ThreadMapPort2(void* parg);
27 bool OpenNetworkConnection(const CAddress& addrConnect);
34 // Global state variables
37 bool fAllowDNS = false;
38 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
39 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
40 CNode* pnodeLocalHost = NULL;
41 uint64 nLocalHostNonce = 0;
42 array<int, 10> vnThreadsRunning;
43 SOCKET hListenSocket = INVALID_SOCKET;
45 vector<CNode*> vNodes;
46 CCriticalSection cs_vNodes;
47 map<vector<unsigned char>, CAddress> mapAddresses;
48 CCriticalSection cs_mapAddresses;
49 map<CInv, CDataStream> mapRelay;
50 deque<pair<int64, CInv> > vRelayExpiration;
51 CCriticalSection cs_mapRelay;
52 map<CInv, int64> mapAlreadyAskedFor;
55 int fUseProxy = false;
56 CAddress addrProxy("127.0.0.1",9050);
62 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
64 // Filter out duplicate requests
65 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
67 pindexLastGetBlocksBegin = pindexBegin;
68 hashLastGetBlocksEnd = hashEnd;
70 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
77 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
79 hSocketRet = INVALID_SOCKET;
81 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
82 if (hSocket == INVALID_SOCKET)
86 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
89 bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
90 bool fProxy = (fUseProxy && fRoutable);
91 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
93 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
101 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
102 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
103 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
104 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
105 char* pszSocks4 = pszSocks4IP;
106 int nSize = sizeof(pszSocks4IP);
108 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
111 closesocket(hSocket);
112 return error("Error sending to proxy");
115 if (recv(hSocket, pchRet, 8, 0) != 8)
117 closesocket(hSocket);
118 return error("Error reading proxy response");
120 if (pchRet[1] != 0x5a)
122 closesocket(hSocket);
123 if (pchRet[1] != 0x5b)
124 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
127 printf("proxy connected %s\n", addrConnect.ToString().c_str());
130 hSocketRet = hSocket;
134 // portDefault is in host order
135 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
140 int port = portDefault;
143 strlcpy(psz, pszName, sizeof(psz));
146 char* pszColon = strrchr(psz+1,':');
147 char *pszPortEnd = NULL;
148 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
149 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
151 if (psz[0] == '[' && pszColon[-1] == ']')
153 // Future: enable IPv6 colon-notation inside []
160 if (port < 0 || port > USHRT_MAX)
165 unsigned int addrIP = inet_addr(pszHost);
166 if (addrIP != INADDR_NONE)
168 // valid IP address passed
169 vaddr.push_back(CAddress(addrIP, port, nServices));
176 struct hostent* phostent = gethostbyname(pszHost);
180 if (phostent->h_addrtype != AF_INET)
183 char** ppAddr = phostent->h_addr_list;
184 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
186 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
188 vaddr.push_back(addr);
192 return (vaddr.size() > 0);
195 // portDefault is in host order
196 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
198 vector<CAddress> vaddr;
199 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
205 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
208 if (!ConnectSocket(addrConnect, hSocket))
209 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
211 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
214 while (RecvLine(hSocket, strLine))
216 if (strLine.empty()) // HTTP response is separated from headers by blank line
220 if (!RecvLine(hSocket, strLine))
222 closesocket(hSocket);
225 if (pszKeyword == NULL)
227 if (strLine.find(pszKeyword) != -1)
229 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
233 closesocket(hSocket);
234 if (strLine.find("<") != -1)
235 strLine = strLine.substr(0, strLine.find("<"));
236 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
237 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
238 strLine.resize(strLine.size()-1);
239 CAddress addr(strLine,0,true);
240 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
241 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
247 closesocket(hSocket);
248 return error("GetMyExternalIP() : connection closed");
251 // We now get our external IP from the IRC server first and only use this as a backup
252 bool GetMyExternalIP(unsigned int& ipRet)
254 CAddress addrConnect;
256 const char* pszKeyword;
261 for (int nLookup = 0; nLookup <= 1; nLookup++)
262 for (int nHost = 1; nHost <= 2; nHost++)
264 // We should be phasing out our use of sites like these. If we need
265 // replacements, we should ask for volunteers to put this simple
266 // php file on their webserver that prints the client IP:
267 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
270 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
274 CAddress addrIP("checkip.dyndns.org", 80, true);
275 if (addrIP.IsValid())
276 addrConnect = addrIP;
279 pszGet = "GET / HTTP/1.1\r\n"
280 "Host: checkip.dyndns.org\r\n"
281 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
282 "Connection: close\r\n"
285 pszKeyword = "Address:";
289 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
293 CAddress addrIP("www.showmyip.com", 80, true);
294 if (addrIP.IsValid())
295 addrConnect = addrIP;
298 pszGet = "GET /simple/ HTTP/1.1\r\n"
299 "Host: www.showmyip.com\r\n"
300 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
301 "Connection: close\r\n"
304 pszKeyword = NULL; // Returns just IP address
307 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
314 void ThreadGetMyExternalIP(void* parg)
316 // Wait for IRC to get it first
317 if (!GetBoolArg("-noirc"))
319 for (int i = 0; i < 2 * 60; i++)
322 if (fGotExternalIP || fShutdown)
327 // Fallback in case IRC fails to get it
328 if (GetMyExternalIP(addrLocalHost.ip))
330 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
331 if (addrLocalHost.IsRoutable())
333 // If we already connected to a few before we had our IP, go back and addr them.
334 // setAddrKnown automatically filters any duplicate sends.
335 CAddress addr(addrLocalHost);
336 addr.nTime = GetAdjustedTime();
337 CRITICAL_BLOCK(cs_vNodes)
338 BOOST_FOREACH(CNode* pnode, vNodes)
339 pnode->PushAddress(addr);
348 bool AddAddress(CAddress addr, int64 nTimePenalty)
350 if (!addr.IsRoutable())
352 if (addr.ip == addrLocalHost.ip)
354 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
355 CRITICAL_BLOCK(cs_mapAddresses)
357 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
358 if (it == mapAddresses.end())
361 printf("AddAddress(%s)\n", addr.ToString().c_str());
362 mapAddresses.insert(make_pair(addr.GetKey(), addr));
363 CAddrDB().WriteAddress(addr);
368 bool fUpdated = false;
369 CAddress& addrFound = (*it).second;
370 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
372 // Services have been added
373 addrFound.nServices |= addr.nServices;
376 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
377 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
378 if (addrFound.nTime < addr.nTime - nUpdateInterval)
380 // Periodically update most recently seen time
381 addrFound.nTime = addr.nTime;
385 CAddrDB().WriteAddress(addrFound);
391 void AddressCurrentlyConnected(const CAddress& addr)
393 CRITICAL_BLOCK(cs_mapAddresses)
395 // Only if it's been published already
396 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
397 if (it != mapAddresses.end())
399 CAddress& addrFound = (*it).second;
400 int64 nUpdateInterval = 20 * 60;
401 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
403 // Periodically update most recently seen time
404 addrFound.nTime = GetAdjustedTime();
406 addrdb.WriteAddress(addrFound);
416 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
418 // If the dialog might get closed before the reply comes back,
419 // call this in the destructor so it doesn't get called after it's deleted.
420 CRITICAL_BLOCK(cs_vNodes)
422 BOOST_FOREACH(CNode* pnode, vNodes)
424 CRITICAL_BLOCK(pnode->cs_mapRequests)
426 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
428 CRequestTracker& tracker = (*mi).second;
429 if (tracker.fn == fn && tracker.param1 == param1)
430 pnode->mapRequests.erase(mi++);
446 // Subscription methods for the broadcast and subscription system.
447 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
449 // The subscription system uses a meet-in-the-middle strategy.
450 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
451 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
454 bool AnySubscribed(unsigned int nChannel)
456 if (pnodeLocalHost->IsSubscribed(nChannel))
458 CRITICAL_BLOCK(cs_vNodes)
459 BOOST_FOREACH(CNode* pnode, vNodes)
460 if (pnode->IsSubscribed(nChannel))
465 bool CNode::IsSubscribed(unsigned int nChannel)
467 if (nChannel >= vfSubscribe.size())
469 return vfSubscribe[nChannel];
472 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
474 if (nChannel >= vfSubscribe.size())
477 if (!AnySubscribed(nChannel))
480 CRITICAL_BLOCK(cs_vNodes)
481 BOOST_FOREACH(CNode* pnode, vNodes)
483 pnode->PushMessage("subscribe", nChannel, nHops);
486 vfSubscribe[nChannel] = true;
489 void CNode::CancelSubscribe(unsigned int nChannel)
491 if (nChannel >= vfSubscribe.size())
494 // Prevent from relaying cancel if wasn't subscribed
495 if (!vfSubscribe[nChannel])
497 vfSubscribe[nChannel] = false;
499 if (!AnySubscribed(nChannel))
501 // Relay subscription cancel
502 CRITICAL_BLOCK(cs_vNodes)
503 BOOST_FOREACH(CNode* pnode, vNodes)
505 pnode->PushMessage("sub-cancel", nChannel);
517 CNode* FindNode(unsigned int ip)
519 CRITICAL_BLOCK(cs_vNodes)
521 BOOST_FOREACH(CNode* pnode, vNodes)
522 if (pnode->addr.ip == ip)
528 CNode* FindNode(CAddress addr)
530 CRITICAL_BLOCK(cs_vNodes)
532 BOOST_FOREACH(CNode* pnode, vNodes)
533 if (pnode->addr == addr)
539 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
541 if (addrConnect.ip == addrLocalHost.ip)
544 // Look for an existing connection
545 CNode* pnode = FindNode(addrConnect.ip);
549 pnode->AddRef(nTimeout);
556 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
557 addrConnect.ToString().c_str(),
558 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
559 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
561 CRITICAL_BLOCK(cs_mapAddresses)
562 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
566 if (ConnectSocket(addrConnect, hSocket))
569 printf("connected %s\n", addrConnect.ToString().c_str());
571 // Set to nonblocking
574 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
575 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
577 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
578 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
582 CNode* pnode = new CNode(hSocket, addrConnect, false);
584 pnode->AddRef(nTimeout);
587 CRITICAL_BLOCK(cs_vNodes)
588 vNodes.push_back(pnode);
590 pnode->nTimeConnected = GetTime();
599 void CNode::CloseSocketDisconnect()
602 if (hSocket != INVALID_SOCKET)
605 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
606 printf("disconnecting node %s\n", addr.ToString().c_str());
607 closesocket(hSocket);
608 hSocket = INVALID_SOCKET;
612 void CNode::Cleanup()
614 // All of a nodes broadcasts and subscriptions are automatically torn down
615 // when it goes down, so a node has to stay up to keep its broadcast going.
617 // Cancel subscriptions
618 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
619 if (vfSubscribe[nChannel])
620 CancelSubscribe(nChannel);
635 void ThreadSocketHandler(void* parg)
637 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
640 vnThreadsRunning[0]++;
641 ThreadSocketHandler2(parg);
642 vnThreadsRunning[0]--;
644 catch (std::exception& e) {
645 vnThreadsRunning[0]--;
646 PrintException(&e, "ThreadSocketHandler()");
648 vnThreadsRunning[0]--;
649 throw; // support pthread_cancel()
651 printf("ThreadSocketHandler exiting\n");
654 void ThreadSocketHandler2(void* parg)
656 printf("ThreadSocketHandler started\n");
657 list<CNode*> vNodesDisconnected;
658 int nPrevNodeCount = 0;
665 CRITICAL_BLOCK(cs_vNodes)
667 // Disconnect unused nodes
668 vector<CNode*> vNodesCopy = vNodes;
669 BOOST_FOREACH(CNode* pnode, vNodesCopy)
671 if (pnode->fDisconnect ||
672 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
674 // remove from vNodes
675 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
677 // close socket and cleanup
678 pnode->CloseSocketDisconnect();
681 // hold in disconnected pool until all refs are released
682 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
683 if (pnode->fNetworkNode || pnode->fInbound)
685 vNodesDisconnected.push_back(pnode);
689 // Delete disconnected nodes
690 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
691 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
693 // wait until threads are done using it
694 if (pnode->GetRefCount() <= 0)
696 bool fDelete = false;
697 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
698 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
699 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
700 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
704 vNodesDisconnected.remove(pnode);
710 if (vNodes.size() != nPrevNodeCount)
712 nPrevNodeCount = vNodes.size();
718 // Find which sockets have data to receive
720 struct timeval timeout;
722 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
729 FD_ZERO(&fdsetError);
730 SOCKET hSocketMax = 0;
732 if(hListenSocket != INVALID_SOCKET)
733 FD_SET(hListenSocket, &fdsetRecv);
734 hSocketMax = max(hSocketMax, hListenSocket);
735 CRITICAL_BLOCK(cs_vNodes)
737 BOOST_FOREACH(CNode* pnode, vNodes)
739 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
741 FD_SET(pnode->hSocket, &fdsetRecv);
742 FD_SET(pnode->hSocket, &fdsetError);
743 hSocketMax = max(hSocketMax, pnode->hSocket);
744 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
745 if (!pnode->vSend.empty())
746 FD_SET(pnode->hSocket, &fdsetSend);
750 vnThreadsRunning[0]--;
751 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
752 vnThreadsRunning[0]++;
755 if (nSelect == SOCKET_ERROR)
757 int nErr = WSAGetLastError();
758 printf("socket select error %d\n", nErr);
759 for (int i = 0; i <= hSocketMax; i++)
760 FD_SET(i, &fdsetRecv);
762 FD_ZERO(&fdsetError);
763 Sleep(timeout.tv_usec/1000);
768 // Accept new connections
770 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
772 struct sockaddr_in sockaddr;
773 socklen_t len = sizeof(sockaddr);
774 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
775 CAddress addr(sockaddr);
778 CRITICAL_BLOCK(cs_vNodes)
779 BOOST_FOREACH(CNode* pnode, vNodes)
782 if (hSocket == INVALID_SOCKET)
784 if (WSAGetLastError() != WSAEWOULDBLOCK)
785 printf("socket error accept failed: %d\n", WSAGetLastError());
787 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
789 closesocket(hSocket);
793 printf("accepted connection %s\n", addr.ToString().c_str());
794 CNode* pnode = new CNode(hSocket, addr, true);
796 CRITICAL_BLOCK(cs_vNodes)
797 vNodes.push_back(pnode);
803 // Service each socket
805 vector<CNode*> vNodesCopy;
806 CRITICAL_BLOCK(cs_vNodes)
809 BOOST_FOREACH(CNode* pnode, vNodesCopy)
812 BOOST_FOREACH(CNode* pnode, vNodesCopy)
820 if (pnode->hSocket == INVALID_SOCKET)
822 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
824 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
826 CDataStream& vRecv = pnode->vRecv;
827 unsigned int nPos = vRecv.size();
829 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
830 if (!pnode->fDisconnect)
831 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
832 pnode->CloseSocketDisconnect();
835 // typical socket buffer is 8K-64K
836 char pchBuf[0x10000];
837 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
840 vRecv.resize(nPos + nBytes);
841 memcpy(&vRecv[nPos], pchBuf, nBytes);
842 pnode->nLastRecv = GetTime();
844 else if (nBytes == 0)
846 // socket closed gracefully
847 if (!pnode->fDisconnect)
848 printf("socket closed\n");
849 pnode->CloseSocketDisconnect();
854 int nErr = WSAGetLastError();
855 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
857 if (!pnode->fDisconnect)
858 printf("socket recv error %d\n", nErr);
859 pnode->CloseSocketDisconnect();
869 if (pnode->hSocket == INVALID_SOCKET)
871 if (FD_ISSET(pnode->hSocket, &fdsetSend))
873 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
875 CDataStream& vSend = pnode->vSend;
878 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
881 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
882 pnode->nLastSend = GetTime();
887 int nErr = WSAGetLastError();
888 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
890 printf("socket send error %d\n", nErr);
891 pnode->CloseSocketDisconnect();
894 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
895 if (!pnode->fDisconnect)
896 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
897 pnode->CloseSocketDisconnect();
904 // Inactivity checking
906 if (pnode->vSend.empty())
907 pnode->nLastSendEmpty = GetTime();
908 if (GetTime() - pnode->nTimeConnected > 60)
910 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
912 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
913 pnode->fDisconnect = true;
915 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
917 printf("socket not sending\n");
918 pnode->fDisconnect = true;
920 else if (GetTime() - pnode->nLastRecv > 90*60)
922 printf("socket inactivity timeout\n");
923 pnode->fDisconnect = true;
927 CRITICAL_BLOCK(cs_vNodes)
929 BOOST_FOREACH(CNode* pnode, vNodesCopy)
946 void ThreadMapPort(void* parg)
948 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
951 vnThreadsRunning[5]++;
952 ThreadMapPort2(parg);
953 vnThreadsRunning[5]--;
955 catch (std::exception& e) {
956 vnThreadsRunning[5]--;
957 PrintException(&e, "ThreadMapPort()");
959 vnThreadsRunning[5]--;
960 PrintException(NULL, "ThreadMapPort()");
962 printf("ThreadMapPort exiting\n");
965 void ThreadMapPort2(void* parg)
967 printf("ThreadMapPort started\n");
970 sprintf(port, "%d", GetDefaultPort());
972 const char * rootdescurl = 0;
973 const char * multicastif = 0;
974 const char * minissdpdpath = 0;
975 struct UPNPDev * devlist = 0;
978 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
980 struct UPNPUrls urls;
981 struct IGDdatas data;
984 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
991 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
992 port, port, lanaddr, 0, "TCP", 0);
994 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
995 port, port, lanaddr, 0, "TCP", 0, "0");
997 if(r!=UPNPCOMMAND_SUCCESS)
998 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
999 port, port, lanaddr, r, strupnperror(r));
1001 printf("UPnP Port Mapping successful.\n");
1003 if (fShutdown || !fUseUPnP)
1005 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1006 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1007 freeUPNPDevlist(devlist); devlist = 0;
1008 FreeUPNPUrls(&urls);
1014 printf("No valid UPnP IGDs found\n");
1015 freeUPNPDevlist(devlist); devlist = 0;
1017 FreeUPNPUrls(&urls);
1019 if (fShutdown || !fUseUPnP)
1026 void MapPort(bool fMapPort)
1028 if (fUseUPnP != fMapPort)
1030 fUseUPnP = fMapPort;
1031 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1033 if (fUseUPnP && vnThreadsRunning[5] < 1)
1035 if (!CreateThread(ThreadMapPort, NULL))
1036 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1050 static const char *strDNSSeed[] = {
1052 "bitseed.bitcoin.org.uk",
1055 void DNSAddressSeed()
1059 printf("Loading addresses from DNS seeds (could take a while)\n");
1061 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1062 vector<CAddress> vaddr;
1063 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1065 BOOST_FOREACH (CAddress& addr, vaddr)
1067 if (addr.GetByte(3) != 127)
1077 printf("%d addresses found from DNS seeds\n", found);
1082 unsigned int pnSeed[] =
1084 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1085 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1086 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1087 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1088 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1089 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1090 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1091 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1092 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1093 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1094 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1095 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1096 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1097 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1098 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1099 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1100 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1101 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1102 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1103 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1104 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1105 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1106 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1107 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1108 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1109 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1110 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1111 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1112 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1113 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1114 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1115 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1116 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1117 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1118 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1119 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1120 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1121 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1122 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1123 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1128 void ThreadOpenConnections(void* parg)
1130 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1133 vnThreadsRunning[1]++;
1134 ThreadOpenConnections2(parg);
1135 vnThreadsRunning[1]--;
1137 catch (std::exception& e) {
1138 vnThreadsRunning[1]--;
1139 PrintException(&e, "ThreadOpenConnections()");
1141 vnThreadsRunning[1]--;
1142 PrintException(NULL, "ThreadOpenConnections()");
1144 printf("ThreadOpenConnections exiting\n");
1147 void ThreadOpenConnections2(void* parg)
1149 printf("ThreadOpenConnections started\n");
1151 // Connect to specific addresses
1152 if (mapArgs.count("-connect"))
1154 for (int64 nLoop = 0;; nLoop++)
1156 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1158 CAddress addr(strAddr, fAllowDNS);
1160 OpenNetworkConnection(addr);
1161 for (int i = 0; i < 10 && i < nLoop; i++)
1171 // Connect to manually added nodes first
1172 if (mapArgs.count("-addnode"))
1174 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1176 CAddress addr(strAddr, fAllowDNS);
1179 OpenNetworkConnection(addr);
1187 // Initiate network connections
1188 int64 nStart = GetTime();
1191 // Limit outbound connections
1192 vnThreadsRunning[1]--;
1197 CRITICAL_BLOCK(cs_vNodes)
1198 BOOST_FOREACH(CNode* pnode, vNodes)
1199 if (!pnode->fInbound)
1201 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1202 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1203 if (nOutbound < nMaxOutboundConnections)
1209 vnThreadsRunning[1]++;
1213 CRITICAL_BLOCK(cs_mapAddresses)
1215 // Add seed nodes if IRC isn't working
1216 static bool fSeedUsed;
1217 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1218 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1220 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1222 // It'll only connect to one or two seed nodes because once it connects,
1223 // it'll get a pile of addresses with newer timestamps.
1225 addr.ip = pnSeed[i];
1232 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1234 // Disconnect seed nodes
1235 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1236 static int64 nSeedDisconnected;
1237 if (nSeedDisconnected == 0)
1239 nSeedDisconnected = GetTime();
1240 CRITICAL_BLOCK(cs_vNodes)
1241 BOOST_FOREACH(CNode* pnode, vNodes)
1242 if (setSeed.count(pnode->addr.ip))
1243 pnode->fDisconnect = true;
1246 // Keep setting timestamps to 0 so they won't reconnect
1247 if (GetTime() - nSeedDisconnected < 60 * 60)
1249 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1251 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1253 item.second.nTime = 0;
1254 CAddrDB().WriteAddress(item.second);
1263 // Choose an address to connect to based on most recently seen
1265 CAddress addrConnect;
1266 int64 nBest = INT64_MIN;
1268 // Only connect to one address per a.b.?.? range.
1269 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1270 set<unsigned int> setConnected;
1271 CRITICAL_BLOCK(cs_vNodes)
1272 BOOST_FOREACH(CNode* pnode, vNodes)
1273 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1275 CRITICAL_BLOCK(cs_mapAddresses)
1277 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1279 const CAddress& addr = item.second;
1280 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1282 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1283 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1285 // Randomize the order in a deterministic way, putting the standard port first
1286 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1287 if (addr.port != htons(GetDefaultPort()))
1288 nRandomizer += 2 * 60 * 60;
1290 // Last seen Base retry frequency
1299 // 365 days 93 hours
1300 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1302 // Fast reconnect for one hour after last seen
1303 if (nSinceLastSeen < 60 * 60)
1306 // Limit retry frequency
1307 if (nSinceLastTry < nDelay)
1310 // If we have IRC, we'll be notified when they first come online,
1311 // and again every 24 hours by the refresh broadcast.
1312 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1315 // Only try the old stuff if we don't have enough connections
1316 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1319 // If multiple addresses are ready, prioritize by time since
1320 // last seen and time since last tried.
1321 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1330 if (addrConnect.IsValid())
1331 OpenNetworkConnection(addrConnect);
1335 bool OpenNetworkConnection(const CAddress& addrConnect)
1338 // Initiate outbound network connection
1342 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1345 vnThreadsRunning[1]--;
1346 CNode* pnode = ConnectNode(addrConnect);
1347 vnThreadsRunning[1]++;
1352 pnode->fNetworkNode = true;
1364 void ThreadMessageHandler(void* parg)
1366 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1369 vnThreadsRunning[2]++;
1370 ThreadMessageHandler2(parg);
1371 vnThreadsRunning[2]--;
1373 catch (std::exception& e) {
1374 vnThreadsRunning[2]--;
1375 PrintException(&e, "ThreadMessageHandler()");
1377 vnThreadsRunning[2]--;
1378 PrintException(NULL, "ThreadMessageHandler()");
1380 printf("ThreadMessageHandler exiting\n");
1383 void ThreadMessageHandler2(void* parg)
1385 printf("ThreadMessageHandler started\n");
1386 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1389 vector<CNode*> vNodesCopy;
1390 CRITICAL_BLOCK(cs_vNodes)
1392 vNodesCopy = vNodes;
1393 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1397 // Poll the connected nodes for messages
1398 CNode* pnodeTrickle = NULL;
1399 if (!vNodesCopy.empty())
1400 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1401 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1404 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1405 ProcessMessages(pnode);
1410 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1411 SendMessages(pnode, pnode == pnodeTrickle);
1416 CRITICAL_BLOCK(cs_vNodes)
1418 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1422 // Wait and allow messages to bunch up.
1423 // Reduce vnThreadsRunning so StopNode has permission to exit while
1424 // we're sleeping, but we must always check fShutdown after doing this.
1425 vnThreadsRunning[2]--;
1427 if (fRequestShutdown)
1429 vnThreadsRunning[2]++;
1443 bool BindListenPort(string& strError)
1447 addrLocalHost.port = htons(GetDefaultPort());
1450 // Initialize Windows Sockets
1452 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1453 if (ret != NO_ERROR)
1455 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1456 printf("%s\n", strError.c_str());
1461 // Create socket for listening for incoming connections
1462 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1463 if (hListenSocket == INVALID_SOCKET)
1465 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1466 printf("%s\n", strError.c_str());
1471 // Different way of disabling SIGPIPE on BSD
1472 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1476 // Allow binding if the port is still in TIME_WAIT state after
1477 // the program was closed and restarted. Not an issue on windows.
1478 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1482 // Set to nonblocking, incoming connections will also inherit this
1483 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1485 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1488 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1489 printf("%s\n", strError.c_str());
1493 // The sockaddr_in structure specifies the address family,
1494 // IP address, and port for the socket that is being bound
1495 struct sockaddr_in sockaddr;
1496 memset(&sockaddr, 0, sizeof(sockaddr));
1497 sockaddr.sin_family = AF_INET;
1498 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1499 sockaddr.sin_port = htons(GetDefaultPort());
1500 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1502 int nErr = WSAGetLastError();
1503 if (nErr == WSAEADDRINUSE)
1504 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1506 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1507 printf("%s\n", strError.c_str());
1510 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1512 // Listen for incoming connections
1513 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1515 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1516 printf("%s\n", strError.c_str());
1523 void StartNode(void* parg)
1525 if (pnodeLocalHost == NULL)
1526 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1529 // Get local host ip
1530 char pszHostName[1000] = "";
1531 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1533 vector<CAddress> vaddr;
1534 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1535 BOOST_FOREACH (const CAddress &addr, vaddr)
1536 if (addr.GetByte(3) != 127)
1538 addrLocalHost = addr;
1543 // Get local host ip
1544 struct ifaddrs* myaddrs;
1545 if (getifaddrs(&myaddrs) == 0)
1547 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1549 if (ifa->ifa_addr == NULL) continue;
1550 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1551 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1552 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1554 if (ifa->ifa_addr->sa_family == AF_INET)
1556 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1557 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1558 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1560 // Take the first IP that isn't loopback 127.x.x.x
1561 CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
1562 if (addr.IsValid() && addr.GetByte(3) != 127)
1564 addrLocalHost = addr;
1568 else if (ifa->ifa_addr->sa_family == AF_INET6)
1570 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1571 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1572 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1575 freeifaddrs(myaddrs);
1578 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1580 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1582 // Proxies can't take incoming connections
1583 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1584 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1588 CreateThread(ThreadGetMyExternalIP, NULL);
1595 // Map ports with UPnP
1599 // Get addresses from IRC and advertise ours
1600 if (!CreateThread(ThreadIRCSeed, NULL))
1601 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1603 // Send and receive from sockets, accept connections
1604 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1606 // Initiate outbound connections
1607 if (!CreateThread(ThreadOpenConnections, NULL))
1608 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1611 if (!CreateThread(ThreadMessageHandler, NULL))
1612 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1614 // Generate coins in the background
1615 GenerateBitcoins(fGenerateBitcoins);
1620 printf("StopNode()\n");
1622 nTransactionsUpdated++;
1623 int64 nStart = GetTime();
1624 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1626 || vnThreadsRunning[5] > 0
1630 if (GetTime() - nStart > 20)
1634 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1635 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1636 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1637 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1638 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1639 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1640 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1656 BOOST_FOREACH(CNode* pnode, vNodes)
1657 if (pnode->hSocket != INVALID_SOCKET)
1658 closesocket(pnode->hSocket);
1659 if (hListenSocket != INVALID_SOCKET)
1660 if (closesocket(hListenSocket) == SOCKET_ERROR)
1661 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1664 // Shutdown Windows Sockets
1669 instance_of_cnetcleanup;