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;
67 static CWaitableCriticalSection csOutbound;
68 static int nOutbound = 0;
69 static CConditionVariable condOutbound;
72 unsigned short GetListenPort()
74 return (unsigned short)(GetArg("-port", GetDefaultPort()));
77 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
79 // Filter out duplicate requests
80 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
82 pindexLastGetBlocksBegin = pindexBegin;
83 hashLastGetBlocksEnd = hashEnd;
85 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
90 bool RecvLine(SOCKET hSocket, string& strLine)
96 int nBytes = recv(hSocket, &c, 1, 0);
104 if (strLine.size() >= 9000)
107 else if (nBytes <= 0)
113 int nErr = WSAGetLastError();
114 if (nErr == WSAEMSGSIZE)
116 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
122 if (!strLine.empty())
127 printf("socket closed\n");
133 int nErr = WSAGetLastError();
134 printf("recv failed: %d\n", nErr);
143 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
146 if (!ConnectSocket(addrConnect, hSocket))
147 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
149 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
152 while (RecvLine(hSocket, strLine))
154 if (strLine.empty()) // HTTP response is separated from headers by blank line
158 if (!RecvLine(hSocket, strLine))
160 closesocket(hSocket);
163 if (pszKeyword == NULL)
165 if (strLine.find(pszKeyword) != -1)
167 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
171 closesocket(hSocket);
172 if (strLine.find("<") != -1)
173 strLine = strLine.substr(0, strLine.find("<"));
174 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
175 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
176 strLine.resize(strLine.size()-1);
177 CService addr(strLine,0,true);
178 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
179 if (!addr.IsValid() || !addr.IsRoutable())
185 closesocket(hSocket);
186 return error("GetMyExternalIP() : connection closed");
189 // We now get our external IP from the IRC server first and only use this as a backup
190 bool GetMyExternalIP(CNetAddr& ipRet)
192 CService addrConnect;
194 const char* pszKeyword;
196 if (fNoListen||fUseProxy)
199 for (int nLookup = 0; nLookup <= 1; nLookup++)
200 for (int nHost = 1; nHost <= 2; nHost++)
202 // We should be phasing out our use of sites like these. If we need
203 // replacements, we should ask for volunteers to put this simple
204 // php file on their webserver that prints the client IP:
205 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
208 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
212 CService addrIP("checkip.dyndns.org", 80, true);
213 if (addrIP.IsValid())
214 addrConnect = addrIP;
217 pszGet = "GET / HTTP/1.1\r\n"
218 "Host: checkip.dyndns.org\r\n"
219 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
220 "Connection: close\r\n"
223 pszKeyword = "Address:";
227 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
231 CService addrIP("www.showmyip.com", 80, true);
232 if (addrIP.IsValid())
233 addrConnect = addrIP;
236 pszGet = "GET /simple/ HTTP/1.1\r\n"
237 "Host: www.showmyip.com\r\n"
238 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
239 "Connection: close\r\n"
242 pszKeyword = NULL; // Returns just IP address
245 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
252 void ThreadGetMyExternalIP(void* parg)
254 // Wait for IRC to get it first
255 if (GetBoolArg("-irc", false))
257 for (int i = 0; i < 2 * 60; i++)
260 if (fGotExternalIP || fShutdown)
265 // Fallback in case IRC fails to get it
266 if (GetMyExternalIP(addrLocalHost))
268 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
269 if (addrLocalHost.IsRoutable())
271 // If we already connected to a few before we had our IP, go back and addr them.
272 // setAddrKnown automatically filters any duplicate sends.
273 CAddress addr(addrLocalHost);
274 addr.nTime = GetAdjustedTime();
275 CRITICAL_BLOCK(cs_vNodes)
276 BOOST_FOREACH(CNode* pnode, vNodes)
277 pnode->PushAddress(addr);
286 void AddressCurrentlyConnected(const CService& addr)
288 addrman.Connected(addr);
297 CNode* FindNode(const CNetAddr& ip)
299 CRITICAL_BLOCK(cs_vNodes)
301 BOOST_FOREACH(CNode* pnode, vNodes)
302 if ((CNetAddr)pnode->addr == ip)
308 CNode* FindNode(const CService& addr)
310 CRITICAL_BLOCK(cs_vNodes)
312 BOOST_FOREACH(CNode* pnode, vNodes)
313 if ((CService)pnode->addr == addr)
319 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
321 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
324 // Look for an existing connection
325 CNode* pnode = FindNode((CService)addrConnect);
329 pnode->AddRef(nTimeout);
336 printf("trying connection %s lastseen=%.1fhrs\n",
337 addrConnect.ToString().c_str(),
338 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
340 addrman.Attempt(addrConnect);
344 if (ConnectSocket(addrConnect, hSocket))
347 printf("connected %s\n", addrConnect.ToString().c_str());
349 // Set to nonblocking
352 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
353 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
355 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
356 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
360 CNode* pnode = new CNode(hSocket, addrConnect, false);
362 pnode->AddRef(nTimeout);
365 CRITICAL_BLOCK(cs_vNodes)
366 vNodes.push_back(pnode);
367 WAITABLE_CRITICAL_BLOCK(csOutbound)
370 pnode->nTimeConnected = GetTime();
379 void CNode::CloseSocketDisconnect()
382 if (hSocket != INVALID_SOCKET)
385 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
386 printf("disconnecting node %s\n", addr.ToString().c_str());
387 closesocket(hSocket);
388 hSocket = INVALID_SOCKET;
393 void CNode::Cleanup()
398 void CNode::PushVersion()
400 /// when NTP implemented, change to just nTime = GetAdjustedTime()
401 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
402 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
403 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
404 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
405 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
406 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
413 std::map<CNetAddr, int64> CNode::setBanned;
414 CCriticalSection CNode::cs_setBanned;
416 void CNode::ClearBanned()
421 bool CNode::IsBanned(CNetAddr ip)
423 bool fResult = false;
424 CRITICAL_BLOCK(cs_setBanned)
426 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
427 if (i != setBanned.end())
429 int64 t = (*i).second;
437 bool CNode::Misbehaving(int howmuch)
441 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
445 nMisbehavior += howmuch;
446 if (nMisbehavior >= GetArg("-banscore", 100))
448 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
449 CRITICAL_BLOCK(cs_setBanned)
450 if (setBanned[addr] < banTime)
451 setBanned[addr] = banTime;
452 CloseSocketDisconnect();
453 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
470 void ThreadSocketHandler(void* parg)
472 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
475 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
476 ThreadSocketHandler2(parg);
477 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
479 catch (std::exception& e) {
480 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
481 PrintException(&e, "ThreadSocketHandler()");
483 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
484 throw; // support pthread_cancel()
486 printf("ThreadSocketHandler exiting\n");
489 void ThreadSocketHandler2(void* parg)
491 printf("ThreadSocketHandler started\n");
492 list<CNode*> vNodesDisconnected;
493 int nPrevNodeCount = 0;
500 CRITICAL_BLOCK(cs_vNodes)
502 // Disconnect unused nodes
503 vector<CNode*> vNodesCopy = vNodes;
504 BOOST_FOREACH(CNode* pnode, vNodesCopy)
506 if (pnode->fDisconnect ||
507 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
509 // remove from vNodes
510 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
512 if (!pnode->fInbound)
513 WAITABLE_CRITICAL_BLOCK(csOutbound)
517 // Connection slot(s) were removed, notify connection creator(s)
518 NOTIFY(condOutbound);
521 // close socket and cleanup
522 pnode->CloseSocketDisconnect();
525 // hold in disconnected pool until all refs are released
526 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
527 if (pnode->fNetworkNode || pnode->fInbound)
529 vNodesDisconnected.push_back(pnode);
533 // Delete disconnected nodes
534 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
535 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
537 // wait until threads are done using it
538 if (pnode->GetRefCount() <= 0)
540 bool fDelete = false;
541 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
542 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
543 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
544 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
548 vNodesDisconnected.remove(pnode);
554 if (vNodes.size() != nPrevNodeCount)
556 nPrevNodeCount = vNodes.size();
562 // Find which sockets have data to receive
564 struct timeval timeout;
566 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
573 FD_ZERO(&fdsetError);
574 SOCKET hSocketMax = 0;
576 if(hListenSocket != INVALID_SOCKET)
577 FD_SET(hListenSocket, &fdsetRecv);
578 hSocketMax = max(hSocketMax, hListenSocket);
579 CRITICAL_BLOCK(cs_vNodes)
581 BOOST_FOREACH(CNode* pnode, vNodes)
583 if (pnode->hSocket == INVALID_SOCKET)
585 FD_SET(pnode->hSocket, &fdsetRecv);
586 FD_SET(pnode->hSocket, &fdsetError);
587 hSocketMax = max(hSocketMax, pnode->hSocket);
588 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
589 if (!pnode->vSend.empty())
590 FD_SET(pnode->hSocket, &fdsetSend);
594 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
595 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
596 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
599 if (nSelect == SOCKET_ERROR)
601 int nErr = WSAGetLastError();
604 printf("socket select error %d\n", nErr);
605 for (int i = 0; i <= hSocketMax; i++)
606 FD_SET(i, &fdsetRecv);
609 FD_ZERO(&fdsetError);
610 Sleep(timeout.tv_usec/1000);
615 // Accept new connections
617 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
619 struct sockaddr_in sockaddr;
620 socklen_t len = sizeof(sockaddr);
621 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
625 if (hSocket != INVALID_SOCKET)
626 addr = CAddress(sockaddr);
628 CRITICAL_BLOCK(cs_vNodes)
629 BOOST_FOREACH(CNode* pnode, vNodes)
633 if (hSocket == INVALID_SOCKET)
635 if (WSAGetLastError() != WSAEWOULDBLOCK)
636 printf("socket error accept failed: %d\n", WSAGetLastError());
638 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
640 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
641 if (!setservAddNodeAddresses.count(addr))
642 closesocket(hSocket);
644 else if (CNode::IsBanned(addr))
646 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
647 closesocket(hSocket);
651 printf("accepted connection %s\n", addr.ToString().c_str());
652 CNode* pnode = new CNode(hSocket, addr, true);
654 CRITICAL_BLOCK(cs_vNodes)
655 vNodes.push_back(pnode);
661 // Service each socket
663 vector<CNode*> vNodesCopy;
664 CRITICAL_BLOCK(cs_vNodes)
667 BOOST_FOREACH(CNode* pnode, vNodesCopy)
670 BOOST_FOREACH(CNode* pnode, vNodesCopy)
678 if (pnode->hSocket == INVALID_SOCKET)
680 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
682 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
684 CDataStream& vRecv = pnode->vRecv;
685 unsigned int nPos = vRecv.size();
687 if (nPos > ReceiveBufferSize()) {
688 if (!pnode->fDisconnect)
689 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
690 pnode->CloseSocketDisconnect();
693 // typical socket buffer is 8K-64K
694 char pchBuf[0x10000];
695 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
698 vRecv.resize(nPos + nBytes);
699 memcpy(&vRecv[nPos], pchBuf, nBytes);
700 pnode->nLastRecv = GetTime();
702 else if (nBytes == 0)
704 // socket closed gracefully
705 if (!pnode->fDisconnect)
706 printf("socket closed\n");
707 pnode->CloseSocketDisconnect();
712 int nErr = WSAGetLastError();
713 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
715 if (!pnode->fDisconnect)
716 printf("socket recv error %d\n", nErr);
717 pnode->CloseSocketDisconnect();
727 if (pnode->hSocket == INVALID_SOCKET)
729 if (FD_ISSET(pnode->hSocket, &fdsetSend))
731 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
733 CDataStream& vSend = pnode->vSend;
736 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
739 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
740 pnode->nLastSend = GetTime();
745 int nErr = WSAGetLastError();
746 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
748 printf("socket send error %d\n", nErr);
749 pnode->CloseSocketDisconnect();
752 if (vSend.size() > SendBufferSize()) {
753 if (!pnode->fDisconnect)
754 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
755 pnode->CloseSocketDisconnect();
762 // Inactivity checking
764 if (pnode->vSend.empty())
765 pnode->nLastSendEmpty = GetTime();
766 if (GetTime() - pnode->nTimeConnected > 60)
768 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
770 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
771 pnode->fDisconnect = true;
773 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
775 printf("socket not sending\n");
776 pnode->fDisconnect = true;
778 else if (GetTime() - pnode->nLastRecv > 90*60)
780 printf("socket inactivity timeout\n");
781 pnode->fDisconnect = true;
785 CRITICAL_BLOCK(cs_vNodes)
787 BOOST_FOREACH(CNode* pnode, vNodesCopy)
804 void ThreadMapPort(void* parg)
806 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
809 vnThreadsRunning[THREAD_UPNP]++;
810 ThreadMapPort2(parg);
811 vnThreadsRunning[THREAD_UPNP]--;
813 catch (std::exception& e) {
814 vnThreadsRunning[THREAD_UPNP]--;
815 PrintException(&e, "ThreadMapPort()");
817 vnThreadsRunning[THREAD_UPNP]--;
818 PrintException(NULL, "ThreadMapPort()");
820 printf("ThreadMapPort exiting\n");
823 void ThreadMapPort2(void* parg)
825 printf("ThreadMapPort started\n");
828 sprintf(port, "%d", GetListenPort());
830 const char * multicastif = 0;
831 const char * minissdpdpath = 0;
832 struct UPNPDev * devlist = 0;
835 #ifndef UPNPDISCOVER_SUCCESS
837 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
841 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
844 struct UPNPUrls urls;
845 struct IGDdatas data;
848 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
851 if (!addrLocalHost.IsRoutable())
853 char externalIPAddress[40];
854 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
855 if(r != UPNPCOMMAND_SUCCESS)
856 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
859 if(externalIPAddress[0])
861 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
862 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
863 if (addrExternalFromUPnP.IsRoutable())
864 addrLocalHost = addrExternalFromUPnP;
867 printf("UPnP: GetExternalIPAddress failed.\n");
871 string strDesc = "Bitcoin " + FormatFullVersion();
872 #ifndef UPNPDISCOVER_SUCCESS
874 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
875 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
878 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
879 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
882 if(r!=UPNPCOMMAND_SUCCESS)
883 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
884 port, port, lanaddr, r, strupnperror(r));
886 printf("UPnP Port Mapping successful.\n");
889 if (fShutdown || !fUseUPnP)
891 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
892 printf("UPNP_DeletePortMapping() returned : %d\n", r);
893 freeUPNPDevlist(devlist); devlist = 0;
897 if (i % 600 == 0) // Refresh every 20 minutes
899 #ifndef UPNPDISCOVER_SUCCESS
901 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
902 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
905 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
906 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
909 if(r!=UPNPCOMMAND_SUCCESS)
910 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
911 port, port, lanaddr, r, strupnperror(r));
913 printf("UPnP Port Mapping successful.\n");;
919 printf("No valid UPnP IGDs found\n");
920 freeUPNPDevlist(devlist); devlist = 0;
924 if (fShutdown || !fUseUPnP)
931 void MapPort(bool fMapPort)
933 if (fUseUPnP != fMapPort)
937 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
939 if (!CreateThread(ThreadMapPort, NULL))
940 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
944 void MapPort(bool /* unused fMapPort */)
946 // Intentionally left blank.
959 // Each pair gives a source name and a seed name.
960 // The first name is used as information source for addrman.
961 // The second name should resolve to a list of seed addresses.
962 static const char *strDNSSeed[][2] = {
963 {"xf2.org", "bitseed.xf2.org"},
964 {"bluematt.me", "dnsseed.bluematt.me"},
965 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
966 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
969 void ThreadDNSAddressSeed(void* parg)
971 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
974 vnThreadsRunning[THREAD_DNSSEED]++;
975 ThreadDNSAddressSeed2(parg);
976 vnThreadsRunning[THREAD_DNSSEED]--;
978 catch (std::exception& e) {
979 vnThreadsRunning[THREAD_DNSSEED]--;
980 PrintException(&e, "ThreadDNSAddressSeed()");
982 vnThreadsRunning[THREAD_DNSSEED]--;
983 throw; // support pthread_cancel()
985 printf("ThreadDNSAddressSeed exiting\n");
988 void ThreadDNSAddressSeed2(void* parg)
990 printf("ThreadDNSAddressSeed started\n");
995 printf("Loading addresses from DNS seeds (could take a while)\n");
997 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
998 vector<CNetAddr> vaddr;
999 vector<CAddress> vAdd;
1000 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1002 BOOST_FOREACH(CNetAddr& ip, vaddr)
1004 int nOneDay = 24*3600;
1005 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1006 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1007 vAdd.push_back(addr);
1011 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1015 printf("%d addresses found from DNS seeds\n", found);
1029 unsigned int pnSeed[] =
1031 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1032 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1033 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1034 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1035 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1036 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1037 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1038 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1039 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1040 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1041 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1042 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1043 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1044 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1045 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1046 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1047 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1048 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1049 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1050 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1051 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1052 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1053 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1054 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1055 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1056 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1057 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1058 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1059 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1060 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1061 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1062 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1063 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1064 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1065 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1066 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1067 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1068 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1069 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1070 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1071 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1072 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1073 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1074 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1075 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1076 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1077 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1078 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1079 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1080 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1081 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1082 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1083 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1084 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1085 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1086 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1087 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1088 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1089 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1090 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1091 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1092 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1093 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1094 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1095 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1096 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1097 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1098 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1099 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1100 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1101 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1102 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1103 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1104 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1105 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1106 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1107 0xc461d84a, 0xb2dbe247,
1110 void DumpAddresses()
1113 adb.WriteAddrman(addrman);
1116 void ThreadDumpAddress2(void* parg)
1118 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1122 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1124 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1126 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1129 void ThreadDumpAddress(void* parg)
1131 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1134 ThreadDumpAddress2(parg);
1136 catch (std::exception& e) {
1137 PrintException(&e, "ThreadDumpAddress()");
1139 printf("ThreadDumpAddress exiting\n");
1142 void ThreadOpenConnections(void* parg)
1144 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1147 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1148 ThreadOpenConnections2(parg);
1149 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1151 catch (std::exception& e) {
1152 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1153 PrintException(&e, "ThreadOpenConnections()");
1155 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1156 PrintException(NULL, "ThreadOpenConnections()");
1158 printf("ThreadOpenConnections exiting\n");
1161 void ThreadOpenConnections2(void* parg)
1163 printf("ThreadOpenConnections started\n");
1165 // Connect to specific addresses
1166 if (mapArgs.count("-connect"))
1168 for (int64 nLoop = 0;; nLoop++)
1170 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1172 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1174 OpenNetworkConnection(addr);
1175 for (int i = 0; i < 10 && i < nLoop; i++)
1185 // Initiate network connections
1186 int64 nStart = GetTime();
1189 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1191 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1195 // Limit outbound connections
1196 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1197 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1198 WAITABLE_CRITICAL_BLOCK(csOutbound)
1199 WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
1200 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1204 bool fAddSeeds = false;
1206 // Add seed nodes if IRC isn't working
1207 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1208 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1210 std::vector<CAddress> vAdd;
1211 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1213 // It'll only connect to one or two seed nodes because once it connects,
1214 // it'll get a pile of addresses with newer timestamps.
1215 // Seed nodes are given a random 'last seen time' of between one and two
1217 const int64 nOneWeek = 7*24*60*60;
1219 memcpy(&ip, &pnSeed[i], sizeof(ip));
1220 CAddress addr(CService(ip, GetDefaultPort()));
1221 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1222 vAdd.push_back(addr);
1224 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1228 // Choose an address to connect to based on most recently seen
1230 CAddress addrConnect;
1231 int64 nBest = std::numeric_limits<int64>::min();
1233 // Only connect to one address per a.b.?.? range.
1234 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1235 set<vector<unsigned char> > setConnected;
1236 CRITICAL_BLOCK(cs_vNodes)
1237 BOOST_FOREACH(CNode* pnode, vNodes)
1238 setConnected.insert(pnode->addr.GetGroup());
1240 int64 nANow = GetAdjustedTime();
1245 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1246 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1248 // if we selected an invalid address, restart
1249 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1254 // only consider very recently tried nodes after 30 failed attempts
1255 if (nANow - addr.nLastTry < 600 && nTries < 30)
1258 // do not allow non-default ports, unless after 50 invalid addresses selected already
1259 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1266 if (addrConnect.IsValid())
1267 OpenNetworkConnection(addrConnect);
1271 void ThreadOpenAddedConnections(void* parg)
1273 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1276 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1277 ThreadOpenAddedConnections2(parg);
1278 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1280 catch (std::exception& e) {
1281 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1282 PrintException(&e, "ThreadOpenAddedConnections()");
1284 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1285 PrintException(NULL, "ThreadOpenAddedConnections()");
1287 printf("ThreadOpenAddedConnections exiting\n");
1290 void ThreadOpenAddedConnections2(void* parg)
1292 printf("ThreadOpenAddedConnections started\n");
1294 if (mapArgs.count("-addnode") == 0)
1297 vector<vector<CService> > vservAddressesToAdd(0);
1298 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1300 vector<CService> vservNode(0);
1301 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1303 vservAddressesToAdd.push_back(vservNode);
1304 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1305 BOOST_FOREACH(CService& serv, vservNode)
1306 setservAddNodeAddresses.insert(serv);
1311 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1312 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1313 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1314 CRITICAL_BLOCK(cs_vNodes)
1315 BOOST_FOREACH(CNode* pnode, vNodes)
1316 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1317 BOOST_FOREACH(CService& addrNode, *(it))
1318 if (pnode->addr == addrNode)
1320 it = vservConnectAddresses.erase(it);
1324 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1326 OpenNetworkConnection(CAddress(*(vserv.begin())));
1333 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1334 Sleep(120000); // Retry every 2 minutes
1335 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1341 bool OpenNetworkConnection(const CAddress& addrConnect)
1344 // Initiate outbound network connection
1348 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1349 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1352 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1353 CNode* pnode = ConnectNode(addrConnect);
1354 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1359 pnode->fNetworkNode = true;
1371 void ThreadMessageHandler(void* parg)
1373 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1376 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1377 ThreadMessageHandler2(parg);
1378 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1380 catch (std::exception& e) {
1381 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1382 PrintException(&e, "ThreadMessageHandler()");
1384 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1385 PrintException(NULL, "ThreadMessageHandler()");
1387 printf("ThreadMessageHandler exiting\n");
1390 void ThreadMessageHandler2(void* parg)
1392 printf("ThreadMessageHandler started\n");
1393 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1396 vector<CNode*> vNodesCopy;
1397 CRITICAL_BLOCK(cs_vNodes)
1399 vNodesCopy = vNodes;
1400 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1404 // Poll the connected nodes for messages
1405 CNode* pnodeTrickle = NULL;
1406 if (!vNodesCopy.empty())
1407 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1408 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1411 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1412 ProcessMessages(pnode);
1417 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1418 SendMessages(pnode, pnode == pnodeTrickle);
1423 CRITICAL_BLOCK(cs_vNodes)
1425 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1429 // Wait and allow messages to bunch up.
1430 // Reduce vnThreadsRunning so StopNode has permission to exit while
1431 // we're sleeping, but we must always check fShutdown after doing this.
1432 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1434 if (fRequestShutdown)
1436 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1447 bool BindListenPort(string& strError)
1451 addrLocalHost.SetPort(GetListenPort());
1454 // Initialize Windows Sockets
1456 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1457 if (ret != NO_ERROR)
1459 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1460 printf("%s\n", strError.c_str());
1465 // Create socket for listening for incoming connections
1466 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1467 if (hListenSocket == INVALID_SOCKET)
1469 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1470 printf("%s\n", strError.c_str());
1475 // Different way of disabling SIGPIPE on BSD
1476 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1480 // Allow binding if the port is still in TIME_WAIT state after
1481 // the program was closed and restarted. Not an issue on windows.
1482 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1486 // Set to nonblocking, incoming connections will also inherit this
1487 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1489 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1492 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1493 printf("%s\n", strError.c_str());
1497 // The sockaddr_in structure specifies the address family,
1498 // IP address, and port for the socket that is being bound
1499 struct sockaddr_in sockaddr;
1500 memset(&sockaddr, 0, sizeof(sockaddr));
1501 sockaddr.sin_family = AF_INET;
1502 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1503 sockaddr.sin_port = htons(GetListenPort());
1504 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1506 int nErr = WSAGetLastError();
1507 if (nErr == WSAEADDRINUSE)
1508 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1510 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1511 printf("%s\n", strError.c_str());
1514 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1516 // Listen for incoming connections
1517 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1519 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1520 printf("%s\n", strError.c_str());
1527 void StartNode(void* parg)
1531 fUseUPnP = GetBoolArg("-upnp", true);
1533 fUseUPnP = GetBoolArg("-upnp", false);
1537 if (pnodeLocalHost == NULL)
1538 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1541 // Get local host ip
1542 char pszHostName[1000] = "";
1543 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1545 vector<CNetAddr> vaddr;
1546 if (LookupHost(pszHostName, vaddr))
1547 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1548 if (!addr.IsLocal())
1550 addrLocalHost.SetIP(addr);
1555 // Get local host ip
1556 struct ifaddrs* myaddrs;
1557 if (getifaddrs(&myaddrs) == 0)
1559 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1561 if (ifa->ifa_addr == NULL) continue;
1562 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1563 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1564 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1566 if (ifa->ifa_addr->sa_family == AF_INET)
1568 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1569 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1570 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1572 // Take the first IP that isn't loopback 127.x.x.x
1573 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1574 if (addr.IsValid() && !addr.IsLocal())
1576 addrLocalHost = addr;
1580 else if (ifa->ifa_addr->sa_family == AF_INET6)
1582 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1583 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1584 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1587 freeifaddrs(myaddrs);
1590 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1592 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1594 // Proxies can't take incoming connections
1595 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1596 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1600 CreateThread(ThreadGetMyExternalIP, NULL);
1607 if (!GetBoolArg("-dnsseed", true))
1608 printf("DNS seeding disabled\n");
1610 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1611 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1613 // Map ports with UPnP
1617 // Get addresses from IRC and advertise ours
1618 if (!CreateThread(ThreadIRCSeed, NULL))
1619 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1621 // Send and receive from sockets, accept connections
1622 if (!CreateThread(ThreadSocketHandler, NULL))
1623 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1625 // Initiate outbound connections from -addnode
1626 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1627 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1629 // Initiate outbound connections
1630 if (!CreateThread(ThreadOpenConnections, NULL))
1631 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1634 if (!CreateThread(ThreadMessageHandler, NULL))
1635 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1637 // Dump network addresses
1638 if (!CreateThread(ThreadDumpAddress, NULL))
1639 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1641 // Generate coins in the background
1642 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1647 printf("StopNode()\n");
1649 nTransactionsUpdated++;
1650 int64 nStart = GetTime();
1651 NOTIFY_ALL(condOutbound);
1654 int nThreadsRunning = 0;
1655 for (int n = 0; n < THREAD_MAX; n++)
1656 nThreadsRunning += vnThreadsRunning[n];
1657 if (nThreadsRunning == 0)
1659 if (GetTime() - nStart > 20)
1663 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1664 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1665 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1666 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1667 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1668 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1669 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1670 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1671 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1672 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1688 BOOST_FOREACH(CNode* pnode, vNodes)
1689 if (pnode->hSocket != INVALID_SOCKET)
1690 closesocket(pnode->hSocket);
1691 if (hListenSocket != INVALID_SOCKET)
1692 if (closesocket(hListenSocket) == SOCKET_ERROR)
1693 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1696 // Shutdown Windows Sockets
1701 instance_of_cnetcleanup;