1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
18 #include <miniupnpc/miniwget.h>
19 #include <miniupnpc/miniupnpc.h>
20 #include <miniupnpc/upnpcommands.h>
21 #include <miniupnpc/upnperrors.h>
25 using namespace boost;
27 static const int MAX_OUTBOUND_CONNECTIONS = 8;
29 void ThreadMessageHandler2(void* parg);
30 void ThreadSocketHandler2(void* parg);
31 void ThreadOpenConnections2(void* parg);
32 void ThreadOpenAddedConnections2(void* parg);
34 void ThreadMapPort2(void* parg);
36 void ThreadDNSAddressSeed2(void* parg);
37 bool OpenNetworkConnection(const CAddress& addrConnect);
44 // Global state variables
47 bool fAllowDNS = false;
48 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
49 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
50 static CNode* pnodeLocalHost = NULL;
51 uint64 nLocalHostNonce = 0;
52 array<int, 10> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
55 vector<CNode*> vNodes;
56 CCriticalSection cs_vNodes;
57 map<vector<unsigned char>, CAddress> mapAddresses;
58 CCriticalSection cs_mapAddresses;
59 map<CInv, CDataStream> mapRelay;
60 deque<pair<int64, CInv> > vRelayExpiration;
61 CCriticalSection cs_mapRelay;
62 map<CInv, int64> mapAlreadyAskedFor;
65 set<CNetAddr> setservAddNodeAddresses;
66 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);
91 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
94 if (!ConnectSocket(addrConnect, hSocket))
95 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
97 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
100 while (RecvLine(hSocket, strLine))
102 if (strLine.empty()) // HTTP response is separated from headers by blank line
106 if (!RecvLine(hSocket, strLine))
108 closesocket(hSocket);
111 if (pszKeyword == NULL)
113 if (strLine.find(pszKeyword) != -1)
115 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
119 closesocket(hSocket);
120 if (strLine.find("<") != -1)
121 strLine = strLine.substr(0, strLine.find("<"));
122 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
123 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
124 strLine.resize(strLine.size()-1);
125 CService addr(strLine,0,true);
126 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
127 if (!addr.IsValid() || !addr.IsRoutable())
133 closesocket(hSocket);
134 return error("GetMyExternalIP() : connection closed");
137 // We now get our external IP from the IRC server first and only use this as a backup
138 bool GetMyExternalIP(CNetAddr& ipRet)
140 CAddress addrConnect;
142 const char* pszKeyword;
147 for (int nLookup = 0; nLookup <= 1; nLookup++)
148 for (int nHost = 1; nHost <= 2; nHost++)
150 // We should be phasing out our use of sites like these. If we need
151 // replacements, we should ask for volunteers to put this simple
152 // php file on their webserver that prints the client IP:
153 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
156 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
160 CService addrIP("checkip.dyndns.org", 80, true);
161 if (addrIP.IsValid())
162 addrConnect = addrIP;
165 pszGet = "GET / HTTP/1.1\r\n"
166 "Host: checkip.dyndns.org\r\n"
167 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
168 "Connection: close\r\n"
171 pszKeyword = "Address:";
175 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
179 CService addrIP("www.showmyip.com", 80, true);
180 if (addrIP.IsValid())
181 addrConnect = addrIP;
184 pszGet = "GET /simple/ HTTP/1.1\r\n"
185 "Host: www.showmyip.com\r\n"
186 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
187 "Connection: close\r\n"
190 pszKeyword = NULL; // Returns just IP address
193 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
200 void ThreadGetMyExternalIP(void* parg)
202 // Wait for IRC to get it first
203 if (!GetBoolArg("-noirc"))
205 for (int i = 0; i < 2 * 60; i++)
208 if (fGotExternalIP || fShutdown)
213 // Fallback in case IRC fails to get it
214 if (GetMyExternalIP(addrLocalHost))
216 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
217 if (addrLocalHost.IsRoutable())
219 // If we already connected to a few before we had our IP, go back and addr them.
220 // setAddrKnown automatically filters any duplicate sends.
221 CAddress addr(addrLocalHost);
222 addr.nTime = GetAdjustedTime();
223 CRITICAL_BLOCK(cs_vNodes)
224 BOOST_FOREACH(CNode* pnode, vNodes)
225 pnode->PushAddress(addr);
234 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
236 if (!addr.IsRoutable())
238 if ((CService)addr == (CService)addrLocalHost)
240 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
241 bool fUpdated = false;
243 CAddress addrFound = addr;
245 CRITICAL_BLOCK(cs_mapAddresses)
247 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
248 if (it == mapAddresses.end())
251 printf("AddAddress(%s)\n", addr.ToString().c_str());
252 mapAddresses.insert(make_pair(addr.GetKey(), addr));
258 addrFound = (*it).second;
259 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
261 // Services have been added
262 addrFound.nServices |= addr.nServices;
265 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
266 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
267 if (addrFound.nTime < addr.nTime - nUpdateInterval)
269 // Periodically update most recently seen time
270 addrFound.nTime = addr.nTime;
275 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
277 // Thread 1: begin db transaction (locks inside-db-mutex)
278 // then AddAddress (locks cs_mapAddresses)
279 // Thread 2: AddAddress (locks cs_mapAddresses)
280 // ... then db operation hangs waiting for inside-db-mutex
284 pAddrDB->WriteAddress(addrFound);
286 CAddrDB().WriteAddress(addrFound);
291 void AddressCurrentlyConnected(const CService& addr)
293 CAddress *paddrFound = NULL;
295 CRITICAL_BLOCK(cs_mapAddresses)
297 // Only if it's been published already
298 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
299 if (it != mapAddresses.end())
300 paddrFound = &(*it).second;
305 int64 nUpdateInterval = 20 * 60;
306 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
308 // Periodically update most recently seen time
309 paddrFound->nTime = GetAdjustedTime();
311 addrdb.WriteAddress(*paddrFound);
320 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
322 // If the dialog might get closed before the reply comes back,
323 // call this in the destructor so it doesn't get called after it's deleted.
324 CRITICAL_BLOCK(cs_vNodes)
326 BOOST_FOREACH(CNode* pnode, vNodes)
328 CRITICAL_BLOCK(pnode->cs_mapRequests)
330 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
332 CRequestTracker& tracker = (*mi).second;
333 if (tracker.fn == fn && tracker.param1 == param1)
334 pnode->mapRequests.erase(mi++);
350 // Subscription methods for the broadcast and subscription system.
351 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
353 // The subscription system uses a meet-in-the-middle strategy.
354 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
355 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
358 bool AnySubscribed(unsigned int nChannel)
360 if (pnodeLocalHost->IsSubscribed(nChannel))
362 CRITICAL_BLOCK(cs_vNodes)
363 BOOST_FOREACH(CNode* pnode, vNodes)
364 if (pnode->IsSubscribed(nChannel))
369 bool CNode::IsSubscribed(unsigned int nChannel)
371 if (nChannel >= vfSubscribe.size())
373 return vfSubscribe[nChannel];
376 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
378 if (nChannel >= vfSubscribe.size())
381 if (!AnySubscribed(nChannel))
384 CRITICAL_BLOCK(cs_vNodes)
385 BOOST_FOREACH(CNode* pnode, vNodes)
387 pnode->PushMessage("subscribe", nChannel, nHops);
390 vfSubscribe[nChannel] = true;
393 void CNode::CancelSubscribe(unsigned int nChannel)
395 if (nChannel >= vfSubscribe.size())
398 // Prevent from relaying cancel if wasn't subscribed
399 if (!vfSubscribe[nChannel])
401 vfSubscribe[nChannel] = false;
403 if (!AnySubscribed(nChannel))
405 // Relay subscription cancel
406 CRITICAL_BLOCK(cs_vNodes)
407 BOOST_FOREACH(CNode* pnode, vNodes)
409 pnode->PushMessage("sub-cancel", nChannel);
421 CNode* FindNode(const CNetAddr& ip)
423 CRITICAL_BLOCK(cs_vNodes)
425 BOOST_FOREACH(CNode* pnode, vNodes)
426 if ((CNetAddr)pnode->addr == ip)
432 CNode* FindNode(const CService& addr)
434 CRITICAL_BLOCK(cs_vNodes)
436 BOOST_FOREACH(CNode* pnode, vNodes)
437 if ((CService)pnode->addr == addr)
443 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
445 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
448 // Look for an existing connection
449 CNode* pnode = FindNode((CService)addrConnect);
453 pnode->AddRef(nTimeout);
460 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
461 addrConnect.ToString().c_str(),
462 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
463 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
465 CRITICAL_BLOCK(cs_mapAddresses)
466 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
470 if (ConnectSocket(addrConnect, hSocket))
473 printf("connected %s\n", addrConnect.ToString().c_str());
475 // Set to nonblocking
478 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
479 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
481 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
482 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
486 CNode* pnode = new CNode(hSocket, addrConnect, false);
488 pnode->AddRef(nTimeout);
491 CRITICAL_BLOCK(cs_vNodes)
492 vNodes.push_back(pnode);
494 pnode->nTimeConnected = GetTime();
503 void CNode::CloseSocketDisconnect()
506 if (hSocket != INVALID_SOCKET)
509 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
510 printf("disconnecting node %s\n", addr.ToString().c_str());
511 closesocket(hSocket);
512 hSocket = INVALID_SOCKET;
516 void CNode::Cleanup()
518 // All of a nodes broadcasts and subscriptions are automatically torn down
519 // when it goes down, so a node has to stay up to keep its broadcast going.
521 // Cancel subscriptions
522 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
523 if (vfSubscribe[nChannel])
524 CancelSubscribe(nChannel);
528 void CNode::PushVersion()
530 /// when NTP implemented, change to just nTime = GetAdjustedTime()
531 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
532 CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
533 CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
534 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
535 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
536 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
543 std::map<CNetAddr, int64> CNode::setBanned;
544 CCriticalSection CNode::cs_setBanned;
546 void CNode::ClearBanned()
551 bool CNode::IsBanned(CNetAddr ip)
553 bool fResult = false;
554 CRITICAL_BLOCK(cs_setBanned)
556 std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
557 if (i != setBanned.end())
559 int64 t = (*i).second;
567 bool CNode::Misbehaving(int howmuch)
571 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
575 nMisbehavior += howmuch;
576 if (nMisbehavior >= GetArg("-banscore", 100))
578 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
579 CRITICAL_BLOCK(cs_setBanned)
580 if (setBanned[addr] < banTime)
581 setBanned[addr] = banTime;
582 CloseSocketDisconnect();
583 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
600 void ThreadSocketHandler(void* parg)
602 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
605 vnThreadsRunning[0]++;
606 ThreadSocketHandler2(parg);
607 vnThreadsRunning[0]--;
609 catch (std::exception& e) {
610 vnThreadsRunning[0]--;
611 PrintException(&e, "ThreadSocketHandler()");
613 vnThreadsRunning[0]--;
614 throw; // support pthread_cancel()
616 printf("ThreadSocketHandler exiting\n");
619 void ThreadSocketHandler2(void* parg)
621 printf("ThreadSocketHandler started\n");
622 list<CNode*> vNodesDisconnected;
623 int nPrevNodeCount = 0;
630 CRITICAL_BLOCK(cs_vNodes)
632 // Disconnect unused nodes
633 vector<CNode*> vNodesCopy = vNodes;
634 BOOST_FOREACH(CNode* pnode, vNodesCopy)
636 if (pnode->fDisconnect ||
637 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
639 // remove from vNodes
640 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
642 // close socket and cleanup
643 pnode->CloseSocketDisconnect();
646 // hold in disconnected pool until all refs are released
647 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
648 if (pnode->fNetworkNode || pnode->fInbound)
650 vNodesDisconnected.push_back(pnode);
654 // Delete disconnected nodes
655 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
656 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
658 // wait until threads are done using it
659 if (pnode->GetRefCount() <= 0)
661 bool fDelete = false;
662 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
663 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
664 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
665 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
669 vNodesDisconnected.remove(pnode);
675 if (vNodes.size() != nPrevNodeCount)
677 nPrevNodeCount = vNodes.size();
683 // Find which sockets have data to receive
685 struct timeval timeout;
687 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
694 FD_ZERO(&fdsetError);
695 SOCKET hSocketMax = 0;
697 if(hListenSocket != INVALID_SOCKET)
698 FD_SET(hListenSocket, &fdsetRecv);
699 hSocketMax = max(hSocketMax, hListenSocket);
700 CRITICAL_BLOCK(cs_vNodes)
702 BOOST_FOREACH(CNode* pnode, vNodes)
704 if (pnode->hSocket == INVALID_SOCKET)
706 FD_SET(pnode->hSocket, &fdsetRecv);
707 FD_SET(pnode->hSocket, &fdsetError);
708 hSocketMax = max(hSocketMax, pnode->hSocket);
709 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
710 if (!pnode->vSend.empty())
711 FD_SET(pnode->hSocket, &fdsetSend);
715 vnThreadsRunning[0]--;
716 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
717 vnThreadsRunning[0]++;
720 if (nSelect == SOCKET_ERROR)
722 int nErr = WSAGetLastError();
725 printf("socket select error %d\n", nErr);
726 for (int i = 0; i <= hSocketMax; i++)
727 FD_SET(i, &fdsetRecv);
730 FD_ZERO(&fdsetError);
731 Sleep(timeout.tv_usec/1000);
736 // Accept new connections
738 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
740 struct sockaddr_in sockaddr;
741 socklen_t len = sizeof(sockaddr);
742 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
743 CAddress addr(sockaddr);
746 CRITICAL_BLOCK(cs_vNodes)
747 BOOST_FOREACH(CNode* pnode, vNodes)
750 if (hSocket == INVALID_SOCKET)
752 if (WSAGetLastError() != WSAEWOULDBLOCK)
753 printf("socket error accept failed: %d\n", WSAGetLastError());
755 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
757 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
758 if (!setservAddNodeAddresses.count(addr))
759 closesocket(hSocket);
761 else if (CNode::IsBanned(addr))
763 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
764 closesocket(hSocket);
768 printf("accepted connection %s\n", addr.ToString().c_str());
769 CNode* pnode = new CNode(hSocket, addr, true);
771 CRITICAL_BLOCK(cs_vNodes)
772 vNodes.push_back(pnode);
778 // Service each socket
780 vector<CNode*> vNodesCopy;
781 CRITICAL_BLOCK(cs_vNodes)
784 BOOST_FOREACH(CNode* pnode, vNodesCopy)
787 BOOST_FOREACH(CNode* pnode, vNodesCopy)
795 if (pnode->hSocket == INVALID_SOCKET)
797 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
799 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
801 CDataStream& vRecv = pnode->vRecv;
802 unsigned int nPos = vRecv.size();
804 if (nPos > ReceiveBufferSize()) {
805 if (!pnode->fDisconnect)
806 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
807 pnode->CloseSocketDisconnect();
810 // typical socket buffer is 8K-64K
811 char pchBuf[0x10000];
812 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
815 vRecv.resize(nPos + nBytes);
816 memcpy(&vRecv[nPos], pchBuf, nBytes);
817 pnode->nLastRecv = GetTime();
819 else if (nBytes == 0)
821 // socket closed gracefully
822 if (!pnode->fDisconnect)
823 printf("socket closed\n");
824 pnode->CloseSocketDisconnect();
829 int nErr = WSAGetLastError();
830 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
832 if (!pnode->fDisconnect)
833 printf("socket recv error %d\n", nErr);
834 pnode->CloseSocketDisconnect();
844 if (pnode->hSocket == INVALID_SOCKET)
846 if (FD_ISSET(pnode->hSocket, &fdsetSend))
848 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
850 CDataStream& vSend = pnode->vSend;
853 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
856 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
857 pnode->nLastSend = GetTime();
862 int nErr = WSAGetLastError();
863 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
865 printf("socket send error %d\n", nErr);
866 pnode->CloseSocketDisconnect();
869 if (vSend.size() > SendBufferSize()) {
870 if (!pnode->fDisconnect)
871 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
872 pnode->CloseSocketDisconnect();
879 // Inactivity checking
881 if (pnode->vSend.empty())
882 pnode->nLastSendEmpty = GetTime();
883 if (GetTime() - pnode->nTimeConnected > 60)
885 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
887 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
888 pnode->fDisconnect = true;
890 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
892 printf("socket not sending\n");
893 pnode->fDisconnect = true;
895 else if (GetTime() - pnode->nLastRecv > 90*60)
897 printf("socket inactivity timeout\n");
898 pnode->fDisconnect = true;
902 CRITICAL_BLOCK(cs_vNodes)
904 BOOST_FOREACH(CNode* pnode, vNodesCopy)
921 void ThreadMapPort(void* parg)
923 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
926 vnThreadsRunning[5]++;
927 ThreadMapPort2(parg);
928 vnThreadsRunning[5]--;
930 catch (std::exception& e) {
931 vnThreadsRunning[5]--;
932 PrintException(&e, "ThreadMapPort()");
934 vnThreadsRunning[5]--;
935 PrintException(NULL, "ThreadMapPort()");
937 printf("ThreadMapPort exiting\n");
940 void ThreadMapPort2(void* parg)
942 printf("ThreadMapPort started\n");
945 sprintf(port, "%d", GetListenPort());
947 const char * rootdescurl = 0;
948 const char * multicastif = 0;
949 const char * minissdpdpath = 0;
950 struct UPNPDev * devlist = 0;
953 #ifndef UPNPDISCOVER_SUCCESS
955 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
959 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
962 struct UPNPUrls urls;
963 struct IGDdatas data;
966 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
971 string strDesc = "Bitcoin " + FormatFullVersion();
972 #ifndef UPNPDISCOVER_SUCCESS
974 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
975 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
978 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
979 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
982 if(r!=UPNPCOMMAND_SUCCESS)
983 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
984 port, port, lanaddr, r, strupnperror(r));
986 printf("UPnP Port Mapping successful.\n");
988 if (fShutdown || !fUseUPnP)
990 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
991 printf("UPNP_DeletePortMapping() returned : %d\n", r);
992 freeUPNPDevlist(devlist); devlist = 0;
999 printf("No valid UPnP IGDs found\n");
1000 freeUPNPDevlist(devlist); devlist = 0;
1002 FreeUPNPUrls(&urls);
1004 if (fShutdown || !fUseUPnP)
1011 void MapPort(bool fMapPort)
1013 if (fUseUPnP != fMapPort)
1015 fUseUPnP = fMapPort;
1016 WriteSetting("fUseUPnP", fUseUPnP);
1018 if (fUseUPnP && vnThreadsRunning[5] < 1)
1020 if (!CreateThread(ThreadMapPort, NULL))
1021 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1025 void MapPort(bool /* unused fMapPort */)
1027 // Intentionally left blank.
1040 static const char *strDNSSeed[] = {
1042 "dnsseed.bluematt.me",
1043 "seed.bitcoin.sipa.be",
1044 "dnsseed.bitcoin.dashjr.org",
1047 void ThreadDNSAddressSeed(void* parg)
1049 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1052 vnThreadsRunning[6]++;
1053 ThreadDNSAddressSeed2(parg);
1054 vnThreadsRunning[6]--;
1056 catch (std::exception& e) {
1057 vnThreadsRunning[6]--;
1058 PrintException(&e, "ThreadDNSAddressSeed()");
1060 vnThreadsRunning[6]--;
1061 throw; // support pthread_cancel()
1063 printf("ThreadDNSAddressSeed exiting\n");
1066 void ThreadDNSAddressSeed2(void* parg)
1068 printf("ThreadDNSAddressSeed started\n");
1073 printf("Loading addresses from DNS seeds (could take a while)\n");
1075 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1076 vector<CNetAddr> vaddr;
1077 if (LookupHost(strDNSSeed[seed_idx], vaddr))
1081 BOOST_FOREACH (CNetAddr& ip, vaddr)
1083 if (ip.IsRoutable())
1085 CAddress addr(CService(ip, GetDefaultPort()), NODE_NETWORK);
1087 AddAddress(addr, 0, &addrDB);
1091 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1096 printf("%d addresses found from DNS seeds\n", found);
1110 unsigned int pnSeed[] =
1112 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1113 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1114 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1115 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1116 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1117 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1118 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1119 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1120 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1121 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1122 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1123 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1124 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1125 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1126 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1127 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1128 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1129 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1130 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1131 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1132 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1133 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1134 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1135 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1136 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1137 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1138 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1139 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1140 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1141 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1142 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1143 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1144 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1145 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1146 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1147 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1148 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1149 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1150 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1151 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1152 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1153 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1154 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1155 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1156 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1157 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1158 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1159 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1160 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1161 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1162 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1163 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1164 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1165 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1166 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1167 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1168 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1169 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1170 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1171 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1172 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1173 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1174 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1175 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1180 void ThreadOpenConnections(void* parg)
1182 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1185 vnThreadsRunning[1]++;
1186 ThreadOpenConnections2(parg);
1187 vnThreadsRunning[1]--;
1189 catch (std::exception& e) {
1190 vnThreadsRunning[1]--;
1191 PrintException(&e, "ThreadOpenConnections()");
1193 vnThreadsRunning[1]--;
1194 PrintException(NULL, "ThreadOpenConnections()");
1196 printf("ThreadOpenConnections exiting\n");
1199 void ThreadOpenConnections2(void* parg)
1201 printf("ThreadOpenConnections started\n");
1203 // Connect to specific addresses
1204 if (mapArgs.count("-connect"))
1206 for (int64 nLoop = 0;; nLoop++)
1208 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1210 CAddress addr(strAddr, fAllowDNS);
1212 OpenNetworkConnection(addr);
1213 for (int i = 0; i < 10 && i < nLoop; i++)
1223 // Initiate network connections
1224 int64 nStart = GetTime();
1227 // Limit outbound connections
1228 vnThreadsRunning[1]--;
1233 CRITICAL_BLOCK(cs_vNodes)
1234 BOOST_FOREACH(CNode* pnode, vNodes)
1235 if (!pnode->fInbound)
1237 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1238 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1239 if (nOutbound < nMaxOutboundConnections)
1245 vnThreadsRunning[1]++;
1249 bool fAddSeeds = false;
1251 CRITICAL_BLOCK(cs_mapAddresses)
1253 // Add seed nodes if IRC isn't working
1254 bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1255 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1261 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1263 // It'll only connect to one or two seed nodes because once it connects,
1264 // it'll get a pile of addresses with newer timestamps.
1265 // Seed nodes are given a random 'last seen time' of between one and two
1267 const int64 nOneWeek = 7*24*60*60;
1269 memcpy(&ip, &pnSeed[i], sizeof(ip));
1270 CAddress addr(CService(ip, GetDefaultPort()));
1271 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1277 // Choose an address to connect to based on most recently seen
1279 CAddress addrConnect;
1280 int64 nBest = std::numeric_limits<int64>::min();
1282 // Only connect to one address per a.b.?.? range.
1283 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1284 set<vector<unsigned char> > setConnected;
1285 CRITICAL_BLOCK(cs_vNodes)
1286 BOOST_FOREACH(CNode* pnode, vNodes)
1287 setConnected.insert(pnode->addr.GetGroup());
1289 int64 nANow = GetAdjustedTime();
1291 CRITICAL_BLOCK(cs_mapAddresses)
1293 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1295 const CAddress& addr = item.second;
1296 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()))
1298 int64 nSinceLastSeen = nANow - addr.nTime;
1299 int64 nSinceLastTry = nANow - addr.nLastTry;
1301 // Randomize the order in a deterministic way, putting the standard port first
1302 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.GetHash()) % (2 * 60 * 60);
1303 if (addr.GetPort() != GetDefaultPort())
1304 nRandomizer += 2 * 60 * 60;
1306 // Last seen Base retry frequency
1315 // 365 days 93 hours
1316 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1318 // Fast reconnect for one hour after last seen
1319 if (nSinceLastSeen < 60 * 60)
1322 // Limit retry frequency
1323 if (nSinceLastTry < nDelay)
1326 // If we have IRC, we'll be notified when they first come online,
1327 // and again every 24 hours by the refresh broadcast.
1328 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1331 // Only try the old stuff if we don't have enough connections
1332 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1335 // If multiple addresses are ready, prioritize by time since
1336 // last seen and time since last tried.
1337 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1346 if (addrConnect.IsValid())
1347 OpenNetworkConnection(addrConnect);
1351 void ThreadOpenAddedConnections(void* parg)
1353 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1356 vnThreadsRunning[7]++;
1357 ThreadOpenAddedConnections2(parg);
1358 vnThreadsRunning[7]--;
1360 catch (std::exception& e) {
1361 vnThreadsRunning[7]--;
1362 PrintException(&e, "ThreadOpenAddedConnections()");
1364 vnThreadsRunning[7]--;
1365 PrintException(NULL, "ThreadOpenAddedConnections()");
1367 printf("ThreadOpenAddedConnections exiting\n");
1370 void ThreadOpenAddedConnections2(void* parg)
1372 printf("ThreadOpenAddedConnections started\n");
1374 if (mapArgs.count("-addnode") == 0)
1377 vector<vector<CService> > vservAddressesToAdd(0);
1378 BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1380 vector<CService> vservNode(0);
1381 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1383 vservAddressesToAdd.push_back(vservNode);
1384 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1385 BOOST_FOREACH(CService& serv, vservNode)
1386 setservAddNodeAddresses.insert(serv);
1391 vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1392 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1393 // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1394 CRITICAL_BLOCK(cs_vNodes)
1395 BOOST_FOREACH(CNode* pnode, vNodes)
1396 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1397 BOOST_FOREACH(CService& addrNode, *(it))
1398 if (pnode->addr == addrNode)
1400 it = vservConnectAddresses.erase(it);
1404 BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1406 OpenNetworkConnection(CAddress(*(vserv.begin())));
1413 vnThreadsRunning[7]--;
1414 Sleep(120000); // Retry every 2 minutes
1415 vnThreadsRunning[7]++;
1421 bool OpenNetworkConnection(const CAddress& addrConnect)
1424 // Initiate outbound network connection
1428 if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1429 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1432 vnThreadsRunning[1]--;
1433 CNode* pnode = ConnectNode(addrConnect);
1434 vnThreadsRunning[1]++;
1439 pnode->fNetworkNode = true;
1451 void ThreadMessageHandler(void* parg)
1453 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1456 vnThreadsRunning[2]++;
1457 ThreadMessageHandler2(parg);
1458 vnThreadsRunning[2]--;
1460 catch (std::exception& e) {
1461 vnThreadsRunning[2]--;
1462 PrintException(&e, "ThreadMessageHandler()");
1464 vnThreadsRunning[2]--;
1465 PrintException(NULL, "ThreadMessageHandler()");
1467 printf("ThreadMessageHandler exiting\n");
1470 void ThreadMessageHandler2(void* parg)
1472 printf("ThreadMessageHandler started\n");
1473 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1476 vector<CNode*> vNodesCopy;
1477 CRITICAL_BLOCK(cs_vNodes)
1479 vNodesCopy = vNodes;
1480 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1484 // Poll the connected nodes for messages
1485 CNode* pnodeTrickle = NULL;
1486 if (!vNodesCopy.empty())
1487 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1488 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1491 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1492 ProcessMessages(pnode);
1497 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1498 SendMessages(pnode, pnode == pnodeTrickle);
1503 CRITICAL_BLOCK(cs_vNodes)
1505 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1509 // Wait and allow messages to bunch up.
1510 // Reduce vnThreadsRunning so StopNode has permission to exit while
1511 // we're sleeping, but we must always check fShutdown after doing this.
1512 vnThreadsRunning[2]--;
1514 if (fRequestShutdown)
1516 vnThreadsRunning[2]++;
1527 bool BindListenPort(string& strError)
1531 addrLocalHost.SetPort(GetListenPort());
1534 // Initialize Windows Sockets
1536 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1537 if (ret != NO_ERROR)
1539 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1540 printf("%s\n", strError.c_str());
1545 // Create socket for listening for incoming connections
1546 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1547 if (hListenSocket == INVALID_SOCKET)
1549 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1550 printf("%s\n", strError.c_str());
1555 // Different way of disabling SIGPIPE on BSD
1556 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1560 // Allow binding if the port is still in TIME_WAIT state after
1561 // the program was closed and restarted. Not an issue on windows.
1562 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1566 // Set to nonblocking, incoming connections will also inherit this
1567 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1569 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1572 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1573 printf("%s\n", strError.c_str());
1577 // The sockaddr_in structure specifies the address family,
1578 // IP address, and port for the socket that is being bound
1579 struct sockaddr_in sockaddr;
1580 memset(&sockaddr, 0, sizeof(sockaddr));
1581 sockaddr.sin_family = AF_INET;
1582 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1583 sockaddr.sin_port = htons(GetListenPort());
1584 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1586 int nErr = WSAGetLastError();
1587 if (nErr == WSAEADDRINUSE)
1588 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1590 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1591 printf("%s\n", strError.c_str());
1594 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1596 // Listen for incoming connections
1597 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1599 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1600 printf("%s\n", strError.c_str());
1607 void StartNode(void* parg)
1609 if (pnodeLocalHost == NULL)
1610 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1613 // Get local host ip
1614 char pszHostName[1000] = "";
1615 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1617 vector<CNetAddr> vaddr;
1618 if (LookupHost(pszHostName, vaddr))
1619 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1620 if (!addr.IsLocal())
1622 addrLocalHost.SetIP(addr);
1627 // Get local host ip
1628 struct ifaddrs* myaddrs;
1629 if (getifaddrs(&myaddrs) == 0)
1631 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1633 if (ifa->ifa_addr == NULL) continue;
1634 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1635 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1636 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1638 if (ifa->ifa_addr->sa_family == AF_INET)
1640 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1641 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1642 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1644 // Take the first IP that isn't loopback 127.x.x.x
1645 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1646 if (addr.IsValid() && !addr.IsLocal())
1648 addrLocalHost = addr;
1652 else if (ifa->ifa_addr->sa_family == AF_INET6)
1654 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1655 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1656 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1659 freeifaddrs(myaddrs);
1662 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1664 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1666 // Proxies can't take incoming connections
1667 addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1668 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1672 CreateThread(ThreadGetMyExternalIP, NULL);
1679 if (GetBoolArg("-nodnsseed"))
1680 printf("DNS seeding disabled\n");
1682 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1683 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1685 // Map ports with UPnP
1689 // Get addresses from IRC and advertise ours
1690 if (!CreateThread(ThreadIRCSeed, NULL))
1691 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1693 // Send and receive from sockets, accept connections
1694 if (!CreateThread(ThreadSocketHandler, NULL))
1695 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1697 // Initiate outbound connections from -addnode
1698 if (!CreateThread(ThreadOpenAddedConnections, NULL))
1699 printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1701 // Initiate outbound connections
1702 if (!CreateThread(ThreadOpenConnections, NULL))
1703 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1706 if (!CreateThread(ThreadMessageHandler, NULL))
1707 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1709 // Generate coins in the background
1710 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1715 printf("StopNode()\n");
1717 nTransactionsUpdated++;
1718 int64 nStart = GetTime();
1719 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 || vnThreadsRunning[6] > 0 || vnThreadsRunning[7] > 0
1721 || vnThreadsRunning[5] > 0
1725 if (GetTime() - nStart > 20)
1729 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1730 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1731 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1732 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1733 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1734 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1735 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1736 if (vnThreadsRunning[7] > 0) printf("ThreadOpenAddedConnections still running\n");
1737 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1753 BOOST_FOREACH(CNode* pnode, vNodes)
1754 if (pnode->hSocket != INVALID_SOCKET)
1755 closesocket(pnode->hSocket);
1756 if (hListenSocket != INVALID_SOCKET)
1757 if (closesocket(hListenSocket) == SOCKET_ERROR)
1758 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1761 // Shutdown Windows Sockets
1766 instance_of_cnetcleanup;