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.
12 #include "ui_interface.h"
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) != string::npos)
167 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
171 closesocket(hSocket);
172 if (strLine.find("<") != string::npos)
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 unsigned 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 (unsigned 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 (unsigned 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 // Add seed nodes if IRC isn't working
1237 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1238 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1240 std::vector<CAddress> vAdd;
1241 for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1243 // It'll only connect to one or two seed nodes because once it connects,
1244 // it'll get a pile of addresses with newer timestamps.
1245 // Seed nodes are given a random 'last seen time' of between one and two
1247 const int64 nOneWeek = 7*24*60*60;
1249 memcpy(&ip, &pnSeed[i], sizeof(ip));
1250 CAddress addr(CService(ip, GetDefaultPort()));
1251 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1252 vAdd.push_back(addr);
1254 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1258 // Choose an address to connect to based on most recently seen
1260 CAddress addrConnect;
1262 // Only connect to one address per a.b.?.? range.
1263 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1264 set<vector<unsigned char> > setConnected;
1267 BOOST_FOREACH(CNode* pnode, vNodes)
1268 setConnected.insert(pnode->addr.GetGroup());
1271 int64 nANow = GetAdjustedTime();
1276 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1277 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1279 // if we selected an invalid address, restart
1280 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1285 // only consider very recently tried nodes after 30 failed attempts
1286 if (nANow - addr.nLastTry < 600 && nTries < 30)
1289 // do not allow non-default ports, unless after 50 invalid addresses selected already
1290 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1297 if (addrConnect.IsValid())
1298 OpenNetworkConnection(addrConnect);
1302 void ThreadOpenAddedConnections(void* parg)
1304 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1307 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1308 ThreadOpenAddedConnections2(parg);
1309 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1311 catch (std::exception& e) {
1312 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1313 PrintException(&e, "ThreadOpenAddedConnections()");
1315 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1316 PrintException(NULL, "ThreadOpenAddedConnections()");
1318 printf("ThreadOpenAddedConnections exiting\n");
1321 void ThreadOpenAddedConnections2(void* parg)
1323 printf("ThreadOpenAddedConnections started\n");
1325 if (mapArgs.count("-addnode") == 0)
1328 vector<vector<CService> > vservAddressesToAdd(0);
1329 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1331 vector<CService> vservNode(0);
1332 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1334 vservAddressesToAdd.push_back(vservNode);
1336 LOCK(cs_setservAddNodeAddresses);
1337 BOOST_FOREACH(CService& serv, vservNode)
1338 setservAddNodeAddresses.insert(serv);
1344 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1345 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1346 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1349 BOOST_FOREACH(CNode* pnode, vNodes)
1350 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1351 BOOST_FOREACH(CService& addrNode, *(it))
1352 if (pnode->addr == addrNode)
1354 it = vservConnectAddresses.erase(it);
1359 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1361 OpenNetworkConnection(CAddress(*(vserv.begin())));
1368 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1369 Sleep(120000); // Retry every 2 minutes
1370 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1376 bool OpenNetworkConnection(const CAddress& addrConnect)
1379 // Initiate outbound network connection
1383 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1384 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1387 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1388 CNode* pnode = ConnectNode(addrConnect);
1389 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1394 pnode->fNetworkNode = true;
1406 void ThreadMessageHandler(void* parg)
1408 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1411 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1412 ThreadMessageHandler2(parg);
1413 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1415 catch (std::exception& e) {
1416 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1417 PrintException(&e, "ThreadMessageHandler()");
1419 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1420 PrintException(NULL, "ThreadMessageHandler()");
1422 printf("ThreadMessageHandler exiting\n");
1425 void ThreadMessageHandler2(void* parg)
1427 printf("ThreadMessageHandler started\n");
1428 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1431 vector<CNode*> vNodesCopy;
1434 vNodesCopy = vNodes;
1435 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1439 // Poll the connected nodes for messages
1440 CNode* pnodeTrickle = NULL;
1441 if (!vNodesCopy.empty())
1442 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1443 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1447 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1449 ProcessMessages(pnode);
1456 TRY_LOCK(pnode->cs_vSend, lockSend);
1458 SendMessages(pnode, pnode == pnodeTrickle);
1466 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1470 // Wait and allow messages to bunch up.
1471 // Reduce vnThreadsRunning so StopNode has permission to exit while
1472 // we're sleeping, but we must always check fShutdown after doing this.
1473 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1475 if (fRequestShutdown)
1477 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1488 bool BindListenPort(string& strError)
1492 addrLocalHost.SetPort(GetListenPort());
1495 // Initialize Windows Sockets
1497 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1498 if (ret != NO_ERROR)
1500 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1501 printf("%s\n", strError.c_str());
1506 // Create socket for listening for incoming connections
1507 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1508 if (hListenSocket == INVALID_SOCKET)
1510 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1511 printf("%s\n", strError.c_str());
1516 // Different way of disabling SIGPIPE on BSD
1517 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1521 // Allow binding if the port is still in TIME_WAIT state after
1522 // the program was closed and restarted. Not an issue on windows.
1523 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1527 // Set to nonblocking, incoming connections will also inherit this
1528 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1530 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1533 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1534 printf("%s\n", strError.c_str());
1538 // The sockaddr_in structure specifies the address family,
1539 // IP address, and port for the socket that is being bound
1540 struct sockaddr_in sockaddr;
1541 memset(&sockaddr, 0, sizeof(sockaddr));
1542 sockaddr.sin_family = AF_INET;
1543 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1544 sockaddr.sin_port = htons(GetListenPort());
1545 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1547 int nErr = WSAGetLastError();
1548 if (nErr == WSAEADDRINUSE)
1549 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1551 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1552 printf("%s\n", strError.c_str());
1555 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1557 // Listen for incoming connections
1558 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1560 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1561 printf("%s\n", strError.c_str());
1568 void StartNode(void* parg)
1572 fUseUPnP = GetBoolArg("-upnp", true);
1574 fUseUPnP = GetBoolArg("-upnp", false);
1578 if (pnodeLocalHost == NULL)
1579 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1582 // Get local host ip
1583 char pszHostName[1000] = "";
1584 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1586 vector<CNetAddr> vaddr;
1587 if (LookupHost(pszHostName, vaddr))
1589 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1591 if (!addr.IsLocal())
1593 addrLocalHost.SetIP(addr);
1600 // Get local host ip
1601 struct ifaddrs* myaddrs;
1602 if (getifaddrs(&myaddrs) == 0)
1604 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1606 if (ifa->ifa_addr == NULL) continue;
1607 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1608 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1609 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1611 if (ifa->ifa_addr->sa_family == AF_INET)
1613 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1614 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1615 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1617 // Take the first IP that isn't loopback 127.x.x.x
1618 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1619 if (addr.IsValid() && !addr.IsLocal())
1621 addrLocalHost = addr;
1625 else if (ifa->ifa_addr->sa_family == AF_INET6)
1627 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1628 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1629 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1632 freeifaddrs(myaddrs);
1635 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1637 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1639 // Proxies can't take incoming connections
1640 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1641 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1645 CreateThread(ThreadGetMyExternalIP, NULL);
1652 if (!GetBoolArg("-dnsseed", true))
1653 printf("DNS seeding disabled\n");
1655 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1656 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1658 // Map ports with UPnP
1662 // Get addresses from IRC and advertise ours
1663 if (!CreateThread(ThreadIRCSeed, NULL))
1664 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1666 // Send and receive from sockets, accept connections
1667 if (!CreateThread(ThreadSocketHandler, NULL))
1668 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1670 // Initiate outbound connections from -addnode
1671 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1672 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1674 // Initiate outbound connections
1675 if (!CreateThread(ThreadOpenConnections, NULL))
1676 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1679 if (!CreateThread(ThreadMessageHandler, NULL))
1680 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1682 // Dump network addresses
1683 if (!CreateThread(ThreadDumpAddress, NULL))
1684 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1686 // Generate coins in the background
1687 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1692 printf("StopNode()\n");
1694 nTransactionsUpdated++;
1695 int64 nStart = GetTime();
1696 NOTIFY_ALL(condOutbound);
1699 int nThreadsRunning = 0;
1700 for (int n = 0; n < THREAD_MAX; n++)
1701 nThreadsRunning += vnThreadsRunning[n];
1702 if (nThreadsRunning == 0)
1704 if (GetTime() - nStart > 20)
1708 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1709 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1710 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1711 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1712 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1713 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1714 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1715 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1716 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1717 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1733 BOOST_FOREACH(CNode* pnode, vNodes)
1734 if (pnode->hSocket != INVALID_SOCKET)
1735 closesocket(pnode->hSocket);
1736 if (hListenSocket != INVALID_SOCKET)
1737 if (closesocket(hListenSocket) == SOCKET_ERROR)
1738 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1741 // Shutdown Windows Sockets
1746 instance_of_cnetcleanup;