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 COPYING 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, bool fUseGrant = true);
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 CSemaphore *semOutbound = NULL;
69 unsigned short GetListenPort()
71 return (unsigned short)(GetArg("-port", GetDefaultPort()));
74 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
76 // Filter out duplicate requests
77 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
79 pindexLastGetBlocksBegin = pindexBegin;
80 hashLastGetBlocksEnd = hashEnd;
82 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
87 bool RecvLine(SOCKET hSocket, string& strLine)
93 int nBytes = recv(hSocket, &c, 1, 0);
101 if (strLine.size() >= 9000)
104 else if (nBytes <= 0)
110 int nErr = WSAGetLastError();
111 if (nErr == WSAEMSGSIZE)
113 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
119 if (!strLine.empty())
124 printf("socket closed\n");
130 int nErr = WSAGetLastError();
131 printf("recv failed: %d\n", nErr);
140 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
143 if (!ConnectSocket(addrConnect, hSocket))
144 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
146 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
149 while (RecvLine(hSocket, strLine))
151 if (strLine.empty()) // HTTP response is separated from headers by blank line
155 if (!RecvLine(hSocket, strLine))
157 closesocket(hSocket);
160 if (pszKeyword == NULL)
162 if (strLine.find(pszKeyword) != string::npos)
164 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
168 closesocket(hSocket);
169 if (strLine.find("<") != string::npos)
170 strLine = strLine.substr(0, strLine.find("<"));
171 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
172 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
173 strLine.resize(strLine.size()-1);
174 CService addr(strLine,0,true);
175 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
176 if (!addr.IsValid() || !addr.IsRoutable())
182 closesocket(hSocket);
183 return error("GetMyExternalIP() : connection closed");
186 // We now get our external IP from the IRC server first and only use this as a backup
187 bool GetMyExternalIP(CNetAddr& ipRet)
189 CService addrConnect;
191 const char* pszKeyword;
193 if (fNoListen||fUseProxy)
196 for (int nLookup = 0; nLookup <= 1; nLookup++)
197 for (int nHost = 1; nHost <= 2; nHost++)
199 // We should be phasing out our use of sites like these. If we need
200 // replacements, we should ask for volunteers to put this simple
201 // php file on their webserver that prints the client IP:
202 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
205 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
209 CService addrIP("checkip.dyndns.org", 80, true);
210 if (addrIP.IsValid())
211 addrConnect = addrIP;
214 pszGet = "GET / HTTP/1.1\r\n"
215 "Host: checkip.dyndns.org\r\n"
216 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
217 "Connection: close\r\n"
220 pszKeyword = "Address:";
224 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
228 CService addrIP("www.showmyip.com", 80, true);
229 if (addrIP.IsValid())
230 addrConnect = addrIP;
233 pszGet = "GET /simple/ HTTP/1.1\r\n"
234 "Host: www.showmyip.com\r\n"
235 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
236 "Connection: close\r\n"
239 pszKeyword = NULL; // Returns just IP address
242 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
249 void ThreadGetMyExternalIP(void* parg)
251 // Wait for IRC to get it first
252 if (GetBoolArg("-irc", false))
254 for (int i = 0; i < 2 * 60; i++)
257 if (fGotExternalIP || fShutdown)
262 // Fallback in case IRC fails to get it
263 if (GetMyExternalIP(addrLocalHost))
265 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
266 if (addrLocalHost.IsRoutable())
268 // If we already connected to a few before we had our IP, go back and addr them.
269 // setAddrKnown automatically filters any duplicate sends.
270 CAddress addr(addrLocalHost);
271 addr.nTime = GetAdjustedTime();
274 BOOST_FOREACH(CNode* pnode, vNodes)
275 pnode->PushAddress(addr);
285 void AddressCurrentlyConnected(const CService& addr)
287 addrman.Connected(addr);
296 CNode* FindNode(const CNetAddr& ip)
300 BOOST_FOREACH(CNode* pnode, vNodes)
301 if ((CNetAddr)pnode->addr == ip)
307 CNode* FindNode(const CService& addr)
311 BOOST_FOREACH(CNode* pnode, vNodes)
312 if ((CService)pnode->addr == addr)
318 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
320 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
323 // Look for an existing connection
324 CNode* pnode = FindNode((CService)addrConnect);
328 pnode->AddRef(nTimeout);
335 printf("trying connection %s lastseen=%.1fhrs\n",
336 addrConnect.ToString().c_str(),
337 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
339 addrman.Attempt(addrConnect);
343 if (ConnectSocket(addrConnect, hSocket))
346 printf("connected %s\n", addrConnect.ToString().c_str());
348 // Set to nonblocking
351 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
352 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
354 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
355 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
359 CNode* pnode = new CNode(hSocket, addrConnect, false);
361 pnode->AddRef(nTimeout);
366 vNodes.push_back(pnode);
369 pnode->nTimeConnected = GetTime();
378 void CNode::CloseSocketDisconnect()
381 if (hSocket != INVALID_SOCKET)
384 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
385 printf("disconnecting node %s\n", addr.ToString().c_str());
386 closesocket(hSocket);
387 hSocket = INVALID_SOCKET;
392 void CNode::Cleanup()
397 void CNode::PushVersion()
399 /// when NTP implemented, change to just nTime = GetAdjustedTime()
400 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
401 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
402 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
403 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
404 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
405 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
412 std::map<CNetAddr, int64> CNode::setBanned;
413 CCriticalSection CNode::cs_setBanned;
415 void CNode::ClearBanned()
420 bool CNode::IsBanned(CNetAddr ip)
422 bool fResult = false;
425 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
426 if (i != setBanned.end())
428 int64 t = (*i).second;
436 bool CNode::Misbehaving(int howmuch)
440 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
444 nMisbehavior += howmuch;
445 if (nMisbehavior >= GetArg("-banscore", 100))
447 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
450 if (setBanned[addr] < banTime)
451 setBanned[addr] = banTime;
453 CloseSocketDisconnect();
454 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
471 void ThreadSocketHandler(void* parg)
473 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
476 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
477 ThreadSocketHandler2(parg);
478 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
480 catch (std::exception& e) {
481 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
482 PrintException(&e, "ThreadSocketHandler()");
484 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
485 throw; // support pthread_cancel()
487 printf("ThreadSocketHandler exiting\n");
490 void ThreadSocketHandler2(void* parg)
492 printf("ThreadSocketHandler started\n");
493 list<CNode*> vNodesDisconnected;
494 unsigned int nPrevNodeCount = 0;
503 // Disconnect unused nodes
504 vector<CNode*> vNodesCopy = vNodes;
505 BOOST_FOREACH(CNode* pnode, vNodesCopy)
507 if (pnode->fDisconnect ||
508 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
510 // remove from vNodes
511 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
513 if (pnode->fHasGrant)
515 pnode->fHasGrant = false;
517 // close socket and cleanup
518 pnode->CloseSocketDisconnect();
521 // hold in disconnected pool until all refs are released
522 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
523 if (pnode->fNetworkNode || pnode->fInbound)
525 vNodesDisconnected.push_back(pnode);
529 // Delete disconnected nodes
530 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
531 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
533 // wait until threads are done using it
534 if (pnode->GetRefCount() <= 0)
536 bool fDelete = false;
538 TRY_LOCK(pnode->cs_vSend, lockSend);
541 TRY_LOCK(pnode->cs_vRecv, lockRecv);
544 TRY_LOCK(pnode->cs_mapRequests, lockReq);
547 TRY_LOCK(pnode->cs_inventory, lockInv);
556 vNodesDisconnected.remove(pnode);
562 if (vNodes.size() != nPrevNodeCount)
564 nPrevNodeCount = vNodes.size();
570 // Find which sockets have data to receive
572 struct timeval timeout;
574 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
581 FD_ZERO(&fdsetError);
582 SOCKET hSocketMax = 0;
584 if(hListenSocket != INVALID_SOCKET)
585 FD_SET(hListenSocket, &fdsetRecv);
586 hSocketMax = max(hSocketMax, hListenSocket);
589 BOOST_FOREACH(CNode* pnode, vNodes)
591 if (pnode->hSocket == INVALID_SOCKET)
593 FD_SET(pnode->hSocket, &fdsetRecv);
594 FD_SET(pnode->hSocket, &fdsetError);
595 hSocketMax = max(hSocketMax, pnode->hSocket);
597 TRY_LOCK(pnode->cs_vSend, lockSend);
598 if (lockSend && !pnode->vSend.empty())
599 FD_SET(pnode->hSocket, &fdsetSend);
604 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
605 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
606 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
609 if (nSelect == SOCKET_ERROR)
611 int nErr = WSAGetLastError();
614 printf("socket select error %d\n", nErr);
615 for (unsigned int i = 0; i <= hSocketMax; i++)
616 FD_SET(i, &fdsetRecv);
619 FD_ZERO(&fdsetError);
620 Sleep(timeout.tv_usec/1000);
625 // Accept new connections
627 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
629 struct sockaddr_in sockaddr;
630 socklen_t len = sizeof(sockaddr);
631 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
635 if (hSocket != INVALID_SOCKET)
636 addr = CAddress(sockaddr);
640 BOOST_FOREACH(CNode* pnode, vNodes)
645 if (hSocket == INVALID_SOCKET)
647 if (WSAGetLastError() != WSAEWOULDBLOCK)
648 printf("socket error accept failed: %d\n", WSAGetLastError());
650 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
653 LOCK(cs_setservAddNodeAddresses);
654 if (!setservAddNodeAddresses.count(addr))
655 closesocket(hSocket);
658 else if (CNode::IsBanned(addr))
660 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
661 closesocket(hSocket);
665 printf("accepted connection %s\n", addr.ToString().c_str());
666 CNode* pnode = new CNode(hSocket, addr, true);
670 vNodes.push_back(pnode);
677 // Service each socket
679 vector<CNode*> vNodesCopy;
683 BOOST_FOREACH(CNode* pnode, vNodesCopy)
686 BOOST_FOREACH(CNode* pnode, vNodesCopy)
694 if (pnode->hSocket == INVALID_SOCKET)
696 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
698 TRY_LOCK(pnode->cs_vRecv, lockRecv);
701 CDataStream& vRecv = pnode->vRecv;
702 unsigned int nPos = vRecv.size();
704 if (nPos > ReceiveBufferSize()) {
705 if (!pnode->fDisconnect)
706 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
707 pnode->CloseSocketDisconnect();
710 // typical socket buffer is 8K-64K
711 char pchBuf[0x10000];
712 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
715 vRecv.resize(nPos + nBytes);
716 memcpy(&vRecv[nPos], pchBuf, nBytes);
717 pnode->nLastRecv = GetTime();
719 else if (nBytes == 0)
721 // socket closed gracefully
722 if (!pnode->fDisconnect)
723 printf("socket closed\n");
724 pnode->CloseSocketDisconnect();
729 int nErr = WSAGetLastError();
730 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
732 if (!pnode->fDisconnect)
733 printf("socket recv error %d\n", nErr);
734 pnode->CloseSocketDisconnect();
744 if (pnode->hSocket == INVALID_SOCKET)
746 if (FD_ISSET(pnode->hSocket, &fdsetSend))
748 TRY_LOCK(pnode->cs_vSend, lockSend);
751 CDataStream& vSend = pnode->vSend;
754 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
757 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
758 pnode->nLastSend = GetTime();
763 int nErr = WSAGetLastError();
764 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
766 printf("socket send error %d\n", nErr);
767 pnode->CloseSocketDisconnect();
770 if (vSend.size() > SendBufferSize()) {
771 if (!pnode->fDisconnect)
772 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
773 pnode->CloseSocketDisconnect();
780 // Inactivity checking
782 if (pnode->vSend.empty())
783 pnode->nLastSendEmpty = GetTime();
784 if (GetTime() - pnode->nTimeConnected > 60)
786 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
788 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
789 pnode->fDisconnect = true;
791 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
793 printf("socket not sending\n");
794 pnode->fDisconnect = true;
796 else if (GetTime() - pnode->nLastRecv > 90*60)
798 printf("socket inactivity timeout\n");
799 pnode->fDisconnect = true;
805 BOOST_FOREACH(CNode* pnode, vNodesCopy)
822 void ThreadMapPort(void* parg)
824 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
827 vnThreadsRunning[THREAD_UPNP]++;
828 ThreadMapPort2(parg);
829 vnThreadsRunning[THREAD_UPNP]--;
831 catch (std::exception& e) {
832 vnThreadsRunning[THREAD_UPNP]--;
833 PrintException(&e, "ThreadMapPort()");
835 vnThreadsRunning[THREAD_UPNP]--;
836 PrintException(NULL, "ThreadMapPort()");
838 printf("ThreadMapPort exiting\n");
841 void ThreadMapPort2(void* parg)
843 printf("ThreadMapPort started\n");
846 sprintf(port, "%d", GetListenPort());
848 const char * multicastif = 0;
849 const char * minissdpdpath = 0;
850 struct UPNPDev * devlist = 0;
853 #ifndef UPNPDISCOVER_SUCCESS
855 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
859 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
862 struct UPNPUrls urls;
863 struct IGDdatas data;
866 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
869 if (!addrLocalHost.IsRoutable())
871 char externalIPAddress[40];
872 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
873 if(r != UPNPCOMMAND_SUCCESS)
874 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
877 if(externalIPAddress[0])
879 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
880 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
881 if (addrExternalFromUPnP.IsRoutable())
882 addrLocalHost = addrExternalFromUPnP;
885 printf("UPnP: GetExternalIPAddress failed.\n");
889 string strDesc = "Bitcoin " + FormatFullVersion();
890 #ifndef UPNPDISCOVER_SUCCESS
892 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
893 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
896 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
897 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
900 if(r!=UPNPCOMMAND_SUCCESS)
901 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
902 port, port, lanaddr, r, strupnperror(r));
904 printf("UPnP Port Mapping successful.\n");
907 if (fShutdown || !fUseUPnP)
909 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
910 printf("UPNP_DeletePortMapping() returned : %d\n", r);
911 freeUPNPDevlist(devlist); devlist = 0;
915 if (i % 600 == 0) // Refresh every 20 minutes
917 #ifndef UPNPDISCOVER_SUCCESS
919 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
920 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
923 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
924 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
927 if(r!=UPNPCOMMAND_SUCCESS)
928 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
929 port, port, lanaddr, r, strupnperror(r));
931 printf("UPnP Port Mapping successful.\n");;
937 printf("No valid UPnP IGDs found\n");
938 freeUPNPDevlist(devlist); devlist = 0;
942 if (fShutdown || !fUseUPnP)
949 void MapPort(bool fMapPort)
951 if (fUseUPnP != fMapPort)
955 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
957 if (!CreateThread(ThreadMapPort, NULL))
958 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
962 void MapPort(bool /* unused fMapPort */)
964 // Intentionally left blank.
977 // Each pair gives a source name and a seed name.
978 // The first name is used as information source for addrman.
979 // The second name should resolve to a list of seed addresses.
980 static const char *strDNSSeed[][2] = {
981 {"xf2.org", "bitseed.xf2.org"},
982 {"bluematt.me", "dnsseed.bluematt.me"},
983 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
984 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
987 void ThreadDNSAddressSeed(void* parg)
989 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
992 vnThreadsRunning[THREAD_DNSSEED]++;
993 ThreadDNSAddressSeed2(parg);
994 vnThreadsRunning[THREAD_DNSSEED]--;
996 catch (std::exception& e) {
997 vnThreadsRunning[THREAD_DNSSEED]--;
998 PrintException(&e, "ThreadDNSAddressSeed()");
1000 vnThreadsRunning[THREAD_DNSSEED]--;
1001 throw; // support pthread_cancel()
1003 printf("ThreadDNSAddressSeed exiting\n");
1006 void ThreadDNSAddressSeed2(void* parg)
1008 printf("ThreadDNSAddressSeed started\n");
1013 printf("Loading addresses from DNS seeds (could take a while)\n");
1015 for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1016 vector<CNetAddr> vaddr;
1017 vector<CAddress> vAdd;
1018 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1020 BOOST_FOREACH(CNetAddr& ip, vaddr)
1022 int nOneDay = 24*3600;
1023 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1024 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1025 vAdd.push_back(addr);
1029 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1033 printf("%d addresses found from DNS seeds\n", found);
1047 unsigned int pnSeed[] =
1049 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1050 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1051 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1052 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1053 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1054 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1055 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1056 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1057 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1058 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1059 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1060 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1061 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1062 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1063 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1064 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1065 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1066 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1067 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1068 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1069 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1070 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1071 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1072 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1073 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1074 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1075 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1076 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1077 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1078 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1079 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1080 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1081 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1082 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1083 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1084 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1085 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1086 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1087 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1088 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1089 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1090 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1091 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1092 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1093 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1094 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1095 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1096 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1097 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1098 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1099 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1100 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1101 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1102 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1103 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1104 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1105 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1106 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1107 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1108 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1109 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1110 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1111 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1112 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1113 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1114 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1115 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1116 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1117 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1118 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1119 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1120 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1121 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1122 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1123 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1124 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1125 0xc461d84a, 0xb2dbe247,
1128 void DumpAddresses()
1131 adb.WriteAddrman(addrman);
1134 void ThreadDumpAddress2(void* parg)
1136 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1140 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1142 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1144 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1147 void ThreadDumpAddress(void* parg)
1149 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1152 ThreadDumpAddress2(parg);
1154 catch (std::exception& e) {
1155 PrintException(&e, "ThreadDumpAddress()");
1157 printf("ThreadDumpAddress exiting\n");
1160 void ThreadOpenConnections(void* parg)
1162 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1165 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1166 ThreadOpenConnections2(parg);
1167 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1169 catch (std::exception& e) {
1170 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1171 PrintException(&e, "ThreadOpenConnections()");
1173 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1174 PrintException(NULL, "ThreadOpenConnections()");
1176 printf("ThreadOpenConnections exiting\n");
1179 void ThreadOpenConnections2(void* parg)
1181 printf("ThreadOpenConnections started\n");
1183 // Connect to specific addresses
1184 if (mapArgs.count("-connect"))
1186 for (int64 nLoop = 0;; nLoop++)
1188 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1190 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1192 OpenNetworkConnection(addr, false);
1193 for (int i = 0; i < 10 && i < nLoop; i++)
1203 // Initiate network connections
1204 int64 nStart = GetTime();
1207 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1209 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1214 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1215 semOutbound->wait();
1216 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1220 // Add seed nodes if IRC isn't working
1221 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1222 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1224 std::vector<CAddress> vAdd;
1225 for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1227 // It'll only connect to one or two seed nodes because once it connects,
1228 // it'll get a pile of addresses with newer timestamps.
1229 // Seed nodes are given a random 'last seen time' of between one and two
1231 const int64 nOneWeek = 7*24*60*60;
1233 memcpy(&ip, &pnSeed[i], sizeof(ip));
1234 CAddress addr(CService(ip, GetDefaultPort()));
1235 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1236 vAdd.push_back(addr);
1238 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1242 // Choose an address to connect to based on most recently seen
1244 CAddress addrConnect;
1246 // Only connect to one address per a.b.?.? range.
1247 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1249 set<vector<unsigned char> > setConnected;
1252 BOOST_FOREACH(CNode* pnode, vNodes) {
1253 setConnected.insert(pnode->addr.GetGroup());
1254 if (!pnode->fInbound)
1259 int64 nANow = GetAdjustedTime();
1264 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1265 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1267 // if we selected an invalid address, restart
1268 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1273 // only consider very recently tried nodes after 30 failed attempts
1274 if (nANow - addr.nLastTry < 600 && nTries < 30)
1277 // do not allow non-default ports, unless after 50 invalid addresses selected already
1278 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1285 if (addrConnect.IsValid())
1286 OpenNetworkConnection(addrConnect);
1288 semOutbound->post();
1292 void ThreadOpenAddedConnections(void* parg)
1294 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1297 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1298 ThreadOpenAddedConnections2(parg);
1299 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1301 catch (std::exception& e) {
1302 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1303 PrintException(&e, "ThreadOpenAddedConnections()");
1305 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1306 PrintException(NULL, "ThreadOpenAddedConnections()");
1308 printf("ThreadOpenAddedConnections exiting\n");
1311 void ThreadOpenAddedConnections2(void* parg)
1313 printf("ThreadOpenAddedConnections started\n");
1315 if (mapArgs.count("-addnode") == 0)
1318 vector<vector<CService> > vservAddressesToAdd(0);
1319 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1321 vector<CService> vservNode(0);
1322 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1324 vservAddressesToAdd.push_back(vservNode);
1326 LOCK(cs_setservAddNodeAddresses);
1327 BOOST_FOREACH(CService& serv, vservNode)
1328 setservAddNodeAddresses.insert(serv);
1334 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1335 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1336 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1339 BOOST_FOREACH(CNode* pnode, vNodes)
1340 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1341 BOOST_FOREACH(CService& addrNode, *(it))
1342 if (pnode->addr == addrNode)
1344 it = vservConnectAddresses.erase(it);
1349 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1351 semOutbound->wait();
1352 OpenNetworkConnection(CAddress(*(vserv.begin())));
1359 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1360 Sleep(120000); // Retry every 2 minutes
1361 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1367 bool static ReleaseGrant(bool fUseGrant) {
1369 semOutbound->post();
1373 // only call this function when semOutbound has been waited for
1374 bool OpenNetworkConnection(const CAddress& addrConnect, bool fUseGrant)
1377 // Initiate outbound network connection
1381 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1382 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1383 return ReleaseGrant(fUseGrant);
1385 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1386 CNode* pnode = ConnectNode(addrConnect);
1387 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1391 return ReleaseGrant(fUseGrant);
1392 if (pnode->fHasGrant) {
1393 // node already has connection grant, release the one that was passed to us
1394 ReleaseGrant(fUseGrant);
1396 pnode->fHasGrant = fUseGrant;
1398 pnode->fNetworkNode = true;
1410 void ThreadMessageHandler(void* parg)
1412 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1415 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1416 ThreadMessageHandler2(parg);
1417 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1419 catch (std::exception& e) {
1420 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1421 PrintException(&e, "ThreadMessageHandler()");
1423 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1424 PrintException(NULL, "ThreadMessageHandler()");
1426 printf("ThreadMessageHandler exiting\n");
1429 void ThreadMessageHandler2(void* parg)
1431 printf("ThreadMessageHandler started\n");
1432 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1435 vector<CNode*> vNodesCopy;
1438 vNodesCopy = vNodes;
1439 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1443 // Poll the connected nodes for messages
1444 CNode* pnodeTrickle = NULL;
1445 if (!vNodesCopy.empty())
1446 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1447 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1451 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1453 ProcessMessages(pnode);
1460 TRY_LOCK(pnode->cs_vSend, lockSend);
1462 SendMessages(pnode, pnode == pnodeTrickle);
1470 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1474 // Wait and allow messages to bunch up.
1475 // Reduce vnThreadsRunning so StopNode has permission to exit while
1476 // we're sleeping, but we must always check fShutdown after doing this.
1477 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1479 if (fRequestShutdown)
1481 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1492 bool BindListenPort(string& strError)
1496 addrLocalHost.SetPort(GetListenPort());
1499 // Initialize Windows Sockets
1501 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1502 if (ret != NO_ERROR)
1504 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1505 printf("%s\n", strError.c_str());
1510 // Create socket for listening for incoming connections
1511 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1512 if (hListenSocket == INVALID_SOCKET)
1514 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1515 printf("%s\n", strError.c_str());
1520 // Different way of disabling SIGPIPE on BSD
1521 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1525 // Allow binding if the port is still in TIME_WAIT state after
1526 // the program was closed and restarted. Not an issue on windows.
1527 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1531 // Set to nonblocking, incoming connections will also inherit this
1532 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1534 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1537 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1538 printf("%s\n", strError.c_str());
1542 // The sockaddr_in structure specifies the address family,
1543 // IP address, and port for the socket that is being bound
1544 struct sockaddr_in sockaddr;
1545 memset(&sockaddr, 0, sizeof(sockaddr));
1546 sockaddr.sin_family = AF_INET;
1547 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1548 sockaddr.sin_port = htons(GetListenPort());
1549 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1551 int nErr = WSAGetLastError();
1552 if (nErr == WSAEADDRINUSE)
1553 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1555 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1556 printf("%s\n", strError.c_str());
1559 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1561 // Listen for incoming connections
1562 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1564 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1565 printf("%s\n", strError.c_str());
1572 void StartNode(void* parg)
1574 if (semOutbound == NULL) {
1575 // initialize semaphore
1576 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1577 semOutbound = new CSemaphore(nMaxOutbound);
1582 fUseUPnP = GetBoolArg("-upnp", true);
1584 fUseUPnP = GetBoolArg("-upnp", false);
1588 if (pnodeLocalHost == NULL)
1589 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1592 // Get local host ip
1593 char pszHostName[1000] = "";
1594 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1596 vector<CNetAddr> vaddr;
1597 if (LookupHost(pszHostName, vaddr))
1599 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1601 if (!addr.IsLocal())
1603 addrLocalHost.SetIP(addr);
1610 // Get local host ip
1611 struct ifaddrs* myaddrs;
1612 if (getifaddrs(&myaddrs) == 0)
1614 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1616 if (ifa->ifa_addr == NULL) continue;
1617 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1618 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1619 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1621 if (ifa->ifa_addr->sa_family == AF_INET)
1623 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1624 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1625 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1627 // Take the first IP that isn't loopback 127.x.x.x
1628 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1629 if (addr.IsValid() && !addr.IsLocal())
1631 addrLocalHost = addr;
1635 else if (ifa->ifa_addr->sa_family == AF_INET6)
1637 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1638 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1639 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1642 freeifaddrs(myaddrs);
1645 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1647 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1649 // Proxies can't take incoming connections
1650 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1651 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1655 CreateThread(ThreadGetMyExternalIP, NULL);
1662 if (!GetBoolArg("-dnsseed", true))
1663 printf("DNS seeding disabled\n");
1665 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1666 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1668 // Map ports with UPnP
1672 // Get addresses from IRC and advertise ours
1673 if (!CreateThread(ThreadIRCSeed, NULL))
1674 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1676 // Send and receive from sockets, accept connections
1677 if (!CreateThread(ThreadSocketHandler, NULL))
1678 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1680 // Initiate outbound connections from -addnode
1681 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1682 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1684 // Initiate outbound connections
1685 if (!CreateThread(ThreadOpenConnections, NULL))
1686 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1689 if (!CreateThread(ThreadMessageHandler, NULL))
1690 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1692 // Dump network addresses
1693 if (!CreateThread(ThreadDumpAddress, NULL))
1694 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1696 // Generate coins in the background
1697 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1702 printf("StopNode()\n");
1704 nTransactionsUpdated++;
1705 int64 nStart = GetTime();
1706 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1707 semOutbound->post();
1710 int nThreadsRunning = 0;
1711 for (int n = 0; n < THREAD_MAX; n++)
1712 nThreadsRunning += vnThreadsRunning[n];
1713 if (nThreadsRunning == 0)
1715 if (GetTime() - nStart > 20)
1719 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1720 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1721 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1722 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1723 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1724 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1725 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1726 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1727 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1728 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1744 BOOST_FOREACH(CNode* pnode, vNodes)
1745 if (pnode->hSocket != INVALID_SOCKET)
1746 closesocket(pnode->hSocket);
1747 if (hListenSocket != INVALID_SOCKET)
1748 if (closesocket(hListenSocket) == SOCKET_ERROR)
1749 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1752 // Shutdown Windows Sockets
1757 instance_of_cnetcleanup;