1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
17 #include <netinet/in.h>
21 #include <miniupnpc/miniwget.h>
22 #include <miniupnpc/miniupnpc.h>
23 #include <miniupnpc/upnpcommands.h>
24 #include <miniupnpc/upnperrors.h>
28 using namespace boost;
30 static const int MAX_OUTBOUND_CONNECTIONS = 8;
32 void ThreadMessageHandler2(void* parg);
33 void ThreadSocketHandler2(void* parg);
34 void ThreadOpenConnections2(void* parg);
35 void ThreadOpenAddedConnections2(void* parg);
37 void ThreadMapPort2(void* parg);
39 void ThreadDNSAddressSeed2(void* parg);
40 bool OpenNetworkConnection(const CAddress& addrConnect);
45 // Global state variables
48 bool fAllowDNS = false;
49 static bool fUseUPnP = false;
50 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
51 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
52 static CNode* pnodeLocalHost = NULL;
53 uint64 nLocalHostNonce = 0;
54 array<int, THREAD_MAX> vnThreadsRunning;
55 static SOCKET hListenSocket = INVALID_SOCKET;
58 vector<CNode*> vNodes;
59 CCriticalSection cs_vNodes;
60 map<CInv, CDataStream> mapRelay;
61 deque<pair<int64, CInv> > vRelayExpiration;
62 CCriticalSection cs_mapRelay;
63 map<CInv, int64> mapAlreadyAskedFor;
66 set<CNetAddr> setservAddNodeAddresses;
67 CCriticalSection cs_setservAddNodeAddresses;
71 unsigned short GetListenPort()
73 return (unsigned short)(GetArg("-port", GetDefaultPort()));
76 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
78 // Filter out duplicate requests
79 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
81 pindexLastGetBlocksBegin = pindexBegin;
82 hashLastGetBlocksEnd = hashEnd;
84 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
89 bool RecvLine(SOCKET hSocket, string& strLine)
95 int nBytes = recv(hSocket, &c, 1, 0);
103 if (strLine.size() >= 9000)
106 else if (nBytes <= 0)
112 int nErr = WSAGetLastError();
113 if (nErr == WSAEMSGSIZE)
115 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
121 if (!strLine.empty())
126 printf("socket closed\n");
132 int nErr = WSAGetLastError();
133 printf("recv failed: %d\n", nErr);
142 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
145 if (!ConnectSocket(addrConnect, hSocket))
146 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
148 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
151 while (RecvLine(hSocket, strLine))
153 if (strLine.empty()) // HTTP response is separated from headers by blank line
157 if (!RecvLine(hSocket, strLine))
159 closesocket(hSocket);
162 if (pszKeyword == NULL)
164 if (strLine.find(pszKeyword) != string::npos)
166 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
170 closesocket(hSocket);
171 if (strLine.find("<") != string::npos)
172 strLine = strLine.substr(0, strLine.find("<"));
173 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
174 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
175 strLine.resize(strLine.size()-1);
176 CService addr(strLine,0,true);
177 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
178 if (!addr.IsValid() || !addr.IsRoutable())
184 closesocket(hSocket);
185 return error("GetMyExternalIP() : connection closed");
188 // We now get our external IP from the IRC server first and only use this as a backup
189 bool GetMyExternalIP(CNetAddr& ipRet)
191 CService addrConnect;
193 const char* pszKeyword;
195 if (fNoListen||fUseProxy)
198 for (int nLookup = 0; nLookup <= 1; nLookup++)
199 for (int nHost = 1; nHost <= 2; nHost++)
201 // We should be phasing out our use of sites like these. If we need
202 // replacements, we should ask for volunteers to put this simple
203 // php file on their webserver that prints the client IP:
204 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
207 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
211 CService addrIP("checkip.dyndns.org", 80, true);
212 if (addrIP.IsValid())
213 addrConnect = addrIP;
216 pszGet = "GET / HTTP/1.1\r\n"
217 "Host: checkip.dyndns.org\r\n"
218 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
219 "Connection: close\r\n"
222 pszKeyword = "Address:";
226 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
230 CService addrIP("www.showmyip.com", 80, true);
231 if (addrIP.IsValid())
232 addrConnect = addrIP;
235 pszGet = "GET /simple/ HTTP/1.1\r\n"
236 "Host: www.showmyip.com\r\n"
237 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
238 "Connection: close\r\n"
241 pszKeyword = NULL; // Returns just IP address
244 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
251 void ThreadGetMyExternalIP(void* parg)
253 // Wait for IRC to get it first
254 if (GetBoolArg("-irc", false))
256 for (int i = 0; i < 2 * 60; i++)
259 if (fGotExternalIP || fShutdown)
264 // Fallback in case IRC fails to get it
265 if (GetMyExternalIP(addrLocalHost))
267 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
268 if (addrLocalHost.IsRoutable())
270 // If we already connected to a few before we had our IP, go back and addr them.
271 // setAddrKnown automatically filters any duplicate sends.
272 CAddress addr(addrLocalHost);
273 addr.nTime = GetAdjustedTime();
274 CRITICAL_BLOCK(cs_vNodes)
275 BOOST_FOREACH(CNode* pnode, vNodes)
276 pnode->PushAddress(addr);
285 void AddressCurrentlyConnected(const CService& addr)
287 addrman.Connected(addr);
294 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
296 // If the dialog might get closed before the reply comes back,
297 // call this in the destructor so it doesn't get called after it's deleted.
298 CRITICAL_BLOCK(cs_vNodes)
300 BOOST_FOREACH(CNode* pnode, vNodes)
302 CRITICAL_BLOCK(pnode->cs_mapRequests)
304 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
306 CRequestTracker& tracker = (*mi).second;
307 if (tracker.fn == fn && tracker.param1 == param1)
308 pnode->mapRequests.erase(mi++);
324 // Subscription methods for the broadcast and subscription system.
325 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
327 // The subscription system uses a meet-in-the-middle strategy.
328 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
329 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
332 bool AnySubscribed(unsigned int nChannel)
334 if (pnodeLocalHost->IsSubscribed(nChannel))
336 CRITICAL_BLOCK(cs_vNodes)
337 BOOST_FOREACH(CNode* pnode, vNodes)
338 if (pnode->IsSubscribed(nChannel))
343 bool CNode::IsSubscribed(unsigned int nChannel)
345 if (nChannel >= vfSubscribe.size())
347 return vfSubscribe[nChannel];
350 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
352 if (nChannel >= vfSubscribe.size())
355 if (!AnySubscribed(nChannel))
358 CRITICAL_BLOCK(cs_vNodes)
359 BOOST_FOREACH(CNode* pnode, vNodes)
361 pnode->PushMessage("subscribe", nChannel, nHops);
364 vfSubscribe[nChannel] = true;
367 void CNode::CancelSubscribe(unsigned int nChannel)
369 if (nChannel >= vfSubscribe.size())
372 // Prevent from relaying cancel if wasn't subscribed
373 if (!vfSubscribe[nChannel])
375 vfSubscribe[nChannel] = false;
377 if (!AnySubscribed(nChannel))
379 // Relay subscription cancel
380 CRITICAL_BLOCK(cs_vNodes)
381 BOOST_FOREACH(CNode* pnode, vNodes)
383 pnode->PushMessage("sub-cancel", nChannel);
395 CNode* FindNode(const CNetAddr& ip)
397 CRITICAL_BLOCK(cs_vNodes)
399 BOOST_FOREACH(CNode* pnode, vNodes)
400 if ((CNetAddr)pnode->addr == ip)
406 CNode* FindNode(const CService& addr)
408 CRITICAL_BLOCK(cs_vNodes)
410 BOOST_FOREACH(CNode* pnode, vNodes)
411 if ((CService)pnode->addr == addr)
417 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
419 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
422 // Look for an existing connection
423 CNode* pnode = FindNode((CService)addrConnect);
427 pnode->AddRef(nTimeout);
434 printf("trying connection %s lastseen=%.1fhrs\n",
435 addrConnect.ToString().c_str(),
436 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
438 addrman.Attempt(addrConnect);
442 if (ConnectSocket(addrConnect, hSocket))
445 printf("connected %s\n", addrConnect.ToString().c_str());
447 // Set to nonblocking
450 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
451 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
453 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
454 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
458 CNode* pnode = new CNode(hSocket, addrConnect, false);
460 pnode->AddRef(nTimeout);
463 CRITICAL_BLOCK(cs_vNodes)
464 vNodes.push_back(pnode);
466 pnode->nTimeConnected = GetTime();
475 void CNode::CloseSocketDisconnect()
478 if (hSocket != INVALID_SOCKET)
481 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
482 printf("disconnecting node %s\n", addr.ToString().c_str());
483 closesocket(hSocket);
484 hSocket = INVALID_SOCKET;
489 void CNode::Cleanup()
491 // All of a nodes broadcasts and subscriptions are automatically torn down
492 // when it goes down, so a node has to stay up to keep its broadcast going.
494 // Cancel subscriptions
495 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
496 if (vfSubscribe[nChannel])
497 CancelSubscribe(nChannel);
501 void CNode::PushVersion()
503 /// when NTP implemented, change to just nTime = GetAdjustedTime()
504 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
505 CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
506 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
507 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
508 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
509 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
516 std::map<CNetAddr, int64> CNode::setBanned;
517 CCriticalSection CNode::cs_setBanned;
519 void CNode::ClearBanned()
524 bool CNode::IsBanned(CNetAddr ip)
526 bool fResult = false;
527 CRITICAL_BLOCK(cs_setBanned)
529 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
530 if (i != setBanned.end())
532 int64 t = (*i).second;
540 bool CNode::Misbehaving(int howmuch)
544 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
548 nMisbehavior += howmuch;
549 if (nMisbehavior >= GetArg("-banscore", 100))
551 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
552 CRITICAL_BLOCK(cs_setBanned)
553 if (setBanned[addr] < banTime)
554 setBanned[addr] = banTime;
555 CloseSocketDisconnect();
556 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
573 void ThreadSocketHandler(void* parg)
575 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
578 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
579 ThreadSocketHandler2(parg);
580 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
582 catch (std::exception& e) {
583 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
584 PrintException(&e, "ThreadSocketHandler()");
586 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
587 throw; // support pthread_cancel()
589 printf("ThreadSocketHandler exiting\n");
592 void ThreadSocketHandler2(void* parg)
594 printf("ThreadSocketHandler started\n");
595 list<CNode*> vNodesDisconnected;
596 int nPrevNodeCount = 0;
603 CRITICAL_BLOCK(cs_vNodes)
605 // Disconnect unused nodes
606 vector<CNode*> vNodesCopy = vNodes;
607 BOOST_FOREACH(CNode* pnode, vNodesCopy)
609 if (pnode->fDisconnect ||
610 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
612 // remove from vNodes
613 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
615 // close socket and cleanup
616 pnode->CloseSocketDisconnect();
619 // hold in disconnected pool until all refs are released
620 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
621 if (pnode->fNetworkNode || pnode->fInbound)
623 vNodesDisconnected.push_back(pnode);
627 // Delete disconnected nodes
628 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
629 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
631 // wait until threads are done using it
632 if (pnode->GetRefCount() <= 0)
634 bool fDelete = false;
635 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
636 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
637 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
638 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
642 vNodesDisconnected.remove(pnode);
648 if (vNodes.size() != nPrevNodeCount)
650 nPrevNodeCount = vNodes.size();
656 // Find which sockets have data to receive
658 struct timeval timeout;
660 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
667 FD_ZERO(&fdsetError);
668 SOCKET hSocketMax = 0;
670 if(hListenSocket != INVALID_SOCKET)
671 FD_SET(hListenSocket, &fdsetRecv);
672 hSocketMax = max(hSocketMax, hListenSocket);
673 CRITICAL_BLOCK(cs_vNodes)
675 BOOST_FOREACH(CNode* pnode, vNodes)
677 if (pnode->hSocket == INVALID_SOCKET)
679 FD_SET(pnode->hSocket, &fdsetRecv);
680 FD_SET(pnode->hSocket, &fdsetError);
681 hSocketMax = max(hSocketMax, pnode->hSocket);
682 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
683 if (!pnode->vSend.empty())
684 FD_SET(pnode->hSocket, &fdsetSend);
688 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
689 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
690 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
693 if (nSelect == SOCKET_ERROR)
695 int nErr = WSAGetLastError();
698 printf("socket select error %d\n", nErr);
699 for (unsigned int i = 0; i <= hSocketMax; i++)
700 FD_SET(i, &fdsetRecv);
703 FD_ZERO(&fdsetError);
704 Sleep(timeout.tv_usec/1000);
709 // Accept new connections
711 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
713 struct sockaddr_in sockaddr;
714 socklen_t len = sizeof(sockaddr);
715 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
719 if (hSocket != INVALID_SOCKET)
720 addr = CAddress(sockaddr);
722 CRITICAL_BLOCK(cs_vNodes)
723 BOOST_FOREACH(CNode* pnode, vNodes)
727 if (hSocket == INVALID_SOCKET)
729 if (WSAGetLastError() != WSAEWOULDBLOCK)
730 printf("socket error accept failed: %d\n", WSAGetLastError());
732 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
734 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
735 if (!setservAddNodeAddresses.count(addr))
736 closesocket(hSocket);
738 else if (CNode::IsBanned(addr))
740 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
741 closesocket(hSocket);
745 printf("accepted connection %s\n", addr.ToString().c_str());
746 CNode* pnode = new CNode(hSocket, addr, true);
748 CRITICAL_BLOCK(cs_vNodes)
749 vNodes.push_back(pnode);
755 // Service each socket
757 vector<CNode*> vNodesCopy;
758 CRITICAL_BLOCK(cs_vNodes)
761 BOOST_FOREACH(CNode* pnode, vNodesCopy)
764 BOOST_FOREACH(CNode* pnode, vNodesCopy)
772 if (pnode->hSocket == INVALID_SOCKET)
774 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
776 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
778 CDataStream& vRecv = pnode->vRecv;
779 unsigned int nPos = vRecv.size();
781 if (nPos > ReceiveBufferSize()) {
782 if (!pnode->fDisconnect)
783 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
784 pnode->CloseSocketDisconnect();
787 // typical socket buffer is 8K-64K
788 char pchBuf[0x10000];
789 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
792 vRecv.resize(nPos + nBytes);
793 memcpy(&vRecv[nPos], pchBuf, nBytes);
794 pnode->nLastRecv = GetTime();
796 else if (nBytes == 0)
798 // socket closed gracefully
799 if (!pnode->fDisconnect)
800 printf("socket closed\n");
801 pnode->CloseSocketDisconnect();
806 int nErr = WSAGetLastError();
807 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
809 if (!pnode->fDisconnect)
810 printf("socket recv error %d\n", nErr);
811 pnode->CloseSocketDisconnect();
821 if (pnode->hSocket == INVALID_SOCKET)
823 if (FD_ISSET(pnode->hSocket, &fdsetSend))
825 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
827 CDataStream& vSend = pnode->vSend;
830 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
833 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
834 pnode->nLastSend = GetTime();
839 int nErr = WSAGetLastError();
840 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
842 printf("socket send error %d\n", nErr);
843 pnode->CloseSocketDisconnect();
846 if (vSend.size() > SendBufferSize()) {
847 if (!pnode->fDisconnect)
848 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
849 pnode->CloseSocketDisconnect();
856 // Inactivity checking
858 if (pnode->vSend.empty())
859 pnode->nLastSendEmpty = GetTime();
860 if (GetTime() - pnode->nTimeConnected > 60)
862 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
864 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
865 pnode->fDisconnect = true;
867 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
869 printf("socket not sending\n");
870 pnode->fDisconnect = true;
872 else if (GetTime() - pnode->nLastRecv > 90*60)
874 printf("socket inactivity timeout\n");
875 pnode->fDisconnect = true;
879 CRITICAL_BLOCK(cs_vNodes)
881 BOOST_FOREACH(CNode* pnode, vNodesCopy)
898 void ThreadMapPort(void* parg)
900 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
903 vnThreadsRunning[THREAD_UPNP]++;
904 ThreadMapPort2(parg);
905 vnThreadsRunning[THREAD_UPNP]--;
907 catch (std::exception& e) {
908 vnThreadsRunning[THREAD_UPNP]--;
909 PrintException(&e, "ThreadMapPort()");
911 vnThreadsRunning[THREAD_UPNP]--;
912 PrintException(NULL, "ThreadMapPort()");
914 printf("ThreadMapPort exiting\n");
917 void ThreadMapPort2(void* parg)
919 printf("ThreadMapPort started\n");
922 sprintf(port, "%d", GetListenPort());
924 const char * multicastif = 0;
925 const char * minissdpdpath = 0;
926 struct UPNPDev * devlist = 0;
929 #ifndef UPNPDISCOVER_SUCCESS
931 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
935 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
938 struct UPNPUrls urls;
939 struct IGDdatas data;
942 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
945 if (!addrLocalHost.IsRoutable())
947 char externalIPAddress[40];
948 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
949 if(r != UPNPCOMMAND_SUCCESS)
950 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
953 if(externalIPAddress[0])
955 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
956 CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
957 if (addrExternalFromUPnP.IsRoutable())
958 addrLocalHost = addrExternalFromUPnP;
961 printf("UPnP: GetExternalIPAddress failed.\n");
965 string strDesc = "Bitcoin " + FormatFullVersion();
966 #ifndef UPNPDISCOVER_SUCCESS
968 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
969 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
972 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
973 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
976 if(r!=UPNPCOMMAND_SUCCESS)
977 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
978 port, port, lanaddr, r, strupnperror(r));
980 printf("UPnP Port Mapping successful.\n");
983 if (fShutdown || !fUseUPnP)
985 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
986 printf("UPNP_DeletePortMapping() returned : %d\n", r);
987 freeUPNPDevlist(devlist); devlist = 0;
991 if (i % 600 == 0) // Refresh every 20 minutes
993 #ifndef UPNPDISCOVER_SUCCESS
995 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
996 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
999 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1000 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1003 if(r!=UPNPCOMMAND_SUCCESS)
1004 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1005 port, port, lanaddr, r, strupnperror(r));
1007 printf("UPnP Port Mapping successful.\n");;
1013 printf("No valid UPnP IGDs found\n");
1014 freeUPNPDevlist(devlist); devlist = 0;
1016 FreeUPNPUrls(&urls);
1018 if (fShutdown || !fUseUPnP)
1025 void MapPort(bool fMapPort)
1027 if (fUseUPnP != fMapPort)
1029 fUseUPnP = fMapPort;
1031 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1033 if (!CreateThread(ThreadMapPort, NULL))
1034 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1038 void MapPort(bool /* unused fMapPort */)
1040 // Intentionally left blank.
1053 // Each pair gives a source name and a seed name.
1054 // The first name is used as information source for addrman.
1055 // The second name should resolve to a list of seed addresses.
1056 static const char *strDNSSeed[][2] = {
1057 {"xf2.org", "bitseed.xf2.org"},
1058 {"bluematt.me", "dnsseed.bluematt.me"},
1059 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1060 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1063 void ThreadDNSAddressSeed(void* parg)
1065 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1068 vnThreadsRunning[THREAD_DNSSEED]++;
1069 ThreadDNSAddressSeed2(parg);
1070 vnThreadsRunning[THREAD_DNSSEED]--;
1072 catch (std::exception& e) {
1073 vnThreadsRunning[THREAD_DNSSEED]--;
1074 PrintException(&e, "ThreadDNSAddressSeed()");
1076 vnThreadsRunning[THREAD_DNSSEED]--;
1077 throw; // support pthread_cancel()
1079 printf("ThreadDNSAddressSeed exiting\n");
1082 void ThreadDNSAddressSeed2(void* parg)
1084 printf("ThreadDNSAddressSeed started\n");
1089 printf("Loading addresses from DNS seeds (could take a while)\n");
1091 for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1092 vector<CNetAddr> vaddr;
1093 vector<CAddress> vAdd;
1094 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1096 BOOST_FOREACH(CNetAddr& ip, vaddr)
1098 int nOneDay = 24*3600;
1099 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1100 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1101 vAdd.push_back(addr);
1105 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1109 printf("%d addresses found from DNS seeds\n", found);
1123 unsigned int pnSeed[] =
1125 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1126 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1127 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1128 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1129 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1130 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1131 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1132 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1133 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1134 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1135 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1136 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1137 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1138 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1139 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1140 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1141 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1142 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1143 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1144 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1145 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1146 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1147 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1148 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1149 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1150 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1151 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1152 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1153 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1154 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1155 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1156 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1157 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1158 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1159 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1160 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1161 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1162 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1163 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1164 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1165 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1166 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1167 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1168 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1169 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1170 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1171 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1172 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1173 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1174 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1175 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1176 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1177 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1178 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1179 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1180 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1181 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1182 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1183 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1184 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1185 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1186 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1187 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1188 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1189 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1190 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1191 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1192 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1193 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1194 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1195 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1196 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1197 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1198 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1199 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1200 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1201 0xc461d84a, 0xb2dbe247,
1204 void DumpAddresses()
1207 adb.WriteAddrman(addrman);
1210 void ThreadDumpAddress2(void* parg)
1212 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1216 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1218 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1220 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1223 void ThreadDumpAddress(void* parg)
1225 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1228 ThreadDumpAddress2(parg);
1230 catch (std::exception& e) {
1231 PrintException(&e, "ThreadDumpAddress()");
1233 printf("ThreadDumpAddress exiting\n");
1236 void ThreadOpenConnections(void* parg)
1238 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1241 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1242 ThreadOpenConnections2(parg);
1243 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1245 catch (std::exception& e) {
1246 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1247 PrintException(&e, "ThreadOpenConnections()");
1249 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1250 PrintException(NULL, "ThreadOpenConnections()");
1252 printf("ThreadOpenConnections exiting\n");
1255 void ThreadOpenConnections2(void* parg)
1257 printf("ThreadOpenConnections started\n");
1259 // Connect to specific addresses
1260 if (mapArgs.count("-connect"))
1262 for (int64 nLoop = 0;; nLoop++)
1264 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1266 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1268 OpenNetworkConnection(addr);
1269 for (int i = 0; i < 10 && i < nLoop; i++)
1279 // Initiate network connections
1280 int64 nStart = GetTime();
1285 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1287 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1291 // Limit outbound connections
1295 CRITICAL_BLOCK(cs_vNodes)
1296 BOOST_FOREACH(CNode* pnode, vNodes)
1297 if (!pnode->fInbound)
1299 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1300 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1301 if (nOutbound < nMaxOutboundConnections)
1303 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1305 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
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 (unsigned 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;
1336 // Only connect to one address per a.b.?.? range.
1337 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1338 set<vector<unsigned char> > setConnected;
1339 CRITICAL_BLOCK(cs_vNodes)
1340 BOOST_FOREACH(CNode* pnode, vNodes)
1341 setConnected.insert(pnode->addr.GetGroup());
1343 int64 nANow = GetAdjustedTime();
1348 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1349 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1351 // if we selected an invalid address, restart
1352 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1357 // only consider very recently tried nodes after 30 failed attempts
1358 if (nANow - addr.nLastTry < 600 && nTries < 30)
1361 // do not allow non-default ports, unless after 50 invalid addresses selected already
1362 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1369 if (addrConnect.IsValid())
1370 OpenNetworkConnection(addrConnect);
1374 void ThreadOpenAddedConnections(void* parg)
1376 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1379 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1380 ThreadOpenAddedConnections2(parg);
1381 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1383 catch (std::exception& e) {
1384 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1385 PrintException(&e, "ThreadOpenAddedConnections()");
1387 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1388 PrintException(NULL, "ThreadOpenAddedConnections()");
1390 printf("ThreadOpenAddedConnections exiting\n");
1393 void ThreadOpenAddedConnections2(void* parg)
1395 printf("ThreadOpenAddedConnections started\n");
1397 if (mapArgs.count("-addnode") == 0)
1400 vector<vector<CService> > vservAddressesToAdd(0);
1401 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1403 vector<CService> vservNode(0);
1404 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1406 vservAddressesToAdd.push_back(vservNode);
1407 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1408 BOOST_FOREACH(CService& serv, vservNode)
1409 setservAddNodeAddresses.insert(serv);
1414 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1415 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1416 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1417 CRITICAL_BLOCK(cs_vNodes)
1418 BOOST_FOREACH(CNode* pnode, vNodes)
1419 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1420 BOOST_FOREACH(CService& addrNode, *(it))
1421 if (pnode->addr == addrNode)
1423 it = vservConnectAddresses.erase(it);
1427 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1429 OpenNetworkConnection(CAddress(*(vserv.begin())));
1436 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1437 Sleep(120000); // Retry every 2 minutes
1438 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1444 bool OpenNetworkConnection(const CAddress& addrConnect)
1447 // Initiate outbound network connection
1451 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1452 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1455 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1456 CNode* pnode = ConnectNode(addrConnect);
1457 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1462 pnode->fNetworkNode = true;
1474 void ThreadMessageHandler(void* parg)
1476 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1479 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1480 ThreadMessageHandler2(parg);
1481 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1483 catch (std::exception& e) {
1484 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1485 PrintException(&e, "ThreadMessageHandler()");
1487 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1488 PrintException(NULL, "ThreadMessageHandler()");
1490 printf("ThreadMessageHandler exiting\n");
1493 void ThreadMessageHandler2(void* parg)
1495 printf("ThreadMessageHandler started\n");
1496 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1499 vector<CNode*> vNodesCopy;
1500 CRITICAL_BLOCK(cs_vNodes)
1502 vNodesCopy = vNodes;
1503 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1507 // Poll the connected nodes for messages
1508 CNode* pnodeTrickle = NULL;
1509 if (!vNodesCopy.empty())
1510 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1511 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1514 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1515 ProcessMessages(pnode);
1520 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1521 SendMessages(pnode, pnode == pnodeTrickle);
1526 CRITICAL_BLOCK(cs_vNodes)
1528 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1532 // Wait and allow messages to bunch up.
1533 // Reduce vnThreadsRunning so StopNode has permission to exit while
1534 // we're sleeping, but we must always check fShutdown after doing this.
1535 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1537 if (fRequestShutdown)
1539 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1550 bool BindListenPort(string& strError)
1554 addrLocalHost.SetPort(GetListenPort());
1557 // Initialize Windows Sockets
1559 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1560 if (ret != NO_ERROR)
1562 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1563 printf("%s\n", strError.c_str());
1568 // Create socket for listening for incoming connections
1569 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1570 if (hListenSocket == INVALID_SOCKET)
1572 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1573 printf("%s\n", strError.c_str());
1578 // Different way of disabling SIGPIPE on BSD
1579 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1583 // Allow binding if the port is still in TIME_WAIT state after
1584 // the program was closed and restarted. Not an issue on windows.
1585 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1589 // Set to nonblocking, incoming connections will also inherit this
1590 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1592 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1595 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1596 printf("%s\n", strError.c_str());
1600 // The sockaddr_in structure specifies the address family,
1601 // IP address, and port for the socket that is being bound
1602 struct sockaddr_in sockaddr;
1603 memset(&sockaddr, 0, sizeof(sockaddr));
1604 sockaddr.sin_family = AF_INET;
1605 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1606 sockaddr.sin_port = htons(GetListenPort());
1607 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1609 int nErr = WSAGetLastError();
1610 if (nErr == WSAEADDRINUSE)
1611 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1613 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1614 printf("%s\n", strError.c_str());
1617 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1619 // Listen for incoming connections
1620 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1622 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1623 printf("%s\n", strError.c_str());
1630 void StartNode(void* parg)
1634 fUseUPnP = GetBoolArg("-upnp", true);
1636 fUseUPnP = GetBoolArg("-upnp", false);
1640 if (pnodeLocalHost == NULL)
1641 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1644 // Get local host ip
1645 char pszHostName[1000] = "";
1646 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1648 vector<CNetAddr> vaddr;
1649 if (LookupHost(pszHostName, vaddr))
1650 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1651 if (!addr.IsLocal())
1653 addrLocalHost.SetIP(addr);
1658 // Get local host ip
1659 struct ifaddrs* myaddrs;
1660 if (getifaddrs(&myaddrs) == 0)
1662 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1664 if (ifa->ifa_addr == NULL) continue;
1665 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1666 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1667 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1669 if (ifa->ifa_addr->sa_family == AF_INET)
1671 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1672 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1673 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1675 // Take the first IP that isn't loopback 127.x.x.x
1676 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1677 if (addr.IsValid() && !addr.IsLocal())
1679 addrLocalHost = addr;
1683 else if (ifa->ifa_addr->sa_family == AF_INET6)
1685 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1686 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1687 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1690 freeifaddrs(myaddrs);
1693 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1695 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1697 // Proxies can't take incoming connections
1698 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1699 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1703 CreateThread(ThreadGetMyExternalIP, NULL);
1710 if (!GetBoolArg("-dnsseed", true))
1711 printf("DNS seeding disabled\n");
1713 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1714 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1716 // Map ports with UPnP
1720 // Get addresses from IRC and advertise ours
1721 if (!CreateThread(ThreadIRCSeed, NULL))
1722 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1724 // Send and receive from sockets, accept connections
1725 if (!CreateThread(ThreadSocketHandler, NULL))
1726 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1728 // Initiate outbound connections from -addnode
1729 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1730 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1732 // Initiate outbound connections
1733 if (!CreateThread(ThreadOpenConnections, NULL))
1734 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1737 if (!CreateThread(ThreadMessageHandler, NULL))
1738 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1740 // Dump network addresses
1741 if (!CreateThread(ThreadDumpAddress, NULL))
1742 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1744 // Generate coins in the background
1745 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1750 printf("StopNode()\n");
1752 nTransactionsUpdated++;
1753 int64 nStart = GetTime();
1756 int nThreadsRunning = 0;
1757 for (int n = 0; n < THREAD_MAX; n++)
1758 nThreadsRunning += vnThreadsRunning[n];
1759 if (nThreadsRunning == 0)
1761 if (GetTime() - nStart > 20)
1765 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1766 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1767 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1768 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1769 if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1770 if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1771 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1772 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1773 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1774 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1790 BOOST_FOREACH(CNode* pnode, vNodes)
1791 if (pnode->hSocket != INVALID_SOCKET)
1792 closesocket(pnode->hSocket);
1793 if (hListenSocket != INVALID_SOCKET)
1794 if (closesocket(hListenSocket) == SOCKET_ERROR)
1795 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1798 // Shutdown Windows Sockets
1803 instance_of_cnetcleanup;