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