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.
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
26 using namespace boost;
28 static const int MAX_OUTBOUND_CONNECTIONS = 8;
30 void ThreadMessageHandler2(void* parg);
31 void ThreadSocketHandler2(void* parg);
32 void ThreadOpenConnections2(void* parg);
33 void ThreadOpenAddedConnections2(void* parg);
35 void ThreadMapPort2(void* parg);
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect);
43 // Global state variables
46 bool fAllowDNS = false;
47 static bool fUseUPnP = 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, THREAD_MAX> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
56 vector<CNode*> vNodes;
57 CCriticalSection cs_vNodes;
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 void AddressCurrentlyConnected(const CService& addr)
285 addrman.Connected(addr);
294 CNode* FindNode(const CNetAddr& ip)
296 CRITICAL_BLOCK(cs_vNodes)
298 BOOST_FOREACH(CNode* pnode, vNodes)
299 if ((CNetAddr)pnode->addr == ip)
305 CNode* FindNode(const CService& addr)
307 CRITICAL_BLOCK(cs_vNodes)
309 BOOST_FOREACH(CNode* pnode, vNodes)
310 if ((CService)pnode->addr == addr)
316 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
318 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
321 // Look for an existing connection
322 CNode* pnode = FindNode((CService)addrConnect);
326 pnode->AddRef(nTimeout);
333 printf("trying connection %s lastseen=%.1fhrs\n",
334 addrConnect.ToString().c_str(),
335 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
337 addrman.Attempt(addrConnect);
341 if (ConnectSocket(addrConnect, hSocket))
344 printf("connected %s\n", addrConnect.ToString().c_str());
346 // Set to nonblocking
349 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
350 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
352 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
353 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
357 CNode* pnode = new CNode(hSocket, addrConnect, false);
359 pnode->AddRef(nTimeout);
362 CRITICAL_BLOCK(cs_vNodes)
363 vNodes.push_back(pnode);
365 pnode->nTimeConnected = GetTime();
374 void CNode::CloseSocketDisconnect()
377 if (hSocket != INVALID_SOCKET)
380 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
381 printf("disconnecting node %s\n", addr.ToString().c_str());
382 closesocket(hSocket);
383 hSocket = INVALID_SOCKET;
388 void CNode::Cleanup()
393 void CNode::PushVersion()
395 /// when NTP implemented, change to just nTime = GetAdjustedTime()
396 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
397 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
398 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
399 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
400 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
401 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
408 std::map<CNetAddr, int64> CNode::setBanned;
409 CCriticalSection CNode::cs_setBanned;
411 void CNode::ClearBanned()
416 bool CNode::IsBanned(CNetAddr ip)
418 bool fResult = false;
419 CRITICAL_BLOCK(cs_setBanned)
421 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
422 if (i != setBanned.end())
424 int64 t = (*i).second;
432 bool CNode::Misbehaving(int howmuch)
436 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
440 nMisbehavior += howmuch;
441 if (nMisbehavior >= GetArg("-banscore", 100))
443 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
444 CRITICAL_BLOCK(cs_setBanned)
445 if (setBanned[addr] < banTime)
446 setBanned[addr] = banTime;
447 CloseSocketDisconnect();
448 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
465 void ThreadSocketHandler(void* parg)
467 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
470 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
471 ThreadSocketHandler2(parg);
472 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
474 catch (std::exception& e) {
475 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
476 PrintException(&e, "ThreadSocketHandler()");
478 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
479 throw; // support pthread_cancel()
481 printf("ThreadSocketHandler exiting\n");
484 void ThreadSocketHandler2(void* parg)
486 printf("ThreadSocketHandler started\n");
487 list<CNode*> vNodesDisconnected;
488 int nPrevNodeCount = 0;
495 CRITICAL_BLOCK(cs_vNodes)
497 // Disconnect unused nodes
498 vector<CNode*> vNodesCopy = vNodes;
499 BOOST_FOREACH(CNode* pnode, vNodesCopy)
501 if (pnode->fDisconnect ||
502 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
504 // remove from vNodes
505 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
507 // close socket and cleanup
508 pnode->CloseSocketDisconnect();
511 // hold in disconnected pool until all refs are released
512 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
513 if (pnode->fNetworkNode || pnode->fInbound)
515 vNodesDisconnected.push_back(pnode);
519 // Delete disconnected nodes
520 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
521 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
523 // wait until threads are done using it
524 if (pnode->GetRefCount() <= 0)
526 bool fDelete = false;
527 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
528 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
529 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
530 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
534 vNodesDisconnected.remove(pnode);
540 if (vNodes.size() != nPrevNodeCount)
542 nPrevNodeCount = vNodes.size();
548 // Find which sockets have data to receive
550 struct timeval timeout;
552 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
559 FD_ZERO(&fdsetError);
560 SOCKET hSocketMax = 0;
562 if(hListenSocket != INVALID_SOCKET)
563 FD_SET(hListenSocket, &fdsetRecv);
564 hSocketMax = max(hSocketMax, hListenSocket);
565 CRITICAL_BLOCK(cs_vNodes)
567 BOOST_FOREACH(CNode* pnode, vNodes)
569 if (pnode->hSocket == INVALID_SOCKET)
571 FD_SET(pnode->hSocket, &fdsetRecv);
572 FD_SET(pnode->hSocket, &fdsetError);
573 hSocketMax = max(hSocketMax, pnode->hSocket);
574 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
575 if (!pnode->vSend.empty())
576 FD_SET(pnode->hSocket, &fdsetSend);
580 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
581 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
582 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
585 if (nSelect == SOCKET_ERROR)
587 int nErr = WSAGetLastError();
590 printf("socket select error %d\n", nErr);
591 for (int i = 0; i <= hSocketMax; i++)
592 FD_SET(i, &fdsetRecv);
595 FD_ZERO(&fdsetError);
596 Sleep(timeout.tv_usec/1000);
601 // Accept new connections
603 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
605 struct sockaddr_in sockaddr;
606 socklen_t len = sizeof(sockaddr);
607 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
611 if (hSocket != INVALID_SOCKET)
612 addr = CAddress(sockaddr);
614 CRITICAL_BLOCK(cs_vNodes)
615 BOOST_FOREACH(CNode* pnode, vNodes)
619 if (hSocket == INVALID_SOCKET)
621 if (WSAGetLastError() != WSAEWOULDBLOCK)
622 printf("socket error accept failed: %d\n", WSAGetLastError());
624 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
626 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
627 if (!setservAddNodeAddresses.count(addr))
628 closesocket(hSocket);
630 else if (CNode::IsBanned(addr))
632 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
633 closesocket(hSocket);
637 printf("accepted connection %s\n", addr.ToString().c_str());
638 CNode* pnode = new CNode(hSocket, addr, true);
640 CRITICAL_BLOCK(cs_vNodes)
641 vNodes.push_back(pnode);
647 // Service each socket
649 vector<CNode*> vNodesCopy;
650 CRITICAL_BLOCK(cs_vNodes)
653 BOOST_FOREACH(CNode* pnode, vNodesCopy)
656 BOOST_FOREACH(CNode* pnode, vNodesCopy)
664 if (pnode->hSocket == INVALID_SOCKET)
666 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
668 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
670 CDataStream& vRecv = pnode->vRecv;
671 unsigned int nPos = vRecv.size();
673 if (nPos > ReceiveBufferSize()) {
674 if (!pnode->fDisconnect)
675 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
676 pnode->CloseSocketDisconnect();
679 // typical socket buffer is 8K-64K
680 char pchBuf[0x10000];
681 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
684 vRecv.resize(nPos + nBytes);
685 memcpy(&vRecv[nPos], pchBuf, nBytes);
686 pnode->nLastRecv = GetTime();
688 else if (nBytes == 0)
690 // socket closed gracefully
691 if (!pnode->fDisconnect)
692 printf("socket closed\n");
693 pnode->CloseSocketDisconnect();
698 int nErr = WSAGetLastError();
699 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
701 if (!pnode->fDisconnect)
702 printf("socket recv error %d\n", nErr);
703 pnode->CloseSocketDisconnect();
713 if (pnode->hSocket == INVALID_SOCKET)
715 if (FD_ISSET(pnode->hSocket, &fdsetSend))
717 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
719 CDataStream& vSend = pnode->vSend;
722 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
725 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
726 pnode->nLastSend = GetTime();
731 int nErr = WSAGetLastError();
732 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
734 printf("socket send error %d\n", nErr);
735 pnode->CloseSocketDisconnect();
738 if (vSend.size() > SendBufferSize()) {
739 if (!pnode->fDisconnect)
740 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
741 pnode->CloseSocketDisconnect();
748 // Inactivity checking
750 if (pnode->vSend.empty())
751 pnode->nLastSendEmpty = GetTime();
752 if (GetTime() - pnode->nTimeConnected > 60)
754 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
756 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
757 pnode->fDisconnect = true;
759 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
761 printf("socket not sending\n");
762 pnode->fDisconnect = true;
764 else if (GetTime() - pnode->nLastRecv > 90*60)
766 printf("socket inactivity timeout\n");
767 pnode->fDisconnect = true;
771 CRITICAL_BLOCK(cs_vNodes)
773 BOOST_FOREACH(CNode* pnode, vNodesCopy)
790 void ThreadMapPort(void* parg)
792 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
795 vnThreadsRunning[THREAD_UPNP]++;
796 ThreadMapPort2(parg);
797 vnThreadsRunning[THREAD_UPNP]--;
799 catch (std::exception& e) {
800 vnThreadsRunning[THREAD_UPNP]--;
801 PrintException(&e, "ThreadMapPort()");
803 vnThreadsRunning[THREAD_UPNP]--;
804 PrintException(NULL, "ThreadMapPort()");
806 printf("ThreadMapPort exiting\n");
809 void ThreadMapPort2(void* parg)
811 printf("ThreadMapPort started\n");
814 sprintf(port, "%d", GetListenPort());
816 const char * multicastif = 0;
817 const char * minissdpdpath = 0;
818 struct UPNPDev * devlist = 0;
821 #ifndef UPNPDISCOVER_SUCCESS
823 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
827 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
830 struct UPNPUrls urls;
831 struct IGDdatas data;
834 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
837 if (!addrLocalHost.IsRoutable())
839 char externalIPAddress[40];
840 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
841 if(r != UPNPCOMMAND_SUCCESS)
842 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
845 if(externalIPAddress[0])
847 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
848 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
849 if (addrExternalFromUPnP.IsRoutable())
850 addrLocalHost = addrExternalFromUPnP;
853 printf("UPnP: GetExternalIPAddress failed.\n");
857 string strDesc = "Bitcoin " + FormatFullVersion();
858 #ifndef UPNPDISCOVER_SUCCESS
860 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
861 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
864 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
865 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
868 if(r!=UPNPCOMMAND_SUCCESS)
869 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
870 port, port, lanaddr, r, strupnperror(r));
872 printf("UPnP Port Mapping successful.\n");
875 if (fShutdown || !fUseUPnP)
877 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
878 printf("UPNP_DeletePortMapping() returned : %d\n", r);
879 freeUPNPDevlist(devlist); devlist = 0;
883 if (i % 600 == 0) // Refresh every 20 minutes
885 #ifndef UPNPDISCOVER_SUCCESS
887 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
888 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
891 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
892 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
895 if(r!=UPNPCOMMAND_SUCCESS)
896 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
897 port, port, lanaddr, r, strupnperror(r));
899 printf("UPnP Port Mapping successful.\n");;
905 printf("No valid UPnP IGDs found\n");
906 freeUPNPDevlist(devlist); devlist = 0;
910 if (fShutdown || !fUseUPnP)
917 void MapPort(bool fMapPort)
919 if (fUseUPnP != fMapPort)
923 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
925 if (!CreateThread(ThreadMapPort, NULL))
926 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
930 void MapPort(bool /* unused fMapPort */)
932 // Intentionally left blank.
945 // Each pair gives a source name and a seed name.
946 // The first name is used as information source for addrman.
947 // The second name should resolve to a list of seed addresses.
948 static const char *strDNSSeed[][2] = {
949 {"xf2.org", "bitseed.xf2.org"},
950 {"bluematt.me", "dnsseed.bluematt.me"},
951 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
952 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
955 void ThreadDNSAddressSeed(void* parg)
957 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
960 vnThreadsRunning[THREAD_DNSSEED]++;
961 ThreadDNSAddressSeed2(parg);
962 vnThreadsRunning[THREAD_DNSSEED]--;
964 catch (std::exception& e) {
965 vnThreadsRunning[THREAD_DNSSEED]--;
966 PrintException(&e, "ThreadDNSAddressSeed()");
968 vnThreadsRunning[THREAD_DNSSEED]--;
969 throw; // support pthread_cancel()
971 printf("ThreadDNSAddressSeed exiting\n");
974 void ThreadDNSAddressSeed2(void* parg)
976 printf("ThreadDNSAddressSeed started\n");
981 printf("Loading addresses from DNS seeds (could take a while)\n");
983 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
984 vector<CNetAddr> vaddr;
985 vector<CAddress> vAdd;
986 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
988 BOOST_FOREACH(CNetAddr& ip, vaddr)
990 int nOneDay = 24*3600;
991 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
992 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
993 vAdd.push_back(addr);
997 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1001 printf("%d addresses found from DNS seeds\n", found);
1015 unsigned int pnSeed[] =
1017 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1018 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1019 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1020 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1021 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1022 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1023 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1024 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1025 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1026 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1027 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1028 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1029 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1030 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1031 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1032 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1033 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1034 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1035 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1036 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1037 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1038 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1039 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1040 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1041 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1042 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1043 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1044 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1045 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1046 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1047 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1048 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1049 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1050 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1051 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1052 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1053 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1054 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1055 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1056 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1057 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1058 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1059 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1060 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1061 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1062 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1063 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1064 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1065 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1066 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1067 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1068 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1069 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1070 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1071 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1072 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1073 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1074 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1075 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1076 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1077 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1078 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1079 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1080 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1081 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1082 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1083 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1084 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1085 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1086 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1087 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1088 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1089 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1090 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1091 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1092 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1093 0xc461d84a, 0xb2dbe247,
1096 void DumpAddresses()
1099 adb.WriteAddrman(addrman);
1102 void ThreadDumpAddress2(void* parg)
1104 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1108 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1110 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1112 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1115 void ThreadDumpAddress(void* parg)
1117 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1120 ThreadDumpAddress2(parg);
1122 catch (std::exception& e) {
1123 PrintException(&e, "ThreadDumpAddress()");
1125 printf("ThreadDumpAddress exiting\n");
1128 void ThreadOpenConnections(void* parg)
1130 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1133 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1134 ThreadOpenConnections2(parg);
1135 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1137 catch (std::exception& e) {
1138 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1139 PrintException(&e, "ThreadOpenConnections()");
1141 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1142 PrintException(NULL, "ThreadOpenConnections()");
1144 printf("ThreadOpenConnections exiting\n");
1147 void ThreadOpenConnections2(void* parg)
1149 printf("ThreadOpenConnections started\n");
1151 // Connect to specific addresses
1152 if (mapArgs.count("-connect"))
1154 for (int64 nLoop = 0;; nLoop++)
1156 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1158 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1160 OpenNetworkConnection(addr);
1161 for (int i = 0; i < 10 && i < nLoop; i++)
1171 // Initiate network connections
1172 int64 nStart = GetTime();
1177 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1179 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1183 // Limit outbound connections
1187 CRITICAL_BLOCK(cs_vNodes)
1188 BOOST_FOREACH(CNode* pnode, vNodes)
1189 if (!pnode->fInbound)
1191 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1192 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1193 if (nOutbound < nMaxOutboundConnections)
1195 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1197 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1202 bool fAddSeeds = false;
1204 // Add seed nodes if IRC isn't working
1205 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1206 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1208 std::vector<CAddress> vAdd;
1209 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1211 // It'll only connect to one or two seed nodes because once it connects,
1212 // it'll get a pile of addresses with newer timestamps.
1213 // Seed nodes are given a random 'last seen time' of between one and two
1215 const int64 nOneWeek = 7*24*60*60;
1217 memcpy(&ip, &pnSeed[i], sizeof(ip));
1218 CAddress addr(CService(ip, GetDefaultPort()));
1219 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1220 vAdd.push_back(addr);
1222 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1226 // Choose an address to connect to based on most recently seen
1228 CAddress addrConnect;
1229 int64 nBest = std::numeric_limits<int64>::min();
1231 // Only connect to one address per a.b.?.? range.
1232 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1233 set<vector<unsigned char> > setConnected;
1234 CRITICAL_BLOCK(cs_vNodes)
1235 BOOST_FOREACH(CNode* pnode, vNodes)
1236 setConnected.insert(pnode->addr.GetGroup());
1238 int64 nANow = GetAdjustedTime();
1243 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1244 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1246 // if we selected an invalid address, restart
1247 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1252 // only consider very recently tried nodes after 30 failed attempts
1253 if (nANow - addr.nLastTry < 600 && nTries < 30)
1256 // do not allow non-default ports, unless after 50 invalid addresses selected already
1257 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1264 if (addrConnect.IsValid())
1265 OpenNetworkConnection(addrConnect);
1269 void ThreadOpenAddedConnections(void* parg)
1271 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1274 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1275 ThreadOpenAddedConnections2(parg);
1276 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1278 catch (std::exception& e) {
1279 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1280 PrintException(&e, "ThreadOpenAddedConnections()");
1282 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1283 PrintException(NULL, "ThreadOpenAddedConnections()");
1285 printf("ThreadOpenAddedConnections exiting\n");
1288 void ThreadOpenAddedConnections2(void* parg)
1290 printf("ThreadOpenAddedConnections started\n");
1292 if (mapArgs.count("-addnode") == 0)
1295 vector<vector<CService> > vservAddressesToAdd(0);
1296 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1298 vector<CService> vservNode(0);
1299 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1301 vservAddressesToAdd.push_back(vservNode);
1302 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1303 BOOST_FOREACH(CService& serv, vservNode)
1304 setservAddNodeAddresses.insert(serv);
1309 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1310 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1311 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1312 CRITICAL_BLOCK(cs_vNodes)
1313 BOOST_FOREACH(CNode* pnode, vNodes)
1314 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1315 BOOST_FOREACH(CService& addrNode, *(it))
1316 if (pnode->addr == addrNode)
1318 it = vservConnectAddresses.erase(it);
1322 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1324 OpenNetworkConnection(CAddress(*(vserv.begin())));
1331 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1332 Sleep(120000); // Retry every 2 minutes
1333 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1339 bool OpenNetworkConnection(const CAddress& addrConnect)
1342 // Initiate outbound network connection
1346 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1347 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1350 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1351 CNode* pnode = ConnectNode(addrConnect);
1352 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1357 pnode->fNetworkNode = true;
1369 void ThreadMessageHandler(void* parg)
1371 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1374 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1375 ThreadMessageHandler2(parg);
1376 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1378 catch (std::exception& e) {
1379 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1380 PrintException(&e, "ThreadMessageHandler()");
1382 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1383 PrintException(NULL, "ThreadMessageHandler()");
1385 printf("ThreadMessageHandler exiting\n");
1388 void ThreadMessageHandler2(void* parg)
1390 printf("ThreadMessageHandler started\n");
1391 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1394 vector<CNode*> vNodesCopy;
1395 CRITICAL_BLOCK(cs_vNodes)
1397 vNodesCopy = vNodes;
1398 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1402 // Poll the connected nodes for messages
1403 CNode* pnodeTrickle = NULL;
1404 if (!vNodesCopy.empty())
1405 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1406 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1409 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1410 ProcessMessages(pnode);
1415 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1416 SendMessages(pnode, pnode == pnodeTrickle);
1421 CRITICAL_BLOCK(cs_vNodes)
1423 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1427 // Wait and allow messages to bunch up.
1428 // Reduce vnThreadsRunning so StopNode has permission to exit while
1429 // we're sleeping, but we must always check fShutdown after doing this.
1430 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1432 if (fRequestShutdown)
1434 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1445 bool BindListenPort(string& strError)
1449 addrLocalHost.SetPort(GetListenPort());
1452 // Initialize Windows Sockets
1454 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1455 if (ret != NO_ERROR)
1457 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1458 printf("%s\n", strError.c_str());
1463 // Create socket for listening for incoming connections
1464 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1465 if (hListenSocket == INVALID_SOCKET)
1467 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1468 printf("%s\n", strError.c_str());
1473 // Different way of disabling SIGPIPE on BSD
1474 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1478 // Allow binding if the port is still in TIME_WAIT state after
1479 // the program was closed and restarted. Not an issue on windows.
1480 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1484 // Set to nonblocking, incoming connections will also inherit this
1485 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1487 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1490 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1491 printf("%s\n", strError.c_str());
1495 // The sockaddr_in structure specifies the address family,
1496 // IP address, and port for the socket that is being bound
1497 struct sockaddr_in sockaddr;
1498 memset(&sockaddr, 0, sizeof(sockaddr));
1499 sockaddr.sin_family = AF_INET;
1500 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1501 sockaddr.sin_port = htons(GetListenPort());
1502 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1504 int nErr = WSAGetLastError();
1505 if (nErr == WSAEADDRINUSE)
1506 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1508 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1509 printf("%s\n", strError.c_str());
1512 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1514 // Listen for incoming connections
1515 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1517 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1518 printf("%s\n", strError.c_str());
1525 void StartNode(void* parg)
1529 fUseUPnP = GetBoolArg("-upnp", true);
1531 fUseUPnP = GetBoolArg("-upnp", false);
1535 if (pnodeLocalHost == NULL)
1536 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1539 // Get local host ip
1540 char pszHostName[1000] = "";
1541 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1543 vector<CNetAddr> vaddr;
1544 if (LookupHost(pszHostName, vaddr))
1545 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1546 if (!addr.IsLocal())
1548 addrLocalHost.SetIP(addr);
1553 // Get local host ip
1554 struct ifaddrs* myaddrs;
1555 if (getifaddrs(&myaddrs) == 0)
1557 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1559 if (ifa->ifa_addr == NULL) continue;
1560 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1561 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1562 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1564 if (ifa->ifa_addr->sa_family == AF_INET)
1566 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1567 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1568 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1570 // Take the first IP that isn't loopback 127.x.x.x
1571 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1572 if (addr.IsValid() && !addr.IsLocal())
1574 addrLocalHost = addr;
1578 else if (ifa->ifa_addr->sa_family == AF_INET6)
1580 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1581 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1582 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1585 freeifaddrs(myaddrs);
1588 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1590 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1592 // Proxies can't take incoming connections
1593 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1594 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1598 CreateThread(ThreadGetMyExternalIP, NULL);
1605 if (!GetBoolArg("-dnsseed", true))
1606 printf("DNS seeding disabled\n");
1608 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1609 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1611 // Map ports with UPnP
1615 // Get addresses from IRC and advertise ours
1616 if (!CreateThread(ThreadIRCSeed, NULL))
1617 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1619 // Send and receive from sockets, accept connections
1620 if (!CreateThread(ThreadSocketHandler, NULL))
1621 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1623 // Initiate outbound connections from -addnode
1624 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1625 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1627 // Initiate outbound connections
1628 if (!CreateThread(ThreadOpenConnections, NULL))
1629 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1632 if (!CreateThread(ThreadMessageHandler, NULL))
1633 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1635 // Dump network addresses
1636 if (!CreateThread(ThreadDumpAddress, NULL))
1637 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1639 // Generate coins in the background
1640 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1645 printf("StopNode()\n");
1647 nTransactionsUpdated++;
1648 int64 nStart = GetTime();
1651 int nThreadsRunning = 0;
1652 for (int n = 0; n < THREAD_MAX; n++)
1653 nThreadsRunning += vnThreadsRunning[n];
1654 if (nThreadsRunning == 0)
1656 if (GetTime() - nStart > 20)
1660 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1661 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1662 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1663 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1664 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1665 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1666 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1667 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1668 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1669 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1685 BOOST_FOREACH(CNode* pnode, vNodes)
1686 if (pnode->hSocket != INVALID_SOCKET)
1687 closesocket(pnode->hSocket);
1688 if (hListenSocket != INVALID_SOCKET)
1689 if (closesocket(hListenSocket) == SOCKET_ERROR)
1690 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1693 // Shutdown Windows Sockets
1698 instance_of_cnetcleanup;