1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
18 #include <miniupnpc/miniwget.h>
19 #include <miniupnpc/miniupnpc.h>
20 #include <miniupnpc/upnpcommands.h>
21 #include <miniupnpc/upnperrors.h>
25 using namespace boost;
27 static const int MAX_OUTBOUND_CONNECTIONS = 8;
29 void ThreadMessageHandler2(void* parg);
30 void ThreadSocketHandler2(void* parg);
31 void ThreadOpenConnections2(void* parg);
32 void ThreadOpenAddedConnections2(void* parg);
34 void ThreadMapPort2(void* parg);
36 void ThreadDNSAddressSeed2(void* parg);
37 bool OpenNetworkConnection(const CAddress& addrConnect);
42 // Global state variables
45 bool fAllowDNS = false;
46 static bool fUseUPnP = false;
47 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
48 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
49 static CNode* pnodeLocalHost = NULL;
50 uint64 nLocalHostNonce = 0;
51 array<int, THREAD_MAX> vnThreadsRunning;
52 static SOCKET hListenSocket = INVALID_SOCKET;
54 vector<CNode*> vNodes;
55 CCriticalSection cs_vNodes;
56 map<vector<unsigned char>, CAddress> mapAddresses;
57 CCriticalSection cs_mapAddresses;
58 map<CInv, CDataStream> mapRelay;
59 deque<pair<int64, CInv> > vRelayExpiration;
60 CCriticalSection cs_mapRelay;
61 map<CInv, int64> mapAlreadyAskedFor;
64 set<CNetAddr> setservAddNodeAddresses;
65 CCriticalSection cs_setservAddNodeAddresses;
69 unsigned short GetListenPort()
71 return (unsigned short)(GetArg("-port", GetDefaultPort()));
74 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
76 // Filter out duplicate requests
77 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
79 pindexLastGetBlocksBegin = pindexBegin;
80 hashLastGetBlocksEnd = hashEnd;
82 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
87 bool RecvLine(SOCKET hSocket, string& strLine)
93 int nBytes = recv(hSocket, &c, 1, 0);
101 if (strLine.size() >= 9000)
104 else if (nBytes <= 0)
110 int nErr = WSAGetLastError();
111 if (nErr == WSAEMSGSIZE)
113 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
119 if (!strLine.empty())
124 printf("socket closed\n");
130 int nErr = WSAGetLastError();
131 printf("recv failed: %d\n", nErr);
140 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
143 if (!ConnectSocket(addrConnect, hSocket))
144 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
146 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
149 while (RecvLine(hSocket, strLine))
151 if (strLine.empty()) // HTTP response is separated from headers by blank line
155 if (!RecvLine(hSocket, strLine))
157 closesocket(hSocket);
160 if (pszKeyword == NULL)
162 if (strLine.find(pszKeyword) != -1)
164 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
168 closesocket(hSocket);
169 if (strLine.find("<") != -1)
170 strLine = strLine.substr(0, strLine.find("<"));
171 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
172 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
173 strLine.resize(strLine.size()-1);
174 CService addr(strLine,0,true);
175 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
176 if (!addr.IsValid() || !addr.IsRoutable())
182 closesocket(hSocket);
183 return error("GetMyExternalIP() : connection closed");
186 // We now get our external IP from the IRC server first and only use this as a backup
187 bool GetMyExternalIP(CNetAddr& ipRet)
189 CService addrConnect;
191 const char* pszKeyword;
193 if (fNoListen||fUseProxy)
196 for (int nLookup = 0; nLookup <= 1; nLookup++)
197 for (int nHost = 1; nHost <= 2; nHost++)
199 // We should be phasing out our use of sites like these. If we need
200 // replacements, we should ask for volunteers to put this simple
201 // php file on their webserver that prints the client IP:
202 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
205 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
209 CService addrIP("checkip.dyndns.org", 80, true);
210 if (addrIP.IsValid())
211 addrConnect = addrIP;
214 pszGet = "GET / HTTP/1.1\r\n"
215 "Host: checkip.dyndns.org\r\n"
216 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
217 "Connection: close\r\n"
220 pszKeyword = "Address:";
224 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
228 CService addrIP("www.showmyip.com", 80, true);
229 if (addrIP.IsValid())
230 addrConnect = addrIP;
233 pszGet = "GET /simple/ HTTP/1.1\r\n"
234 "Host: www.showmyip.com\r\n"
235 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
236 "Connection: close\r\n"
239 pszKeyword = NULL; // Returns just IP address
242 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
249 void ThreadGetMyExternalIP(void* parg)
251 // Wait for IRC to get it first
252 if (GetBoolArg("-irc", false))
254 for (int i = 0; i < 2 * 60; i++)
257 if (fGotExternalIP || fShutdown)
262 // Fallback in case IRC fails to get it
263 if (GetMyExternalIP(addrLocalHost))
265 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
266 if (addrLocalHost.IsRoutable())
268 // If we already connected to a few before we had our IP, go back and addr them.
269 // setAddrKnown automatically filters any duplicate sends.
270 CAddress addr(addrLocalHost);
271 addr.nTime = GetAdjustedTime();
272 CRITICAL_BLOCK(cs_vNodes)
273 BOOST_FOREACH(CNode* pnode, vNodes)
274 pnode->PushAddress(addr);
283 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
285 if (!addr.IsRoutable())
287 if ((CService)addr == (CService)addrLocalHost)
289 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
290 bool fUpdated = false;
292 CAddress addrFound = addr;
294 CRITICAL_BLOCK(cs_mapAddresses)
296 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
297 if (it == mapAddresses.end())
300 printf("AddAddress(%s)\n", addr.ToString().c_str());
301 mapAddresses.insert(make_pair(addr.GetKey(), addr));
307 addrFound = (*it).second;
308 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
310 // Services have been added
311 addrFound.nServices |= addr.nServices;
314 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
315 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
316 if (addrFound.nTime < addr.nTime - nUpdateInterval)
318 // Periodically update most recently seen time
319 addrFound.nTime = addr.nTime;
324 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
326 // Thread 1: begin db transaction (locks inside-db-mutex)
327 // then AddAddress (locks cs_mapAddresses)
328 // Thread 2: AddAddress (locks cs_mapAddresses)
329 // ... then db operation hangs waiting for inside-db-mutex
333 pAddrDB->WriteAddress(addrFound);
335 CAddrDB().WriteAddress(addrFound);
340 void AddressCurrentlyConnected(const CService& addr)
342 CAddress *paddrFound = NULL;
344 CRITICAL_BLOCK(cs_mapAddresses)
346 // Only if it's been published already
347 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
348 if (it != mapAddresses.end())
349 paddrFound = &(*it).second;
354 int64 nUpdateInterval = 20 * 60;
355 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
357 // Periodically update most recently seen time
358 paddrFound->nTime = GetAdjustedTime();
360 addrdb.WriteAddress(*paddrFound);
369 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
371 // If the dialog might get closed before the reply comes back,
372 // call this in the destructor so it doesn't get called after it's deleted.
373 CRITICAL_BLOCK(cs_vNodes)
375 BOOST_FOREACH(CNode* pnode, vNodes)
377 CRITICAL_BLOCK(pnode->cs_mapRequests)
379 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
381 CRequestTracker& tracker = (*mi).second;
382 if (tracker.fn == fn && tracker.param1 == param1)
383 pnode->mapRequests.erase(mi++);
399 // Subscription methods for the broadcast and subscription system.
400 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
402 // The subscription system uses a meet-in-the-middle strategy.
403 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
404 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
407 bool AnySubscribed(unsigned int nChannel)
409 if (pnodeLocalHost->IsSubscribed(nChannel))
411 CRITICAL_BLOCK(cs_vNodes)
412 BOOST_FOREACH(CNode* pnode, vNodes)
413 if (pnode->IsSubscribed(nChannel))
418 bool CNode::IsSubscribed(unsigned int nChannel)
420 if (nChannel >= vfSubscribe.size())
422 return vfSubscribe[nChannel];
425 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
427 if (nChannel >= vfSubscribe.size())
430 if (!AnySubscribed(nChannel))
433 CRITICAL_BLOCK(cs_vNodes)
434 BOOST_FOREACH(CNode* pnode, vNodes)
436 pnode->PushMessage("subscribe", nChannel, nHops);
439 vfSubscribe[nChannel] = true;
442 void CNode::CancelSubscribe(unsigned int nChannel)
444 if (nChannel >= vfSubscribe.size())
447 // Prevent from relaying cancel if wasn't subscribed
448 if (!vfSubscribe[nChannel])
450 vfSubscribe[nChannel] = false;
452 if (!AnySubscribed(nChannel))
454 // Relay subscription cancel
455 CRITICAL_BLOCK(cs_vNodes)
456 BOOST_FOREACH(CNode* pnode, vNodes)
458 pnode->PushMessage("sub-cancel", nChannel);
470 CNode* FindNode(const CNetAddr& ip)
472 CRITICAL_BLOCK(cs_vNodes)
474 BOOST_FOREACH(CNode* pnode, vNodes)
475 if ((CNetAddr)pnode->addr == ip)
481 CNode* FindNode(const CService& addr)
483 CRITICAL_BLOCK(cs_vNodes)
485 BOOST_FOREACH(CNode* pnode, vNodes)
486 if ((CService)pnode->addr == addr)
492 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
494 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
497 // Look for an existing connection
498 CNode* pnode = FindNode((CService)addrConnect);
502 pnode->AddRef(nTimeout);
509 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
510 addrConnect.ToString().c_str(),
511 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
512 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
514 CRITICAL_BLOCK(cs_mapAddresses)
515 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
519 if (ConnectSocket(addrConnect, hSocket))
522 printf("connected %s\n", addrConnect.ToString().c_str());
524 // Set to nonblocking
527 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
528 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
530 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
531 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
535 CNode* pnode = new CNode(hSocket, addrConnect, false);
537 pnode->AddRef(nTimeout);
540 CRITICAL_BLOCK(cs_vNodes)
541 vNodes.push_back(pnode);
543 pnode->nTimeConnected = GetTime();
552 void CNode::CloseSocketDisconnect()
555 if (hSocket != INVALID_SOCKET)
558 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
559 printf("disconnecting node %s\n", addr.ToString().c_str());
560 closesocket(hSocket);
561 hSocket = INVALID_SOCKET;
566 void CNode::Cleanup()
568 // All of a nodes broadcasts and subscriptions are automatically torn down
569 // when it goes down, so a node has to stay up to keep its broadcast going.
571 // Cancel subscriptions
572 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
573 if (vfSubscribe[nChannel])
574 CancelSubscribe(nChannel);
578 void CNode::PushVersion()
580 /// when NTP implemented, change to just nTime = GetAdjustedTime()
581 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
582 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
583 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
584 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
585 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
586 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
593 std::map<CNetAddr, int64> CNode::setBanned;
594 CCriticalSection CNode::cs_setBanned;
596 void CNode::ClearBanned()
601 bool CNode::IsBanned(CNetAddr ip)
603 bool fResult = false;
604 CRITICAL_BLOCK(cs_setBanned)
606 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
607 if (i != setBanned.end())
609 int64 t = (*i).second;
617 bool CNode::Misbehaving(int howmuch)
621 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
625 nMisbehavior += howmuch;
626 if (nMisbehavior >= GetArg("-banscore", 100))
628 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
629 CRITICAL_BLOCK(cs_setBanned)
630 if (setBanned[addr] < banTime)
631 setBanned[addr] = banTime;
632 CloseSocketDisconnect();
633 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
650 void ThreadSocketHandler(void* parg)
652 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
655 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
656 ThreadSocketHandler2(parg);
657 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
659 catch (std::exception& e) {
660 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
661 PrintException(&e, "ThreadSocketHandler()");
663 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
664 throw; // support pthread_cancel()
666 printf("ThreadSocketHandler exiting\n");
669 void ThreadSocketHandler2(void* parg)
671 printf("ThreadSocketHandler started\n");
672 list<CNode*> vNodesDisconnected;
673 int nPrevNodeCount = 0;
680 CRITICAL_BLOCK(cs_vNodes)
682 // Disconnect unused nodes
683 vector<CNode*> vNodesCopy = vNodes;
684 BOOST_FOREACH(CNode* pnode, vNodesCopy)
686 if (pnode->fDisconnect ||
687 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
689 // remove from vNodes
690 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
692 // close socket and cleanup
693 pnode->CloseSocketDisconnect();
696 // hold in disconnected pool until all refs are released
697 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
698 if (pnode->fNetworkNode || pnode->fInbound)
700 vNodesDisconnected.push_back(pnode);
704 // Delete disconnected nodes
705 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
706 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
708 // wait until threads are done using it
709 if (pnode->GetRefCount() <= 0)
711 bool fDelete = false;
712 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
713 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
714 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
715 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
719 vNodesDisconnected.remove(pnode);
725 if (vNodes.size() != nPrevNodeCount)
727 nPrevNodeCount = vNodes.size();
733 // Find which sockets have data to receive
735 struct timeval timeout;
737 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
744 FD_ZERO(&fdsetError);
745 SOCKET hSocketMax = 0;
747 if(hListenSocket != INVALID_SOCKET)
748 FD_SET(hListenSocket, &fdsetRecv);
749 hSocketMax = max(hSocketMax, hListenSocket);
750 CRITICAL_BLOCK(cs_vNodes)
752 BOOST_FOREACH(CNode* pnode, vNodes)
754 if (pnode->hSocket == INVALID_SOCKET)
756 FD_SET(pnode->hSocket, &fdsetRecv);
757 FD_SET(pnode->hSocket, &fdsetError);
758 hSocketMax = max(hSocketMax, pnode->hSocket);
759 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
760 if (!pnode->vSend.empty())
761 FD_SET(pnode->hSocket, &fdsetSend);
765 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
766 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
767 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
770 if (nSelect == SOCKET_ERROR)
772 int nErr = WSAGetLastError();
775 printf("socket select error %d\n", nErr);
776 for (int i = 0; i <= hSocketMax; i++)
777 FD_SET(i, &fdsetRecv);
780 FD_ZERO(&fdsetError);
781 Sleep(timeout.tv_usec/1000);
786 // Accept new connections
788 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
790 struct sockaddr_in sockaddr;
791 socklen_t len = sizeof(sockaddr);
792 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
796 if (hSocket != INVALID_SOCKET)
797 addr = CAddress(sockaddr);
799 CRITICAL_BLOCK(cs_vNodes)
800 BOOST_FOREACH(CNode* pnode, vNodes)
804 if (hSocket == INVALID_SOCKET)
806 if (WSAGetLastError() != WSAEWOULDBLOCK)
807 printf("socket error accept failed: %d\n", WSAGetLastError());
809 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
811 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
812 if (!setservAddNodeAddresses.count(addr))
813 closesocket(hSocket);
815 else if (CNode::IsBanned(addr))
817 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
818 closesocket(hSocket);
822 printf("accepted connection %s\n", addr.ToString().c_str());
823 CNode* pnode = new CNode(hSocket, addr, true);
825 CRITICAL_BLOCK(cs_vNodes)
826 vNodes.push_back(pnode);
832 // Service each socket
834 vector<CNode*> vNodesCopy;
835 CRITICAL_BLOCK(cs_vNodes)
838 BOOST_FOREACH(CNode* pnode, vNodesCopy)
841 BOOST_FOREACH(CNode* pnode, vNodesCopy)
849 if (pnode->hSocket == INVALID_SOCKET)
851 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
853 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
855 CDataStream& vRecv = pnode->vRecv;
856 unsigned int nPos = vRecv.size();
858 if (nPos > ReceiveBufferSize()) {
859 if (!pnode->fDisconnect)
860 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
861 pnode->CloseSocketDisconnect();
864 // typical socket buffer is 8K-64K
865 char pchBuf[0x10000];
866 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
869 vRecv.resize(nPos + nBytes);
870 memcpy(&vRecv[nPos], pchBuf, nBytes);
871 pnode->nLastRecv = GetTime();
873 else if (nBytes == 0)
875 // socket closed gracefully
876 if (!pnode->fDisconnect)
877 printf("socket closed\n");
878 pnode->CloseSocketDisconnect();
883 int nErr = WSAGetLastError();
884 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
886 if (!pnode->fDisconnect)
887 printf("socket recv error %d\n", nErr);
888 pnode->CloseSocketDisconnect();
898 if (pnode->hSocket == INVALID_SOCKET)
900 if (FD_ISSET(pnode->hSocket, &fdsetSend))
902 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
904 CDataStream& vSend = pnode->vSend;
907 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
910 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
911 pnode->nLastSend = GetTime();
916 int nErr = WSAGetLastError();
917 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
919 printf("socket send error %d\n", nErr);
920 pnode->CloseSocketDisconnect();
923 if (vSend.size() > SendBufferSize()) {
924 if (!pnode->fDisconnect)
925 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
926 pnode->CloseSocketDisconnect();
933 // Inactivity checking
935 if (pnode->vSend.empty())
936 pnode->nLastSendEmpty = GetTime();
937 if (GetTime() - pnode->nTimeConnected > 60)
939 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
941 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
942 pnode->fDisconnect = true;
944 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
946 printf("socket not sending\n");
947 pnode->fDisconnect = true;
949 else if (GetTime() - pnode->nLastRecv > 90*60)
951 printf("socket inactivity timeout\n");
952 pnode->fDisconnect = true;
956 CRITICAL_BLOCK(cs_vNodes)
958 BOOST_FOREACH(CNode* pnode, vNodesCopy)
975 void ThreadMapPort(void* parg)
977 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
980 vnThreadsRunning[THREAD_UPNP]++;
981 ThreadMapPort2(parg);
982 vnThreadsRunning[THREAD_UPNP]--;
984 catch (std::exception& e) {
985 vnThreadsRunning[THREAD_UPNP]--;
986 PrintException(&e, "ThreadMapPort()");
988 vnThreadsRunning[THREAD_UPNP]--;
989 PrintException(NULL, "ThreadMapPort()");
991 printf("ThreadMapPort exiting\n");
994 void ThreadMapPort2(void* parg)
996 printf("ThreadMapPort started\n");
999 sprintf(port, "%d", GetListenPort());
1001 const char * multicastif = 0;
1002 const char * minissdpdpath = 0;
1003 struct UPNPDev * devlist = 0;
1006 #ifndef UPNPDISCOVER_SUCCESS
1008 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1012 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1015 struct UPNPUrls urls;
1016 struct IGDdatas data;
1019 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1022 if (!addrLocalHost.IsRoutable())
1024 char externalIPAddress[40];
1025 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1026 if(r != UPNPCOMMAND_SUCCESS)
1027 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1030 if(externalIPAddress[0])
1032 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1033 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
1034 if (addrExternalFromUPnP.IsRoutable())
1035 addrLocalHost = addrExternalFromUPnP;
1038 printf("UPnP: GetExternalIPAddress failed.\n");
1042 string strDesc = "Bitcoin " + FormatFullVersion();
1043 #ifndef UPNPDISCOVER_SUCCESS
1045 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1046 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1049 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1050 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1053 if(r!=UPNPCOMMAND_SUCCESS)
1054 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1055 port, port, lanaddr, r, strupnperror(r));
1057 printf("UPnP Port Mapping successful.\n");
1060 if (fShutdown || !fUseUPnP)
1062 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1063 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1064 freeUPNPDevlist(devlist); devlist = 0;
1065 FreeUPNPUrls(&urls);
1068 if (i % 600 == 0) // Refresh every 20 minutes
1070 #ifndef UPNPDISCOVER_SUCCESS
1072 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1073 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1076 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1077 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1080 if(r!=UPNPCOMMAND_SUCCESS)
1081 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1082 port, port, lanaddr, r, strupnperror(r));
1084 printf("UPnP Port Mapping successful.\n");;
1090 printf("No valid UPnP IGDs found\n");
1091 freeUPNPDevlist(devlist); devlist = 0;
1093 FreeUPNPUrls(&urls);
1095 if (fShutdown || !fUseUPnP)
1102 void MapPort(bool fMapPort)
1104 if (fUseUPnP != fMapPort)
1106 fUseUPnP = fMapPort;
1108 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1110 if (!CreateThread(ThreadMapPort, NULL))
1111 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1115 void MapPort(bool /* unused fMapPort */)
1117 // Intentionally left blank.
1130 static const char *strDNSSeed[] = {
1132 "dnsseed.bluematt.me",
1133 "seed.bitcoin.sipa.be",
1134 "dnsseed.bitcoin.dashjr.org",
1137 void ThreadDNSAddressSeed(void* parg)
1139 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1142 vnThreadsRunning[THREAD_DNSSEED]++;
1143 ThreadDNSAddressSeed2(parg);
1144 vnThreadsRunning[THREAD_DNSSEED]--;
1146 catch (std::exception& e) {
1147 vnThreadsRunning[THREAD_DNSSEED]--;
1148 PrintException(&e, "ThreadDNSAddressSeed()");
1150 vnThreadsRunning[THREAD_DNSSEED]--;
1151 throw; // support pthread_cancel()
1153 printf("ThreadDNSAddressSeed exiting\n");
1156 void ThreadDNSAddressSeed2(void* parg)
1158 printf("ThreadDNSAddressSeed started\n");
1163 printf("Loading addresses from DNS seeds (could take a while)\n");
1165 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1166 vector<CNetAddr> vaddr;
1167 if (LookupHost(strDNSSeed[seed_idx], vaddr))
1171 BOOST_FOREACH (CNetAddr& ip, vaddr)
1173 if (ip.IsRoutable())
1175 CAddress addr(CService(ip, GetDefaultPort()), NODE_NETWORK);
1177 AddAddress(addr, 0, &addrDB);
1181 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1186 printf("%d addresses found from DNS seeds\n", found);
1200 unsigned int pnSeed[] =
1202 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1203 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1204 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1205 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1206 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1207 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1208 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1209 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1210 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1211 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1212 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1213 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1214 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1215 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1216 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1217 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1218 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1219 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1220 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1221 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1222 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1223 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1224 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1225 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1226 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1227 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1228 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1229 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1230 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1231 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1232 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1233 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1234 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1235 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1236 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1237 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1238 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1239 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1240 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1241 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1242 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1243 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1244 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1245 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1246 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1247 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1248 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1249 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1250 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1251 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1252 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1253 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1254 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1255 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1256 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1257 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1258 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1259 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1260 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1261 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1262 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1263 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1264 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1265 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1266 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1267 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1268 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1269 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1270 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1271 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1272 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1273 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1274 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1275 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1276 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1277 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1278 0xc461d84a, 0xb2dbe247,
1283 void ThreadOpenConnections(void* parg)
1285 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1288 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1289 ThreadOpenConnections2(parg);
1290 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1292 catch (std::exception& e) {
1293 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1294 PrintException(&e, "ThreadOpenConnections()");
1296 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1297 PrintException(NULL, "ThreadOpenConnections()");
1299 printf("ThreadOpenConnections exiting\n");
1302 void ThreadOpenConnections2(void* parg)
1304 printf("ThreadOpenConnections started\n");
1306 // Connect to specific addresses
1307 if (mapArgs.count("-connect"))
1309 for (int64 nLoop = 0;; nLoop++)
1311 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1313 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1315 OpenNetworkConnection(addr);
1316 for (int i = 0; i < 10 && i < nLoop; i++)
1326 // Initiate network connections
1327 int64 nStart = GetTime();
1330 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1332 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1336 // Limit outbound connections
1340 CRITICAL_BLOCK(cs_vNodes)
1341 BOOST_FOREACH(CNode* pnode, vNodes)
1342 if (!pnode->fInbound)
1344 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1345 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1346 if (nOutbound < nMaxOutboundConnections)
1348 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1350 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1355 bool fAddSeeds = false;
1357 CRITICAL_BLOCK(cs_mapAddresses)
1359 // Add seed nodes if IRC isn't working
1360 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1361 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1367 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1369 // It'll only connect to one or two seed nodes because once it connects,
1370 // it'll get a pile of addresses with newer timestamps.
1371 // Seed nodes are given a random 'last seen time' of between one and two
1373 const int64 nOneWeek = 7*24*60*60;
1375 memcpy(&ip, &pnSeed[i], sizeof(ip));
1376 CAddress addr(CService(ip, GetDefaultPort()));
1377 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1383 // Choose an address to connect to based on most recently seen
1385 CAddress addrConnect;
1386 int64 nBest = std::numeric_limits<int64>::min();
1388 // Only connect to one address per a.b.?.? range.
1389 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1390 set<vector<unsigned char> > setConnected;
1391 CRITICAL_BLOCK(cs_vNodes)
1392 BOOST_FOREACH(CNode* pnode, vNodes)
1393 setConnected.insert(pnode->addr.GetGroup());
1395 int64 nANow = GetAdjustedTime();
1397 CRITICAL_BLOCK(cs_mapAddresses)
1399 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1401 const CAddress& addr = item.second;
1402 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()))
1404 int64 nSinceLastSeen = nANow - addr.nTime;
1405 int64 nSinceLastTry = nANow - addr.nLastTry;
1407 // Randomize the order in a deterministic way, putting the standard port first
1408 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.GetHash()) % (2 * 60 * 60);
1409 if (addr.GetPort() != GetDefaultPort())
1410 nRandomizer += 2 * 60 * 60;
1412 // Last seen Base retry frequency
1421 // 365 days 93 hours
1422 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1424 // Fast reconnect for one hour after last seen
1425 if (nSinceLastSeen < 60 * 60)
1428 // Limit retry frequency
1429 if (nSinceLastTry < nDelay)
1432 // If we have IRC, we'll be notified when they first come online,
1433 // and again every 24 hours by the refresh broadcast.
1434 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1437 // Only try the old stuff if we don't have enough connections
1438 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1441 // If multiple addresses are ready, prioritize by time since
1442 // last seen and time since last tried.
1443 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1452 if (addrConnect.IsValid())
1453 OpenNetworkConnection(addrConnect);
1457 void ThreadOpenAddedConnections(void* parg)
1459 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1462 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1463 ThreadOpenAddedConnections2(parg);
1464 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1466 catch (std::exception& e) {
1467 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1468 PrintException(&e, "ThreadOpenAddedConnections()");
1470 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1471 PrintException(NULL, "ThreadOpenAddedConnections()");
1473 printf("ThreadOpenAddedConnections exiting\n");
1476 void ThreadOpenAddedConnections2(void* parg)
1478 printf("ThreadOpenAddedConnections started\n");
1480 if (mapArgs.count("-addnode") == 0)
1483 vector<vector<CService> > vservAddressesToAdd(0);
1484 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1486 vector<CService> vservNode(0);
1487 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1489 vservAddressesToAdd.push_back(vservNode);
1490 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1491 BOOST_FOREACH(CService& serv, vservNode)
1492 setservAddNodeAddresses.insert(serv);
1497 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1498 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1499 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1500 CRITICAL_BLOCK(cs_vNodes)
1501 BOOST_FOREACH(CNode* pnode, vNodes)
1502 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1503 BOOST_FOREACH(CService& addrNode, *(it))
1504 if (pnode->addr == addrNode)
1506 it = vservConnectAddresses.erase(it);
1510 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1512 OpenNetworkConnection(CAddress(*(vserv.begin())));
1519 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1520 Sleep(120000); // Retry every 2 minutes
1521 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1527 bool OpenNetworkConnection(const CAddress& addrConnect)
1530 // Initiate outbound network connection
1534 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1535 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1538 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1539 CNode* pnode = ConnectNode(addrConnect);
1540 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1545 pnode->fNetworkNode = true;
1557 void ThreadMessageHandler(void* parg)
1559 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1562 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1563 ThreadMessageHandler2(parg);
1564 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1566 catch (std::exception& e) {
1567 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1568 PrintException(&e, "ThreadMessageHandler()");
1570 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1571 PrintException(NULL, "ThreadMessageHandler()");
1573 printf("ThreadMessageHandler exiting\n");
1576 void ThreadMessageHandler2(void* parg)
1578 printf("ThreadMessageHandler started\n");
1579 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1582 vector<CNode*> vNodesCopy;
1583 CRITICAL_BLOCK(cs_vNodes)
1585 vNodesCopy = vNodes;
1586 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1590 // Poll the connected nodes for messages
1591 CNode* pnodeTrickle = NULL;
1592 if (!vNodesCopy.empty())
1593 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1594 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1597 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1598 ProcessMessages(pnode);
1603 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1604 SendMessages(pnode, pnode == pnodeTrickle);
1609 CRITICAL_BLOCK(cs_vNodes)
1611 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1615 // Wait and allow messages to bunch up.
1616 // Reduce vnThreadsRunning so StopNode has permission to exit while
1617 // we're sleeping, but we must always check fShutdown after doing this.
1618 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1620 if (fRequestShutdown)
1622 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1633 bool BindListenPort(string& strError)
1637 addrLocalHost.SetPort(GetListenPort());
1640 // Initialize Windows Sockets
1642 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1643 if (ret != NO_ERROR)
1645 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1646 printf("%s\n", strError.c_str());
1651 // Create socket for listening for incoming connections
1652 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1653 if (hListenSocket == INVALID_SOCKET)
1655 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1656 printf("%s\n", strError.c_str());
1661 // Different way of disabling SIGPIPE on BSD
1662 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1666 // Allow binding if the port is still in TIME_WAIT state after
1667 // the program was closed and restarted. Not an issue on windows.
1668 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1672 // Set to nonblocking, incoming connections will also inherit this
1673 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1675 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1678 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1679 printf("%s\n", strError.c_str());
1683 // The sockaddr_in structure specifies the address family,
1684 // IP address, and port for the socket that is being bound
1685 struct sockaddr_in sockaddr;
1686 memset(&sockaddr, 0, sizeof(sockaddr));
1687 sockaddr.sin_family = AF_INET;
1688 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1689 sockaddr.sin_port = htons(GetListenPort());
1690 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1692 int nErr = WSAGetLastError();
1693 if (nErr == WSAEADDRINUSE)
1694 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1696 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1697 printf("%s\n", strError.c_str());
1700 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1702 // Listen for incoming connections
1703 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1705 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1706 printf("%s\n", strError.c_str());
1713 void StartNode(void* parg)
1717 fUseUPnP = GetBoolArg("-upnp", true);
1719 fUseUPnP = GetBoolArg("-upnp", false);
1723 if (pnodeLocalHost == NULL)
1724 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1727 // Get local host ip
1728 char pszHostName[1000] = "";
1729 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1731 vector<CNetAddr> vaddr;
1732 if (LookupHost(pszHostName, vaddr))
1733 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1734 if (!addr.IsLocal())
1736 addrLocalHost.SetIP(addr);
1741 // Get local host ip
1742 struct ifaddrs* myaddrs;
1743 if (getifaddrs(&myaddrs) == 0)
1745 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1747 if (ifa->ifa_addr == NULL) continue;
1748 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1749 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1750 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1752 if (ifa->ifa_addr->sa_family == AF_INET)
1754 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1755 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1756 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1758 // Take the first IP that isn't loopback 127.x.x.x
1759 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1760 if (addr.IsValid() && !addr.IsLocal())
1762 addrLocalHost = addr;
1766 else if (ifa->ifa_addr->sa_family == AF_INET6)
1768 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1769 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1770 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1773 freeifaddrs(myaddrs);
1776 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1778 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1780 // Proxies can't take incoming connections
1781 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1782 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1786 CreateThread(ThreadGetMyExternalIP, NULL);
1793 if (!GetBoolArg("-dnsseed", true))
1794 printf("DNS seeding disabled\n");
1796 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1797 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1799 // Map ports with UPnP
1803 // Get addresses from IRC and advertise ours
1804 if (!CreateThread(ThreadIRCSeed, NULL))
1805 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1807 // Send and receive from sockets, accept connections
1808 if (!CreateThread(ThreadSocketHandler, NULL))
1809 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1811 // Initiate outbound connections from -addnode
1812 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1813 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1815 // Initiate outbound connections
1816 if (!CreateThread(ThreadOpenConnections, NULL))
1817 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1820 if (!CreateThread(ThreadMessageHandler, NULL))
1821 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1823 // Generate coins in the background
1824 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1829 printf("StopNode()\n");
1831 nTransactionsUpdated++;
1832 int64 nStart = GetTime();
1835 int nThreadsRunning = 0;
1836 for (int n = 0; n < THREAD_MAX; n++)
1837 nThreadsRunning += vnThreadsRunning[n];
1838 if (nThreadsRunning == 0)
1840 if (GetTime() - nStart > 20)
1844 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1845 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1846 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1847 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1848 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1849 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1850 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1851 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1852 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1868 BOOST_FOREACH(CNode* pnode, vNodes)
1869 if (pnode->hSocket != INVALID_SOCKET)
1870 closesocket(pnode->hSocket);
1871 if (hListenSocket != INVALID_SOCKET)
1872 if (closesocket(hListenSocket) == SOCKET_ERROR)
1873 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1876 // Shutdown Windows Sockets
1881 instance_of_cnetcleanup;