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();
277 BOOST_FOREACH(CNode* pnode, vNodes)
278 pnode->PushAddress(addr);
288 void AddressCurrentlyConnected(const CService& addr)
290 addrman.Connected(addr);
299 CNode* FindNode(const CNetAddr& ip)
303 BOOST_FOREACH(CNode* pnode, vNodes)
304 if ((CNetAddr)pnode->addr == ip)
310 CNode* FindNode(const CService& addr)
314 BOOST_FOREACH(CNode* pnode, vNodes)
315 if ((CService)pnode->addr == addr)
321 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
323 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
326 // Look for an existing connection
327 CNode* pnode = FindNode((CService)addrConnect);
331 pnode->AddRef(nTimeout);
338 printf("trying connection %s lastseen=%.1fhrs\n",
339 addrConnect.ToString().c_str(),
340 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
342 addrman.Attempt(addrConnect);
346 if (ConnectSocket(addrConnect, hSocket))
349 printf("connected %s\n", addrConnect.ToString().c_str());
351 // Set to nonblocking
354 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
355 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
357 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
358 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
362 CNode* pnode = new CNode(hSocket, addrConnect, false);
364 pnode->AddRef(nTimeout);
369 vNodes.push_back(pnode);
372 WAITABLE_LOCK(csOutbound);
376 pnode->nTimeConnected = GetTime();
385 void CNode::CloseSocketDisconnect()
388 if (hSocket != INVALID_SOCKET)
391 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
392 printf("disconnecting node %s\n", addr.ToString().c_str());
393 closesocket(hSocket);
394 hSocket = INVALID_SOCKET;
399 void CNode::Cleanup()
404 void CNode::PushVersion()
406 /// when NTP implemented, change to just nTime = GetAdjustedTime()
407 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
408 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
409 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
410 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
411 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
412 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
419 std::map<CNetAddr, int64> CNode::setBanned;
420 CCriticalSection CNode::cs_setBanned;
422 void CNode::ClearBanned()
427 bool CNode::IsBanned(CNetAddr ip)
429 bool fResult = false;
432 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
433 if (i != setBanned.end())
435 int64 t = (*i).second;
443 bool CNode::Misbehaving(int howmuch)
447 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
451 nMisbehavior += howmuch;
452 if (nMisbehavior >= GetArg("-banscore", 100))
454 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
457 if (setBanned[addr] < banTime)
458 setBanned[addr] = banTime;
460 CloseSocketDisconnect();
461 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
478 void ThreadSocketHandler(void* parg)
480 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
483 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
484 ThreadSocketHandler2(parg);
485 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
487 catch (std::exception& e) {
488 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
489 PrintException(&e, "ThreadSocketHandler()");
491 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
492 throw; // support pthread_cancel()
494 printf("ThreadSocketHandler exiting\n");
497 void ThreadSocketHandler2(void* parg)
499 printf("ThreadSocketHandler started\n");
500 list<CNode*> vNodesDisconnected;
501 int nPrevNodeCount = 0;
510 // Disconnect unused nodes
511 vector<CNode*> vNodesCopy = vNodes;
512 BOOST_FOREACH(CNode* pnode, vNodesCopy)
514 if (pnode->fDisconnect ||
515 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
517 // remove from vNodes
518 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
520 if (!pnode->fInbound)
522 WAITABLE_LOCK(csOutbound);
525 // Connection slot(s) were removed, notify connection creator(s)
526 NOTIFY(condOutbound);
529 // close socket and cleanup
530 pnode->CloseSocketDisconnect();
533 // hold in disconnected pool until all refs are released
534 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
535 if (pnode->fNetworkNode || pnode->fInbound)
537 vNodesDisconnected.push_back(pnode);
541 // Delete disconnected nodes
542 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
543 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
545 // wait until threads are done using it
546 if (pnode->GetRefCount() <= 0)
548 bool fDelete = false;
550 TRY_LOCK(pnode->cs_vSend, lockSend);
553 TRY_LOCK(pnode->cs_vRecv, lockRecv);
556 TRY_LOCK(pnode->cs_mapRequests, lockReq);
559 TRY_LOCK(pnode->cs_inventory, lockInv);
568 vNodesDisconnected.remove(pnode);
574 if (vNodes.size() != nPrevNodeCount)
576 nPrevNodeCount = vNodes.size();
582 // Find which sockets have data to receive
584 struct timeval timeout;
586 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
593 FD_ZERO(&fdsetError);
594 SOCKET hSocketMax = 0;
596 if(hListenSocket != INVALID_SOCKET)
597 FD_SET(hListenSocket, &fdsetRecv);
598 hSocketMax = max(hSocketMax, hListenSocket);
601 BOOST_FOREACH(CNode* pnode, vNodes)
603 if (pnode->hSocket == INVALID_SOCKET)
605 FD_SET(pnode->hSocket, &fdsetRecv);
606 FD_SET(pnode->hSocket, &fdsetError);
607 hSocketMax = max(hSocketMax, pnode->hSocket);
609 TRY_LOCK(pnode->cs_vSend, lockSend);
610 if (lockSend && !pnode->vSend.empty())
611 FD_SET(pnode->hSocket, &fdsetSend);
616 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
617 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
618 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
621 if (nSelect == SOCKET_ERROR)
623 int nErr = WSAGetLastError();
626 printf("socket select error %d\n", nErr);
627 for (int i = 0; i <= hSocketMax; i++)
628 FD_SET(i, &fdsetRecv);
631 FD_ZERO(&fdsetError);
632 Sleep(timeout.tv_usec/1000);
637 // Accept new connections
639 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
641 struct sockaddr_in sockaddr;
642 socklen_t len = sizeof(sockaddr);
643 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
647 if (hSocket != INVALID_SOCKET)
648 addr = CAddress(sockaddr);
652 BOOST_FOREACH(CNode* pnode, vNodes)
657 if (hSocket == INVALID_SOCKET)
659 if (WSAGetLastError() != WSAEWOULDBLOCK)
660 printf("socket error accept failed: %d\n", WSAGetLastError());
662 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
665 LOCK(cs_setservAddNodeAddresses);
666 if (!setservAddNodeAddresses.count(addr))
667 closesocket(hSocket);
670 else if (CNode::IsBanned(addr))
672 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
673 closesocket(hSocket);
677 printf("accepted connection %s\n", addr.ToString().c_str());
678 CNode* pnode = new CNode(hSocket, addr, true);
682 vNodes.push_back(pnode);
689 // Service each socket
691 vector<CNode*> vNodesCopy;
695 BOOST_FOREACH(CNode* pnode, vNodesCopy)
698 BOOST_FOREACH(CNode* pnode, vNodesCopy)
706 if (pnode->hSocket == INVALID_SOCKET)
708 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
710 TRY_LOCK(pnode->cs_vRecv, lockRecv);
713 CDataStream& vRecv = pnode->vRecv;
714 unsigned int nPos = vRecv.size();
716 if (nPos > ReceiveBufferSize()) {
717 if (!pnode->fDisconnect)
718 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
719 pnode->CloseSocketDisconnect();
722 // typical socket buffer is 8K-64K
723 char pchBuf[0x10000];
724 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
727 vRecv.resize(nPos + nBytes);
728 memcpy(&vRecv[nPos], pchBuf, nBytes);
729 pnode->nLastRecv = GetTime();
731 else if (nBytes == 0)
733 // socket closed gracefully
734 if (!pnode->fDisconnect)
735 printf("socket closed\n");
736 pnode->CloseSocketDisconnect();
741 int nErr = WSAGetLastError();
742 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
744 if (!pnode->fDisconnect)
745 printf("socket recv error %d\n", nErr);
746 pnode->CloseSocketDisconnect();
756 if (pnode->hSocket == INVALID_SOCKET)
758 if (FD_ISSET(pnode->hSocket, &fdsetSend))
760 TRY_LOCK(pnode->cs_vSend, lockSend);
763 CDataStream& vSend = pnode->vSend;
766 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
769 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
770 pnode->nLastSend = GetTime();
775 int nErr = WSAGetLastError();
776 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
778 printf("socket send error %d\n", nErr);
779 pnode->CloseSocketDisconnect();
782 if (vSend.size() > SendBufferSize()) {
783 if (!pnode->fDisconnect)
784 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
785 pnode->CloseSocketDisconnect();
792 // Inactivity checking
794 if (pnode->vSend.empty())
795 pnode->nLastSendEmpty = GetTime();
796 if (GetTime() - pnode->nTimeConnected > 60)
798 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
800 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
801 pnode->fDisconnect = true;
803 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
805 printf("socket not sending\n");
806 pnode->fDisconnect = true;
808 else if (GetTime() - pnode->nLastRecv > 90*60)
810 printf("socket inactivity timeout\n");
811 pnode->fDisconnect = true;
817 BOOST_FOREACH(CNode* pnode, vNodesCopy)
834 void ThreadMapPort(void* parg)
836 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
839 vnThreadsRunning[THREAD_UPNP]++;
840 ThreadMapPort2(parg);
841 vnThreadsRunning[THREAD_UPNP]--;
843 catch (std::exception& e) {
844 vnThreadsRunning[THREAD_UPNP]--;
845 PrintException(&e, "ThreadMapPort()");
847 vnThreadsRunning[THREAD_UPNP]--;
848 PrintException(NULL, "ThreadMapPort()");
850 printf("ThreadMapPort exiting\n");
853 void ThreadMapPort2(void* parg)
855 printf("ThreadMapPort started\n");
858 sprintf(port, "%d", GetListenPort());
860 const char * multicastif = 0;
861 const char * minissdpdpath = 0;
862 struct UPNPDev * devlist = 0;
865 #ifndef UPNPDISCOVER_SUCCESS
867 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
871 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
874 struct UPNPUrls urls;
875 struct IGDdatas data;
878 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
881 if (!addrLocalHost.IsRoutable())
883 char externalIPAddress[40];
884 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
885 if(r != UPNPCOMMAND_SUCCESS)
886 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
889 if(externalIPAddress[0])
891 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
892 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
893 if (addrExternalFromUPnP.IsRoutable())
894 addrLocalHost = addrExternalFromUPnP;
897 printf("UPnP: GetExternalIPAddress failed.\n");
901 string strDesc = "Bitcoin " + FormatFullVersion();
902 #ifndef UPNPDISCOVER_SUCCESS
904 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
905 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
908 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
909 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
912 if(r!=UPNPCOMMAND_SUCCESS)
913 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
914 port, port, lanaddr, r, strupnperror(r));
916 printf("UPnP Port Mapping successful.\n");
919 if (fShutdown || !fUseUPnP)
921 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
922 printf("UPNP_DeletePortMapping() returned : %d\n", r);
923 freeUPNPDevlist(devlist); devlist = 0;
927 if (i % 600 == 0) // Refresh every 20 minutes
929 #ifndef UPNPDISCOVER_SUCCESS
931 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
932 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
935 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
936 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
939 if(r!=UPNPCOMMAND_SUCCESS)
940 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
941 port, port, lanaddr, r, strupnperror(r));
943 printf("UPnP Port Mapping successful.\n");;
949 printf("No valid UPnP IGDs found\n");
950 freeUPNPDevlist(devlist); devlist = 0;
954 if (fShutdown || !fUseUPnP)
961 void MapPort(bool fMapPort)
963 if (fUseUPnP != fMapPort)
967 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
969 if (!CreateThread(ThreadMapPort, NULL))
970 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
974 void MapPort(bool /* unused fMapPort */)
976 // Intentionally left blank.
989 // Each pair gives a source name and a seed name.
990 // The first name is used as information source for addrman.
991 // The second name should resolve to a list of seed addresses.
992 static const char *strDNSSeed[][2] = {
993 {"xf2.org", "bitseed.xf2.org"},
994 {"bluematt.me", "dnsseed.bluematt.me"},
995 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
996 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
999 void ThreadDNSAddressSeed(void* parg)
1001 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1004 vnThreadsRunning[THREAD_DNSSEED]++;
1005 ThreadDNSAddressSeed2(parg);
1006 vnThreadsRunning[THREAD_DNSSEED]--;
1008 catch (std::exception& e) {
1009 vnThreadsRunning[THREAD_DNSSEED]--;
1010 PrintException(&e, "ThreadDNSAddressSeed()");
1012 vnThreadsRunning[THREAD_DNSSEED]--;
1013 throw; // support pthread_cancel()
1015 printf("ThreadDNSAddressSeed exiting\n");
1018 void ThreadDNSAddressSeed2(void* parg)
1020 printf("ThreadDNSAddressSeed started\n");
1025 printf("Loading addresses from DNS seeds (could take a while)\n");
1027 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1028 vector<CNetAddr> vaddr;
1029 vector<CAddress> vAdd;
1030 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1032 BOOST_FOREACH(CNetAddr& ip, vaddr)
1034 int nOneDay = 24*3600;
1035 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1036 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1037 vAdd.push_back(addr);
1041 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1045 printf("%d addresses found from DNS seeds\n", found);
1059 unsigned int pnSeed[] =
1061 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1062 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1063 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1064 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1065 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1066 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1067 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1068 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1069 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1070 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1071 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1072 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1073 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1074 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1075 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1076 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1077 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1078 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1079 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1080 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1081 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1082 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1083 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1084 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1085 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1086 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1087 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1088 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1089 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1090 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1091 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1092 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1093 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1094 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1095 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1096 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1097 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1098 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1099 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1100 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1101 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1102 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1103 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1104 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1105 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1106 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1107 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1108 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1109 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1110 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1111 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1112 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1113 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1114 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1115 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1116 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1117 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1118 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1119 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1120 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1121 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1122 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1123 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1124 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1125 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1126 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1127 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1128 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1129 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1130 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1131 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1132 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1133 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1134 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1135 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1136 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1137 0xc461d84a, 0xb2dbe247,
1140 void DumpAddresses()
1143 adb.WriteAddrman(addrman);
1146 void ThreadDumpAddress2(void* parg)
1148 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1152 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1154 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1156 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1159 void ThreadDumpAddress(void* parg)
1161 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1164 ThreadDumpAddress2(parg);
1166 catch (std::exception& e) {
1167 PrintException(&e, "ThreadDumpAddress()");
1169 printf("ThreadDumpAddress exiting\n");
1172 void ThreadOpenConnections(void* parg)
1174 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1177 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1178 ThreadOpenConnections2(parg);
1179 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1181 catch (std::exception& e) {
1182 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1183 PrintException(&e, "ThreadOpenConnections()");
1185 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1186 PrintException(NULL, "ThreadOpenConnections()");
1188 printf("ThreadOpenConnections exiting\n");
1191 void ThreadOpenConnections2(void* parg)
1193 printf("ThreadOpenConnections started\n");
1195 // Connect to specific addresses
1196 if (mapArgs.count("-connect"))
1198 for (int64 nLoop = 0;; nLoop++)
1200 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1202 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1204 OpenNetworkConnection(addr);
1205 for (int i = 0; i < 10 && i < nLoop; i++)
1215 // Initiate network connections
1216 int64 nStart = GetTime();
1219 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1221 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1225 // Limit outbound connections
1226 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1227 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1229 WAITABLE_LOCK(csOutbound);
1230 WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
1232 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1236 bool fAddSeeds = false;
1238 // Add seed nodes if IRC isn't working
1239 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1240 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1242 std::vector<CAddress> vAdd;
1243 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1245 // It'll only connect to one or two seed nodes because once it connects,
1246 // it'll get a pile of addresses with newer timestamps.
1247 // Seed nodes are given a random 'last seen time' of between one and two
1249 const int64 nOneWeek = 7*24*60*60;
1251 memcpy(&ip, &pnSeed[i], sizeof(ip));
1252 CAddress addr(CService(ip, GetDefaultPort()));
1253 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1254 vAdd.push_back(addr);
1256 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1260 // Choose an address to connect to based on most recently seen
1262 CAddress addrConnect;
1263 int64 nBest = std::numeric_limits<int64>::min();
1265 // Only connect to one address per a.b.?.? range.
1266 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1267 set<vector<unsigned char> > setConnected;
1270 BOOST_FOREACH(CNode* pnode, vNodes)
1271 setConnected.insert(pnode->addr.GetGroup());
1274 int64 nANow = GetAdjustedTime();
1279 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1280 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1282 // if we selected an invalid address, restart
1283 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1288 // only consider very recently tried nodes after 30 failed attempts
1289 if (nANow - addr.nLastTry < 600 && nTries < 30)
1292 // do not allow non-default ports, unless after 50 invalid addresses selected already
1293 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1300 if (addrConnect.IsValid())
1301 OpenNetworkConnection(addrConnect);
1305 void ThreadOpenAddedConnections(void* parg)
1307 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1310 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1311 ThreadOpenAddedConnections2(parg);
1312 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1314 catch (std::exception& e) {
1315 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1316 PrintException(&e, "ThreadOpenAddedConnections()");
1318 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1319 PrintException(NULL, "ThreadOpenAddedConnections()");
1321 printf("ThreadOpenAddedConnections exiting\n");
1324 void ThreadOpenAddedConnections2(void* parg)
1326 printf("ThreadOpenAddedConnections started\n");
1328 if (mapArgs.count("-addnode") == 0)
1331 vector<vector<CService> > vservAddressesToAdd(0);
1332 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1334 vector<CService> vservNode(0);
1335 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1337 vservAddressesToAdd.push_back(vservNode);
1339 LOCK(cs_setservAddNodeAddresses);
1340 BOOST_FOREACH(CService& serv, vservNode)
1341 setservAddNodeAddresses.insert(serv);
1347 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1348 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1349 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1352 BOOST_FOREACH(CNode* pnode, vNodes)
1353 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1354 BOOST_FOREACH(CService& addrNode, *(it))
1355 if (pnode->addr == addrNode)
1357 it = vservConnectAddresses.erase(it);
1362 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1364 OpenNetworkConnection(CAddress(*(vserv.begin())));
1371 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1372 Sleep(120000); // Retry every 2 minutes
1373 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1379 bool OpenNetworkConnection(const CAddress& addrConnect)
1382 // Initiate outbound network connection
1386 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1387 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1390 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1391 CNode* pnode = ConnectNode(addrConnect);
1392 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1397 pnode->fNetworkNode = true;
1409 void ThreadMessageHandler(void* parg)
1411 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1414 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1415 ThreadMessageHandler2(parg);
1416 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1418 catch (std::exception& e) {
1419 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1420 PrintException(&e, "ThreadMessageHandler()");
1422 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1423 PrintException(NULL, "ThreadMessageHandler()");
1425 printf("ThreadMessageHandler exiting\n");
1428 void ThreadMessageHandler2(void* parg)
1430 printf("ThreadMessageHandler started\n");
1431 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1434 vector<CNode*> vNodesCopy;
1437 vNodesCopy = vNodes;
1438 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1442 // Poll the connected nodes for messages
1443 CNode* pnodeTrickle = NULL;
1444 if (!vNodesCopy.empty())
1445 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1446 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1450 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1452 ProcessMessages(pnode);
1459 TRY_LOCK(pnode->cs_vSend, lockSend);
1461 SendMessages(pnode, pnode == pnodeTrickle);
1469 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1473 // Wait and allow messages to bunch up.
1474 // Reduce vnThreadsRunning so StopNode has permission to exit while
1475 // we're sleeping, but we must always check fShutdown after doing this.
1476 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1478 if (fRequestShutdown)
1480 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1491 bool BindListenPort(string& strError)
1495 addrLocalHost.SetPort(GetListenPort());
1498 // Initialize Windows Sockets
1500 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1501 if (ret != NO_ERROR)
1503 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1504 printf("%s\n", strError.c_str());
1509 // Create socket for listening for incoming connections
1510 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1511 if (hListenSocket == INVALID_SOCKET)
1513 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1514 printf("%s\n", strError.c_str());
1519 // Different way of disabling SIGPIPE on BSD
1520 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1524 // Allow binding if the port is still in TIME_WAIT state after
1525 // the program was closed and restarted. Not an issue on windows.
1526 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1530 // Set to nonblocking, incoming connections will also inherit this
1531 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1533 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1536 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1537 printf("%s\n", strError.c_str());
1541 // The sockaddr_in structure specifies the address family,
1542 // IP address, and port for the socket that is being bound
1543 struct sockaddr_in sockaddr;
1544 memset(&sockaddr, 0, sizeof(sockaddr));
1545 sockaddr.sin_family = AF_INET;
1546 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1547 sockaddr.sin_port = htons(GetListenPort());
1548 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1550 int nErr = WSAGetLastError();
1551 if (nErr == WSAEADDRINUSE)
1552 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1554 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1555 printf("%s\n", strError.c_str());
1558 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1560 // Listen for incoming connections
1561 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1563 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1564 printf("%s\n", strError.c_str());
1571 void StartNode(void* parg)
1575 fUseUPnP = GetBoolArg("-upnp", true);
1577 fUseUPnP = GetBoolArg("-upnp", false);
1581 if (pnodeLocalHost == NULL)
1582 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1585 // Get local host ip
1586 char pszHostName[1000] = "";
1587 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1589 vector<CNetAddr> vaddr;
1590 if (LookupHost(pszHostName, vaddr))
1591 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1592 if (!addr.IsLocal())
1594 addrLocalHost.SetIP(addr);
1599 // Get local host ip
1600 struct ifaddrs* myaddrs;
1601 if (getifaddrs(&myaddrs) == 0)
1603 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1605 if (ifa->ifa_addr == NULL) continue;
1606 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1607 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1608 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1610 if (ifa->ifa_addr->sa_family == AF_INET)
1612 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1613 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1614 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1616 // Take the first IP that isn't loopback 127.x.x.x
1617 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1618 if (addr.IsValid() && !addr.IsLocal())
1620 addrLocalHost = addr;
1624 else if (ifa->ifa_addr->sa_family == AF_INET6)
1626 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1627 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1628 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1631 freeifaddrs(myaddrs);
1634 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1636 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1638 // Proxies can't take incoming connections
1639 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1640 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1644 CreateThread(ThreadGetMyExternalIP, NULL);
1651 if (!GetBoolArg("-dnsseed", true))
1652 printf("DNS seeding disabled\n");
1654 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1655 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1657 // Map ports with UPnP
1661 // Get addresses from IRC and advertise ours
1662 if (!CreateThread(ThreadIRCSeed, NULL))
1663 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1665 // Send and receive from sockets, accept connections
1666 if (!CreateThread(ThreadSocketHandler, NULL))
1667 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1669 // Initiate outbound connections from -addnode
1670 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1671 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1673 // Initiate outbound connections
1674 if (!CreateThread(ThreadOpenConnections, NULL))
1675 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1678 if (!CreateThread(ThreadMessageHandler, NULL))
1679 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1681 // Dump network addresses
1682 if (!CreateThread(ThreadDumpAddress, NULL))
1683 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1685 // Generate coins in the background
1686 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1691 printf("StopNode()\n");
1693 nTransactionsUpdated++;
1694 int64 nStart = GetTime();
1695 NOTIFY_ALL(condOutbound);
1698 int nThreadsRunning = 0;
1699 for (int n = 0; n < THREAD_MAX; n++)
1700 nThreadsRunning += vnThreadsRunning[n];
1701 if (nThreadsRunning == 0)
1703 if (GetTime() - nStart > 20)
1707 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1708 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1709 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1710 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1711 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1712 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1713 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1714 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1715 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1716 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1732 BOOST_FOREACH(CNode* pnode, vNodes)
1733 if (pnode->hSocket != INVALID_SOCKET)
1734 closesocket(pnode->hSocket);
1735 if (hListenSocket != INVALID_SOCKET)
1736 if (closesocket(hListenSocket) == SOCKET_ERROR)
1737 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1740 // Shutdown Windows Sockets
1745 instance_of_cnetcleanup;