1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
26 using namespace boost;
28 static const int MAX_OUTBOUND_CONNECTIONS = 8;
30 void ThreadMessageHandler2(void* parg);
31 void ThreadSocketHandler2(void* parg);
32 void ThreadOpenConnections2(void* parg);
33 void ThreadOpenAddedConnections2(void* parg);
35 void ThreadMapPort2(void* parg);
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect);
43 // Global state variables
46 bool fAllowDNS = false;
47 static bool fUseUPnP = false;
48 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
49 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
50 static CNode* pnodeLocalHost = NULL;
51 uint64 nLocalHostNonce = 0;
52 array<int, THREAD_MAX> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
56 vector<CNode*> vNodes;
57 CCriticalSection cs_vNodes;
58 map<CInv, CDataStream> mapRelay;
59 deque<pair<int64, CInv> > vRelayExpiration;
60 CCriticalSection cs_mapRelay;
61 map<CInv, int64> mapAlreadyAskedFor;
64 set<CNetAddr> setservAddNodeAddresses;
65 CCriticalSection cs_setservAddNodeAddresses;
67 static CWaitableCriticalSection csOutbound;
68 static int nOutbound = 0;
69 static CConditionVariable condOutbound;
72 unsigned short GetListenPort()
74 return (unsigned short)(GetArg("-port", GetDefaultPort()));
77 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
79 // Filter out duplicate requests
80 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
82 pindexLastGetBlocksBegin = pindexBegin;
83 hashLastGetBlocksEnd = hashEnd;
85 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
90 bool RecvLine(SOCKET hSocket, string& strLine)
96 int nBytes = recv(hSocket, &c, 1, 0);
104 if (strLine.size() >= 9000)
107 else if (nBytes <= 0)
113 int nErr = WSAGetLastError();
114 if (nErr == WSAEMSGSIZE)
116 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
122 if (!strLine.empty())
127 printf("socket closed\n");
133 int nErr = WSAGetLastError();
134 printf("recv failed: %d\n", nErr);
143 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
146 if (!ConnectSocket(addrConnect, hSocket))
147 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
149 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
152 while (RecvLine(hSocket, strLine))
154 if (strLine.empty()) // HTTP response is separated from headers by blank line
158 if (!RecvLine(hSocket, strLine))
160 closesocket(hSocket);
163 if (pszKeyword == NULL)
165 if (strLine.find(pszKeyword) != -1)
167 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
171 closesocket(hSocket);
172 if (strLine.find("<") != -1)
173 strLine = strLine.substr(0, strLine.find("<"));
174 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
175 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
176 strLine.resize(strLine.size()-1);
177 CService addr(strLine,0,true);
178 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
179 if (!addr.IsValid() || !addr.IsRoutable())
185 closesocket(hSocket);
186 return error("GetMyExternalIP() : connection closed");
189 // We now get our external IP from the IRC server first and only use this as a backup
190 bool GetMyExternalIP(CNetAddr& ipRet)
192 CService addrConnect;
194 const char* pszKeyword;
196 if (fNoListen||fUseProxy)
199 for (int nLookup = 0; nLookup <= 1; nLookup++)
200 for (int nHost = 1; nHost <= 2; nHost++)
202 // We should be phasing out our use of sites like these. If we need
203 // replacements, we should ask for volunteers to put this simple
204 // php file on their webserver that prints the client IP:
205 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
208 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
212 CService addrIP("checkip.dyndns.org", 80, true);
213 if (addrIP.IsValid())
214 addrConnect = addrIP;
217 pszGet = "GET / HTTP/1.1\r\n"
218 "Host: checkip.dyndns.org\r\n"
219 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
220 "Connection: close\r\n"
223 pszKeyword = "Address:";
227 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
231 CService addrIP("www.showmyip.com", 80, true);
232 if (addrIP.IsValid())
233 addrConnect = addrIP;
236 pszGet = "GET /simple/ HTTP/1.1\r\n"
237 "Host: www.showmyip.com\r\n"
238 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
239 "Connection: close\r\n"
242 pszKeyword = NULL; // Returns just IP address
245 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
252 void ThreadGetMyExternalIP(void* parg)
254 // Wait for IRC to get it first
255 if (GetBoolArg("-irc", false))
257 for (int i = 0; i < 2 * 60; i++)
260 if (fGotExternalIP || fShutdown)
265 // Fallback in case IRC fails to get it
266 if (GetMyExternalIP(addrLocalHost))
268 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
269 if (addrLocalHost.IsRoutable())
271 // If we already connected to a few before we had our IP, go back and addr them.
272 // setAddrKnown automatically filters any duplicate sends.
273 CAddress addr(addrLocalHost);
274 addr.nTime = GetAdjustedTime();
275 CRITICAL_BLOCK(cs_vNodes)
276 BOOST_FOREACH(CNode* pnode, vNodes)
277 pnode->PushAddress(addr);
286 void AddressCurrentlyConnected(const CService& addr)
288 addrman.Connected(addr);
295 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
297 // If the dialog might get closed before the reply comes back,
298 // call this in the destructor so it doesn't get called after it's deleted.
299 CRITICAL_BLOCK(cs_vNodes)
301 BOOST_FOREACH(CNode* pnode, vNodes)
303 CRITICAL_BLOCK(pnode->cs_mapRequests)
305 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
307 CRequestTracker& tracker = (*mi).second;
308 if (tracker.fn == fn && tracker.param1 == param1)
309 pnode->mapRequests.erase(mi++);
325 // Subscription methods for the broadcast and subscription system.
326 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
328 // The subscription system uses a meet-in-the-middle strategy.
329 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
330 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
333 bool AnySubscribed(unsigned int nChannel)
335 if (pnodeLocalHost->IsSubscribed(nChannel))
337 CRITICAL_BLOCK(cs_vNodes)
338 BOOST_FOREACH(CNode* pnode, vNodes)
339 if (pnode->IsSubscribed(nChannel))
344 bool CNode::IsSubscribed(unsigned int nChannel)
346 if (nChannel >= vfSubscribe.size())
348 return vfSubscribe[nChannel];
351 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
353 if (nChannel >= vfSubscribe.size())
356 if (!AnySubscribed(nChannel))
359 CRITICAL_BLOCK(cs_vNodes)
360 BOOST_FOREACH(CNode* pnode, vNodes)
362 pnode->PushMessage("subscribe", nChannel, nHops);
365 vfSubscribe[nChannel] = true;
368 void CNode::CancelSubscribe(unsigned int nChannel)
370 if (nChannel >= vfSubscribe.size())
373 // Prevent from relaying cancel if wasn't subscribed
374 if (!vfSubscribe[nChannel])
376 vfSubscribe[nChannel] = false;
378 if (!AnySubscribed(nChannel))
380 // Relay subscription cancel
381 CRITICAL_BLOCK(cs_vNodes)
382 BOOST_FOREACH(CNode* pnode, vNodes)
384 pnode->PushMessage("sub-cancel", nChannel);
396 CNode* FindNode(const CNetAddr& ip)
398 CRITICAL_BLOCK(cs_vNodes)
400 BOOST_FOREACH(CNode* pnode, vNodes)
401 if ((CNetAddr)pnode->addr == ip)
407 CNode* FindNode(const CService& addr)
409 CRITICAL_BLOCK(cs_vNodes)
411 BOOST_FOREACH(CNode* pnode, vNodes)
412 if ((CService)pnode->addr == addr)
418 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
420 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
423 // Look for an existing connection
424 CNode* pnode = FindNode((CService)addrConnect);
428 pnode->AddRef(nTimeout);
435 printf("trying connection %s lastseen=%.1fhrs\n",
436 addrConnect.ToString().c_str(),
437 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
439 addrman.Attempt(addrConnect);
443 if (ConnectSocket(addrConnect, hSocket))
446 printf("connected %s\n", addrConnect.ToString().c_str());
448 // Set to nonblocking
451 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
452 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
454 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
455 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
459 CNode* pnode = new CNode(hSocket, addrConnect, false);
461 pnode->AddRef(nTimeout);
464 CRITICAL_BLOCK(cs_vNodes)
465 vNodes.push_back(pnode);
466 WAITABLE_CRITICAL_BLOCK(csOutbound)
469 pnode->nTimeConnected = GetTime();
478 void CNode::CloseSocketDisconnect()
481 if (hSocket != INVALID_SOCKET)
484 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
485 printf("disconnecting node %s\n", addr.ToString().c_str());
486 closesocket(hSocket);
487 hSocket = INVALID_SOCKET;
492 void CNode::Cleanup()
494 // All of a nodes broadcasts and subscriptions are automatically torn down
495 // when it goes down, so a node has to stay up to keep its broadcast going.
497 // Cancel subscriptions
498 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
499 if (vfSubscribe[nChannel])
500 CancelSubscribe(nChannel);
504 void CNode::PushVersion()
506 /// when NTP implemented, change to just nTime = GetAdjustedTime()
507 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
508 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
509 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
510 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
511 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
512 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
519 std::map<CNetAddr, int64> CNode::setBanned;
520 CCriticalSection CNode::cs_setBanned;
522 void CNode::ClearBanned()
527 bool CNode::IsBanned(CNetAddr ip)
529 bool fResult = false;
530 CRITICAL_BLOCK(cs_setBanned)
532 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
533 if (i != setBanned.end())
535 int64 t = (*i).second;
543 bool CNode::Misbehaving(int howmuch)
547 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
551 nMisbehavior += howmuch;
552 if (nMisbehavior >= GetArg("-banscore", 100))
554 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
555 CRITICAL_BLOCK(cs_setBanned)
556 if (setBanned[addr] < banTime)
557 setBanned[addr] = banTime;
558 CloseSocketDisconnect();
559 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
576 void ThreadSocketHandler(void* parg)
578 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
581 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
582 ThreadSocketHandler2(parg);
583 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
585 catch (std::exception& e) {
586 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
587 PrintException(&e, "ThreadSocketHandler()");
589 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
590 throw; // support pthread_cancel()
592 printf("ThreadSocketHandler exiting\n");
595 void ThreadSocketHandler2(void* parg)
597 printf("ThreadSocketHandler started\n");
598 list<CNode*> vNodesDisconnected;
599 int nPrevNodeCount = 0;
606 CRITICAL_BLOCK(cs_vNodes)
608 // Disconnect unused nodes
609 vector<CNode*> vNodesCopy = vNodes;
610 BOOST_FOREACH(CNode* pnode, vNodesCopy)
612 if (pnode->fDisconnect ||
613 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
615 // remove from vNodes
616 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
618 if (!pnode->fInbound)
619 WAITABLE_CRITICAL_BLOCK(csOutbound)
623 // Connection slot(s) were removed, notify connection creator(s)
624 NOTIFY(condOutbound);
627 // close socket and cleanup
628 pnode->CloseSocketDisconnect();
631 // hold in disconnected pool until all refs are released
632 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
633 if (pnode->fNetworkNode || pnode->fInbound)
635 vNodesDisconnected.push_back(pnode);
639 // Delete disconnected nodes
640 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
641 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
643 // wait until threads are done using it
644 if (pnode->GetRefCount() <= 0)
646 bool fDelete = false;
647 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
648 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
649 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
650 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
654 vNodesDisconnected.remove(pnode);
660 if (vNodes.size() != nPrevNodeCount)
662 nPrevNodeCount = vNodes.size();
668 // Find which sockets have data to receive
670 struct timeval timeout;
672 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
679 FD_ZERO(&fdsetError);
680 SOCKET hSocketMax = 0;
682 if(hListenSocket != INVALID_SOCKET)
683 FD_SET(hListenSocket, &fdsetRecv);
684 hSocketMax = max(hSocketMax, hListenSocket);
685 CRITICAL_BLOCK(cs_vNodes)
687 BOOST_FOREACH(CNode* pnode, vNodes)
689 if (pnode->hSocket == INVALID_SOCKET)
691 FD_SET(pnode->hSocket, &fdsetRecv);
692 FD_SET(pnode->hSocket, &fdsetError);
693 hSocketMax = max(hSocketMax, pnode->hSocket);
694 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
695 if (!pnode->vSend.empty())
696 FD_SET(pnode->hSocket, &fdsetSend);
700 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
701 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
702 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
705 if (nSelect == SOCKET_ERROR)
707 int nErr = WSAGetLastError();
710 printf("socket select error %d\n", nErr);
711 for (int i = 0; i <= hSocketMax; i++)
712 FD_SET(i, &fdsetRecv);
715 FD_ZERO(&fdsetError);
716 Sleep(timeout.tv_usec/1000);
721 // Accept new connections
723 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
725 struct sockaddr_in sockaddr;
726 socklen_t len = sizeof(sockaddr);
727 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
731 if (hSocket != INVALID_SOCKET)
732 addr = CAddress(sockaddr);
734 CRITICAL_BLOCK(cs_vNodes)
735 BOOST_FOREACH(CNode* pnode, vNodes)
739 if (hSocket == INVALID_SOCKET)
741 if (WSAGetLastError() != WSAEWOULDBLOCK)
742 printf("socket error accept failed: %d\n", WSAGetLastError());
744 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
746 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
747 if (!setservAddNodeAddresses.count(addr))
748 closesocket(hSocket);
750 else if (CNode::IsBanned(addr))
752 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
753 closesocket(hSocket);
757 printf("accepted connection %s\n", addr.ToString().c_str());
758 CNode* pnode = new CNode(hSocket, addr, true);
760 CRITICAL_BLOCK(cs_vNodes)
761 vNodes.push_back(pnode);
767 // Service each socket
769 vector<CNode*> vNodesCopy;
770 CRITICAL_BLOCK(cs_vNodes)
773 BOOST_FOREACH(CNode* pnode, vNodesCopy)
776 BOOST_FOREACH(CNode* pnode, vNodesCopy)
784 if (pnode->hSocket == INVALID_SOCKET)
786 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
788 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
790 CDataStream& vRecv = pnode->vRecv;
791 unsigned int nPos = vRecv.size();
793 if (nPos > ReceiveBufferSize()) {
794 if (!pnode->fDisconnect)
795 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
796 pnode->CloseSocketDisconnect();
799 // typical socket buffer is 8K-64K
800 char pchBuf[0x10000];
801 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
804 vRecv.resize(nPos + nBytes);
805 memcpy(&vRecv[nPos], pchBuf, nBytes);
806 pnode->nLastRecv = GetTime();
808 else if (nBytes == 0)
810 // socket closed gracefully
811 if (!pnode->fDisconnect)
812 printf("socket closed\n");
813 pnode->CloseSocketDisconnect();
818 int nErr = WSAGetLastError();
819 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
821 if (!pnode->fDisconnect)
822 printf("socket recv error %d\n", nErr);
823 pnode->CloseSocketDisconnect();
833 if (pnode->hSocket == INVALID_SOCKET)
835 if (FD_ISSET(pnode->hSocket, &fdsetSend))
837 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
839 CDataStream& vSend = pnode->vSend;
842 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
845 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
846 pnode->nLastSend = GetTime();
851 int nErr = WSAGetLastError();
852 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
854 printf("socket send error %d\n", nErr);
855 pnode->CloseSocketDisconnect();
858 if (vSend.size() > SendBufferSize()) {
859 if (!pnode->fDisconnect)
860 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
861 pnode->CloseSocketDisconnect();
868 // Inactivity checking
870 if (pnode->vSend.empty())
871 pnode->nLastSendEmpty = GetTime();
872 if (GetTime() - pnode->nTimeConnected > 60)
874 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
876 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
877 pnode->fDisconnect = true;
879 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
881 printf("socket not sending\n");
882 pnode->fDisconnect = true;
884 else if (GetTime() - pnode->nLastRecv > 90*60)
886 printf("socket inactivity timeout\n");
887 pnode->fDisconnect = true;
891 CRITICAL_BLOCK(cs_vNodes)
893 BOOST_FOREACH(CNode* pnode, vNodesCopy)
910 void ThreadMapPort(void* parg)
912 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
915 vnThreadsRunning[THREAD_UPNP]++;
916 ThreadMapPort2(parg);
917 vnThreadsRunning[THREAD_UPNP]--;
919 catch (std::exception& e) {
920 vnThreadsRunning[THREAD_UPNP]--;
921 PrintException(&e, "ThreadMapPort()");
923 vnThreadsRunning[THREAD_UPNP]--;
924 PrintException(NULL, "ThreadMapPort()");
926 printf("ThreadMapPort exiting\n");
929 void ThreadMapPort2(void* parg)
931 printf("ThreadMapPort started\n");
934 sprintf(port, "%d", GetListenPort());
936 const char * multicastif = 0;
937 const char * minissdpdpath = 0;
938 struct UPNPDev * devlist = 0;
941 #ifndef UPNPDISCOVER_SUCCESS
943 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
947 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
950 struct UPNPUrls urls;
951 struct IGDdatas data;
954 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
957 if (!addrLocalHost.IsRoutable())
959 char externalIPAddress[40];
960 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
961 if(r != UPNPCOMMAND_SUCCESS)
962 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
965 if(externalIPAddress[0])
967 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
968 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
969 if (addrExternalFromUPnP.IsRoutable())
970 addrLocalHost = addrExternalFromUPnP;
973 printf("UPnP: GetExternalIPAddress failed.\n");
977 string strDesc = "Bitcoin " + FormatFullVersion();
978 #ifndef UPNPDISCOVER_SUCCESS
980 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
981 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
984 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
985 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
988 if(r!=UPNPCOMMAND_SUCCESS)
989 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
990 port, port, lanaddr, r, strupnperror(r));
992 printf("UPnP Port Mapping successful.\n");
995 if (fShutdown || !fUseUPnP)
997 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
998 printf("UPNP_DeletePortMapping() returned : %d\n", r);
999 freeUPNPDevlist(devlist); devlist = 0;
1000 FreeUPNPUrls(&urls);
1003 if (i % 600 == 0) // Refresh every 20 minutes
1005 #ifndef UPNPDISCOVER_SUCCESS
1007 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1008 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1011 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1012 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1015 if(r!=UPNPCOMMAND_SUCCESS)
1016 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1017 port, port, lanaddr, r, strupnperror(r));
1019 printf("UPnP Port Mapping successful.\n");;
1025 printf("No valid UPnP IGDs found\n");
1026 freeUPNPDevlist(devlist); devlist = 0;
1028 FreeUPNPUrls(&urls);
1030 if (fShutdown || !fUseUPnP)
1037 void MapPort(bool fMapPort)
1039 if (fUseUPnP != fMapPort)
1041 fUseUPnP = fMapPort;
1043 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1045 if (!CreateThread(ThreadMapPort, NULL))
1046 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1050 void MapPort(bool /* unused fMapPort */)
1052 // Intentionally left blank.
1065 // Each pair gives a source name and a seed name.
1066 // The first name is used as information source for addrman.
1067 // The second name should resolve to a list of seed addresses.
1068 static const char *strDNSSeed[][2] = {
1069 {"xf2.org", "bitseed.xf2.org"},
1070 {"bluematt.me", "dnsseed.bluematt.me"},
1071 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1072 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1075 void ThreadDNSAddressSeed(void* parg)
1077 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1080 vnThreadsRunning[THREAD_DNSSEED]++;
1081 ThreadDNSAddressSeed2(parg);
1082 vnThreadsRunning[THREAD_DNSSEED]--;
1084 catch (std::exception& e) {
1085 vnThreadsRunning[THREAD_DNSSEED]--;
1086 PrintException(&e, "ThreadDNSAddressSeed()");
1088 vnThreadsRunning[THREAD_DNSSEED]--;
1089 throw; // support pthread_cancel()
1091 printf("ThreadDNSAddressSeed exiting\n");
1094 void ThreadDNSAddressSeed2(void* parg)
1096 printf("ThreadDNSAddressSeed started\n");
1101 printf("Loading addresses from DNS seeds (could take a while)\n");
1103 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1104 vector<CNetAddr> vaddr;
1105 vector<CAddress> vAdd;
1106 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1108 BOOST_FOREACH(CNetAddr& ip, vaddr)
1110 int nOneDay = 24*3600;
1111 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1112 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1113 vAdd.push_back(addr);
1117 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1121 printf("%d addresses found from DNS seeds\n", found);
1135 unsigned int pnSeed[] =
1137 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1138 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1139 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1140 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1141 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1142 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1143 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1144 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1145 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1146 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1147 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1148 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1149 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1150 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1151 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1152 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1153 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1154 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1155 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1156 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1157 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1158 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1159 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1160 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1161 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1162 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1163 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1164 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1165 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1166 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1167 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1168 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1169 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1170 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1171 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1172 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1173 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1174 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1175 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1176 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1177 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1178 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1179 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1180 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1181 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1182 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1183 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1184 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1185 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1186 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1187 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1188 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1189 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1190 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1191 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1192 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1193 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1194 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1195 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1196 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1197 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1198 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1199 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1200 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1201 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1202 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1203 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1204 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1205 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1206 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1207 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1208 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1209 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1210 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1211 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1212 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1213 0xc461d84a, 0xb2dbe247,
1216 void DumpAddresses()
1219 adb.WriteAddrman(addrman);
1222 void ThreadDumpAddress2(void* parg)
1224 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1228 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1230 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1232 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1235 void ThreadDumpAddress(void* parg)
1237 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1240 ThreadDumpAddress2(parg);
1242 catch (std::exception& e) {
1243 PrintException(&e, "ThreadDumpAddress()");
1245 printf("ThreadDumpAddress exiting\n");
1248 void ThreadOpenConnections(void* parg)
1250 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1253 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1254 ThreadOpenConnections2(parg);
1255 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1257 catch (std::exception& e) {
1258 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1259 PrintException(&e, "ThreadOpenConnections()");
1261 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1262 PrintException(NULL, "ThreadOpenConnections()");
1264 printf("ThreadOpenConnections exiting\n");
1267 void ThreadOpenConnections2(void* parg)
1269 printf("ThreadOpenConnections started\n");
1271 // Connect to specific addresses
1272 if (mapArgs.count("-connect"))
1274 for (int64 nLoop = 0;; nLoop++)
1276 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1278 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1280 OpenNetworkConnection(addr);
1281 for (int i = 0; i < 10 && i < nLoop; i++)
1291 // Initiate network connections
1292 int64 nStart = GetTime();
1295 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1297 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1301 // Limit outbound connections
1302 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1303 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1304 WAITABLE_CRITICAL_BLOCK(csOutbound)
1305 WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
1306 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1310 bool fAddSeeds = false;
1312 // Add seed nodes if IRC isn't working
1313 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1314 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1316 std::vector<CAddress> vAdd;
1317 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1319 // It'll only connect to one or two seed nodes because once it connects,
1320 // it'll get a pile of addresses with newer timestamps.
1321 // Seed nodes are given a random 'last seen time' of between one and two
1323 const int64 nOneWeek = 7*24*60*60;
1325 memcpy(&ip, &pnSeed[i], sizeof(ip));
1326 CAddress addr(CService(ip, GetDefaultPort()));
1327 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1328 vAdd.push_back(addr);
1330 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1334 // Choose an address to connect to based on most recently seen
1336 CAddress addrConnect;
1337 int64 nBest = std::numeric_limits<int64>::min();
1339 // Only connect to one address per a.b.?.? range.
1340 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1341 set<vector<unsigned char> > setConnected;
1342 CRITICAL_BLOCK(cs_vNodes)
1343 BOOST_FOREACH(CNode* pnode, vNodes)
1344 setConnected.insert(pnode->addr.GetGroup());
1346 int64 nANow = GetAdjustedTime();
1351 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1352 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1354 // if we selected an invalid address, restart
1355 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1360 // only consider very recently tried nodes after 30 failed attempts
1361 if (nANow - addr.nLastTry < 600 && nTries < 30)
1364 // do not allow non-default ports, unless after 50 invalid addresses selected already
1365 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1372 if (addrConnect.IsValid())
1373 OpenNetworkConnection(addrConnect);
1377 void ThreadOpenAddedConnections(void* parg)
1379 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1382 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1383 ThreadOpenAddedConnections2(parg);
1384 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1386 catch (std::exception& e) {
1387 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1388 PrintException(&e, "ThreadOpenAddedConnections()");
1390 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1391 PrintException(NULL, "ThreadOpenAddedConnections()");
1393 printf("ThreadOpenAddedConnections exiting\n");
1396 void ThreadOpenAddedConnections2(void* parg)
1398 printf("ThreadOpenAddedConnections started\n");
1400 if (mapArgs.count("-addnode") == 0)
1403 vector<vector<CService> > vservAddressesToAdd(0);
1404 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1406 vector<CService> vservNode(0);
1407 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1409 vservAddressesToAdd.push_back(vservNode);
1410 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1411 BOOST_FOREACH(CService& serv, vservNode)
1412 setservAddNodeAddresses.insert(serv);
1417 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1418 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1419 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1420 CRITICAL_BLOCK(cs_vNodes)
1421 BOOST_FOREACH(CNode* pnode, vNodes)
1422 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1423 BOOST_FOREACH(CService& addrNode, *(it))
1424 if (pnode->addr == addrNode)
1426 it = vservConnectAddresses.erase(it);
1430 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1432 OpenNetworkConnection(CAddress(*(vserv.begin())));
1439 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1440 Sleep(120000); // Retry every 2 minutes
1441 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1447 bool OpenNetworkConnection(const CAddress& addrConnect)
1450 // Initiate outbound network connection
1454 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1455 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1458 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1459 CNode* pnode = ConnectNode(addrConnect);
1460 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1465 pnode->fNetworkNode = true;
1477 void ThreadMessageHandler(void* parg)
1479 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1482 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1483 ThreadMessageHandler2(parg);
1484 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1486 catch (std::exception& e) {
1487 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1488 PrintException(&e, "ThreadMessageHandler()");
1490 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1491 PrintException(NULL, "ThreadMessageHandler()");
1493 printf("ThreadMessageHandler exiting\n");
1496 void ThreadMessageHandler2(void* parg)
1498 printf("ThreadMessageHandler started\n");
1499 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1502 vector<CNode*> vNodesCopy;
1503 CRITICAL_BLOCK(cs_vNodes)
1505 vNodesCopy = vNodes;
1506 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1510 // Poll the connected nodes for messages
1511 CNode* pnodeTrickle = NULL;
1512 if (!vNodesCopy.empty())
1513 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1514 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1517 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1518 ProcessMessages(pnode);
1523 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1524 SendMessages(pnode, pnode == pnodeTrickle);
1529 CRITICAL_BLOCK(cs_vNodes)
1531 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1535 // Wait and allow messages to bunch up.
1536 // Reduce vnThreadsRunning so StopNode has permission to exit while
1537 // we're sleeping, but we must always check fShutdown after doing this.
1538 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1540 if (fRequestShutdown)
1542 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1553 bool BindListenPort(string& strError)
1557 addrLocalHost.SetPort(GetListenPort());
1560 // Initialize Windows Sockets
1562 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1563 if (ret != NO_ERROR)
1565 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1566 printf("%s\n", strError.c_str());
1571 // Create socket for listening for incoming connections
1572 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1573 if (hListenSocket == INVALID_SOCKET)
1575 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1576 printf("%s\n", strError.c_str());
1581 // Different way of disabling SIGPIPE on BSD
1582 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1586 // Allow binding if the port is still in TIME_WAIT state after
1587 // the program was closed and restarted. Not an issue on windows.
1588 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1592 // Set to nonblocking, incoming connections will also inherit this
1593 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1595 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1598 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1599 printf("%s\n", strError.c_str());
1603 // The sockaddr_in structure specifies the address family,
1604 // IP address, and port for the socket that is being bound
1605 struct sockaddr_in sockaddr;
1606 memset(&sockaddr, 0, sizeof(sockaddr));
1607 sockaddr.sin_family = AF_INET;
1608 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1609 sockaddr.sin_port = htons(GetListenPort());
1610 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1612 int nErr = WSAGetLastError();
1613 if (nErr == WSAEADDRINUSE)
1614 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1616 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1617 printf("%s\n", strError.c_str());
1620 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1622 // Listen for incoming connections
1623 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1625 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1626 printf("%s\n", strError.c_str());
1633 void StartNode(void* parg)
1637 fUseUPnP = GetBoolArg("-upnp", true);
1639 fUseUPnP = GetBoolArg("-upnp", false);
1643 if (pnodeLocalHost == NULL)
1644 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1647 // Get local host ip
1648 char pszHostName[1000] = "";
1649 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1651 vector<CNetAddr> vaddr;
1652 if (LookupHost(pszHostName, vaddr))
1653 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1654 if (!addr.IsLocal())
1656 addrLocalHost.SetIP(addr);
1661 // Get local host ip
1662 struct ifaddrs* myaddrs;
1663 if (getifaddrs(&myaddrs) == 0)
1665 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1667 if (ifa->ifa_addr == NULL) continue;
1668 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1669 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1670 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1672 if (ifa->ifa_addr->sa_family == AF_INET)
1674 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1675 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1676 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1678 // Take the first IP that isn't loopback 127.x.x.x
1679 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1680 if (addr.IsValid() && !addr.IsLocal())
1682 addrLocalHost = addr;
1686 else if (ifa->ifa_addr->sa_family == AF_INET6)
1688 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1689 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1690 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1693 freeifaddrs(myaddrs);
1696 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1698 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1700 // Proxies can't take incoming connections
1701 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1702 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1706 CreateThread(ThreadGetMyExternalIP, NULL);
1713 if (!GetBoolArg("-dnsseed", true))
1714 printf("DNS seeding disabled\n");
1716 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1717 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1719 // Map ports with UPnP
1723 // Get addresses from IRC and advertise ours
1724 if (!CreateThread(ThreadIRCSeed, NULL))
1725 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1727 // Send and receive from sockets, accept connections
1728 if (!CreateThread(ThreadSocketHandler, NULL))
1729 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1731 // Initiate outbound connections from -addnode
1732 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1733 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1735 // Initiate outbound connections
1736 if (!CreateThread(ThreadOpenConnections, NULL))
1737 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1740 if (!CreateThread(ThreadMessageHandler, NULL))
1741 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1743 // Dump network addresses
1744 if (!CreateThread(ThreadDumpAddress, NULL))
1745 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1747 // Generate coins in the background
1748 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1753 printf("StopNode()\n");
1755 nTransactionsUpdated++;
1756 int64 nStart = GetTime();
1757 NOTIFY_ALL(condOutbound);
1760 int nThreadsRunning = 0;
1761 for (int n = 0; n < THREAD_MAX; n++)
1762 nThreadsRunning += vnThreadsRunning[n];
1763 if (nThreadsRunning == 0)
1765 if (GetTime() - nStart > 20)
1769 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1770 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1771 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1772 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1773 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1774 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1775 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1776 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1777 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1778 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1794 BOOST_FOREACH(CNode* pnode, vNodes)
1795 if (pnode->hSocket != INVALID_SOCKET)
1796 closesocket(pnode->hSocket);
1797 if (hListenSocket != INVALID_SOCKET)
1798 if (closesocket(hListenSocket) == SOCKET_ERROR)
1799 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1802 // Shutdown Windows Sockets
1807 instance_of_cnetcleanup;