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);
44 // Global state variables
47 bool fAllowDNS = false;
48 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
49 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
50 static CNode* pnodeLocalHost = NULL;
51 uint64 nLocalHostNonce = 0;
52 array<int, 10> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
55 vector<CNode*> vNodes;
56 CCriticalSection cs_vNodes;
57 map<vector<unsigned char>, CAddress> mapAddresses;
58 CCriticalSection cs_mapAddresses;
59 map<CInv, CDataStream> mapRelay;
60 deque<pair<int64, CInv> > vRelayExpiration;
61 CCriticalSection cs_mapRelay;
62 map<CInv, int64> mapAlreadyAskedFor;
65 set<CNetAddr> setservAddNodeAddresses;
66 CCriticalSection cs_setservAddNodeAddresses;
71 unsigned short GetListenPort()
73 return (unsigned short)(GetArg("-port", GetDefaultPort()));
76 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
78 // Filter out duplicate requests
79 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
81 pindexLastGetBlocksBegin = pindexBegin;
82 hashLastGetBlocksEnd = hashEnd;
84 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
91 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
94 if (!ConnectSocket(addrConnect, hSocket))
95 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
97 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
100 while (RecvLine(hSocket, strLine))
102 if (strLine.empty()) // HTTP response is separated from headers by blank line
106 if (!RecvLine(hSocket, strLine))
108 closesocket(hSocket);
111 if (pszKeyword == NULL)
113 if (strLine.find(pszKeyword) != -1)
115 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
119 closesocket(hSocket);
120 if (strLine.find("<") != -1)
121 strLine = strLine.substr(0, strLine.find("<"));
122 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
123 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
124 strLine.resize(strLine.size()-1);
125 CService addr(strLine,0,true);
126 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
127 if (!addr.IsValid() || !addr.IsRoutable())
133 closesocket(hSocket);
134 return error("GetMyExternalIP() : connection closed");
137 // We now get our external IP from the IRC server first and only use this as a backup
138 bool GetMyExternalIP(CNetAddr& ipRet)
140 CService addrConnect;
142 const char* pszKeyword;
144 if (fNoListen||fUseProxy)
147 for (int nLookup = 0; nLookup <= 1; nLookup++)
148 for (int nHost = 1; nHost <= 2; nHost++)
150 // We should be phasing out our use of sites like these. If we need
151 // replacements, we should ask for volunteers to put this simple
152 // php file on their webserver that prints the client IP:
153 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
156 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
160 CService addrIP("checkip.dyndns.org", 80, true);
161 if (addrIP.IsValid())
162 addrConnect = addrIP;
165 pszGet = "GET / HTTP/1.1\r\n"
166 "Host: checkip.dyndns.org\r\n"
167 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
168 "Connection: close\r\n"
171 pszKeyword = "Address:";
175 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
179 CService addrIP("www.showmyip.com", 80, true);
180 if (addrIP.IsValid())
181 addrConnect = addrIP;
184 pszGet = "GET /simple/ HTTP/1.1\r\n"
185 "Host: www.showmyip.com\r\n"
186 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
187 "Connection: close\r\n"
190 pszKeyword = NULL; // Returns just IP address
193 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
200 void ThreadGetMyExternalIP(void* parg)
202 // Wait for IRC to get it first
203 if (GetBoolArg("-irc", false))
205 for (int i = 0; i < 2 * 60; i++)
208 if (fGotExternalIP || fShutdown)
213 // Fallback in case IRC fails to get it
214 if (GetMyExternalIP(addrLocalHost))
216 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
217 if (addrLocalHost.IsRoutable())
219 // If we already connected to a few before we had our IP, go back and addr them.
220 // setAddrKnown automatically filters any duplicate sends.
221 CAddress addr(addrLocalHost);
222 addr.nTime = GetAdjustedTime();
223 CRITICAL_BLOCK(cs_vNodes)
224 BOOST_FOREACH(CNode* pnode, vNodes)
225 pnode->PushAddress(addr);
234 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
236 if (!addr.IsRoutable())
238 if ((CService)addr == (CService)addrLocalHost)
240 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
241 bool fUpdated = false;
243 CAddress addrFound = addr;
245 CRITICAL_BLOCK(cs_mapAddresses)
247 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
248 if (it == mapAddresses.end())
251 printf("AddAddress(%s)\n", addr.ToString().c_str());
252 mapAddresses.insert(make_pair(addr.GetKey(), addr));
258 addrFound = (*it).second;
259 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
261 // Services have been added
262 addrFound.nServices |= addr.nServices;
265 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
266 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
267 if (addrFound.nTime < addr.nTime - nUpdateInterval)
269 // Periodically update most recently seen time
270 addrFound.nTime = addr.nTime;
275 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
277 // Thread 1: begin db transaction (locks inside-db-mutex)
278 // then AddAddress (locks cs_mapAddresses)
279 // Thread 2: AddAddress (locks cs_mapAddresses)
280 // ... then db operation hangs waiting for inside-db-mutex
284 pAddrDB->WriteAddress(addrFound);
286 CAddrDB().WriteAddress(addrFound);
291 void AddressCurrentlyConnected(const CService& addr)
293 CAddress *paddrFound = NULL;
295 CRITICAL_BLOCK(cs_mapAddresses)
297 // Only if it's been published already
298 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
299 if (it != mapAddresses.end())
300 paddrFound = &(*it).second;
305 int64 nUpdateInterval = 20 * 60;
306 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
308 // Periodically update most recently seen time
309 paddrFound->nTime = GetAdjustedTime();
311 addrdb.WriteAddress(*paddrFound);
320 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
322 // If the dialog might get closed before the reply comes back,
323 // call this in the destructor so it doesn't get called after it's deleted.
324 CRITICAL_BLOCK(cs_vNodes)
326 BOOST_FOREACH(CNode* pnode, vNodes)
328 CRITICAL_BLOCK(pnode->cs_mapRequests)
330 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
332 CRequestTracker& tracker = (*mi).second;
333 if (tracker.fn == fn && tracker.param1 == param1)
334 pnode->mapRequests.erase(mi++);
350 // Subscription methods for the broadcast and subscription system.
351 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
353 // The subscription system uses a meet-in-the-middle strategy.
354 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
355 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
358 bool AnySubscribed(unsigned int nChannel)
360 if (pnodeLocalHost->IsSubscribed(nChannel))
362 CRITICAL_BLOCK(cs_vNodes)
363 BOOST_FOREACH(CNode* pnode, vNodes)
364 if (pnode->IsSubscribed(nChannel))
369 bool CNode::IsSubscribed(unsigned int nChannel)
371 if (nChannel >= vfSubscribe.size())
373 return vfSubscribe[nChannel];
376 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
378 if (nChannel >= vfSubscribe.size())
381 if (!AnySubscribed(nChannel))
384 CRITICAL_BLOCK(cs_vNodes)
385 BOOST_FOREACH(CNode* pnode, vNodes)
387 pnode->PushMessage("subscribe", nChannel, nHops);
390 vfSubscribe[nChannel] = true;
393 void CNode::CancelSubscribe(unsigned int nChannel)
395 if (nChannel >= vfSubscribe.size())
398 // Prevent from relaying cancel if wasn't subscribed
399 if (!vfSubscribe[nChannel])
401 vfSubscribe[nChannel] = false;
403 if (!AnySubscribed(nChannel))
405 // Relay subscription cancel
406 CRITICAL_BLOCK(cs_vNodes)
407 BOOST_FOREACH(CNode* pnode, vNodes)
409 pnode->PushMessage("sub-cancel", nChannel);
421 CNode* FindNode(const CNetAddr& ip)
423 CRITICAL_BLOCK(cs_vNodes)
425 BOOST_FOREACH(CNode* pnode, vNodes)
426 if ((CNetAddr)pnode->addr == ip)
432 CNode* FindNode(const CService& addr)
434 CRITICAL_BLOCK(cs_vNodes)
436 BOOST_FOREACH(CNode* pnode, vNodes)
437 if ((CService)pnode->addr == addr)
443 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
445 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
448 // Look for an existing connection
449 CNode* pnode = FindNode((CService)addrConnect);
453 pnode->AddRef(nTimeout);
460 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
461 addrConnect.ToString().c_str(),
462 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
463 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
465 CRITICAL_BLOCK(cs_mapAddresses)
466 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
470 if (ConnectSocket(addrConnect, hSocket))
473 printf("connected %s\n", addrConnect.ToString().c_str());
475 // Set to nonblocking
478 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
479 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
481 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
482 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
486 CNode* pnode = new CNode(hSocket, addrConnect, false);
488 pnode->AddRef(nTimeout);
491 CRITICAL_BLOCK(cs_vNodes)
492 vNodes.push_back(pnode);
494 pnode->nTimeConnected = GetTime();
503 void CNode::CloseSocketDisconnect()
506 if (hSocket != INVALID_SOCKET)
509 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
510 printf("disconnecting node %s\n", addr.ToString().c_str());
511 closesocket(hSocket);
512 hSocket = INVALID_SOCKET;
516 void CNode::Cleanup()
518 // All of a nodes broadcasts and subscriptions are automatically torn down
519 // when it goes down, so a node has to stay up to keep its broadcast going.
521 // Cancel subscriptions
522 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
523 if (vfSubscribe[nChannel])
524 CancelSubscribe(nChannel);
528 void CNode::PushVersion()
530 /// when NTP implemented, change to just nTime = GetAdjustedTime()
531 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
532 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
533 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
534 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
535 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
536 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
543 std::map<CNetAddr, int64> CNode::setBanned;
544 CCriticalSection CNode::cs_setBanned;
546 void CNode::ClearBanned()
551 bool CNode::IsBanned(CNetAddr ip)
553 bool fResult = false;
554 CRITICAL_BLOCK(cs_setBanned)
556 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
557 if (i != setBanned.end())
559 int64 t = (*i).second;
567 bool CNode::Misbehaving(int howmuch)
571 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
575 nMisbehavior += howmuch;
576 if (nMisbehavior >= GetArg("-banscore", 100))
578 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
579 CRITICAL_BLOCK(cs_setBanned)
580 if (setBanned[addr] < banTime)
581 setBanned[addr] = banTime;
582 CloseSocketDisconnect();
583 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
600 void ThreadSocketHandler(void* parg)
602 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
605 vnThreadsRunning[0]++;
606 ThreadSocketHandler2(parg);
607 vnThreadsRunning[0]--;
609 catch (std::exception& e) {
610 vnThreadsRunning[0]--;
611 PrintException(&e, "ThreadSocketHandler()");
613 vnThreadsRunning[0]--;
614 throw; // support pthread_cancel()
616 printf("ThreadSocketHandler exiting\n");
619 void ThreadSocketHandler2(void* parg)
621 printf("ThreadSocketHandler started\n");
622 list<CNode*> vNodesDisconnected;
623 int nPrevNodeCount = 0;
630 CRITICAL_BLOCK(cs_vNodes)
632 // Disconnect unused nodes
633 vector<CNode*> vNodesCopy = vNodes;
634 BOOST_FOREACH(CNode* pnode, vNodesCopy)
636 if (pnode->fDisconnect ||
637 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
639 // remove from vNodes
640 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
642 // close socket and cleanup
643 pnode->CloseSocketDisconnect();
646 // hold in disconnected pool until all refs are released
647 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
648 if (pnode->fNetworkNode || pnode->fInbound)
650 vNodesDisconnected.push_back(pnode);
654 // Delete disconnected nodes
655 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
656 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
658 // wait until threads are done using it
659 if (pnode->GetRefCount() <= 0)
661 bool fDelete = false;
662 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
663 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
664 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
665 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
669 vNodesDisconnected.remove(pnode);
675 if (vNodes.size() != nPrevNodeCount)
677 nPrevNodeCount = vNodes.size();
683 // Find which sockets have data to receive
685 struct timeval timeout;
687 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
694 FD_ZERO(&fdsetError);
695 SOCKET hSocketMax = 0;
697 if(hListenSocket != INVALID_SOCKET)
698 FD_SET(hListenSocket, &fdsetRecv);
699 hSocketMax = max(hSocketMax, hListenSocket);
700 CRITICAL_BLOCK(cs_vNodes)
702 BOOST_FOREACH(CNode* pnode, vNodes)
704 if (pnode->hSocket == INVALID_SOCKET)
706 FD_SET(pnode->hSocket, &fdsetRecv);
707 FD_SET(pnode->hSocket, &fdsetError);
708 hSocketMax = max(hSocketMax, pnode->hSocket);
709 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
710 if (!pnode->vSend.empty())
711 FD_SET(pnode->hSocket, &fdsetSend);
715 vnThreadsRunning[0]--;
716 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
717 vnThreadsRunning[0]++;
720 if (nSelect == SOCKET_ERROR)
722 int nErr = WSAGetLastError();
725 printf("socket select error %d\n", nErr);
726 for (int i = 0; i <= hSocketMax; i++)
727 FD_SET(i, &fdsetRecv);
730 FD_ZERO(&fdsetError);
731 Sleep(timeout.tv_usec/1000);
736 // Accept new connections
738 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
740 struct sockaddr_in sockaddr;
741 socklen_t len = sizeof(sockaddr);
742 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
743 CAddress addr(sockaddr);
746 CRITICAL_BLOCK(cs_vNodes)
747 BOOST_FOREACH(CNode* pnode, vNodes)
750 if (hSocket == INVALID_SOCKET)
752 if (WSAGetLastError() != WSAEWOULDBLOCK)
753 printf("socket error accept failed: %d\n", WSAGetLastError());
755 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
757 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
758 if (!setservAddNodeAddresses.count(addr))
759 closesocket(hSocket);
761 else if (CNode::IsBanned(addr))
763 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
764 closesocket(hSocket);
768 printf("accepted connection %s\n", addr.ToString().c_str());
769 CNode* pnode = new CNode(hSocket, addr, true);
771 CRITICAL_BLOCK(cs_vNodes)
772 vNodes.push_back(pnode);
778 // Service each socket
780 vector<CNode*> vNodesCopy;
781 CRITICAL_BLOCK(cs_vNodes)
784 BOOST_FOREACH(CNode* pnode, vNodesCopy)
787 BOOST_FOREACH(CNode* pnode, vNodesCopy)
795 if (pnode->hSocket == INVALID_SOCKET)
797 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
799 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
801 CDataStream& vRecv = pnode->vRecv;
802 unsigned int nPos = vRecv.size();
804 if (nPos > ReceiveBufferSize()) {
805 if (!pnode->fDisconnect)
806 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
807 pnode->CloseSocketDisconnect();
810 // typical socket buffer is 8K-64K
811 char pchBuf[0x10000];
812 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
815 vRecv.resize(nPos + nBytes);
816 memcpy(&vRecv[nPos], pchBuf, nBytes);
817 pnode->nLastRecv = GetTime();
819 else if (nBytes == 0)
821 // socket closed gracefully
822 if (!pnode->fDisconnect)
823 printf("socket closed\n");
824 pnode->CloseSocketDisconnect();
829 int nErr = WSAGetLastError();
830 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
832 if (!pnode->fDisconnect)
833 printf("socket recv error %d\n", nErr);
834 pnode->CloseSocketDisconnect();
844 if (pnode->hSocket == INVALID_SOCKET)
846 if (FD_ISSET(pnode->hSocket, &fdsetSend))
848 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
850 CDataStream& vSend = pnode->vSend;
853 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
856 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
857 pnode->nLastSend = GetTime();
862 int nErr = WSAGetLastError();
863 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
865 printf("socket send error %d\n", nErr);
866 pnode->CloseSocketDisconnect();
869 if (vSend.size() > SendBufferSize()) {
870 if (!pnode->fDisconnect)
871 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
872 pnode->CloseSocketDisconnect();
879 // Inactivity checking
881 if (pnode->vSend.empty())
882 pnode->nLastSendEmpty = GetTime();
883 if (GetTime() - pnode->nTimeConnected > 60)
885 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
887 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
888 pnode->fDisconnect = true;
890 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
892 printf("socket not sending\n");
893 pnode->fDisconnect = true;
895 else if (GetTime() - pnode->nLastRecv > 90*60)
897 printf("socket inactivity timeout\n");
898 pnode->fDisconnect = true;
902 CRITICAL_BLOCK(cs_vNodes)
904 BOOST_FOREACH(CNode* pnode, vNodesCopy)
921 void ThreadMapPort(void* parg)
923 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
926 vnThreadsRunning[5]++;
927 ThreadMapPort2(parg);
928 vnThreadsRunning[5]--;
930 catch (std::exception& e) {
931 vnThreadsRunning[5]--;
932 PrintException(&e, "ThreadMapPort()");
934 vnThreadsRunning[5]--;
935 PrintException(NULL, "ThreadMapPort()");
937 printf("ThreadMapPort exiting\n");
940 void ThreadMapPort2(void* parg)
942 printf("ThreadMapPort started\n");
945 sprintf(port, "%d", GetListenPort());
947 const char * multicastif = 0;
948 const char * minissdpdpath = 0;
949 struct UPNPDev * devlist = 0;
952 #ifndef UPNPDISCOVER_SUCCESS
954 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
958 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
961 struct UPNPUrls urls;
962 struct IGDdatas data;
965 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
968 if (!addrLocalHost.IsRoutable())
970 char externalIPAddress[40];
971 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
972 if(r != UPNPCOMMAND_SUCCESS)
973 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
976 if(externalIPAddress[0])
978 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
979 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
980 if (addrExternalFromUPnP.IsRoutable())
981 addrLocalHost = addrExternalFromUPnP;
984 printf("UPnP: GetExternalIPAddress failed.\n");
988 string strDesc = "Bitcoin " + FormatFullVersion();
989 #ifndef UPNPDISCOVER_SUCCESS
991 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
992 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
995 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
996 port, port, lanaddr, strDesc.c_str(), "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");
1006 if (fShutdown || !fUseUPnP)
1008 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1009 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1010 freeUPNPDevlist(devlist); devlist = 0;
1011 FreeUPNPUrls(&urls);
1014 if (i % 600 == 0) // Refresh every 20 minutes
1016 #ifndef UPNPDISCOVER_SUCCESS
1018 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1019 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1022 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1023 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1026 if(r!=UPNPCOMMAND_SUCCESS)
1027 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1028 port, port, lanaddr, r, strupnperror(r));
1030 printf("UPnP Port Mapping successful.\n");;
1036 printf("No valid UPnP IGDs found\n");
1037 freeUPNPDevlist(devlist); devlist = 0;
1039 FreeUPNPUrls(&urls);
1041 if (fShutdown || !fUseUPnP)
1048 void MapPort(bool fMapPort)
1050 if (fUseUPnP != fMapPort)
1052 fUseUPnP = fMapPort;
1053 WriteSetting("fUseUPnP", fUseUPnP);
1055 if (fUseUPnP && vnThreadsRunning[5] < 1)
1057 if (!CreateThread(ThreadMapPort, NULL))
1058 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1062 void MapPort(bool /* unused fMapPort */)
1064 // Intentionally left blank.
1077 static const char *strDNSSeed[] = {
1079 "dnsseed.bluematt.me",
1080 "seed.bitcoin.sipa.be",
1081 "dnsseed.bitcoin.dashjr.org",
1084 void ThreadDNSAddressSeed(void* parg)
1086 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1089 vnThreadsRunning[6]++;
1090 ThreadDNSAddressSeed2(parg);
1091 vnThreadsRunning[6]--;
1093 catch (std::exception& e) {
1094 vnThreadsRunning[6]--;
1095 PrintException(&e, "ThreadDNSAddressSeed()");
1097 vnThreadsRunning[6]--;
1098 throw; // support pthread_cancel()
1100 printf("ThreadDNSAddressSeed exiting\n");
1103 void ThreadDNSAddressSeed2(void* parg)
1105 printf("ThreadDNSAddressSeed started\n");
1110 printf("Loading addresses from DNS seeds (could take a while)\n");
1112 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1113 vector<CNetAddr> vaddr;
1114 if (LookupHost(strDNSSeed[seed_idx], vaddr))
1118 BOOST_FOREACH (CNetAddr& ip, vaddr)
1120 if (ip.IsRoutable())
1122 CAddress addr(CService(ip, GetDefaultPort()), NODE_NETWORK);
1124 AddAddress(addr, 0, &addrDB);
1128 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1133 printf("%d addresses found from DNS seeds\n", found);
1147 unsigned int pnSeed[] =
1149 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1150 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1151 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1152 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1153 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1154 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1155 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1156 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1157 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1158 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1159 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1160 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1161 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1162 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1163 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1164 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1165 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1166 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1167 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1168 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1169 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1170 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1171 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1172 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1173 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1174 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1175 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1176 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1177 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1178 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1179 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1180 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1181 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1182 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1183 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1184 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1185 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1186 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1187 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1188 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1189 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1190 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1191 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1192 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1193 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1194 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1195 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1196 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1197 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1198 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1199 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1200 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1201 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1202 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1203 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1204 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1205 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1206 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1207 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1208 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1209 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1210 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1211 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1212 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1213 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1214 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1215 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1216 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1217 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1218 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1219 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1220 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1221 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1222 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1223 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1224 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1225 0xc461d84a, 0xb2dbe247,
1230 void ThreadOpenConnections(void* parg)
1232 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1235 vnThreadsRunning[1]++;
1236 ThreadOpenConnections2(parg);
1237 vnThreadsRunning[1]--;
1239 catch (std::exception& e) {
1240 vnThreadsRunning[1]--;
1241 PrintException(&e, "ThreadOpenConnections()");
1243 vnThreadsRunning[1]--;
1244 PrintException(NULL, "ThreadOpenConnections()");
1246 printf("ThreadOpenConnections exiting\n");
1249 void ThreadOpenConnections2(void* parg)
1251 printf("ThreadOpenConnections started\n");
1253 // Connect to specific addresses
1254 if (mapArgs.count("-connect"))
1256 for (int64 nLoop = 0;; nLoop++)
1258 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1260 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1262 OpenNetworkConnection(addr);
1263 for (int i = 0; i < 10 && i < nLoop; i++)
1273 // Initiate network connections
1274 int64 nStart = GetTime();
1277 // Limit outbound connections
1278 vnThreadsRunning[1]--;
1283 CRITICAL_BLOCK(cs_vNodes)
1284 BOOST_FOREACH(CNode* pnode, vNodes)
1285 if (!pnode->fInbound)
1287 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1288 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1289 if (nOutbound < nMaxOutboundConnections)
1295 vnThreadsRunning[1]++;
1299 bool fAddSeeds = false;
1301 CRITICAL_BLOCK(cs_mapAddresses)
1303 // Add seed nodes if IRC isn't working
1304 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1305 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1311 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1313 // It'll only connect to one or two seed nodes because once it connects,
1314 // it'll get a pile of addresses with newer timestamps.
1315 // Seed nodes are given a random 'last seen time' of between one and two
1317 const int64 nOneWeek = 7*24*60*60;
1319 memcpy(&ip, &pnSeed[i], sizeof(ip));
1320 CAddress addr(CService(ip, GetDefaultPort()));
1321 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1327 // Choose an address to connect to based on most recently seen
1329 CAddress addrConnect;
1330 int64 nBest = std::numeric_limits<int64>::min();
1332 // Only connect to one address per a.b.?.? range.
1333 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1334 set<vector<unsigned char> > setConnected;
1335 CRITICAL_BLOCK(cs_vNodes)
1336 BOOST_FOREACH(CNode* pnode, vNodes)
1337 setConnected.insert(pnode->addr.GetGroup());
1339 int64 nANow = GetAdjustedTime();
1341 CRITICAL_BLOCK(cs_mapAddresses)
1343 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1345 const CAddress& addr = item.second;
1346 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()))
1348 int64 nSinceLastSeen = nANow - addr.nTime;
1349 int64 nSinceLastTry = nANow - addr.nLastTry;
1351 // Randomize the order in a deterministic way, putting the standard port first
1352 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.GetHash()) % (2 * 60 * 60);
1353 if (addr.GetPort() != GetDefaultPort())
1354 nRandomizer += 2 * 60 * 60;
1356 // Last seen Base retry frequency
1365 // 365 days 93 hours
1366 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1368 // Fast reconnect for one hour after last seen
1369 if (nSinceLastSeen < 60 * 60)
1372 // Limit retry frequency
1373 if (nSinceLastTry < nDelay)
1376 // If we have IRC, we'll be notified when they first come online,
1377 // and again every 24 hours by the refresh broadcast.
1378 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1381 // Only try the old stuff if we don't have enough connections
1382 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1385 // If multiple addresses are ready, prioritize by time since
1386 // last seen and time since last tried.
1387 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1396 if (addrConnect.IsValid())
1397 OpenNetworkConnection(addrConnect);
1401 void ThreadOpenAddedConnections(void* parg)
1403 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1406 vnThreadsRunning[7]++;
1407 ThreadOpenAddedConnections2(parg);
1408 vnThreadsRunning[7]--;
1410 catch (std::exception& e) {
1411 vnThreadsRunning[7]--;
1412 PrintException(&e, "ThreadOpenAddedConnections()");
1414 vnThreadsRunning[7]--;
1415 PrintException(NULL, "ThreadOpenAddedConnections()");
1417 printf("ThreadOpenAddedConnections exiting\n");
1420 void ThreadOpenAddedConnections2(void* parg)
1422 printf("ThreadOpenAddedConnections started\n");
1424 if (mapArgs.count("-addnode") == 0)
1427 vector<vector<CService> > vservAddressesToAdd(0);
1428 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1430 vector<CService> vservNode(0);
1431 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1433 vservAddressesToAdd.push_back(vservNode);
1434 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1435 BOOST_FOREACH(CService& serv, vservNode)
1436 setservAddNodeAddresses.insert(serv);
1441 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1442 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1443 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1444 CRITICAL_BLOCK(cs_vNodes)
1445 BOOST_FOREACH(CNode* pnode, vNodes)
1446 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1447 BOOST_FOREACH(CService& addrNode, *(it))
1448 if (pnode->addr == addrNode)
1450 it = vservConnectAddresses.erase(it);
1454 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1456 OpenNetworkConnection(CAddress(*(vserv.begin())));
1463 vnThreadsRunning[7]--;
1464 Sleep(120000); // Retry every 2 minutes
1465 vnThreadsRunning[7]++;
1471 bool OpenNetworkConnection(const CAddress& addrConnect)
1474 // Initiate outbound network connection
1478 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1479 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1482 vnThreadsRunning[1]--;
1483 CNode* pnode = ConnectNode(addrConnect);
1484 vnThreadsRunning[1]++;
1489 pnode->fNetworkNode = true;
1501 void ThreadMessageHandler(void* parg)
1503 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1506 vnThreadsRunning[2]++;
1507 ThreadMessageHandler2(parg);
1508 vnThreadsRunning[2]--;
1510 catch (std::exception& e) {
1511 vnThreadsRunning[2]--;
1512 PrintException(&e, "ThreadMessageHandler()");
1514 vnThreadsRunning[2]--;
1515 PrintException(NULL, "ThreadMessageHandler()");
1517 printf("ThreadMessageHandler exiting\n");
1520 void ThreadMessageHandler2(void* parg)
1522 printf("ThreadMessageHandler started\n");
1523 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1526 vector<CNode*> vNodesCopy;
1527 CRITICAL_BLOCK(cs_vNodes)
1529 vNodesCopy = vNodes;
1530 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1534 // Poll the connected nodes for messages
1535 CNode* pnodeTrickle = NULL;
1536 if (!vNodesCopy.empty())
1537 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1538 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1541 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1542 ProcessMessages(pnode);
1547 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1548 SendMessages(pnode, pnode == pnodeTrickle);
1553 CRITICAL_BLOCK(cs_vNodes)
1555 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1559 // Wait and allow messages to bunch up.
1560 // Reduce vnThreadsRunning so StopNode has permission to exit while
1561 // we're sleeping, but we must always check fShutdown after doing this.
1562 vnThreadsRunning[2]--;
1564 if (fRequestShutdown)
1566 vnThreadsRunning[2]++;
1577 bool BindListenPort(string& strError)
1581 addrLocalHost.SetPort(GetListenPort());
1584 // Initialize Windows Sockets
1586 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1587 if (ret != NO_ERROR)
1589 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1590 printf("%s\n", strError.c_str());
1595 // Create socket for listening for incoming connections
1596 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1597 if (hListenSocket == INVALID_SOCKET)
1599 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1600 printf("%s\n", strError.c_str());
1605 // Different way of disabling SIGPIPE on BSD
1606 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1610 // Allow binding if the port is still in TIME_WAIT state after
1611 // the program was closed and restarted. Not an issue on windows.
1612 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1616 // Set to nonblocking, incoming connections will also inherit this
1617 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1619 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1622 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1623 printf("%s\n", strError.c_str());
1627 // The sockaddr_in structure specifies the address family,
1628 // IP address, and port for the socket that is being bound
1629 struct sockaddr_in sockaddr;
1630 memset(&sockaddr, 0, sizeof(sockaddr));
1631 sockaddr.sin_family = AF_INET;
1632 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1633 sockaddr.sin_port = htons(GetListenPort());
1634 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1636 int nErr = WSAGetLastError();
1637 if (nErr == WSAEADDRINUSE)
1638 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1640 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1641 printf("%s\n", strError.c_str());
1644 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1646 // Listen for incoming connections
1647 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1649 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1650 printf("%s\n", strError.c_str());
1657 void StartNode(void* parg)
1659 if (pnodeLocalHost == NULL)
1660 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1663 // Get local host ip
1664 char pszHostName[1000] = "";
1665 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1667 vector<CNetAddr> vaddr;
1668 if (LookupHost(pszHostName, vaddr))
1669 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1670 if (!addr.IsLocal())
1672 addrLocalHost.SetIP(addr);
1677 // Get local host ip
1678 struct ifaddrs* myaddrs;
1679 if (getifaddrs(&myaddrs) == 0)
1681 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1683 if (ifa->ifa_addr == NULL) continue;
1684 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1685 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1686 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1688 if (ifa->ifa_addr->sa_family == AF_INET)
1690 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1691 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1692 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1694 // Take the first IP that isn't loopback 127.x.x.x
1695 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1696 if (addr.IsValid() && !addr.IsLocal())
1698 addrLocalHost = addr;
1702 else if (ifa->ifa_addr->sa_family == AF_INET6)
1704 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1705 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1706 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1709 freeifaddrs(myaddrs);
1712 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1714 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1716 // Proxies can't take incoming connections
1717 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1718 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1722 CreateThread(ThreadGetMyExternalIP, NULL);
1729 if (!GetBoolArg("-dnsseed", true))
1730 printf("DNS seeding disabled\n");
1732 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1733 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1735 // Map ports with UPnP
1739 // Get addresses from IRC and advertise ours
1740 if (!CreateThread(ThreadIRCSeed, NULL))
1741 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1743 // Send and receive from sockets, accept connections
1744 if (!CreateThread(ThreadSocketHandler, NULL))
1745 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1747 // Initiate outbound connections from -addnode
1748 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1749 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1751 // Initiate outbound connections
1752 if (!CreateThread(ThreadOpenConnections, NULL))
1753 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1756 if (!CreateThread(ThreadMessageHandler, NULL))
1757 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1759 // Generate coins in the background
1760 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1765 printf("StopNode()\n");
1767 nTransactionsUpdated++;
1768 int64 nStart = GetTime();
1769 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1770 || (fHaveUPnP && vnThreadsRunning[5] > 0) || vnThreadsRunning[6] > 0 || vnThreadsRunning[7] > 0
1773 if (GetTime() - nStart > 20)
1777 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1778 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1779 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1780 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1781 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1782 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1783 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1784 if (vnThreadsRunning[7] > 0) printf("ThreadOpenAddedConnections still running\n");
1785 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1801 BOOST_FOREACH(CNode* pnode, vNodes)
1802 if (pnode->hSocket != INVALID_SOCKET)
1803 closesocket(pnode->hSocket);
1804 if (hListenSocket != INVALID_SOCKET)
1805 if (closesocket(hListenSocket) == SOCKET_ERROR)
1806 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1809 // Shutdown Windows Sockets
1814 instance_of_cnetcleanup;