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;
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) != -1)
164 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
168 closesocket(hSocket);
169 if (strLine.find("<") != -1)
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();
272 CRITICAL_BLOCK(cs_vNodes)
273 BOOST_FOREACH(CNode* pnode, vNodes)
274 pnode->PushAddress(addr);
283 void AddressCurrentlyConnected(const CService& addr)
285 addrman.Connected(addr);
292 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
294 // If the dialog might get closed before the reply comes back,
295 // call this in the destructor so it doesn't get called after it's deleted.
296 CRITICAL_BLOCK(cs_vNodes)
298 BOOST_FOREACH(CNode* pnode, vNodes)
300 CRITICAL_BLOCK(pnode->cs_mapRequests)
302 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
304 CRequestTracker& tracker = (*mi).second;
305 if (tracker.fn == fn && tracker.param1 == param1)
306 pnode->mapRequests.erase(mi++);
322 // Subscription methods for the broadcast and subscription system.
323 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
325 // The subscription system uses a meet-in-the-middle strategy.
326 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
327 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
330 bool AnySubscribed(unsigned int nChannel)
332 if (pnodeLocalHost->IsSubscribed(nChannel))
334 CRITICAL_BLOCK(cs_vNodes)
335 BOOST_FOREACH(CNode* pnode, vNodes)
336 if (pnode->IsSubscribed(nChannel))
341 bool CNode::IsSubscribed(unsigned int nChannel)
343 if (nChannel >= vfSubscribe.size())
345 return vfSubscribe[nChannel];
348 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
350 if (nChannel >= vfSubscribe.size())
353 if (!AnySubscribed(nChannel))
356 CRITICAL_BLOCK(cs_vNodes)
357 BOOST_FOREACH(CNode* pnode, vNodes)
359 pnode->PushMessage("subscribe", nChannel, nHops);
362 vfSubscribe[nChannel] = true;
365 void CNode::CancelSubscribe(unsigned int nChannel)
367 if (nChannel >= vfSubscribe.size())
370 // Prevent from relaying cancel if wasn't subscribed
371 if (!vfSubscribe[nChannel])
373 vfSubscribe[nChannel] = false;
375 if (!AnySubscribed(nChannel))
377 // Relay subscription cancel
378 CRITICAL_BLOCK(cs_vNodes)
379 BOOST_FOREACH(CNode* pnode, vNodes)
381 pnode->PushMessage("sub-cancel", nChannel);
393 CNode* FindNode(const CNetAddr& ip)
395 CRITICAL_BLOCK(cs_vNodes)
397 BOOST_FOREACH(CNode* pnode, vNodes)
398 if ((CNetAddr)pnode->addr == ip)
404 CNode* FindNode(const CService& addr)
406 CRITICAL_BLOCK(cs_vNodes)
408 BOOST_FOREACH(CNode* pnode, vNodes)
409 if ((CService)pnode->addr == addr)
415 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
417 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
420 // Look for an existing connection
421 CNode* pnode = FindNode((CService)addrConnect);
425 pnode->AddRef(nTimeout);
432 printf("trying connection %s lastseen=%.1fhrs\n",
433 addrConnect.ToString().c_str(),
434 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
436 addrman.Attempt(addrConnect);
440 if (ConnectSocket(addrConnect, hSocket))
443 printf("connected %s\n", addrConnect.ToString().c_str());
445 // Set to nonblocking
448 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
449 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
451 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
452 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
456 CNode* pnode = new CNode(hSocket, addrConnect, false);
458 pnode->AddRef(nTimeout);
461 CRITICAL_BLOCK(cs_vNodes)
462 vNodes.push_back(pnode);
464 pnode->nTimeConnected = GetTime();
473 void CNode::CloseSocketDisconnect()
476 if (hSocket != INVALID_SOCKET)
479 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
480 printf("disconnecting node %s\n", addr.ToString().c_str());
481 closesocket(hSocket);
482 hSocket = INVALID_SOCKET;
487 void CNode::Cleanup()
489 // All of a nodes broadcasts and subscriptions are automatically torn down
490 // when it goes down, so a node has to stay up to keep its broadcast going.
492 // Cancel subscriptions
493 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
494 if (vfSubscribe[nChannel])
495 CancelSubscribe(nChannel);
499 void CNode::PushVersion()
501 /// when NTP implemented, change to just nTime = GetAdjustedTime()
502 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
503 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
504 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
505 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
506 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
507 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
514 std::map<CNetAddr, int64> CNode::setBanned;
515 CCriticalSection CNode::cs_setBanned;
517 void CNode::ClearBanned()
522 bool CNode::IsBanned(CNetAddr ip)
524 bool fResult = false;
525 CRITICAL_BLOCK(cs_setBanned)
527 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
528 if (i != setBanned.end())
530 int64 t = (*i).second;
538 bool CNode::Misbehaving(int howmuch)
542 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
546 nMisbehavior += howmuch;
547 if (nMisbehavior >= GetArg("-banscore", 100))
549 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
550 CRITICAL_BLOCK(cs_setBanned)
551 if (setBanned[addr] < banTime)
552 setBanned[addr] = banTime;
553 CloseSocketDisconnect();
554 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
571 void ThreadSocketHandler(void* parg)
573 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
576 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
577 ThreadSocketHandler2(parg);
578 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
580 catch (std::exception& e) {
581 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
582 PrintException(&e, "ThreadSocketHandler()");
584 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
585 throw; // support pthread_cancel()
587 printf("ThreadSocketHandler exiting\n");
590 void ThreadSocketHandler2(void* parg)
592 printf("ThreadSocketHandler started\n");
593 list<CNode*> vNodesDisconnected;
594 int nPrevNodeCount = 0;
601 CRITICAL_BLOCK(cs_vNodes)
603 // Disconnect unused nodes
604 vector<CNode*> vNodesCopy = vNodes;
605 BOOST_FOREACH(CNode* pnode, vNodesCopy)
607 if (pnode->fDisconnect ||
608 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
610 // remove from vNodes
611 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
613 // close socket and cleanup
614 pnode->CloseSocketDisconnect();
617 // hold in disconnected pool until all refs are released
618 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
619 if (pnode->fNetworkNode || pnode->fInbound)
621 vNodesDisconnected.push_back(pnode);
625 // Delete disconnected nodes
626 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
627 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
629 // wait until threads are done using it
630 if (pnode->GetRefCount() <= 0)
632 bool fDelete = false;
633 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
634 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
635 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
636 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
640 vNodesDisconnected.remove(pnode);
646 if (vNodes.size() != nPrevNodeCount)
648 nPrevNodeCount = vNodes.size();
654 // Find which sockets have data to receive
656 struct timeval timeout;
658 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
665 FD_ZERO(&fdsetError);
666 SOCKET hSocketMax = 0;
668 if(hListenSocket != INVALID_SOCKET)
669 FD_SET(hListenSocket, &fdsetRecv);
670 hSocketMax = max(hSocketMax, hListenSocket);
671 CRITICAL_BLOCK(cs_vNodes)
673 BOOST_FOREACH(CNode* pnode, vNodes)
675 if (pnode->hSocket == INVALID_SOCKET)
677 FD_SET(pnode->hSocket, &fdsetRecv);
678 FD_SET(pnode->hSocket, &fdsetError);
679 hSocketMax = max(hSocketMax, pnode->hSocket);
680 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
681 if (!pnode->vSend.empty())
682 FD_SET(pnode->hSocket, &fdsetSend);
686 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
687 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
688 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
691 if (nSelect == SOCKET_ERROR)
693 int nErr = WSAGetLastError();
696 printf("socket select error %d\n", nErr);
697 for (int i = 0; i <= hSocketMax; i++)
698 FD_SET(i, &fdsetRecv);
701 FD_ZERO(&fdsetError);
702 Sleep(timeout.tv_usec/1000);
707 // Accept new connections
709 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
711 struct sockaddr_in sockaddr;
712 socklen_t len = sizeof(sockaddr);
713 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
717 if (hSocket != INVALID_SOCKET)
718 addr = CAddress(sockaddr);
720 CRITICAL_BLOCK(cs_vNodes)
721 BOOST_FOREACH(CNode* pnode, vNodes)
725 if (hSocket == INVALID_SOCKET)
727 if (WSAGetLastError() != WSAEWOULDBLOCK)
728 printf("socket error accept failed: %d\n", WSAGetLastError());
730 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
732 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
733 if (!setservAddNodeAddresses.count(addr))
734 closesocket(hSocket);
736 else if (CNode::IsBanned(addr))
738 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
739 closesocket(hSocket);
743 printf("accepted connection %s\n", addr.ToString().c_str());
744 CNode* pnode = new CNode(hSocket, addr, true);
746 CRITICAL_BLOCK(cs_vNodes)
747 vNodes.push_back(pnode);
753 // Service each socket
755 vector<CNode*> vNodesCopy;
756 CRITICAL_BLOCK(cs_vNodes)
759 BOOST_FOREACH(CNode* pnode, vNodesCopy)
762 BOOST_FOREACH(CNode* pnode, vNodesCopy)
770 if (pnode->hSocket == INVALID_SOCKET)
772 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
774 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
776 CDataStream& vRecv = pnode->vRecv;
777 unsigned int nPos = vRecv.size();
779 if (nPos > ReceiveBufferSize()) {
780 if (!pnode->fDisconnect)
781 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
782 pnode->CloseSocketDisconnect();
785 // typical socket buffer is 8K-64K
786 char pchBuf[0x10000];
787 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
790 vRecv.resize(nPos + nBytes);
791 memcpy(&vRecv[nPos], pchBuf, nBytes);
792 pnode->nLastRecv = GetTime();
794 else if (nBytes == 0)
796 // socket closed gracefully
797 if (!pnode->fDisconnect)
798 printf("socket closed\n");
799 pnode->CloseSocketDisconnect();
804 int nErr = WSAGetLastError();
805 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
807 if (!pnode->fDisconnect)
808 printf("socket recv error %d\n", nErr);
809 pnode->CloseSocketDisconnect();
819 if (pnode->hSocket == INVALID_SOCKET)
821 if (FD_ISSET(pnode->hSocket, &fdsetSend))
823 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
825 CDataStream& vSend = pnode->vSend;
828 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
831 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
832 pnode->nLastSend = GetTime();
837 int nErr = WSAGetLastError();
838 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
840 printf("socket send error %d\n", nErr);
841 pnode->CloseSocketDisconnect();
844 if (vSend.size() > SendBufferSize()) {
845 if (!pnode->fDisconnect)
846 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
847 pnode->CloseSocketDisconnect();
854 // Inactivity checking
856 if (pnode->vSend.empty())
857 pnode->nLastSendEmpty = GetTime();
858 if (GetTime() - pnode->nTimeConnected > 60)
860 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
862 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
863 pnode->fDisconnect = true;
865 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
867 printf("socket not sending\n");
868 pnode->fDisconnect = true;
870 else if (GetTime() - pnode->nLastRecv > 90*60)
872 printf("socket inactivity timeout\n");
873 pnode->fDisconnect = true;
877 CRITICAL_BLOCK(cs_vNodes)
879 BOOST_FOREACH(CNode* pnode, vNodesCopy)
896 void ThreadMapPort(void* parg)
898 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
901 vnThreadsRunning[THREAD_UPNP]++;
902 ThreadMapPort2(parg);
903 vnThreadsRunning[THREAD_UPNP]--;
905 catch (std::exception& e) {
906 vnThreadsRunning[THREAD_UPNP]--;
907 PrintException(&e, "ThreadMapPort()");
909 vnThreadsRunning[THREAD_UPNP]--;
910 PrintException(NULL, "ThreadMapPort()");
912 printf("ThreadMapPort exiting\n");
915 void ThreadMapPort2(void* parg)
917 printf("ThreadMapPort started\n");
920 sprintf(port, "%d", GetListenPort());
922 const char * multicastif = 0;
923 const char * minissdpdpath = 0;
924 struct UPNPDev * devlist = 0;
927 #ifndef UPNPDISCOVER_SUCCESS
929 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
933 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
936 struct UPNPUrls urls;
937 struct IGDdatas data;
940 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
943 if (!addrLocalHost.IsRoutable())
945 char externalIPAddress[40];
946 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
947 if(r != UPNPCOMMAND_SUCCESS)
948 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
951 if(externalIPAddress[0])
953 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
954 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
955 if (addrExternalFromUPnP.IsRoutable())
956 addrLocalHost = addrExternalFromUPnP;
959 printf("UPnP: GetExternalIPAddress failed.\n");
963 string strDesc = "Bitcoin " + FormatFullVersion();
964 #ifndef UPNPDISCOVER_SUCCESS
966 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
967 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
970 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
971 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
974 if(r!=UPNPCOMMAND_SUCCESS)
975 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
976 port, port, lanaddr, r, strupnperror(r));
978 printf("UPnP Port Mapping successful.\n");
981 if (fShutdown || !fUseUPnP)
983 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
984 printf("UPNP_DeletePortMapping() returned : %d\n", r);
985 freeUPNPDevlist(devlist); devlist = 0;
989 if (i % 600 == 0) // Refresh every 20 minutes
991 #ifndef UPNPDISCOVER_SUCCESS
993 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
994 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
997 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
998 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1001 if(r!=UPNPCOMMAND_SUCCESS)
1002 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1003 port, port, lanaddr, r, strupnperror(r));
1005 printf("UPnP Port Mapping successful.\n");;
1011 printf("No valid UPnP IGDs found\n");
1012 freeUPNPDevlist(devlist); devlist = 0;
1014 FreeUPNPUrls(&urls);
1016 if (fShutdown || !fUseUPnP)
1023 void MapPort(bool fMapPort)
1025 if (fUseUPnP != fMapPort)
1027 fUseUPnP = fMapPort;
1029 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1031 if (!CreateThread(ThreadMapPort, NULL))
1032 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1036 void MapPort(bool /* unused fMapPort */)
1038 // Intentionally left blank.
1051 // Each pair gives a source name and a seed name.
1052 // The first name is used as information source for addrman.
1053 // The second name should resolve to a list of seed addresses.
1054 static const char *strDNSSeed[][2] = {
1055 {"xf2.org", "bitseed.xf2.org"},
1056 {"bluematt.me", "dnsseed.bluematt.me"},
1057 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1058 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1061 void ThreadDNSAddressSeed(void* parg)
1063 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1066 vnThreadsRunning[THREAD_DNSSEED]++;
1067 ThreadDNSAddressSeed2(parg);
1068 vnThreadsRunning[THREAD_DNSSEED]--;
1070 catch (std::exception& e) {
1071 vnThreadsRunning[THREAD_DNSSEED]--;
1072 PrintException(&e, "ThreadDNSAddressSeed()");
1074 vnThreadsRunning[THREAD_DNSSEED]--;
1075 throw; // support pthread_cancel()
1077 printf("ThreadDNSAddressSeed exiting\n");
1080 void ThreadDNSAddressSeed2(void* parg)
1082 printf("ThreadDNSAddressSeed started\n");
1087 printf("Loading addresses from DNS seeds (could take a while)\n");
1089 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1090 vector<CNetAddr> vaddr;
1091 vector<CAddress> vAdd;
1092 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1094 BOOST_FOREACH(CNetAddr& ip, vaddr)
1096 int nOneDay = 24*3600;
1097 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1098 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1099 vAdd.push_back(addr);
1103 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1107 printf("%d addresses found from DNS seeds\n", found);
1121 unsigned int pnSeed[] =
1123 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1124 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1125 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1126 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1127 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1128 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1129 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1130 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1131 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1132 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1133 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1134 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1135 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1136 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1137 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1138 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1139 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1140 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1141 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1142 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1143 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1144 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1145 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1146 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1147 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1148 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1149 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1150 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1151 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1152 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1153 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1154 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1155 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1156 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1157 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1158 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1159 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1160 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1161 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1162 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1163 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1164 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1165 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1166 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1167 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1168 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1169 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1170 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1171 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1172 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1173 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1174 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1175 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1176 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1177 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1178 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1179 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1180 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1181 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1182 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1183 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1184 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1185 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1186 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1187 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1188 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1189 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1190 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1191 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1192 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1193 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1194 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1195 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1196 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1197 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1198 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1199 0xc461d84a, 0xb2dbe247,
1202 void DumpAddresses()
1205 adb.WriteAddrman(addrman);
1208 void ThreadDumpAddress2(void* parg)
1210 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1214 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1216 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1218 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1221 void ThreadDumpAddress(void* parg)
1223 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1226 ThreadDumpAddress2(parg);
1228 catch (std::exception& e) {
1229 PrintException(&e, "ThreadDumpAddress()");
1231 printf("ThreadDumpAddress exiting\n");
1234 void ThreadOpenConnections(void* parg)
1236 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1239 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1240 ThreadOpenConnections2(parg);
1241 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1243 catch (std::exception& e) {
1244 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1245 PrintException(&e, "ThreadOpenConnections()");
1247 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1248 PrintException(NULL, "ThreadOpenConnections()");
1250 printf("ThreadOpenConnections exiting\n");
1253 void ThreadOpenConnections2(void* parg)
1255 printf("ThreadOpenConnections started\n");
1257 // Connect to specific addresses
1258 if (mapArgs.count("-connect"))
1260 for (int64 nLoop = 0;; nLoop++)
1262 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1264 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1266 OpenNetworkConnection(addr);
1267 for (int i = 0; i < 10 && i < nLoop; i++)
1277 // Initiate network connections
1278 int64 nStart = GetTime();
1283 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1285 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1289 // Limit outbound connections
1293 CRITICAL_BLOCK(cs_vNodes)
1294 BOOST_FOREACH(CNode* pnode, vNodes)
1295 if (!pnode->fInbound)
1297 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1298 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1299 if (nOutbound < nMaxOutboundConnections)
1301 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1303 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1308 bool fAddSeeds = false;
1310 // Add seed nodes if IRC isn't working
1311 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1312 if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1314 std::vector<CAddress> vAdd;
1315 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1317 // It'll only connect to one or two seed nodes because once it connects,
1318 // it'll get a pile of addresses with newer timestamps.
1319 // Seed nodes are given a random 'last seen time' of between one and two
1321 const int64 nOneWeek = 7*24*60*60;
1323 memcpy(&ip, &pnSeed[i], sizeof(ip));
1324 CAddress addr(CService(ip, GetDefaultPort()));
1325 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1326 vAdd.push_back(addr);
1328 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1332 // Choose an address to connect to based on most recently seen
1334 CAddress addrConnect;
1335 int64 nBest = std::numeric_limits<int64>::min();
1337 // Only connect to one address per a.b.?.? range.
1338 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1339 set<vector<unsigned char> > setConnected;
1340 CRITICAL_BLOCK(cs_vNodes)
1341 BOOST_FOREACH(CNode* pnode, vNodes)
1342 setConnected.insert(pnode->addr.GetGroup());
1344 int64 nANow = GetAdjustedTime();
1349 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1350 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1352 // if we selected an invalid address, restart
1353 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1358 // only consider very recently tried nodes after 30 failed attempts
1359 if (nANow - addr.nLastTry < 600 && nTries < 30)
1362 // do not allow non-default ports, unless after 50 invalid addresses selected already
1363 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1370 if (addrConnect.IsValid())
1371 OpenNetworkConnection(addrConnect);
1375 void ThreadOpenAddedConnections(void* parg)
1377 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1380 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1381 ThreadOpenAddedConnections2(parg);
1382 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1384 catch (std::exception& e) {
1385 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1386 PrintException(&e, "ThreadOpenAddedConnections()");
1388 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1389 PrintException(NULL, "ThreadOpenAddedConnections()");
1391 printf("ThreadOpenAddedConnections exiting\n");
1394 void ThreadOpenAddedConnections2(void* parg)
1396 printf("ThreadOpenAddedConnections started\n");
1398 if (mapArgs.count("-addnode") == 0)
1401 vector<vector<CService> > vservAddressesToAdd(0);
1402 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1404 vector<CService> vservNode(0);
1405 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1407 vservAddressesToAdd.push_back(vservNode);
1408 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1409 BOOST_FOREACH(CService& serv, vservNode)
1410 setservAddNodeAddresses.insert(serv);
1415 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1416 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1417 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1418 CRITICAL_BLOCK(cs_vNodes)
1419 BOOST_FOREACH(CNode* pnode, vNodes)
1420 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1421 BOOST_FOREACH(CService& addrNode, *(it))
1422 if (pnode->addr == addrNode)
1424 it = vservConnectAddresses.erase(it);
1428 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1430 OpenNetworkConnection(CAddress(*(vserv.begin())));
1437 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1438 Sleep(120000); // Retry every 2 minutes
1439 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1445 bool OpenNetworkConnection(const CAddress& addrConnect)
1448 // Initiate outbound network connection
1452 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1453 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1456 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1457 CNode* pnode = ConnectNode(addrConnect);
1458 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1463 pnode->fNetworkNode = true;
1475 void ThreadMessageHandler(void* parg)
1477 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1480 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1481 ThreadMessageHandler2(parg);
1482 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1484 catch (std::exception& e) {
1485 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1486 PrintException(&e, "ThreadMessageHandler()");
1488 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1489 PrintException(NULL, "ThreadMessageHandler()");
1491 printf("ThreadMessageHandler exiting\n");
1494 void ThreadMessageHandler2(void* parg)
1496 printf("ThreadMessageHandler started\n");
1497 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1500 vector<CNode*> vNodesCopy;
1501 CRITICAL_BLOCK(cs_vNodes)
1503 vNodesCopy = vNodes;
1504 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1508 // Poll the connected nodes for messages
1509 CNode* pnodeTrickle = NULL;
1510 if (!vNodesCopy.empty())
1511 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1512 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1515 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1516 ProcessMessages(pnode);
1521 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1522 SendMessages(pnode, pnode == pnodeTrickle);
1527 CRITICAL_BLOCK(cs_vNodes)
1529 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1533 // Wait and allow messages to bunch up.
1534 // Reduce vnThreadsRunning so StopNode has permission to exit while
1535 // we're sleeping, but we must always check fShutdown after doing this.
1536 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1538 if (fRequestShutdown)
1540 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1551 bool BindListenPort(string& strError)
1555 addrLocalHost.SetPort(GetListenPort());
1558 // Initialize Windows Sockets
1560 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1561 if (ret != NO_ERROR)
1563 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1564 printf("%s\n", strError.c_str());
1569 // Create socket for listening for incoming connections
1570 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1571 if (hListenSocket == INVALID_SOCKET)
1573 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1574 printf("%s\n", strError.c_str());
1579 // Different way of disabling SIGPIPE on BSD
1580 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1584 // Allow binding if the port is still in TIME_WAIT state after
1585 // the program was closed and restarted. Not an issue on windows.
1586 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1590 // Set to nonblocking, incoming connections will also inherit this
1591 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1593 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1596 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1597 printf("%s\n", strError.c_str());
1601 // The sockaddr_in structure specifies the address family,
1602 // IP address, and port for the socket that is being bound
1603 struct sockaddr_in sockaddr;
1604 memset(&sockaddr, 0, sizeof(sockaddr));
1605 sockaddr.sin_family = AF_INET;
1606 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1607 sockaddr.sin_port = htons(GetListenPort());
1608 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1610 int nErr = WSAGetLastError();
1611 if (nErr == WSAEADDRINUSE)
1612 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1614 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1615 printf("%s\n", strError.c_str());
1618 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1620 // Listen for incoming connections
1621 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1623 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1624 printf("%s\n", strError.c_str());
1631 void StartNode(void* parg)
1635 fUseUPnP = GetBoolArg("-upnp", true);
1637 fUseUPnP = GetBoolArg("-upnp", false);
1641 if (pnodeLocalHost == NULL)
1642 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1645 // Get local host ip
1646 char pszHostName[1000] = "";
1647 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1649 vector<CNetAddr> vaddr;
1650 if (LookupHost(pszHostName, vaddr))
1651 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1652 if (!addr.IsLocal())
1654 addrLocalHost.SetIP(addr);
1659 // Get local host ip
1660 struct ifaddrs* myaddrs;
1661 if (getifaddrs(&myaddrs) == 0)
1663 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1665 if (ifa->ifa_addr == NULL) continue;
1666 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1667 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1668 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1670 if (ifa->ifa_addr->sa_family == AF_INET)
1672 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1673 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1674 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1676 // Take the first IP that isn't loopback 127.x.x.x
1677 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1678 if (addr.IsValid() && !addr.IsLocal())
1680 addrLocalHost = addr;
1684 else if (ifa->ifa_addr->sa_family == AF_INET6)
1686 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1687 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1688 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1691 freeifaddrs(myaddrs);
1694 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1696 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1698 // Proxies can't take incoming connections
1699 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1700 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1704 CreateThread(ThreadGetMyExternalIP, NULL);
1711 if (!GetBoolArg("-dnsseed", true))
1712 printf("DNS seeding disabled\n");
1714 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1715 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1717 // Map ports with UPnP
1721 // Get addresses from IRC and advertise ours
1722 if (!CreateThread(ThreadIRCSeed, NULL))
1723 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1725 // Send and receive from sockets, accept connections
1726 if (!CreateThread(ThreadSocketHandler, NULL))
1727 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1729 // Initiate outbound connections from -addnode
1730 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1731 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1733 // Initiate outbound connections
1734 if (!CreateThread(ThreadOpenConnections, NULL))
1735 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1738 if (!CreateThread(ThreadMessageHandler, NULL))
1739 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1741 // Dump network addresses
1742 if (!CreateThread(ThreadDumpAddress, NULL))
1743 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1745 // Generate coins in the background
1746 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1751 printf("StopNode()\n");
1753 nTransactionsUpdated++;
1754 int64 nStart = GetTime();
1757 int nThreadsRunning = 0;
1758 for (int n = 0; n < THREAD_MAX; n++)
1759 nThreadsRunning += vnThreadsRunning[n];
1760 if (nThreadsRunning == 0)
1762 if (GetTime() - nStart > 20)
1766 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1767 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1768 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1769 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1770 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1771 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1772 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1773 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1774 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1775 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1791 BOOST_FOREACH(CNode* pnode, vNodes)
1792 if (pnode->hSocket != INVALID_SOCKET)
1793 closesocket(pnode->hSocket);
1794 if (hListenSocket != INVALID_SOCKET)
1795 if (closesocket(hListenSocket) == SOCKET_ERROR)
1796 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1799 // Shutdown Windows Sockets
1804 instance_of_cnetcleanup;