1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
12 #include "ui_interface.h"
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
26 using namespace boost;
28 static const int MAX_OUTBOUND_CONNECTIONS = 8;
30 void ThreadMessageHandler2(void* parg);
31 void ThreadSocketHandler2(void* parg);
32 void ThreadOpenConnections2(void* parg);
33 void ThreadOpenAddedConnections2(void* parg);
35 void ThreadMapPort2(void* parg);
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
41 struct LocalServiceInfo {
47 // Global state variables
50 bool fDiscover = true;
51 bool fUseUPnP = false;
52 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
53 static CCriticalSection cs_mapLocalHost;
54 static map<CNetAddr, LocalServiceInfo> mapLocalHost;
55 static bool vfReachable[NET_MAX] = {};
56 static bool vfLimited[NET_MAX] = {};
57 static CNode* pnodeLocalHost = NULL;
58 uint64 nLocalHostNonce = 0;
59 array<int, THREAD_MAX> vnThreadsRunning;
60 static std::vector<SOCKET> vhListenSocket;
63 vector<CNode*> vNodes;
64 CCriticalSection cs_vNodes;
65 map<CInv, CDataStream> mapRelay;
66 deque<pair<int64, CInv> > vRelayExpiration;
67 CCriticalSection cs_mapRelay;
68 map<CInv, int64> mapAlreadyAskedFor;
70 static deque<string> vOneShots;
71 CCriticalSection cs_vOneShots;
73 set<CNetAddr> setservAddNodeAddresses;
74 CCriticalSection cs_setservAddNodeAddresses;
76 static CSemaphore *semOutbound = NULL;
78 void AddOneShot(string strDest)
81 vOneShots.push_back(strDest);
84 unsigned short GetListenPort()
86 return (unsigned short)(GetArg("-port", GetDefaultPort()));
89 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
91 // Filter out duplicate requests
92 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
94 pindexLastGetBlocksBegin = pindexBegin;
95 hashLastGetBlocksEnd = hashEnd;
97 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
100 // find 'best' local address for a particular peer
101 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
107 int nBestReachability = -1;
109 LOCK(cs_mapLocalHost);
110 for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
112 int nScore = (*it).second.nScore;
113 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
114 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
116 addr = CService((*it).first, (*it).second.nPort);
117 nBestReachability = nReachability;
122 return nBestScore >= 0;
125 // get best local address for a particular peer as a CAddress
126 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
128 CAddress ret(CService("0.0.0.0",0),0);
130 if (GetLocal(addr, paddrPeer))
132 ret = CAddress(addr);
133 ret.nServices = nLocalServices;
134 ret.nTime = GetAdjustedTime();
139 bool RecvLine(SOCKET hSocket, string& strLine)
145 int nBytes = recv(hSocket, &c, 1, 0);
153 if (strLine.size() >= 9000)
156 else if (nBytes <= 0)
162 int nErr = WSAGetLastError();
163 if (nErr == WSAEMSGSIZE)
165 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
171 if (!strLine.empty())
176 printf("socket closed\n");
182 int nErr = WSAGetLastError();
183 printf("recv failed: %d\n", nErr);
190 // used when scores of local addresses may have changed
191 // pushes better local address to peers
192 void static AdvertizeLocal()
195 BOOST_FOREACH(CNode* pnode, vNodes)
197 if (pnode->fSuccessfullyConnected)
199 CAddress addrLocal = GetLocalAddress(&pnode->addr);
200 if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
202 pnode->PushAddress(addrLocal);
203 pnode->addrLocal = addrLocal;
209 void SetReachable(enum Network net, bool fFlag)
211 LOCK(cs_mapLocalHost);
212 vfReachable[net] = fFlag;
213 if (net == NET_IPV6 && fFlag)
214 vfReachable[NET_IPV4] = true;
217 // learn a new local address
218 bool AddLocal(const CService& addr, int nScore)
220 if (!addr.IsRoutable())
223 if (!fDiscover && nScore < LOCAL_MANUAL)
229 printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
232 LOCK(cs_mapLocalHost);
233 bool fAlready = mapLocalHost.count(addr) > 0;
234 LocalServiceInfo &info = mapLocalHost[addr];
235 if (!fAlready || nScore >= info.nScore) {
236 info.nScore = nScore + (fAlready ? 1 : 0);
237 info.nPort = addr.GetPort();
239 SetReachable(addr.GetNetwork());
247 bool AddLocal(const CNetAddr &addr, int nScore)
249 return AddLocal(CService(addr, GetListenPort()), nScore);
252 /** Make a particular network entirely off-limits (no automatic connects to it) */
253 void SetLimited(enum Network net, bool fLimited)
255 if (net == NET_UNROUTABLE)
257 LOCK(cs_mapLocalHost);
258 vfLimited[net] = fLimited;
261 bool IsLimited(enum Network net)
263 LOCK(cs_mapLocalHost);
264 return vfLimited[net];
267 bool IsLimited(const CNetAddr &addr)
269 return IsLimited(addr.GetNetwork());
272 /** vote for a local address */
273 bool SeenLocal(const CService& addr)
276 LOCK(cs_mapLocalHost);
277 if (mapLocalHost.count(addr) == 0)
279 mapLocalHost[addr].nScore++;
287 /** check whether a given address is potentially local */
288 bool IsLocal(const CService& addr)
290 LOCK(cs_mapLocalHost);
291 return mapLocalHost.count(addr) > 0;
294 /** check whether a given address is in a network we can probably connect to */
295 bool IsReachable(const CNetAddr& addr)
297 LOCK(cs_mapLocalHost);
298 enum Network net = addr.GetNetwork();
299 return vfReachable[net] && !vfLimited[net];
302 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
305 if (!ConnectSocket(addrConnect, hSocket))
306 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
308 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
311 while (RecvLine(hSocket, strLine))
313 if (strLine.empty()) // HTTP response is separated from headers by blank line
317 if (!RecvLine(hSocket, strLine))
319 closesocket(hSocket);
322 if (pszKeyword == NULL)
324 if (strLine.find(pszKeyword) != string::npos)
326 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
330 closesocket(hSocket);
331 if (strLine.find("<") != string::npos)
332 strLine = strLine.substr(0, strLine.find("<"));
333 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
334 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
335 strLine.resize(strLine.size()-1);
336 CService addr(strLine,0,true);
337 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
338 if (!addr.IsValid() || !addr.IsRoutable())
344 closesocket(hSocket);
345 return error("GetMyExternalIP() : connection closed");
348 // We now get our external IP from the IRC server first and only use this as a backup
349 bool GetMyExternalIP(CNetAddr& ipRet)
351 CService addrConnect;
353 const char* pszKeyword;
355 for (int nLookup = 0; nLookup <= 1; nLookup++)
356 for (int nHost = 1; nHost <= 2; nHost++)
358 // We should be phasing out our use of sites like these. If we need
359 // replacements, we should ask for volunteers to put this simple
360 // php file on their web server that prints the client IP:
361 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
364 addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
368 CService addrIP("checkip.dyndns.org", 80, true);
369 if (addrIP.IsValid())
370 addrConnect = addrIP;
373 pszGet = "GET / HTTP/1.1\r\n"
374 "Host: checkip.dyndns.org\r\n"
375 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
376 "Connection: close\r\n"
379 pszKeyword = "Address:";
383 addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
387 CService addrIP("www.showmyip.com", 80, true);
388 if (addrIP.IsValid())
389 addrConnect = addrIP;
392 pszGet = "GET /simple/ HTTP/1.1\r\n"
393 "Host: www.showmyip.com\r\n"
394 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
395 "Connection: close\r\n"
398 pszKeyword = NULL; // Returns just IP address
401 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
408 void ThreadGetMyExternalIP(void* parg)
410 // Make this thread recognisable as the external IP detection thread
411 RenameThread("bitcoin-ext-ip");
413 CNetAddr addrLocalHost;
414 if (GetMyExternalIP(addrLocalHost))
416 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
417 AddLocal(addrLocalHost, LOCAL_HTTP);
425 void AddressCurrentlyConnected(const CService& addr)
427 addrman.Connected(addr);
436 CNode* FindNode(const CNetAddr& ip)
440 BOOST_FOREACH(CNode* pnode, vNodes)
441 if ((CNetAddr)pnode->addr == ip)
447 CNode* FindNode(std::string addrName)
450 BOOST_FOREACH(CNode* pnode, vNodes)
451 if (pnode->addrName == addrName)
456 CNode* FindNode(const CService& addr)
460 BOOST_FOREACH(CNode* pnode, vNodes)
461 if ((CService)pnode->addr == addr)
467 CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout)
469 if (pszDest == NULL) {
470 if (IsLocal(addrConnect))
473 // Look for an existing connection
474 CNode* pnode = FindNode((CService)addrConnect);
478 pnode->AddRef(nTimeout);
487 printf("trying connection %s lastseen=%.1fhrs\n",
488 pszDest ? pszDest : addrConnect.ToString().c_str(),
489 pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
493 if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
495 addrman.Attempt(addrConnect);
498 printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
500 // Set to non-blocking
503 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
504 printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
506 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
507 printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
511 CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
513 pnode->AddRef(nTimeout);
519 vNodes.push_back(pnode);
522 pnode->nTimeConnected = GetTime();
531 void CNode::CloseSocketDisconnect()
534 if (hSocket != INVALID_SOCKET)
536 printf("disconnecting node %s\n", addrName.c_str());
537 closesocket(hSocket);
538 hSocket = INVALID_SOCKET;
543 void CNode::Cleanup()
548 void CNode::PushVersion()
550 /// when NTP implemented, change to just nTime = GetAdjustedTime()
551 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
552 CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
553 CAddress addrMe = GetLocalAddress(&addr);
554 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
555 printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
556 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
557 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
564 std::map<CNetAddr, int64> CNode::setBanned;
565 CCriticalSection CNode::cs_setBanned;
567 void CNode::ClearBanned()
572 bool CNode::IsBanned(CNetAddr ip)
574 bool fResult = false;
577 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
578 if (i != setBanned.end())
580 int64 t = (*i).second;
588 bool CNode::Misbehaving(int howmuch)
592 printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
596 nMisbehavior += howmuch;
597 if (nMisbehavior >= GetArg("-banscore", 100))
599 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
600 printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
603 if (setBanned[addr] < banTime)
604 setBanned[addr] = banTime;
606 CloseSocketDisconnect();
609 printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
614 #define X(name) stats.name = name
615 void CNode::copyStats(CNodeStats &stats)
640 void ThreadSocketHandler(void* parg)
642 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
644 // Make this thread recognisable as the networking thread
645 RenameThread("bitcoin-net");
649 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
650 ThreadSocketHandler2(parg);
651 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
653 catch (std::exception& e) {
654 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
655 PrintException(&e, "ThreadSocketHandler()");
657 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
658 throw; // support pthread_cancel()
660 printf("ThreadSocketHandler exited\n");
663 void ThreadSocketHandler2(void* parg)
665 printf("ThreadSocketHandler started\n");
666 list<CNode*> vNodesDisconnected;
667 unsigned int nPrevNodeCount = 0;
676 // Disconnect unused nodes
677 vector<CNode*> vNodesCopy = vNodes;
678 BOOST_FOREACH(CNode* pnode, vNodesCopy)
680 if (pnode->fDisconnect ||
681 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
683 // remove from vNodes
684 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
686 // release outbound grant (if any)
687 pnode->grantOutbound.Release();
689 // close socket and cleanup
690 pnode->CloseSocketDisconnect();
693 // hold in disconnected pool until all refs are released
694 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
695 if (pnode->fNetworkNode || pnode->fInbound)
697 vNodesDisconnected.push_back(pnode);
701 // Delete disconnected nodes
702 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
703 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
705 // wait until threads are done using it
706 if (pnode->GetRefCount() <= 0)
708 bool fDelete = false;
710 TRY_LOCK(pnode->cs_vSend, lockSend);
713 TRY_LOCK(pnode->cs_vRecv, lockRecv);
716 TRY_LOCK(pnode->cs_mapRequests, lockReq);
719 TRY_LOCK(pnode->cs_inventory, lockInv);
728 vNodesDisconnected.remove(pnode);
734 if (vNodes.size() != nPrevNodeCount)
736 nPrevNodeCount = vNodes.size();
737 uiInterface.NotifyNumConnectionsChanged(vNodes.size());
742 // Find which sockets have data to receive
744 struct timeval timeout;
746 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
753 FD_ZERO(&fdsetError);
754 SOCKET hSocketMax = 0;
756 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
757 FD_SET(hListenSocket, &fdsetRecv);
758 hSocketMax = max(hSocketMax, hListenSocket);
762 BOOST_FOREACH(CNode* pnode, vNodes)
764 if (pnode->hSocket == INVALID_SOCKET)
766 FD_SET(pnode->hSocket, &fdsetRecv);
767 FD_SET(pnode->hSocket, &fdsetError);
768 hSocketMax = max(hSocketMax, pnode->hSocket);
770 TRY_LOCK(pnode->cs_vSend, lockSend);
771 if (lockSend && !pnode->vSend.empty())
772 FD_SET(pnode->hSocket, &fdsetSend);
777 vnThreadsRunning[THREAD_SOCKETHANDLER]--;
778 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
779 vnThreadsRunning[THREAD_SOCKETHANDLER]++;
782 if (nSelect == SOCKET_ERROR)
784 int nErr = WSAGetLastError();
785 if (hSocketMax != INVALID_SOCKET)
787 printf("socket select error %d\n", nErr);
788 for (unsigned int i = 0; i <= hSocketMax; i++)
789 FD_SET(i, &fdsetRecv);
792 FD_ZERO(&fdsetError);
793 Sleep(timeout.tv_usec/1000);
798 // Accept new connections
800 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
801 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
804 struct sockaddr_storage sockaddr;
806 struct sockaddr sockaddr;
808 socklen_t len = sizeof(sockaddr);
809 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
813 if (hSocket != INVALID_SOCKET)
814 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
815 printf("Warning: Unknown socket family\n");
819 BOOST_FOREACH(CNode* pnode, vNodes)
824 if (hSocket == INVALID_SOCKET)
826 if (WSAGetLastError() != WSAEWOULDBLOCK)
827 printf("socket error accept failed: %d\n", WSAGetLastError());
829 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
832 LOCK(cs_setservAddNodeAddresses);
833 if (!setservAddNodeAddresses.count(addr))
834 closesocket(hSocket);
837 else if (CNode::IsBanned(addr))
839 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
840 closesocket(hSocket);
844 printf("accepted connection %s\n", addr.ToString().c_str());
845 CNode* pnode = new CNode(hSocket, addr, "", true);
849 vNodes.push_back(pnode);
856 // Service each socket
858 vector<CNode*> vNodesCopy;
862 BOOST_FOREACH(CNode* pnode, vNodesCopy)
865 BOOST_FOREACH(CNode* pnode, vNodesCopy)
873 if (pnode->hSocket == INVALID_SOCKET)
875 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
877 TRY_LOCK(pnode->cs_vRecv, lockRecv);
880 CDataStream& vRecv = pnode->vRecv;
881 unsigned int nPos = vRecv.size();
883 if (nPos > ReceiveBufferSize()) {
884 if (!pnode->fDisconnect)
885 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
886 pnode->CloseSocketDisconnect();
889 // typical socket buffer is 8K-64K
890 char pchBuf[0x10000];
891 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
894 vRecv.resize(nPos + nBytes);
895 memcpy(&vRecv[nPos], pchBuf, nBytes);
896 pnode->nLastRecv = GetTime();
898 else if (nBytes == 0)
900 // socket closed gracefully
901 if (!pnode->fDisconnect)
902 printf("socket closed\n");
903 pnode->CloseSocketDisconnect();
908 int nErr = WSAGetLastError();
909 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
911 if (!pnode->fDisconnect)
912 printf("socket recv error %d\n", nErr);
913 pnode->CloseSocketDisconnect();
923 if (pnode->hSocket == INVALID_SOCKET)
925 if (FD_ISSET(pnode->hSocket, &fdsetSend))
927 TRY_LOCK(pnode->cs_vSend, lockSend);
930 CDataStream& vSend = pnode->vSend;
933 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
936 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
937 pnode->nLastSend = GetTime();
942 int nErr = WSAGetLastError();
943 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
945 printf("socket send error %d\n", nErr);
946 pnode->CloseSocketDisconnect();
954 // Inactivity checking
956 if (pnode->vSend.empty())
957 pnode->nLastSendEmpty = GetTime();
958 if (GetTime() - pnode->nTimeConnected > 60)
960 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
962 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
963 pnode->fDisconnect = true;
965 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
967 printf("socket not sending\n");
968 pnode->fDisconnect = true;
970 else if (GetTime() - pnode->nLastRecv > 90*60)
972 printf("socket inactivity timeout\n");
973 pnode->fDisconnect = true;
979 BOOST_FOREACH(CNode* pnode, vNodesCopy)
996 void ThreadMapPort(void* parg)
998 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1000 // Make this thread recognisable as the UPnP thread
1001 RenameThread("bitcoin-UPnP");
1005 vnThreadsRunning[THREAD_UPNP]++;
1006 ThreadMapPort2(parg);
1007 vnThreadsRunning[THREAD_UPNP]--;
1009 catch (std::exception& e) {
1010 vnThreadsRunning[THREAD_UPNP]--;
1011 PrintException(&e, "ThreadMapPort()");
1013 vnThreadsRunning[THREAD_UPNP]--;
1014 PrintException(NULL, "ThreadMapPort()");
1016 printf("ThreadMapPort exited\n");
1019 void ThreadMapPort2(void* parg)
1021 printf("ThreadMapPort started\n");
1024 sprintf(port, "%d", GetListenPort());
1026 const char * multicastif = 0;
1027 const char * minissdpdpath = 0;
1028 struct UPNPDev * devlist = 0;
1031 #ifndef UPNPDISCOVER_SUCCESS
1033 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1037 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1040 struct UPNPUrls urls;
1041 struct IGDdatas data;
1044 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1048 char externalIPAddress[40];
1049 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1050 if(r != UPNPCOMMAND_SUCCESS)
1051 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1054 if(externalIPAddress[0])
1056 printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1057 AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1060 printf("UPnP: GetExternalIPAddress failed.\n");
1064 string strDesc = "Bitcoin " + FormatFullVersion();
1065 #ifndef UPNPDISCOVER_SUCCESS
1067 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1068 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1071 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1072 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1075 if(r!=UPNPCOMMAND_SUCCESS)
1076 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1077 port, port, lanaddr, r, strupnperror(r));
1079 printf("UPnP Port Mapping successful.\n");
1082 if (fShutdown || !fUseUPnP)
1084 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1085 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1086 freeUPNPDevlist(devlist); devlist = 0;
1087 FreeUPNPUrls(&urls);
1090 if (i % 600 == 0) // Refresh every 20 minutes
1092 #ifndef UPNPDISCOVER_SUCCESS
1094 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1095 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1098 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1099 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1102 if(r!=UPNPCOMMAND_SUCCESS)
1103 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1104 port, port, lanaddr, r, strupnperror(r));
1106 printf("UPnP Port Mapping successful.\n");;
1112 printf("No valid UPnP IGDs found\n");
1113 freeUPNPDevlist(devlist); devlist = 0;
1115 FreeUPNPUrls(&urls);
1117 if (fShutdown || !fUseUPnP)
1126 if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
1128 if (!CreateThread(ThreadMapPort, NULL))
1129 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1135 // Intentionally left blank.
1148 // Each pair gives a source name and a seed name.
1149 // The first name is used as information source for addrman.
1150 // The second name should resolve to a list of seed addresses.
1151 static const char *strDNSSeed[][2] = {
1152 {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
1153 {"bluematt.me", "dnsseed.bluematt.me"},
1154 {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
1155 {"xf2.org", "bitseed.xf2.org"},
1158 void ThreadDNSAddressSeed(void* parg)
1160 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1162 // Make this thread recognisable as the DNS seeding thread
1163 RenameThread("bitcoin-dnsseed");
1167 vnThreadsRunning[THREAD_DNSSEED]++;
1168 ThreadDNSAddressSeed2(parg);
1169 vnThreadsRunning[THREAD_DNSSEED]--;
1171 catch (std::exception& e) {
1172 vnThreadsRunning[THREAD_DNSSEED]--;
1173 PrintException(&e, "ThreadDNSAddressSeed()");
1175 vnThreadsRunning[THREAD_DNSSEED]--;
1176 throw; // support pthread_cancel()
1178 printf("ThreadDNSAddressSeed exited\n");
1181 void ThreadDNSAddressSeed2(void* parg)
1183 printf("ThreadDNSAddressSeed started\n");
1188 printf("Loading addresses from DNS seeds (could take a while)\n");
1190 for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1191 if (GetNameProxy()) {
1192 AddOneShot(strDNSSeed[seed_idx][1]);
1194 vector<CNetAddr> vaddr;
1195 vector<CAddress> vAdd;
1196 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1198 BOOST_FOREACH(CNetAddr& ip, vaddr)
1200 int nOneDay = 24*3600;
1201 CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1202 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1203 vAdd.push_back(addr);
1207 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1212 printf("%d addresses found from DNS seeds\n", found);
1226 unsigned int pnSeed[] =
1228 0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1229 0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1230 0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1231 0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1232 0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1233 0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1234 0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1235 0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1236 0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1237 0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1238 0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1239 0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1240 0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1241 0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1242 0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1243 0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1244 0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1245 0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1246 0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1247 0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1248 0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1249 0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1250 0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1251 0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1252 0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1253 0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1254 0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1255 0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1256 0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1257 0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1258 0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1259 0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1260 0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1261 0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1262 0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1263 0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1264 0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1265 0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1266 0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1267 0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1268 0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1269 0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1270 0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1271 0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1272 0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1273 0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1274 0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1275 0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1276 0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1277 0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1278 0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1279 0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1280 0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1281 0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1282 0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1283 0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1284 0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1285 0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1286 0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1287 0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1288 0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1289 0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1290 0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1291 0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1292 0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1293 0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1294 0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1295 0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1296 0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1297 0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1298 0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1299 0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1300 0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1301 0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1302 0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1303 0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1304 0xc461d84a, 0xb2dbe247,
1307 void DumpAddresses()
1309 int64 nStart = GetTimeMillis();
1314 printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
1315 addrman.size(), GetTimeMillis() - nStart);
1318 void ThreadDumpAddress2(void* parg)
1320 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1324 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1326 vnThreadsRunning[THREAD_DUMPADDRESS]++;
1328 vnThreadsRunning[THREAD_DUMPADDRESS]--;
1331 void ThreadDumpAddress(void* parg)
1333 IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1335 // Make this thread recognisable as the address dumping thread
1336 RenameThread("bitcoin-adrdump");
1340 ThreadDumpAddress2(parg);
1342 catch (std::exception& e) {
1343 PrintException(&e, "ThreadDumpAddress()");
1345 printf("ThreadDumpAddress exited\n");
1348 void ThreadOpenConnections(void* parg)
1350 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1352 // Make this thread recognisable as the connection opening thread
1353 RenameThread("bitcoin-opencon");
1357 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1358 ThreadOpenConnections2(parg);
1359 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1361 catch (std::exception& e) {
1362 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1363 PrintException(&e, "ThreadOpenConnections()");
1365 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1366 PrintException(NULL, "ThreadOpenConnections()");
1368 printf("ThreadOpenConnections exited\n");
1371 void static ProcessOneShot()
1376 if (vOneShots.empty())
1378 strDest = vOneShots.front();
1379 vOneShots.pop_front();
1382 CSemaphoreGrant grant(*semOutbound, true);
1384 if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1385 AddOneShot(strDest);
1389 void ThreadOpenConnections2(void* parg)
1391 printf("ThreadOpenConnections started\n");
1393 // Connect to specific addresses
1394 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1396 for (int64 nLoop = 0;; nLoop++)
1399 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1402 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1403 for (int i = 0; i < 10 && i < nLoop; i++)
1414 // Initiate network connections
1415 int64 nStart = GetTime();
1420 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1422 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1427 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1428 CSemaphoreGrant grant(*semOutbound);
1429 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1433 // Add seed nodes if IRC isn't working
1434 if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1436 std::vector<CAddress> vAdd;
1437 for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1439 // It'll only connect to one or two seed nodes because once it connects,
1440 // it'll get a pile of addresses with newer timestamps.
1441 // Seed nodes are given a random 'last seen time' of between one and two
1443 const int64 nOneWeek = 7*24*60*60;
1445 memcpy(&ip, &pnSeed[i], sizeof(ip));
1446 CAddress addr(CService(ip, GetDefaultPort()));
1447 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1448 vAdd.push_back(addr);
1450 addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1454 // Choose an address to connect to based on most recently seen
1456 CAddress addrConnect;
1458 // Only connect out to one peer per network group (/16 for IPv4).
1459 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1461 set<vector<unsigned char> > setConnected;
1464 BOOST_FOREACH(CNode* pnode, vNodes) {
1465 if (!pnode->fInbound) {
1466 setConnected.insert(pnode->addr.GetGroup());
1472 int64 nANow = GetAdjustedTime();
1477 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1478 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1480 // if we selected an invalid address, restart
1481 if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1484 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1485 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1486 // already-connected network ranges, ...) before trying new addrman addresses.
1491 if (IsLimited(addr))
1494 // only consider very recently tried nodes after 30 failed attempts
1495 if (nANow - addr.nLastTry < 600 && nTries < 30)
1498 // do not allow non-default ports, unless after 50 invalid addresses selected already
1499 if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1506 if (addrConnect.IsValid())
1507 OpenNetworkConnection(addrConnect, &grant);
1511 void ThreadOpenAddedConnections(void* parg)
1513 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1515 // Make this thread recognisable as the connection opening thread
1516 RenameThread("bitcoin-opencon");
1520 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1521 ThreadOpenAddedConnections2(parg);
1522 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1524 catch (std::exception& e) {
1525 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1526 PrintException(&e, "ThreadOpenAddedConnections()");
1528 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1529 PrintException(NULL, "ThreadOpenAddedConnections()");
1531 printf("ThreadOpenAddedConnections exited\n");
1534 void ThreadOpenAddedConnections2(void* parg)
1536 printf("ThreadOpenAddedConnections started\n");
1538 if (mapArgs.count("-addnode") == 0)
1541 if (GetNameProxy()) {
1543 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
1545 CSemaphoreGrant grant(*semOutbound);
1546 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1549 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1550 Sleep(120000); // Retry every 2 minutes
1551 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1556 vector<vector<CService> > vservAddressesToAdd(0);
1557 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1559 vector<CService> vservNode(0);
1560 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1562 vservAddressesToAdd.push_back(vservNode);
1564 LOCK(cs_setservAddNodeAddresses);
1565 BOOST_FOREACH(CService& serv, vservNode)
1566 setservAddNodeAddresses.insert(serv);
1572 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1573 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1574 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1577 BOOST_FOREACH(CNode* pnode, vNodes)
1578 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1579 BOOST_FOREACH(CService& addrNode, *(it))
1580 if (pnode->addr == addrNode)
1582 it = vservConnectAddresses.erase(it);
1587 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1589 CSemaphoreGrant grant(*semOutbound);
1590 OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
1597 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1598 Sleep(120000); // Retry every 2 minutes
1599 vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1605 // if successful, this moves the passed grant to the constructed node
1606 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1609 // Initiate outbound network connection
1614 if (IsLocal(addrConnect) ||
1615 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1616 FindNode(addrConnect.ToStringIPPort().c_str()))
1618 if (strDest && FindNode(strDest))
1621 vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1622 CNode* pnode = ConnectNode(addrConnect, strDest);
1623 vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1629 grantOutbound->MoveTo(pnode->grantOutbound);
1630 pnode->fNetworkNode = true;
1632 pnode->fOneShot = true;
1644 void ThreadMessageHandler(void* parg)
1646 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1648 // Make this thread recognisable as the message handling thread
1649 RenameThread("bitcoin-msghand");
1653 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1654 ThreadMessageHandler2(parg);
1655 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1657 catch (std::exception& e) {
1658 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1659 PrintException(&e, "ThreadMessageHandler()");
1661 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1662 PrintException(NULL, "ThreadMessageHandler()");
1664 printf("ThreadMessageHandler exited\n");
1667 void ThreadMessageHandler2(void* parg)
1669 printf("ThreadMessageHandler started\n");
1670 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1673 vector<CNode*> vNodesCopy;
1676 vNodesCopy = vNodes;
1677 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1681 // Poll the connected nodes for messages
1682 CNode* pnodeTrickle = NULL;
1683 if (!vNodesCopy.empty())
1684 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1685 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1689 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1691 ProcessMessages(pnode);
1698 TRY_LOCK(pnode->cs_vSend, lockSend);
1700 SendMessages(pnode, pnode == pnodeTrickle);
1708 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1712 // Wait and allow messages to bunch up.
1713 // Reduce vnThreadsRunning so StopNode has permission to exit while
1714 // we're sleeping, but we must always check fShutdown after doing this.
1715 vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1717 if (fRequestShutdown)
1719 vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1730 bool BindListenPort(const CService &addrBind, string& strError)
1736 // Initialize Windows Sockets
1738 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1739 if (ret != NO_ERROR)
1741 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1742 printf("%s\n", strError.c_str());
1747 // Create socket for listening for incoming connections
1749 struct sockaddr_storage sockaddr;
1751 struct sockaddr sockaddr;
1753 socklen_t len = sizeof(sockaddr);
1754 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1756 strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1757 printf("%s\n", strError.c_str());
1761 SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1762 if (hListenSocket == INVALID_SOCKET)
1764 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1765 printf("%s\n", strError.c_str());
1770 // Different way of disabling SIGPIPE on BSD
1771 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1775 // Allow binding if the port is still in TIME_WAIT state after
1776 // the program was closed and restarted. Not an issue on windows.
1777 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1782 // Set to non-blocking, incoming connections will also inherit this
1783 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1785 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1788 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1789 printf("%s\n", strError.c_str());
1794 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1795 // and enable it by default or not. Try to enable it, if possible.
1796 if (addrBind.IsIPv6()) {
1798 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1801 int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1802 int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1803 // this call is allowed to fail
1804 setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1809 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1811 int nErr = WSAGetLastError();
1812 if (nErr == WSAEADDRINUSE)
1813 strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
1815 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1816 printf("%s\n", strError.c_str());
1819 printf("Bound to %s\n", addrBind.ToString().c_str());
1821 // Listen for incoming connections
1822 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1824 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1825 printf("%s\n", strError.c_str());
1829 vhListenSocket.push_back(hListenSocket);
1831 if (addrBind.IsRoutable() && fDiscover)
1832 AddLocal(addrBind, LOCAL_BIND);
1837 void static Discover()
1843 // Get local host IP
1844 char pszHostName[1000] = "";
1845 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1847 vector<CNetAddr> vaddr;
1848 if (LookupHost(pszHostName, vaddr))
1850 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1852 AddLocal(addr, LOCAL_IF);
1857 // Get local host ip
1858 struct ifaddrs* myaddrs;
1859 if (getifaddrs(&myaddrs) == 0)
1861 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1863 if (ifa->ifa_addr == NULL) continue;
1864 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1865 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1866 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1867 if (ifa->ifa_addr->sa_family == AF_INET)
1869 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1870 CNetAddr addr(s4->sin_addr);
1871 if (AddLocal(addr, LOCAL_IF))
1872 printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1875 else if (ifa->ifa_addr->sa_family == AF_INET6)
1877 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1878 CNetAddr addr(s6->sin6_addr);
1879 if (AddLocal(addr, LOCAL_IF))
1880 printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1884 freeifaddrs(myaddrs);
1888 // Don't use external IPv4 discovery, when -onlynet="IPv6"
1889 if (!IsLimited(NET_IPV4))
1890 CreateThread(ThreadGetMyExternalIP, NULL);
1893 void StartNode(void* parg)
1895 // Make this thread recognisable as the startup thread
1896 RenameThread("bitcoin-start");
1898 if (semOutbound == NULL) {
1899 // initialize semaphore
1900 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
1901 semOutbound = new CSemaphore(nMaxOutbound);
1904 if (pnodeLocalHost == NULL)
1905 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1913 if (!GetBoolArg("-dnsseed", true))
1914 printf("DNS seeding disabled\n");
1916 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1917 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1919 // Map ports with UPnP
1923 // Get addresses from IRC and advertise ours
1924 if (!CreateThread(ThreadIRCSeed, NULL))
1925 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1927 // Send and receive from sockets, accept connections
1928 if (!CreateThread(ThreadSocketHandler, NULL))
1929 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1931 // Initiate outbound connections from -addnode
1932 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1933 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1935 // Initiate outbound connections
1936 if (!CreateThread(ThreadOpenConnections, NULL))
1937 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1940 if (!CreateThread(ThreadMessageHandler, NULL))
1941 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1943 // Dump network addresses
1944 if (!CreateThread(ThreadDumpAddress, NULL))
1945 printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1947 // Generate coins in the background
1948 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1953 printf("StopNode()\n");
1955 nTransactionsUpdated++;
1956 int64 nStart = GetTime();
1958 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1959 semOutbound->post();
1962 int nThreadsRunning = 0;
1963 for (int n = 0; n < THREAD_MAX; n++)
1964 nThreadsRunning += vnThreadsRunning[n];
1965 if (nThreadsRunning == 0)
1967 if (GetTime() - nStart > 20)
1971 if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1972 if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1973 if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1974 if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1975 if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1976 if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1978 if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1980 if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1981 if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1982 if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1983 while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
1999 BOOST_FOREACH(CNode* pnode, vNodes)
2000 if (pnode->hSocket != INVALID_SOCKET)
2001 closesocket(pnode->hSocket);
2002 BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
2003 if (hListenSocket != INVALID_SOCKET)
2004 if (closesocket(hListenSocket) == SOCKET_ERROR)
2005 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
2008 // Shutdown Windows Sockets
2013 instance_of_cnetcleanup;