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 fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
92 bool fProxy = (fUseProxy && fRoutable);
93 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
95 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
103 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
104 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
105 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
106 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
107 char* pszSocks4 = pszSocks4IP;
108 int nSize = sizeof(pszSocks4IP);
110 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
113 closesocket(hSocket);
114 return error("Error sending to proxy");
117 if (recv(hSocket, pchRet, 8, 0) != 8)
119 closesocket(hSocket);
120 return error("Error reading proxy response");
122 if (pchRet[1] != 0x5a)
124 closesocket(hSocket);
125 if (pchRet[1] != 0x5b)
126 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
129 printf("proxy connected %s\n", addrConnect.ToString().c_str());
132 hSocketRet = hSocket;
136 // portDefault is in host order
137 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
142 int port = portDefault;
145 strlcpy(psz, pszName, sizeof(psz));
148 char* pszColon = strrchr(psz+1,':');
149 char *pszPortEnd = NULL;
150 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
151 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
153 if (psz[0] == '[' && pszColon[-1] == ']')
155 // Future: enable IPv6 colon-notation inside []
162 if (port < 0 || port > USHRT_MAX)
167 unsigned int addrIP = inet_addr(pszHost);
168 if (addrIP != INADDR_NONE)
170 // valid IP address passed
171 vaddr.push_back(CAddress(addrIP, port, nServices));
178 struct hostent* phostent = gethostbyname(pszHost);
182 if (phostent->h_addrtype != AF_INET)
185 char** ppAddr = phostent->h_addr_list;
186 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
188 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
190 vaddr.push_back(addr);
194 return (vaddr.size() > 0);
197 // portDefault is in host order
198 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
200 vector<CAddress> vaddr;
201 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
207 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
210 if (!ConnectSocket(addrConnect, hSocket))
211 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
213 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
216 while (RecvLine(hSocket, strLine))
218 if (strLine.empty()) // HTTP response is separated from headers by blank line
222 if (!RecvLine(hSocket, strLine))
224 closesocket(hSocket);
227 if (pszKeyword == NULL)
229 if (strLine.find(pszKeyword) != -1)
231 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
235 closesocket(hSocket);
236 if (strLine.find("<") != -1)
237 strLine = strLine.substr(0, strLine.find("<"));
238 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
239 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
240 strLine.resize(strLine.size()-1);
241 CAddress addr(strLine,0,true);
242 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
243 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
249 closesocket(hSocket);
250 return error("GetMyExternalIP() : connection closed");
253 // We now get our external IP from the IRC server first and only use this as a backup
254 bool GetMyExternalIP(unsigned int& ipRet)
256 CAddress addrConnect;
258 const char* pszKeyword;
263 for (int nLookup = 0; nLookup <= 1; nLookup++)
264 for (int nHost = 1; nHost <= 2; nHost++)
266 // We should be phasing out our use of sites like these. If we need
267 // replacements, we should ask for volunteers to put this simple
268 // php file on their webserver that prints the client IP:
269 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
272 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
276 CAddress addrIP("checkip.dyndns.org", 80, true);
277 if (addrIP.IsValid())
278 addrConnect = addrIP;
281 pszGet = "GET / HTTP/1.1\r\n"
282 "Host: checkip.dyndns.org\r\n"
283 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
284 "Connection: close\r\n"
287 pszKeyword = "Address:";
291 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
295 CAddress addrIP("www.showmyip.com", 80, true);
296 if (addrIP.IsValid())
297 addrConnect = addrIP;
300 pszGet = "GET /simple/ HTTP/1.1\r\n"
301 "Host: www.showmyip.com\r\n"
302 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
303 "Connection: close\r\n"
306 pszKeyword = NULL; // Returns just IP address
309 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
316 void ThreadGetMyExternalIP(void* parg)
318 // Wait for IRC to get it first
319 if (!GetBoolArg("-noirc"))
321 for (int i = 0; i < 2 * 60; i++)
324 if (fGotExternalIP || fShutdown)
329 // Fallback in case IRC fails to get it
330 if (GetMyExternalIP(addrLocalHost.ip))
332 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
333 if (addrLocalHost.IsRoutable())
335 // If we already connected to a few before we had our IP, go back and addr them.
336 // setAddrKnown automatically filters any duplicate sends.
337 CAddress addr(addrLocalHost);
338 addr.nTime = GetAdjustedTime();
339 CRITICAL_BLOCK(cs_vNodes)
340 BOOST_FOREACH(CNode* pnode, vNodes)
341 pnode->PushAddress(addr);
350 bool AddAddress(CAddress addr, int64 nTimePenalty)
352 if (!addr.IsRoutable())
354 if (addr.ip == addrLocalHost.ip)
356 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
357 CRITICAL_BLOCK(cs_mapAddresses)
359 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
360 if (it == mapAddresses.end())
363 printf("AddAddress(%s)\n", addr.ToString().c_str());
364 mapAddresses.insert(make_pair(addr.GetKey(), addr));
365 CAddrDB().WriteAddress(addr);
370 bool fUpdated = false;
371 CAddress& addrFound = (*it).second;
372 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
374 // Services have been added
375 addrFound.nServices |= addr.nServices;
378 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
379 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
380 if (addrFound.nTime < addr.nTime - nUpdateInterval)
382 // Periodically update most recently seen time
383 addrFound.nTime = addr.nTime;
387 CAddrDB().WriteAddress(addrFound);
393 void AddressCurrentlyConnected(const CAddress& addr)
395 CRITICAL_BLOCK(cs_mapAddresses)
397 // Only if it's been published already
398 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
399 if (it != mapAddresses.end())
401 CAddress& addrFound = (*it).second;
402 int64 nUpdateInterval = 20 * 60;
403 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
405 // Periodically update most recently seen time
406 addrFound.nTime = GetAdjustedTime();
408 addrdb.WriteAddress(addrFound);
418 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
420 // If the dialog might get closed before the reply comes back,
421 // call this in the destructor so it doesn't get called after it's deleted.
422 CRITICAL_BLOCK(cs_vNodes)
424 BOOST_FOREACH(CNode* pnode, vNodes)
426 CRITICAL_BLOCK(pnode->cs_mapRequests)
428 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
430 CRequestTracker& tracker = (*mi).second;
431 if (tracker.fn == fn && tracker.param1 == param1)
432 pnode->mapRequests.erase(mi++);
448 // Subscription methods for the broadcast and subscription system.
449 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
451 // The subscription system uses a meet-in-the-middle strategy.
452 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
453 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
456 bool AnySubscribed(unsigned int nChannel)
458 if (pnodeLocalHost->IsSubscribed(nChannel))
460 CRITICAL_BLOCK(cs_vNodes)
461 BOOST_FOREACH(CNode* pnode, vNodes)
462 if (pnode->IsSubscribed(nChannel))
467 bool CNode::IsSubscribed(unsigned int nChannel)
469 if (nChannel >= vfSubscribe.size())
471 return vfSubscribe[nChannel];
474 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
476 if (nChannel >= vfSubscribe.size())
479 if (!AnySubscribed(nChannel))
482 CRITICAL_BLOCK(cs_vNodes)
483 BOOST_FOREACH(CNode* pnode, vNodes)
485 pnode->PushMessage("subscribe", nChannel, nHops);
488 vfSubscribe[nChannel] = true;
491 void CNode::CancelSubscribe(unsigned int nChannel)
493 if (nChannel >= vfSubscribe.size())
496 // Prevent from relaying cancel if wasn't subscribed
497 if (!vfSubscribe[nChannel])
499 vfSubscribe[nChannel] = false;
501 if (!AnySubscribed(nChannel))
503 // Relay subscription cancel
504 CRITICAL_BLOCK(cs_vNodes)
505 BOOST_FOREACH(CNode* pnode, vNodes)
507 pnode->PushMessage("sub-cancel", nChannel);
519 CNode* FindNode(unsigned int ip)
521 CRITICAL_BLOCK(cs_vNodes)
523 BOOST_FOREACH(CNode* pnode, vNodes)
524 if (pnode->addr.ip == ip)
530 CNode* FindNode(CAddress addr)
532 CRITICAL_BLOCK(cs_vNodes)
534 BOOST_FOREACH(CNode* pnode, vNodes)
535 if (pnode->addr == addr)
541 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
543 if (addrConnect.ip == addrLocalHost.ip)
546 // Look for an existing connection
547 CNode* pnode = FindNode(addrConnect.ip);
551 pnode->AddRef(nTimeout);
558 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
559 addrConnect.ToString().c_str(),
560 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
561 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
563 CRITICAL_BLOCK(cs_mapAddresses)
564 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
568 if (ConnectSocket(addrConnect, hSocket))
571 printf("connected %s\n", addrConnect.ToString().c_str());
573 // Set to nonblocking
576 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
577 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
579 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
580 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
584 CNode* pnode = new CNode(hSocket, addrConnect, false);
586 pnode->AddRef(nTimeout);
589 CRITICAL_BLOCK(cs_vNodes)
590 vNodes.push_back(pnode);
592 pnode->nTimeConnected = GetTime();
601 void CNode::CloseSocketDisconnect()
604 if (hSocket != INVALID_SOCKET)
607 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
608 printf("disconnecting node %s\n", addr.ToString().c_str());
609 closesocket(hSocket);
610 hSocket = INVALID_SOCKET;
614 void CNode::Cleanup()
616 // All of a nodes broadcasts and subscriptions are automatically torn down
617 // when it goes down, so a node has to stay up to keep its broadcast going.
619 // Cancel subscriptions
620 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
621 if (vfSubscribe[nChannel])
622 CancelSubscribe(nChannel);
637 void ThreadSocketHandler(void* parg)
639 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
642 vnThreadsRunning[0]++;
643 ThreadSocketHandler2(parg);
644 vnThreadsRunning[0]--;
646 catch (std::exception& e) {
647 vnThreadsRunning[0]--;
648 PrintException(&e, "ThreadSocketHandler()");
650 vnThreadsRunning[0]--;
651 throw; // support pthread_cancel()
653 printf("ThreadSocketHandler exiting\n");
656 void ThreadSocketHandler2(void* parg)
658 printf("ThreadSocketHandler started\n");
659 list<CNode*> vNodesDisconnected;
660 int nPrevNodeCount = 0;
667 CRITICAL_BLOCK(cs_vNodes)
669 // Disconnect unused nodes
670 vector<CNode*> vNodesCopy = vNodes;
671 BOOST_FOREACH(CNode* pnode, vNodesCopy)
673 if (pnode->fDisconnect ||
674 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
676 // remove from vNodes
677 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
679 // close socket and cleanup
680 pnode->CloseSocketDisconnect();
683 // hold in disconnected pool until all refs are released
684 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
685 if (pnode->fNetworkNode || pnode->fInbound)
687 vNodesDisconnected.push_back(pnode);
691 // Delete disconnected nodes
692 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
693 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
695 // wait until threads are done using it
696 if (pnode->GetRefCount() <= 0)
698 bool fDelete = false;
699 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
700 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
701 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
702 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
706 vNodesDisconnected.remove(pnode);
712 if (vNodes.size() != nPrevNodeCount)
714 nPrevNodeCount = vNodes.size();
720 // Find which sockets have data to receive
722 struct timeval timeout;
724 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
731 FD_ZERO(&fdsetError);
732 SOCKET hSocketMax = 0;
734 if(hListenSocket != INVALID_SOCKET)
735 FD_SET(hListenSocket, &fdsetRecv);
736 hSocketMax = max(hSocketMax, hListenSocket);
737 CRITICAL_BLOCK(cs_vNodes)
739 BOOST_FOREACH(CNode* pnode, vNodes)
741 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
743 FD_SET(pnode->hSocket, &fdsetRecv);
744 FD_SET(pnode->hSocket, &fdsetError);
745 hSocketMax = max(hSocketMax, pnode->hSocket);
746 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
747 if (!pnode->vSend.empty())
748 FD_SET(pnode->hSocket, &fdsetSend);
752 vnThreadsRunning[0]--;
753 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
754 vnThreadsRunning[0]++;
757 if (nSelect == SOCKET_ERROR)
759 int nErr = WSAGetLastError();
760 printf("socket select error %d\n", nErr);
761 for (int i = 0; i <= hSocketMax; i++)
762 FD_SET(i, &fdsetRecv);
764 FD_ZERO(&fdsetError);
765 Sleep(timeout.tv_usec/1000);
770 // Accept new connections
772 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
774 struct sockaddr_in sockaddr;
775 socklen_t len = sizeof(sockaddr);
776 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
777 CAddress addr(sockaddr);
780 CRITICAL_BLOCK(cs_vNodes)
781 BOOST_FOREACH(CNode* pnode, vNodes)
784 if (hSocket == INVALID_SOCKET)
786 if (WSAGetLastError() != WSAEWOULDBLOCK)
787 printf("socket error accept failed: %d\n", WSAGetLastError());
789 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
791 closesocket(hSocket);
795 printf("accepted connection %s\n", addr.ToString().c_str());
796 CNode* pnode = new CNode(hSocket, addr, true);
798 CRITICAL_BLOCK(cs_vNodes)
799 vNodes.push_back(pnode);
805 // Service each socket
807 vector<CNode*> vNodesCopy;
808 CRITICAL_BLOCK(cs_vNodes)
811 BOOST_FOREACH(CNode* pnode, vNodesCopy)
814 BOOST_FOREACH(CNode* pnode, vNodesCopy)
822 if (pnode->hSocket == INVALID_SOCKET)
824 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
826 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
828 CDataStream& vRecv = pnode->vRecv;
829 unsigned int nPos = vRecv.size();
831 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
832 if (!pnode->fDisconnect)
833 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
834 pnode->CloseSocketDisconnect();
837 // typical socket buffer is 8K-64K
838 char pchBuf[0x10000];
839 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
842 vRecv.resize(nPos + nBytes);
843 memcpy(&vRecv[nPos], pchBuf, nBytes);
844 pnode->nLastRecv = GetTime();
846 else if (nBytes == 0)
848 // socket closed gracefully
849 if (!pnode->fDisconnect)
850 printf("socket closed\n");
851 pnode->CloseSocketDisconnect();
856 int nErr = WSAGetLastError();
857 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
859 if (!pnode->fDisconnect)
860 printf("socket recv error %d\n", nErr);
861 pnode->CloseSocketDisconnect();
871 if (pnode->hSocket == INVALID_SOCKET)
873 if (FD_ISSET(pnode->hSocket, &fdsetSend))
875 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
877 CDataStream& vSend = pnode->vSend;
880 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
883 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
884 pnode->nLastSend = GetTime();
889 int nErr = WSAGetLastError();
890 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
892 printf("socket send error %d\n", nErr);
893 pnode->CloseSocketDisconnect();
896 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
897 if (!pnode->fDisconnect)
898 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
899 pnode->CloseSocketDisconnect();
906 // Inactivity checking
908 if (pnode->vSend.empty())
909 pnode->nLastSendEmpty = GetTime();
910 if (GetTime() - pnode->nTimeConnected > 60)
912 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
914 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
915 pnode->fDisconnect = true;
917 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
919 printf("socket not sending\n");
920 pnode->fDisconnect = true;
922 else if (GetTime() - pnode->nLastRecv > 90*60)
924 printf("socket inactivity timeout\n");
925 pnode->fDisconnect = true;
929 CRITICAL_BLOCK(cs_vNodes)
931 BOOST_FOREACH(CNode* pnode, vNodesCopy)
948 void ThreadMapPort(void* parg)
950 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
953 vnThreadsRunning[5]++;
954 ThreadMapPort2(parg);
955 vnThreadsRunning[5]--;
957 catch (std::exception& e) {
958 vnThreadsRunning[5]--;
959 PrintException(&e, "ThreadMapPort()");
961 vnThreadsRunning[5]--;
962 PrintException(NULL, "ThreadMapPort()");
964 printf("ThreadMapPort exiting\n");
967 void ThreadMapPort2(void* parg)
969 printf("ThreadMapPort started\n");
972 sprintf(port, "%d", GetListenPort());
974 const char * rootdescurl = 0;
975 const char * multicastif = 0;
976 const char * minissdpdpath = 0;
977 struct UPNPDev * devlist = 0;
980 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
982 struct UPNPUrls urls;
983 struct IGDdatas data;
986 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
993 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
994 port, port, lanaddr, 0, "TCP", 0);
996 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
997 port, port, lanaddr, 0, "TCP", 0, "0");
999 if(r!=UPNPCOMMAND_SUCCESS)
1000 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1001 port, port, lanaddr, r, strupnperror(r));
1003 printf("UPnP Port Mapping successful.\n");
1005 if (fShutdown || !fUseUPnP)
1007 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1008 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1009 freeUPNPDevlist(devlist); devlist = 0;
1010 FreeUPNPUrls(&urls);
1016 printf("No valid UPnP IGDs found\n");
1017 freeUPNPDevlist(devlist); devlist = 0;
1019 FreeUPNPUrls(&urls);
1021 if (fShutdown || !fUseUPnP)
1028 void MapPort(bool fMapPort)
1030 if (fUseUPnP != fMapPort)
1032 fUseUPnP = fMapPort;
1033 CWalletDB().WriteSetting("fUseUPnP", fUseUPnP);
1035 if (fUseUPnP && vnThreadsRunning[5] < 1)
1037 if (!CreateThread(ThreadMapPort, NULL))
1038 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1052 static const char *strDNSSeed[] = {
1054 "bitseed.bitcoin.org.uk",
1057 void DNSAddressSeed()
1061 printf("Loading addresses from DNS seeds (could take a while)\n");
1063 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1064 vector<CAddress> vaddr;
1065 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
1067 BOOST_FOREACH (CAddress& addr, vaddr)
1069 if (addr.GetByte(3) != 127)
1079 printf("%d addresses found from DNS seeds\n", found);
1084 unsigned int pnSeed[] =
1086 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1087 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1088 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1089 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1090 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1091 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1092 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1093 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1094 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1095 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1096 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1097 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1098 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1099 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1100 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1101 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1102 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1103 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1104 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1105 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1106 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1107 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1108 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1109 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1110 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1111 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1112 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1113 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1114 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1115 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1116 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1117 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1118 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1119 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1120 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1121 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1122 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1123 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1124 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1125 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1130 void ThreadOpenConnections(void* parg)
1132 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1135 vnThreadsRunning[1]++;
1136 ThreadOpenConnections2(parg);
1137 vnThreadsRunning[1]--;
1139 catch (std::exception& e) {
1140 vnThreadsRunning[1]--;
1141 PrintException(&e, "ThreadOpenConnections()");
1143 vnThreadsRunning[1]--;
1144 PrintException(NULL, "ThreadOpenConnections()");
1146 printf("ThreadOpenConnections exiting\n");
1149 void ThreadOpenConnections2(void* parg)
1151 printf("ThreadOpenConnections started\n");
1153 // Connect to specific addresses
1154 if (mapArgs.count("-connect"))
1156 for (int64 nLoop = 0;; nLoop++)
1158 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1160 CAddress addr(strAddr, fAllowDNS);
1162 OpenNetworkConnection(addr);
1163 for (int i = 0; i < 10 && i < nLoop; i++)
1173 // Connect to manually added nodes first
1174 if (mapArgs.count("-addnode"))
1176 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1178 CAddress addr(strAddr, fAllowDNS);
1181 OpenNetworkConnection(addr);
1189 // Initiate network connections
1190 int64 nStart = GetTime();
1193 // Limit outbound connections
1194 vnThreadsRunning[1]--;
1199 CRITICAL_BLOCK(cs_vNodes)
1200 BOOST_FOREACH(CNode* pnode, vNodes)
1201 if (!pnode->fInbound)
1203 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1204 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1205 if (nOutbound < nMaxOutboundConnections)
1211 vnThreadsRunning[1]++;
1215 CRITICAL_BLOCK(cs_mapAddresses)
1217 // Add seed nodes if IRC isn't working
1218 static bool fSeedUsed;
1219 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1220 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1222 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1224 // It'll only connect to one or two seed nodes because once it connects,
1225 // it'll get a pile of addresses with newer timestamps.
1227 addr.ip = pnSeed[i];
1234 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1236 // Disconnect seed nodes
1237 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1238 static int64 nSeedDisconnected;
1239 if (nSeedDisconnected == 0)
1241 nSeedDisconnected = GetTime();
1242 CRITICAL_BLOCK(cs_vNodes)
1243 BOOST_FOREACH(CNode* pnode, vNodes)
1244 if (setSeed.count(pnode->addr.ip))
1245 pnode->fDisconnect = true;
1248 // Keep setting timestamps to 0 so they won't reconnect
1249 if (GetTime() - nSeedDisconnected < 60 * 60)
1251 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1253 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1255 item.second.nTime = 0;
1256 CAddrDB().WriteAddress(item.second);
1265 // Choose an address to connect to based on most recently seen
1267 CAddress addrConnect;
1268 int64 nBest = INT64_MIN;
1270 // Only connect to one address per a.b.?.? range.
1271 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1272 set<unsigned int> setConnected;
1273 CRITICAL_BLOCK(cs_vNodes)
1274 BOOST_FOREACH(CNode* pnode, vNodes)
1275 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1277 CRITICAL_BLOCK(cs_mapAddresses)
1279 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1281 const CAddress& addr = item.second;
1282 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1284 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1285 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1287 // Randomize the order in a deterministic way, putting the standard port first
1288 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1289 if (addr.port != htons(GetDefaultPort()))
1290 nRandomizer += 2 * 60 * 60;
1292 // Last seen Base retry frequency
1301 // 365 days 93 hours
1302 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1304 // Fast reconnect for one hour after last seen
1305 if (nSinceLastSeen < 60 * 60)
1308 // Limit retry frequency
1309 if (nSinceLastTry < nDelay)
1312 // If we have IRC, we'll be notified when they first come online,
1313 // and again every 24 hours by the refresh broadcast.
1314 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1317 // Only try the old stuff if we don't have enough connections
1318 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1321 // If multiple addresses are ready, prioritize by time since
1322 // last seen and time since last tried.
1323 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1332 if (addrConnect.IsValid())
1333 OpenNetworkConnection(addrConnect);
1337 bool OpenNetworkConnection(const CAddress& addrConnect)
1340 // Initiate outbound network connection
1344 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1347 vnThreadsRunning[1]--;
1348 CNode* pnode = ConnectNode(addrConnect);
1349 vnThreadsRunning[1]++;
1354 pnode->fNetworkNode = true;
1366 void ThreadMessageHandler(void* parg)
1368 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1371 vnThreadsRunning[2]++;
1372 ThreadMessageHandler2(parg);
1373 vnThreadsRunning[2]--;
1375 catch (std::exception& e) {
1376 vnThreadsRunning[2]--;
1377 PrintException(&e, "ThreadMessageHandler()");
1379 vnThreadsRunning[2]--;
1380 PrintException(NULL, "ThreadMessageHandler()");
1382 printf("ThreadMessageHandler exiting\n");
1385 void ThreadMessageHandler2(void* parg)
1387 printf("ThreadMessageHandler started\n");
1388 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1391 vector<CNode*> vNodesCopy;
1392 CRITICAL_BLOCK(cs_vNodes)
1394 vNodesCopy = vNodes;
1395 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1399 // Poll the connected nodes for messages
1400 CNode* pnodeTrickle = NULL;
1401 if (!vNodesCopy.empty())
1402 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1403 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1406 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1407 ProcessMessages(pnode);
1412 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1413 SendMessages(pnode, pnode == pnodeTrickle);
1418 CRITICAL_BLOCK(cs_vNodes)
1420 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1424 // Wait and allow messages to bunch up.
1425 // Reduce vnThreadsRunning so StopNode has permission to exit while
1426 // we're sleeping, but we must always check fShutdown after doing this.
1427 vnThreadsRunning[2]--;
1429 if (fRequestShutdown)
1431 vnThreadsRunning[2]++;
1442 bool BindListenPort(string& strError)
1446 addrLocalHost.port = htons(GetListenPort());
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(GetListenPort());
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, GetListenPort(), 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;