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);
33 void ThreadMapPort2(void* parg);
35 bool OpenNetworkConnection(const CAddress& addrConnect);
42 // Global state variables
45 bool fAllowDNS = false;
46 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
47 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
48 static CNode* pnodeLocalHost = NULL;
49 uint64 nLocalHostNonce = 0;
50 array<int, 10> vnThreadsRunning;
51 static SOCKET hListenSocket = INVALID_SOCKET;
53 vector<CNode*> vNodes;
54 CCriticalSection cs_vNodes;
55 map<vector<unsigned char>, CAddress> mapAddresses;
56 CCriticalSection cs_mapAddresses;
57 map<CInv, CDataStream> mapRelay;
58 deque<pair<int64, CInv> > vRelayExpiration;
59 CCriticalSection cs_mapRelay;
60 map<CInv, int64> mapAlreadyAskedFor;
63 int fUseProxy = false;
64 int nConnectTimeout = 5000;
65 CAddress addrProxy("127.0.0.1",9050);
70 unsigned short GetListenPort()
72 return (unsigned short)(GetArg("-port", GetDefaultPort()));
75 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
77 // Filter out duplicate requests
78 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
80 pindexLastGetBlocksBegin = pindexBegin;
81 hashLastGetBlocksEnd = hashEnd;
83 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
90 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
92 hSocketRet = INVALID_SOCKET;
94 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
95 if (hSocket == INVALID_SOCKET)
99 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
102 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
103 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
106 u_long fNonblock = 1;
107 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
109 int fFlags = fcntl(hSocket, F_GETFL, 0);
110 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
113 closesocket(hSocket);
118 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
120 // WSAEINVAL is here because some legacy version of winsock uses it
121 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
123 struct timeval timeout;
124 timeout.tv_sec = nTimeout / 1000;
125 timeout.tv_usec = (nTimeout % 1000) * 1000;
129 FD_SET(hSocket, &fdset);
130 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
133 printf("connection timeout\n");
134 closesocket(hSocket);
137 if (nRet == SOCKET_ERROR)
139 printf("select() for connection failed: %i\n",WSAGetLastError());
140 closesocket(hSocket);
143 socklen_t nRetSize = sizeof(nRet);
145 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
147 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
150 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
151 closesocket(hSocket);
156 printf("connect() failed after select(): %s\n",strerror(nRet));
157 closesocket(hSocket);
162 else if (WSAGetLastError() != WSAEISCONN)
167 printf("connect() failed: %i\n",WSAGetLastError());
168 closesocket(hSocket);
174 this isn't even strictly necessary
175 CNode::ConnectNode immediately turns the socket back to non-blocking
176 but we'll turn it back to blocking just in case
180 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
182 fFlags = fcntl(hSocket, F_GETFL, 0);
183 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
186 closesocket(hSocket);
192 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
193 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
194 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
195 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
196 char* pszSocks4 = pszSocks4IP;
197 int nSize = sizeof(pszSocks4IP);
199 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
202 closesocket(hSocket);
203 return error("Error sending to proxy");
206 if (recv(hSocket, pchRet, 8, 0) != 8)
208 closesocket(hSocket);
209 return error("Error reading proxy response");
211 if (pchRet[1] != 0x5a)
213 closesocket(hSocket);
214 if (pchRet[1] != 0x5b)
215 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
218 printf("proxy connected %s\n", addrConnect.ToString().c_str());
221 hSocketRet = hSocket;
225 // portDefault is in host order
226 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
231 int port = portDefault;
234 strlcpy(psz, pszName, sizeof(psz));
237 char* pszColon = strrchr(psz+1,':');
238 char *pszPortEnd = NULL;
239 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
240 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
242 if (psz[0] == '[' && pszColon[-1] == ']')
244 // Future: enable IPv6 colon-notation inside []
251 if (port < 0 || port > USHRT_MAX)
256 unsigned int addrIP = inet_addr(pszHost);
257 if (addrIP != INADDR_NONE)
259 // valid IP address passed
260 vaddr.push_back(CAddress(addrIP, port, nServices));
267 struct hostent* phostent = gethostbyname(pszHost);
271 if (phostent->h_addrtype != AF_INET)
274 char** ppAddr = phostent->h_addr_list;
275 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
277 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
279 vaddr.push_back(addr);
283 return (vaddr.size() > 0);
286 // portDefault is in host order
287 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
289 vector<CAddress> vaddr;
290 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
296 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
299 if (!ConnectSocket(addrConnect, hSocket))
300 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
302 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
305 while (RecvLine(hSocket, strLine))
307 if (strLine.empty()) // HTTP response is separated from headers by blank line
311 if (!RecvLine(hSocket, strLine))
313 closesocket(hSocket);
316 if (pszKeyword == NULL)
318 if (strLine.find(pszKeyword) != -1)
320 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
324 closesocket(hSocket);
325 if (strLine.find("<") != -1)
326 strLine = strLine.substr(0, strLine.find("<"));
327 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
328 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
329 strLine.resize(strLine.size()-1);
330 CAddress addr(strLine,0,true);
331 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
332 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
338 closesocket(hSocket);
339 return error("GetMyExternalIP() : connection closed");
342 // We now get our external IP from the IRC server first and only use this as a backup
343 bool GetMyExternalIP(unsigned int& ipRet)
345 CAddress addrConnect;
347 const char* pszKeyword;
352 for (int nLookup = 0; nLookup <= 1; nLookup++)
353 for (int nHost = 1; nHost <= 2; nHost++)
355 // We should be phasing out our use of sites like these. If we need
356 // replacements, we should ask for volunteers to put this simple
357 // php file on their webserver that prints the client IP:
358 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
361 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
365 CAddress addrIP("checkip.dyndns.org", 80, true);
366 if (addrIP.IsValid())
367 addrConnect = addrIP;
370 pszGet = "GET / HTTP/1.1\r\n"
371 "Host: checkip.dyndns.org\r\n"
372 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
373 "Connection: close\r\n"
376 pszKeyword = "Address:";
380 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
384 CAddress addrIP("www.showmyip.com", 80, true);
385 if (addrIP.IsValid())
386 addrConnect = addrIP;
389 pszGet = "GET /simple/ HTTP/1.1\r\n"
390 "Host: www.showmyip.com\r\n"
391 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
392 "Connection: close\r\n"
395 pszKeyword = NULL; // Returns just IP address
398 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
405 void ThreadGetMyExternalIP(void* parg)
407 // Wait for IRC to get it first
408 if (!GetBoolArg("-noirc"))
410 for (int i = 0; i < 2 * 60; i++)
413 if (fGotExternalIP || fShutdown)
418 // Fallback in case IRC fails to get it
419 if (GetMyExternalIP(addrLocalHost.ip))
421 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
422 if (addrLocalHost.IsRoutable())
424 // If we already connected to a few before we had our IP, go back and addr them.
425 // setAddrKnown automatically filters any duplicate sends.
426 CAddress addr(addrLocalHost);
427 addr.nTime = GetAdjustedTime();
428 CRITICAL_BLOCK(cs_vNodes)
429 BOOST_FOREACH(CNode* pnode, vNodes)
430 pnode->PushAddress(addr);
439 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
441 if (!addr.IsRoutable())
443 if (addr.ip == addrLocalHost.ip)
445 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
446 CRITICAL_BLOCK(cs_mapAddresses)
448 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
449 if (it == mapAddresses.end())
452 printf("AddAddress(%s)\n", addr.ToString().c_str());
453 mapAddresses.insert(make_pair(addr.GetKey(), addr));
455 pAddrDB->WriteAddress(addr);
457 CAddrDB().WriteAddress(addr);
462 bool fUpdated = false;
463 CAddress& addrFound = (*it).second;
464 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
466 // Services have been added
467 addrFound.nServices |= addr.nServices;
470 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
471 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
472 if (addrFound.nTime < addr.nTime - nUpdateInterval)
474 // Periodically update most recently seen time
475 addrFound.nTime = addr.nTime;
481 pAddrDB->WriteAddress(addrFound);
483 CAddrDB().WriteAddress(addrFound);
490 void AddressCurrentlyConnected(const CAddress& addr)
492 CRITICAL_BLOCK(cs_mapAddresses)
494 // Only if it's been published already
495 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
496 if (it != mapAddresses.end())
498 CAddress& addrFound = (*it).second;
499 int64 nUpdateInterval = 20 * 60;
500 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
502 // Periodically update most recently seen time
503 addrFound.nTime = GetAdjustedTime();
505 addrdb.WriteAddress(addrFound);
515 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
517 // If the dialog might get closed before the reply comes back,
518 // call this in the destructor so it doesn't get called after it's deleted.
519 CRITICAL_BLOCK(cs_vNodes)
521 BOOST_FOREACH(CNode* pnode, vNodes)
523 CRITICAL_BLOCK(pnode->cs_mapRequests)
525 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
527 CRequestTracker& tracker = (*mi).second;
528 if (tracker.fn == fn && tracker.param1 == param1)
529 pnode->mapRequests.erase(mi++);
545 // Subscription methods for the broadcast and subscription system.
546 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
548 // The subscription system uses a meet-in-the-middle strategy.
549 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
550 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
553 bool AnySubscribed(unsigned int nChannel)
555 if (pnodeLocalHost->IsSubscribed(nChannel))
557 CRITICAL_BLOCK(cs_vNodes)
558 BOOST_FOREACH(CNode* pnode, vNodes)
559 if (pnode->IsSubscribed(nChannel))
564 bool CNode::IsSubscribed(unsigned int nChannel)
566 if (nChannel >= vfSubscribe.size())
568 return vfSubscribe[nChannel];
571 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
573 if (nChannel >= vfSubscribe.size())
576 if (!AnySubscribed(nChannel))
579 CRITICAL_BLOCK(cs_vNodes)
580 BOOST_FOREACH(CNode* pnode, vNodes)
582 pnode->PushMessage("subscribe", nChannel, nHops);
585 vfSubscribe[nChannel] = true;
588 void CNode::CancelSubscribe(unsigned int nChannel)
590 if (nChannel >= vfSubscribe.size())
593 // Prevent from relaying cancel if wasn't subscribed
594 if (!vfSubscribe[nChannel])
596 vfSubscribe[nChannel] = false;
598 if (!AnySubscribed(nChannel))
600 // Relay subscription cancel
601 CRITICAL_BLOCK(cs_vNodes)
602 BOOST_FOREACH(CNode* pnode, vNodes)
604 pnode->PushMessage("sub-cancel", nChannel);
616 CNode* FindNode(unsigned int ip)
618 CRITICAL_BLOCK(cs_vNodes)
620 BOOST_FOREACH(CNode* pnode, vNodes)
621 if (pnode->addr.ip == ip)
627 CNode* FindNode(CAddress addr)
629 CRITICAL_BLOCK(cs_vNodes)
631 BOOST_FOREACH(CNode* pnode, vNodes)
632 if (pnode->addr == addr)
638 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
640 if (addrConnect.ip == addrLocalHost.ip)
643 // Look for an existing connection
644 CNode* pnode = FindNode(addrConnect.ip);
648 pnode->AddRef(nTimeout);
655 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
656 addrConnect.ToString().c_str(),
657 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
658 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
660 CRITICAL_BLOCK(cs_mapAddresses)
661 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
665 if (ConnectSocket(addrConnect, hSocket))
668 printf("connected %s\n", addrConnect.ToString().c_str());
670 // Set to nonblocking
673 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
674 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
676 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
677 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
681 CNode* pnode = new CNode(hSocket, addrConnect, false);
683 pnode->AddRef(nTimeout);
686 CRITICAL_BLOCK(cs_vNodes)
687 vNodes.push_back(pnode);
689 pnode->nTimeConnected = GetTime();
698 void CNode::CloseSocketDisconnect()
701 if (hSocket != INVALID_SOCKET)
704 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
705 printf("disconnecting node %s\n", addr.ToString().c_str());
706 closesocket(hSocket);
707 hSocket = INVALID_SOCKET;
711 void CNode::Cleanup()
713 // All of a nodes broadcasts and subscriptions are automatically torn down
714 // when it goes down, so a node has to stay up to keep its broadcast going.
716 // Cancel subscriptions
717 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
718 if (vfSubscribe[nChannel])
719 CancelSubscribe(nChannel);
734 void ThreadSocketHandler(void* parg)
736 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
739 vnThreadsRunning[0]++;
740 ThreadSocketHandler2(parg);
741 vnThreadsRunning[0]--;
743 catch (std::exception& e) {
744 vnThreadsRunning[0]--;
745 PrintException(&e, "ThreadSocketHandler()");
747 vnThreadsRunning[0]--;
748 throw; // support pthread_cancel()
750 printf("ThreadSocketHandler exiting\n");
753 void ThreadSocketHandler2(void* parg)
755 printf("ThreadSocketHandler started\n");
756 list<CNode*> vNodesDisconnected;
757 int nPrevNodeCount = 0;
764 CRITICAL_BLOCK(cs_vNodes)
766 // Disconnect unused nodes
767 vector<CNode*> vNodesCopy = vNodes;
768 BOOST_FOREACH(CNode* pnode, vNodesCopy)
770 if (pnode->fDisconnect ||
771 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
773 // remove from vNodes
774 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
776 // close socket and cleanup
777 pnode->CloseSocketDisconnect();
780 // hold in disconnected pool until all refs are released
781 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
782 if (pnode->fNetworkNode || pnode->fInbound)
784 vNodesDisconnected.push_back(pnode);
788 // Delete disconnected nodes
789 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
790 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
792 // wait until threads are done using it
793 if (pnode->GetRefCount() <= 0)
795 bool fDelete = false;
796 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
797 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
798 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
799 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
803 vNodesDisconnected.remove(pnode);
809 if (vNodes.size() != nPrevNodeCount)
811 nPrevNodeCount = vNodes.size();
817 // Find which sockets have data to receive
819 struct timeval timeout;
821 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
828 FD_ZERO(&fdsetError);
829 SOCKET hSocketMax = 0;
831 if(hListenSocket != INVALID_SOCKET)
832 FD_SET(hListenSocket, &fdsetRecv);
833 hSocketMax = max(hSocketMax, hListenSocket);
834 CRITICAL_BLOCK(cs_vNodes)
836 BOOST_FOREACH(CNode* pnode, vNodes)
838 if (pnode->hSocket == INVALID_SOCKET)
840 FD_SET(pnode->hSocket, &fdsetRecv);
841 FD_SET(pnode->hSocket, &fdsetError);
842 hSocketMax = max(hSocketMax, pnode->hSocket);
843 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
844 if (!pnode->vSend.empty())
845 FD_SET(pnode->hSocket, &fdsetSend);
849 vnThreadsRunning[0]--;
850 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
851 vnThreadsRunning[0]++;
854 if (nSelect == SOCKET_ERROR)
856 int nErr = WSAGetLastError();
859 printf("socket select error %d\n", nErr);
860 for (int i = 0; i <= hSocketMax; i++)
861 FD_SET(i, &fdsetRecv);
864 FD_ZERO(&fdsetError);
865 Sleep(timeout.tv_usec/1000);
870 // Accept new connections
872 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
874 struct sockaddr_in sockaddr;
875 socklen_t len = sizeof(sockaddr);
876 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
877 CAddress addr(sockaddr);
880 CRITICAL_BLOCK(cs_vNodes)
881 BOOST_FOREACH(CNode* pnode, vNodes)
884 if (hSocket == INVALID_SOCKET)
886 if (WSAGetLastError() != WSAEWOULDBLOCK)
887 printf("socket error accept failed: %d\n", WSAGetLastError());
889 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
891 closesocket(hSocket);
895 printf("accepted connection %s\n", addr.ToString().c_str());
896 CNode* pnode = new CNode(hSocket, addr, true);
898 CRITICAL_BLOCK(cs_vNodes)
899 vNodes.push_back(pnode);
905 // Service each socket
907 vector<CNode*> vNodesCopy;
908 CRITICAL_BLOCK(cs_vNodes)
911 BOOST_FOREACH(CNode* pnode, vNodesCopy)
914 BOOST_FOREACH(CNode* pnode, vNodesCopy)
922 if (pnode->hSocket == INVALID_SOCKET)
924 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
926 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
928 CDataStream& vRecv = pnode->vRecv;
929 unsigned int nPos = vRecv.size();
931 if (nPos > ReceiveBufferSize()) {
932 if (!pnode->fDisconnect)
933 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
934 pnode->CloseSocketDisconnect();
937 // typical socket buffer is 8K-64K
938 char pchBuf[0x10000];
939 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
942 vRecv.resize(nPos + nBytes);
943 memcpy(&vRecv[nPos], pchBuf, nBytes);
944 pnode->nLastRecv = GetTime();
946 else if (nBytes == 0)
948 // socket closed gracefully
949 if (!pnode->fDisconnect)
950 printf("socket closed\n");
951 pnode->CloseSocketDisconnect();
956 int nErr = WSAGetLastError();
957 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
959 if (!pnode->fDisconnect)
960 printf("socket recv error %d\n", nErr);
961 pnode->CloseSocketDisconnect();
971 if (pnode->hSocket == INVALID_SOCKET)
973 if (FD_ISSET(pnode->hSocket, &fdsetSend))
975 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
977 CDataStream& vSend = pnode->vSend;
980 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
983 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
984 pnode->nLastSend = GetTime();
989 int nErr = WSAGetLastError();
990 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
992 printf("socket send error %d\n", nErr);
993 pnode->CloseSocketDisconnect();
996 if (vSend.size() > SendBufferSize()) {
997 if (!pnode->fDisconnect)
998 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
999 pnode->CloseSocketDisconnect();
1006 // Inactivity checking
1008 if (pnode->vSend.empty())
1009 pnode->nLastSendEmpty = GetTime();
1010 if (GetTime() - pnode->nTimeConnected > 60)
1012 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1014 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1015 pnode->fDisconnect = true;
1017 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1019 printf("socket not sending\n");
1020 pnode->fDisconnect = true;
1022 else if (GetTime() - pnode->nLastRecv > 90*60)
1024 printf("socket inactivity timeout\n");
1025 pnode->fDisconnect = true;
1029 CRITICAL_BLOCK(cs_vNodes)
1031 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1048 void ThreadMapPort(void* parg)
1050 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1053 vnThreadsRunning[5]++;
1054 ThreadMapPort2(parg);
1055 vnThreadsRunning[5]--;
1057 catch (std::exception& e) {
1058 vnThreadsRunning[5]--;
1059 PrintException(&e, "ThreadMapPort()");
1061 vnThreadsRunning[5]--;
1062 PrintException(NULL, "ThreadMapPort()");
1064 printf("ThreadMapPort exiting\n");
1067 void ThreadMapPort2(void* parg)
1069 printf("ThreadMapPort started\n");
1072 sprintf(port, "%d", GetListenPort());
1074 const char * rootdescurl = 0;
1075 const char * multicastif = 0;
1076 const char * minissdpdpath = 0;
1078 struct UPNPDev * devlist = 0;
1081 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1083 struct UPNPUrls urls;
1084 struct IGDdatas data;
1087 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1092 string strDesc = "Bitcoin " + FormatFullVersion();
1093 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1094 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1096 if(r!=UPNPCOMMAND_SUCCESS)
1097 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1098 port, port, lanaddr, r, strupnperror(r));
1100 printf("UPnP Port Mapping successful.\n");
1102 if (fShutdown || !fUseUPnP)
1104 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1105 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1106 freeUPNPDevlist(devlist); devlist = 0;
1107 FreeUPNPUrls(&urls);
1113 printf("No valid UPnP IGDs found\n");
1114 freeUPNPDevlist(devlist); devlist = 0;
1116 FreeUPNPUrls(&urls);
1118 if (fShutdown || !fUseUPnP)
1125 void MapPort(bool fMapPort)
1127 if (fUseUPnP != fMapPort)
1129 fUseUPnP = fMapPort;
1130 WriteSetting("fUseUPnP", fUseUPnP);
1132 if (fUseUPnP && vnThreadsRunning[5] < 1)
1134 if (!CreateThread(ThreadMapPort, NULL))
1135 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1139 void MapPort(bool /* unused fMapPort */)
1141 // Intentionally left blank.
1154 static const char *strDNSSeed[] = {
1156 "bitseed.bitcoin.org.uk",
1157 "dnsseed.bluematt.me",
1160 void DNSAddressSeed()
1166 printf("Loading addresses from DNS seeds (could take a while)\n");
1170 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1171 vector<CAddress> vaddr;
1172 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1174 BOOST_FOREACH (CAddress& addr, vaddr)
1176 if (addr.GetByte(3) != 127)
1179 AddAddress(addr, 0, &addrDB);
1186 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1189 printf("%d addresses found from DNS seeds\n", found);
1194 unsigned int pnSeed[] =
1196 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1197 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1198 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1199 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1200 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1201 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1202 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1203 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1204 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1205 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1206 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1207 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1208 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1209 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1210 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1211 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1212 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1213 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1214 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1215 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1216 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1217 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1218 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1219 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1220 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1221 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1222 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1223 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1224 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1225 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1226 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1227 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1228 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1229 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1230 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1231 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1232 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1233 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1234 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1235 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1236 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1237 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1238 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1239 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1240 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1241 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1242 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1243 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1244 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1245 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1246 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1247 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1248 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1249 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1250 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1251 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1252 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1253 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1254 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1255 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1256 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1257 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1258 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1259 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1264 void ThreadOpenConnections(void* parg)
1266 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1269 vnThreadsRunning[1]++;
1270 ThreadOpenConnections2(parg);
1271 vnThreadsRunning[1]--;
1273 catch (std::exception& e) {
1274 vnThreadsRunning[1]--;
1275 PrintException(&e, "ThreadOpenConnections()");
1277 vnThreadsRunning[1]--;
1278 PrintException(NULL, "ThreadOpenConnections()");
1280 printf("ThreadOpenConnections exiting\n");
1283 void ThreadOpenConnections2(void* parg)
1285 printf("ThreadOpenConnections started\n");
1287 // Connect to specific addresses
1288 if (mapArgs.count("-connect"))
1290 for (int64 nLoop = 0;; nLoop++)
1292 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1294 CAddress addr(strAddr, fAllowDNS);
1296 OpenNetworkConnection(addr);
1297 for (int i = 0; i < 10 && i < nLoop; i++)
1307 // Connect to manually added nodes first
1308 if (mapArgs.count("-addnode"))
1310 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1312 CAddress addr(strAddr, fAllowDNS);
1315 OpenNetworkConnection(addr);
1323 // Initiate network connections
1324 int64 nStart = GetTime();
1327 // Limit outbound connections
1328 vnThreadsRunning[1]--;
1333 CRITICAL_BLOCK(cs_vNodes)
1334 BOOST_FOREACH(CNode* pnode, vNodes)
1335 if (!pnode->fInbound)
1337 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1338 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1339 if (nOutbound < nMaxOutboundConnections)
1345 vnThreadsRunning[1]++;
1349 CRITICAL_BLOCK(cs_mapAddresses)
1351 // Add seed nodes if IRC isn't working
1352 static bool fSeedUsed;
1353 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1354 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1356 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1358 // It'll only connect to one or two seed nodes because once it connects,
1359 // it'll get a pile of addresses with newer timestamps.
1361 addr.ip = pnSeed[i];
1368 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1370 // Disconnect seed nodes
1371 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1372 static int64 nSeedDisconnected;
1373 if (nSeedDisconnected == 0)
1375 nSeedDisconnected = GetTime();
1376 CRITICAL_BLOCK(cs_vNodes)
1377 BOOST_FOREACH(CNode* pnode, vNodes)
1378 if (setSeed.count(pnode->addr.ip))
1379 pnode->fDisconnect = true;
1382 // Keep setting timestamps to 0 so they won't reconnect
1383 if (GetTime() - nSeedDisconnected < 60 * 60)
1385 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1387 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1389 item.second.nTime = 0;
1390 CAddrDB().WriteAddress(item.second);
1399 // Choose an address to connect to based on most recently seen
1401 CAddress addrConnect;
1402 int64 nBest = INT64_MIN;
1404 // Only connect to one address per a.b.?.? range.
1405 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1406 set<unsigned int> setConnected;
1407 CRITICAL_BLOCK(cs_vNodes)
1408 BOOST_FOREACH(CNode* pnode, vNodes)
1409 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1411 CRITICAL_BLOCK(cs_mapAddresses)
1413 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1415 const CAddress& addr = item.second;
1416 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1418 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1419 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1421 // Randomize the order in a deterministic way, putting the standard port first
1422 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1423 if (addr.port != htons(GetDefaultPort()))
1424 nRandomizer += 2 * 60 * 60;
1426 // Last seen Base retry frequency
1435 // 365 days 93 hours
1436 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1438 // Fast reconnect for one hour after last seen
1439 if (nSinceLastSeen < 60 * 60)
1442 // Limit retry frequency
1443 if (nSinceLastTry < nDelay)
1446 // If we have IRC, we'll be notified when they first come online,
1447 // and again every 24 hours by the refresh broadcast.
1448 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1451 // Only try the old stuff if we don't have enough connections
1452 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1455 // If multiple addresses are ready, prioritize by time since
1456 // last seen and time since last tried.
1457 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1466 if (addrConnect.IsValid())
1467 OpenNetworkConnection(addrConnect);
1471 bool OpenNetworkConnection(const CAddress& addrConnect)
1474 // Initiate outbound network connection
1478 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1481 vnThreadsRunning[1]--;
1482 CNode* pnode = ConnectNode(addrConnect);
1483 vnThreadsRunning[1]++;
1488 pnode->fNetworkNode = true;
1500 void ThreadMessageHandler(void* parg)
1502 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1505 vnThreadsRunning[2]++;
1506 ThreadMessageHandler2(parg);
1507 vnThreadsRunning[2]--;
1509 catch (std::exception& e) {
1510 vnThreadsRunning[2]--;
1511 PrintException(&e, "ThreadMessageHandler()");
1513 vnThreadsRunning[2]--;
1514 PrintException(NULL, "ThreadMessageHandler()");
1516 printf("ThreadMessageHandler exiting\n");
1519 void ThreadMessageHandler2(void* parg)
1521 printf("ThreadMessageHandler started\n");
1522 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1525 vector<CNode*> vNodesCopy;
1526 CRITICAL_BLOCK(cs_vNodes)
1528 vNodesCopy = vNodes;
1529 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1533 // Poll the connected nodes for messages
1534 CNode* pnodeTrickle = NULL;
1535 if (!vNodesCopy.empty())
1536 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1537 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1540 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1541 ProcessMessages(pnode);
1546 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1547 SendMessages(pnode, pnode == pnodeTrickle);
1552 CRITICAL_BLOCK(cs_vNodes)
1554 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1558 // Wait and allow messages to bunch up.
1559 // Reduce vnThreadsRunning so StopNode has permission to exit while
1560 // we're sleeping, but we must always check fShutdown after doing this.
1561 vnThreadsRunning[2]--;
1563 if (fRequestShutdown)
1565 vnThreadsRunning[2]++;
1576 bool BindListenPort(string& strError)
1580 addrLocalHost.port = htons(GetListenPort());
1583 // Initialize Windows Sockets
1585 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1586 if (ret != NO_ERROR)
1588 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1589 printf("%s\n", strError.c_str());
1594 // Create socket for listening for incoming connections
1595 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1596 if (hListenSocket == INVALID_SOCKET)
1598 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1599 printf("%s\n", strError.c_str());
1604 // Different way of disabling SIGPIPE on BSD
1605 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1609 // Allow binding if the port is still in TIME_WAIT state after
1610 // the program was closed and restarted. Not an issue on windows.
1611 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1615 // Set to nonblocking, incoming connections will also inherit this
1616 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1618 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1621 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1622 printf("%s\n", strError.c_str());
1626 // The sockaddr_in structure specifies the address family,
1627 // IP address, and port for the socket that is being bound
1628 struct sockaddr_in sockaddr;
1629 memset(&sockaddr, 0, sizeof(sockaddr));
1630 sockaddr.sin_family = AF_INET;
1631 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1632 sockaddr.sin_port = htons(GetListenPort());
1633 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1635 int nErr = WSAGetLastError();
1636 if (nErr == WSAEADDRINUSE)
1637 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1639 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1640 printf("%s\n", strError.c_str());
1643 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1645 // Listen for incoming connections
1646 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1648 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1649 printf("%s\n", strError.c_str());
1656 void StartNode(void* parg)
1658 if (pnodeLocalHost == NULL)
1659 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1662 // Get local host ip
1663 char pszHostName[1000] = "";
1664 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1666 vector<CAddress> vaddr;
1667 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1668 BOOST_FOREACH (const CAddress &addr, vaddr)
1669 if (addr.GetByte(3) != 127)
1671 addrLocalHost = addr;
1676 // Get local host ip
1677 struct ifaddrs* myaddrs;
1678 if (getifaddrs(&myaddrs) == 0)
1680 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1682 if (ifa->ifa_addr == NULL) continue;
1683 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1684 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1685 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1687 if (ifa->ifa_addr->sa_family == AF_INET)
1689 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1690 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1691 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1693 // Take the first IP that isn't loopback 127.x.x.x
1694 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1695 if (addr.IsValid() && addr.GetByte(3) != 127)
1697 addrLocalHost = addr;
1701 else if (ifa->ifa_addr->sa_family == AF_INET6)
1703 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1704 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1705 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1708 freeifaddrs(myaddrs);
1711 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1713 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1715 // Proxies can't take incoming connections
1716 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1717 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1721 CreateThread(ThreadGetMyExternalIP, NULL);
1728 // Map ports with UPnP
1732 // Get addresses from IRC and advertise ours
1733 if (!CreateThread(ThreadIRCSeed, NULL))
1734 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1736 // Send and receive from sockets, accept connections
1737 CreateThread(ThreadSocketHandler, NULL, true);
1739 // Initiate outbound connections
1740 if (!CreateThread(ThreadOpenConnections, NULL))
1741 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1744 if (!CreateThread(ThreadMessageHandler, NULL))
1745 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1747 // Generate coins in the background
1748 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1753 printf("StopNode()\n");
1755 nTransactionsUpdated++;
1756 int64 nStart = GetTime();
1757 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1759 || vnThreadsRunning[5] > 0
1763 if (GetTime() - nStart > 20)
1767 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1768 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1769 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1770 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1771 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1772 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1773 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1789 BOOST_FOREACH(CNode* pnode, vNodes)
1790 if (pnode->hSocket != INVALID_SOCKET)
1791 closesocket(pnode->hSocket);
1792 if (hListenSocket != INVALID_SOCKET)
1793 if (closesocket(hListenSocket) == SOCKET_ERROR)
1794 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1797 // Shutdown Windows Sockets
1802 instance_of_cnetcleanup;