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 void ThreadDNSAddressSeed2(void* parg);
36 bool OpenNetworkConnection(const CAddress& addrConnect);
43 // Global state variables
46 bool fAllowDNS = false;
47 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
48 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
49 static CNode* pnodeLocalHost = NULL;
50 uint64 nLocalHostNonce = 0;
51 array<int, 10> vnThreadsRunning;
52 static SOCKET hListenSocket = INVALID_SOCKET;
54 vector<CNode*> vNodes;
55 CCriticalSection cs_vNodes;
56 map<vector<unsigned char>, CAddress> mapAddresses;
57 CCriticalSection cs_mapAddresses;
58 map<CInv, CDataStream> mapRelay;
59 deque<pair<int64, CInv> > vRelayExpiration;
60 CCriticalSection cs_mapRelay;
61 map<CInv, int64> mapAlreadyAskedFor;
64 int fUseProxy = false;
65 int nConnectTimeout = 5000;
66 CAddress addrProxy("127.0.0.1",9050);
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 ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
93 hSocketRet = INVALID_SOCKET;
95 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
96 if (hSocket == INVALID_SOCKET)
100 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
103 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
104 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
107 u_long fNonblock = 1;
108 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
110 int fFlags = fcntl(hSocket, F_GETFL, 0);
111 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
114 closesocket(hSocket);
119 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
121 // WSAEINVAL is here because some legacy version of winsock uses it
122 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
124 struct timeval timeout;
125 timeout.tv_sec = nTimeout / 1000;
126 timeout.tv_usec = (nTimeout % 1000) * 1000;
130 FD_SET(hSocket, &fdset);
131 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
134 printf("connection timeout\n");
135 closesocket(hSocket);
138 if (nRet == SOCKET_ERROR)
140 printf("select() for connection failed: %i\n",WSAGetLastError());
141 closesocket(hSocket);
144 socklen_t nRetSize = sizeof(nRet);
146 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
148 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
151 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
152 closesocket(hSocket);
157 printf("connect() failed after select(): %s\n",strerror(nRet));
158 closesocket(hSocket);
163 else if (WSAGetLastError() != WSAEISCONN)
168 printf("connect() failed: %i\n",WSAGetLastError());
169 closesocket(hSocket);
175 this isn't even strictly necessary
176 CNode::ConnectNode immediately turns the socket back to non-blocking
177 but we'll turn it back to blocking just in case
181 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
183 fFlags = fcntl(hSocket, F_GETFL, 0);
184 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
187 closesocket(hSocket);
193 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
194 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
195 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
196 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
197 char* pszSocks4 = pszSocks4IP;
198 int nSize = sizeof(pszSocks4IP);
200 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
203 closesocket(hSocket);
204 return error("Error sending to proxy");
207 if (recv(hSocket, pchRet, 8, 0) != 8)
209 closesocket(hSocket);
210 return error("Error reading proxy response");
212 if (pchRet[1] != 0x5a)
214 closesocket(hSocket);
215 if (pchRet[1] != 0x5b)
216 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
219 printf("proxy connected %s\n", addrConnect.ToString().c_str());
222 hSocketRet = hSocket;
226 // portDefault is in host order
227 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
232 int port = portDefault;
235 strlcpy(psz, pszName, sizeof(psz));
238 char* pszColon = strrchr(psz+1,':');
239 char *pszPortEnd = NULL;
240 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
241 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
243 if (psz[0] == '[' && pszColon[-1] == ']')
245 // Future: enable IPv6 colon-notation inside []
252 if (port < 0 || port > USHRT_MAX)
257 unsigned int addrIP = inet_addr(pszHost);
258 if (addrIP != INADDR_NONE)
260 // valid IP address passed
261 vaddr.push_back(CAddress(addrIP, port, nServices));
268 struct hostent* phostent = gethostbyname(pszHost);
272 if (phostent->h_addrtype != AF_INET)
275 char** ppAddr = phostent->h_addr_list;
276 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
278 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
280 vaddr.push_back(addr);
284 return (vaddr.size() > 0);
287 // portDefault is in host order
288 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
290 vector<CAddress> vaddr;
291 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
297 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
300 if (!ConnectSocket(addrConnect, hSocket))
301 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
303 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
306 while (RecvLine(hSocket, strLine))
308 if (strLine.empty()) // HTTP response is separated from headers by blank line
312 if (!RecvLine(hSocket, strLine))
314 closesocket(hSocket);
317 if (pszKeyword == NULL)
319 if (strLine.find(pszKeyword) != -1)
321 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
325 closesocket(hSocket);
326 if (strLine.find("<") != -1)
327 strLine = strLine.substr(0, strLine.find("<"));
328 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
329 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
330 strLine.resize(strLine.size()-1);
331 CAddress addr(strLine,0,true);
332 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
333 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
339 closesocket(hSocket);
340 return error("GetMyExternalIP() : connection closed");
343 // We now get our external IP from the IRC server first and only use this as a backup
344 bool GetMyExternalIP(unsigned int& ipRet)
346 CAddress addrConnect;
348 const char* pszKeyword;
353 for (int nLookup = 0; nLookup <= 1; nLookup++)
354 for (int nHost = 1; nHost <= 2; nHost++)
356 // We should be phasing out our use of sites like these. If we need
357 // replacements, we should ask for volunteers to put this simple
358 // php file on their webserver that prints the client IP:
359 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
362 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
366 CAddress addrIP("checkip.dyndns.org", 80, true);
367 if (addrIP.IsValid())
368 addrConnect = addrIP;
371 pszGet = "GET / HTTP/1.1\r\n"
372 "Host: checkip.dyndns.org\r\n"
373 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
374 "Connection: close\r\n"
377 pszKeyword = "Address:";
381 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
385 CAddress addrIP("www.showmyip.com", 80, true);
386 if (addrIP.IsValid())
387 addrConnect = addrIP;
390 pszGet = "GET /simple/ HTTP/1.1\r\n"
391 "Host: www.showmyip.com\r\n"
392 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
393 "Connection: close\r\n"
396 pszKeyword = NULL; // Returns just IP address
399 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
406 void ThreadGetMyExternalIP(void* parg)
408 // Wait for IRC to get it first
409 if (!GetBoolArg("-noirc"))
411 for (int i = 0; i < 2 * 60; i++)
414 if (fGotExternalIP || fShutdown)
419 // Fallback in case IRC fails to get it
420 if (GetMyExternalIP(addrLocalHost.ip))
422 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
423 if (addrLocalHost.IsRoutable())
425 // If we already connected to a few before we had our IP, go back and addr them.
426 // setAddrKnown automatically filters any duplicate sends.
427 CAddress addr(addrLocalHost);
428 addr.nTime = GetAdjustedTime();
429 CRITICAL_BLOCK(cs_vNodes)
430 BOOST_FOREACH(CNode* pnode, vNodes)
431 pnode->PushAddress(addr);
440 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
442 if (!addr.IsRoutable())
444 if (addr.ip == addrLocalHost.ip)
446 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
447 bool fUpdated = false;
449 CAddress addrFound = addr;
451 CRITICAL_BLOCK(cs_mapAddresses)
453 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
454 if (it == mapAddresses.end())
457 printf("AddAddress(%s)\n", addr.ToString().c_str());
458 mapAddresses.insert(make_pair(addr.GetKey(), addr));
464 addrFound = (*it).second;
465 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
467 // Services have been added
468 addrFound.nServices |= addr.nServices;
471 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
472 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
473 if (addrFound.nTime < addr.nTime - nUpdateInterval)
475 // Periodically update most recently seen time
476 addrFound.nTime = addr.nTime;
481 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
483 // Thread 1: begin db transaction (locks inside-db-mutex)
484 // then AddAddress (locks cs_mapAddresses)
485 // Thread 2: AddAddress (locks cs_mapAddresses)
486 // ... then db operation hangs waiting for inside-db-mutex
490 pAddrDB->WriteAddress(addrFound);
492 CAddrDB().WriteAddress(addrFound);
497 void AddressCurrentlyConnected(const CAddress& addr)
499 CAddress *paddrFound = NULL;
501 CRITICAL_BLOCK(cs_mapAddresses)
503 // Only if it's been published already
504 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
505 if (it != mapAddresses.end())
506 paddrFound = &(*it).second;
511 int64 nUpdateInterval = 20 * 60;
512 if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
514 // Periodically update most recently seen time
515 paddrFound->nTime = GetAdjustedTime();
517 addrdb.WriteAddress(*paddrFound);
526 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
528 // If the dialog might get closed before the reply comes back,
529 // call this in the destructor so it doesn't get called after it's deleted.
530 CRITICAL_BLOCK(cs_vNodes)
532 BOOST_FOREACH(CNode* pnode, vNodes)
534 CRITICAL_BLOCK(pnode->cs_mapRequests)
536 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
538 CRequestTracker& tracker = (*mi).second;
539 if (tracker.fn == fn && tracker.param1 == param1)
540 pnode->mapRequests.erase(mi++);
556 // Subscription methods for the broadcast and subscription system.
557 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
559 // The subscription system uses a meet-in-the-middle strategy.
560 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
561 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
564 bool AnySubscribed(unsigned int nChannel)
566 if (pnodeLocalHost->IsSubscribed(nChannel))
568 CRITICAL_BLOCK(cs_vNodes)
569 BOOST_FOREACH(CNode* pnode, vNodes)
570 if (pnode->IsSubscribed(nChannel))
575 bool CNode::IsSubscribed(unsigned int nChannel)
577 if (nChannel >= vfSubscribe.size())
579 return vfSubscribe[nChannel];
582 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
584 if (nChannel >= vfSubscribe.size())
587 if (!AnySubscribed(nChannel))
590 CRITICAL_BLOCK(cs_vNodes)
591 BOOST_FOREACH(CNode* pnode, vNodes)
593 pnode->PushMessage("subscribe", nChannel, nHops);
596 vfSubscribe[nChannel] = true;
599 void CNode::CancelSubscribe(unsigned int nChannel)
601 if (nChannel >= vfSubscribe.size())
604 // Prevent from relaying cancel if wasn't subscribed
605 if (!vfSubscribe[nChannel])
607 vfSubscribe[nChannel] = false;
609 if (!AnySubscribed(nChannel))
611 // Relay subscription cancel
612 CRITICAL_BLOCK(cs_vNodes)
613 BOOST_FOREACH(CNode* pnode, vNodes)
615 pnode->PushMessage("sub-cancel", nChannel);
627 CNode* FindNode(unsigned int ip)
629 CRITICAL_BLOCK(cs_vNodes)
631 BOOST_FOREACH(CNode* pnode, vNodes)
632 if (pnode->addr.ip == ip)
638 CNode* FindNode(CAddress addr)
640 CRITICAL_BLOCK(cs_vNodes)
642 BOOST_FOREACH(CNode* pnode, vNodes)
643 if (pnode->addr == addr)
649 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
651 if (addrConnect.ip == addrLocalHost.ip)
654 // Look for an existing connection
655 CNode* pnode = FindNode(addrConnect.ip);
659 pnode->AddRef(nTimeout);
666 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
667 addrConnect.ToString().c_str(),
668 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
669 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
671 CRITICAL_BLOCK(cs_mapAddresses)
672 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
676 if (ConnectSocket(addrConnect, hSocket))
679 printf("connected %s\n", addrConnect.ToString().c_str());
681 // Set to nonblocking
684 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
685 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
687 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
688 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
692 CNode* pnode = new CNode(hSocket, addrConnect, false);
694 pnode->AddRef(nTimeout);
697 CRITICAL_BLOCK(cs_vNodes)
698 vNodes.push_back(pnode);
700 pnode->nTimeConnected = GetTime();
709 void CNode::CloseSocketDisconnect()
712 if (hSocket != INVALID_SOCKET)
715 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
716 printf("disconnecting node %s\n", addr.ToString().c_str());
717 closesocket(hSocket);
718 hSocket = INVALID_SOCKET;
722 void CNode::Cleanup()
724 // All of a nodes broadcasts and subscriptions are automatically torn down
725 // when it goes down, so a node has to stay up to keep its broadcast going.
727 // Cancel subscriptions
728 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
729 if (vfSubscribe[nChannel])
730 CancelSubscribe(nChannel);
745 void ThreadSocketHandler(void* parg)
747 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
750 vnThreadsRunning[0]++;
751 ThreadSocketHandler2(parg);
752 vnThreadsRunning[0]--;
754 catch (std::exception& e) {
755 vnThreadsRunning[0]--;
756 PrintException(&e, "ThreadSocketHandler()");
758 vnThreadsRunning[0]--;
759 throw; // support pthread_cancel()
761 printf("ThreadSocketHandler exiting\n");
764 void ThreadSocketHandler2(void* parg)
766 printf("ThreadSocketHandler started\n");
767 list<CNode*> vNodesDisconnected;
768 int nPrevNodeCount = 0;
775 CRITICAL_BLOCK(cs_vNodes)
777 // Disconnect unused nodes
778 vector<CNode*> vNodesCopy = vNodes;
779 BOOST_FOREACH(CNode* pnode, vNodesCopy)
781 if (pnode->fDisconnect ||
782 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
784 // remove from vNodes
785 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
787 // close socket and cleanup
788 pnode->CloseSocketDisconnect();
791 // hold in disconnected pool until all refs are released
792 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
793 if (pnode->fNetworkNode || pnode->fInbound)
795 vNodesDisconnected.push_back(pnode);
799 // Delete disconnected nodes
800 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
801 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
803 // wait until threads are done using it
804 if (pnode->GetRefCount() <= 0)
806 bool fDelete = false;
807 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
808 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
809 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
810 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
814 vNodesDisconnected.remove(pnode);
820 if (vNodes.size() != nPrevNodeCount)
822 nPrevNodeCount = vNodes.size();
828 // Find which sockets have data to receive
830 struct timeval timeout;
832 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
839 FD_ZERO(&fdsetError);
840 SOCKET hSocketMax = 0;
842 if(hListenSocket != INVALID_SOCKET)
843 FD_SET(hListenSocket, &fdsetRecv);
844 hSocketMax = max(hSocketMax, hListenSocket);
845 CRITICAL_BLOCK(cs_vNodes)
847 BOOST_FOREACH(CNode* pnode, vNodes)
849 if (pnode->hSocket == INVALID_SOCKET)
851 FD_SET(pnode->hSocket, &fdsetRecv);
852 FD_SET(pnode->hSocket, &fdsetError);
853 hSocketMax = max(hSocketMax, pnode->hSocket);
854 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
855 if (!pnode->vSend.empty())
856 FD_SET(pnode->hSocket, &fdsetSend);
860 vnThreadsRunning[0]--;
861 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
862 vnThreadsRunning[0]++;
865 if (nSelect == SOCKET_ERROR)
867 int nErr = WSAGetLastError();
870 printf("socket select error %d\n", nErr);
871 for (int i = 0; i <= hSocketMax; i++)
872 FD_SET(i, &fdsetRecv);
875 FD_ZERO(&fdsetError);
876 Sleep(timeout.tv_usec/1000);
881 // Accept new connections
883 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
885 struct sockaddr_in sockaddr;
886 socklen_t len = sizeof(sockaddr);
887 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
888 CAddress addr(sockaddr);
891 CRITICAL_BLOCK(cs_vNodes)
892 BOOST_FOREACH(CNode* pnode, vNodes)
895 if (hSocket == INVALID_SOCKET)
897 if (WSAGetLastError() != WSAEWOULDBLOCK)
898 printf("socket error accept failed: %d\n", WSAGetLastError());
900 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
902 closesocket(hSocket);
906 printf("accepted connection %s\n", addr.ToString().c_str());
907 CNode* pnode = new CNode(hSocket, addr, true);
909 CRITICAL_BLOCK(cs_vNodes)
910 vNodes.push_back(pnode);
916 // Service each socket
918 vector<CNode*> vNodesCopy;
919 CRITICAL_BLOCK(cs_vNodes)
922 BOOST_FOREACH(CNode* pnode, vNodesCopy)
925 BOOST_FOREACH(CNode* pnode, vNodesCopy)
933 if (pnode->hSocket == INVALID_SOCKET)
935 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
937 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
939 CDataStream& vRecv = pnode->vRecv;
940 unsigned int nPos = vRecv.size();
942 if (nPos > ReceiveBufferSize()) {
943 if (!pnode->fDisconnect)
944 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
945 pnode->CloseSocketDisconnect();
948 // typical socket buffer is 8K-64K
949 char pchBuf[0x10000];
950 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
953 vRecv.resize(nPos + nBytes);
954 memcpy(&vRecv[nPos], pchBuf, nBytes);
955 pnode->nLastRecv = GetTime();
957 else if (nBytes == 0)
959 // socket closed gracefully
960 if (!pnode->fDisconnect)
961 printf("socket closed\n");
962 pnode->CloseSocketDisconnect();
967 int nErr = WSAGetLastError();
968 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
970 if (!pnode->fDisconnect)
971 printf("socket recv error %d\n", nErr);
972 pnode->CloseSocketDisconnect();
982 if (pnode->hSocket == INVALID_SOCKET)
984 if (FD_ISSET(pnode->hSocket, &fdsetSend))
986 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
988 CDataStream& vSend = pnode->vSend;
991 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
994 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
995 pnode->nLastSend = GetTime();
1000 int nErr = WSAGetLastError();
1001 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1003 printf("socket send error %d\n", nErr);
1004 pnode->CloseSocketDisconnect();
1007 if (vSend.size() > SendBufferSize()) {
1008 if (!pnode->fDisconnect)
1009 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1010 pnode->CloseSocketDisconnect();
1017 // Inactivity checking
1019 if (pnode->vSend.empty())
1020 pnode->nLastSendEmpty = GetTime();
1021 if (GetTime() - pnode->nTimeConnected > 60)
1023 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1025 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1026 pnode->fDisconnect = true;
1028 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1030 printf("socket not sending\n");
1031 pnode->fDisconnect = true;
1033 else if (GetTime() - pnode->nLastRecv > 90*60)
1035 printf("socket inactivity timeout\n");
1036 pnode->fDisconnect = true;
1040 CRITICAL_BLOCK(cs_vNodes)
1042 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1059 void ThreadMapPort(void* parg)
1061 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1064 vnThreadsRunning[5]++;
1065 ThreadMapPort2(parg);
1066 vnThreadsRunning[5]--;
1068 catch (std::exception& e) {
1069 vnThreadsRunning[5]--;
1070 PrintException(&e, "ThreadMapPort()");
1072 vnThreadsRunning[5]--;
1073 PrintException(NULL, "ThreadMapPort()");
1075 printf("ThreadMapPort exiting\n");
1078 void ThreadMapPort2(void* parg)
1080 printf("ThreadMapPort started\n");
1083 sprintf(port, "%d", GetListenPort());
1085 const char * rootdescurl = 0;
1086 const char * multicastif = 0;
1087 const char * minissdpdpath = 0;
1088 struct UPNPDev * devlist = 0;
1091 #ifndef UPNPDISCOVER_SUCCESS
1093 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1097 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1100 struct UPNPUrls urls;
1101 struct IGDdatas data;
1104 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1109 string strDesc = "Bitcoin " + FormatFullVersion();
1110 #ifndef UPNPDISCOVER_SUCCESS
1112 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1113 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1116 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1117 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1120 if(r!=UPNPCOMMAND_SUCCESS)
1121 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1122 port, port, lanaddr, r, strupnperror(r));
1124 printf("UPnP Port Mapping successful.\n");
1126 if (fShutdown || !fUseUPnP)
1128 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1129 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1130 freeUPNPDevlist(devlist); devlist = 0;
1131 FreeUPNPUrls(&urls);
1137 printf("No valid UPnP IGDs found\n");
1138 freeUPNPDevlist(devlist); devlist = 0;
1140 FreeUPNPUrls(&urls);
1142 if (fShutdown || !fUseUPnP)
1149 void MapPort(bool fMapPort)
1151 if (fUseUPnP != fMapPort)
1153 fUseUPnP = fMapPort;
1154 WriteSetting("fUseUPnP", fUseUPnP);
1156 if (fUseUPnP && vnThreadsRunning[5] < 1)
1158 if (!CreateThread(ThreadMapPort, NULL))
1159 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1163 void MapPort(bool /* unused fMapPort */)
1165 // Intentionally left blank.
1178 static const char *strDNSSeed[] = {
1180 "dnsseed.bluematt.me",
1181 "seed.bitcoin.sipa.be",
1182 "dnsseed.bitcoin.dashjr.org",
1185 void ThreadDNSAddressSeed(void* parg)
1187 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1190 vnThreadsRunning[6]++;
1191 ThreadDNSAddressSeed2(parg);
1192 vnThreadsRunning[6]--;
1194 catch (std::exception& e) {
1195 vnThreadsRunning[6]--;
1196 PrintException(&e, "ThreadDNSAddressSeed()");
1198 vnThreadsRunning[6]--;
1199 throw; // support pthread_cancel()
1201 printf("ThreadDNSAddressSeed exiting\n");
1204 void ThreadDNSAddressSeed2(void* parg)
1206 printf("ThreadDNSAddressSeed started\n");
1211 printf("Loading addresses from DNS seeds (could take a while)\n");
1213 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1214 vector<CAddress> vaddr;
1215 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1219 BOOST_FOREACH (CAddress& addr, vaddr)
1221 if (addr.GetByte(3) != 127)
1224 AddAddress(addr, 0, &addrDB);
1228 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1233 printf("%d addresses found from DNS seeds\n", found);
1247 unsigned int pnSeed[] =
1249 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1250 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1251 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1252 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1253 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1254 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1255 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1256 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1257 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1258 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1259 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1260 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1261 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1262 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1263 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1264 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1265 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1266 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1267 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1268 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1269 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1270 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1271 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1272 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1273 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1274 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1275 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1276 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1277 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1278 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1279 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1280 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1281 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1282 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1283 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1284 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1285 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1286 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1287 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1288 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1289 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1290 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1291 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1292 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1293 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1294 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1295 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1296 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1297 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1298 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1299 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1300 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1301 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1302 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1303 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1304 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1305 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1306 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1307 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1308 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1309 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1310 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1311 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1312 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1317 void ThreadOpenConnections(void* parg)
1319 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1322 vnThreadsRunning[1]++;
1323 ThreadOpenConnections2(parg);
1324 vnThreadsRunning[1]--;
1326 catch (std::exception& e) {
1327 vnThreadsRunning[1]--;
1328 PrintException(&e, "ThreadOpenConnections()");
1330 vnThreadsRunning[1]--;
1331 PrintException(NULL, "ThreadOpenConnections()");
1333 printf("ThreadOpenConnections exiting\n");
1336 void ThreadOpenConnections2(void* parg)
1338 printf("ThreadOpenConnections started\n");
1340 // Connect to specific addresses
1341 if (mapArgs.count("-connect"))
1343 for (int64 nLoop = 0;; nLoop++)
1345 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1347 CAddress addr(strAddr, fAllowDNS);
1349 OpenNetworkConnection(addr);
1350 for (int i = 0; i < 10 && i < nLoop; i++)
1360 // Connect to manually added nodes first
1361 if (mapArgs.count("-addnode"))
1363 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1365 CAddress addr(strAddr, fAllowDNS);
1368 OpenNetworkConnection(addr);
1376 // Initiate network connections
1377 int64 nStart = GetTime();
1380 // Limit outbound connections
1381 vnThreadsRunning[1]--;
1386 CRITICAL_BLOCK(cs_vNodes)
1387 BOOST_FOREACH(CNode* pnode, vNodes)
1388 if (!pnode->fInbound)
1390 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1391 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1392 if (nOutbound < nMaxOutboundConnections)
1398 vnThreadsRunning[1]++;
1402 bool fAddSeeds = false;
1404 CRITICAL_BLOCK(cs_mapAddresses)
1406 // Add seed nodes if IRC isn't working
1407 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1408 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1414 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1416 // It'll only connect to one or two seed nodes because once it connects,
1417 // it'll get a pile of addresses with newer timestamps.
1418 // Seed nodes are given a random 'last seen time' of between one and two
1420 const int64 nOneWeek = 7*24*60*60;
1422 addr.ip = pnSeed[i];
1423 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1429 // Choose an address to connect to based on most recently seen
1431 CAddress addrConnect;
1432 int64 nBest = INT64_MIN;
1434 // Only connect to one address per a.b.?.? range.
1435 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1436 set<unsigned int> setConnected;
1437 CRITICAL_BLOCK(cs_vNodes)
1438 BOOST_FOREACH(CNode* pnode, vNodes)
1439 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1441 CRITICAL_BLOCK(cs_mapAddresses)
1443 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1445 const CAddress& addr = item.second;
1446 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1448 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1449 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1451 // Randomize the order in a deterministic way, putting the standard port first
1452 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1453 if (addr.port != htons(GetDefaultPort()))
1454 nRandomizer += 2 * 60 * 60;
1456 // Last seen Base retry frequency
1465 // 365 days 93 hours
1466 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1468 // Fast reconnect for one hour after last seen
1469 if (nSinceLastSeen < 60 * 60)
1472 // Limit retry frequency
1473 if (nSinceLastTry < nDelay)
1476 // If we have IRC, we'll be notified when they first come online,
1477 // and again every 24 hours by the refresh broadcast.
1478 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1481 // Only try the old stuff if we don't have enough connections
1482 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1485 // If multiple addresses are ready, prioritize by time since
1486 // last seen and time since last tried.
1487 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1496 if (addrConnect.IsValid())
1497 OpenNetworkConnection(addrConnect);
1501 bool OpenNetworkConnection(const CAddress& addrConnect)
1504 // Initiate outbound network connection
1508 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1511 vnThreadsRunning[1]--;
1512 CNode* pnode = ConnectNode(addrConnect);
1513 vnThreadsRunning[1]++;
1518 pnode->fNetworkNode = true;
1530 void ThreadMessageHandler(void* parg)
1532 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1535 vnThreadsRunning[2]++;
1536 ThreadMessageHandler2(parg);
1537 vnThreadsRunning[2]--;
1539 catch (std::exception& e) {
1540 vnThreadsRunning[2]--;
1541 PrintException(&e, "ThreadMessageHandler()");
1543 vnThreadsRunning[2]--;
1544 PrintException(NULL, "ThreadMessageHandler()");
1546 printf("ThreadMessageHandler exiting\n");
1549 void ThreadMessageHandler2(void* parg)
1551 printf("ThreadMessageHandler started\n");
1552 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1555 vector<CNode*> vNodesCopy;
1556 CRITICAL_BLOCK(cs_vNodes)
1558 vNodesCopy = vNodes;
1559 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1563 // Poll the connected nodes for messages
1564 CNode* pnodeTrickle = NULL;
1565 if (!vNodesCopy.empty())
1566 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1567 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1570 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1571 ProcessMessages(pnode);
1576 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1577 SendMessages(pnode, pnode == pnodeTrickle);
1582 CRITICAL_BLOCK(cs_vNodes)
1584 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1588 // Wait and allow messages to bunch up.
1589 // Reduce vnThreadsRunning so StopNode has permission to exit while
1590 // we're sleeping, but we must always check fShutdown after doing this.
1591 vnThreadsRunning[2]--;
1593 if (fRequestShutdown)
1595 vnThreadsRunning[2]++;
1606 bool BindListenPort(string& strError)
1610 addrLocalHost.port = htons(GetListenPort());
1613 // Initialize Windows Sockets
1615 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1616 if (ret != NO_ERROR)
1618 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1619 printf("%s\n", strError.c_str());
1624 // Create socket for listening for incoming connections
1625 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1626 if (hListenSocket == INVALID_SOCKET)
1628 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1629 printf("%s\n", strError.c_str());
1634 // Different way of disabling SIGPIPE on BSD
1635 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1639 // Allow binding if the port is still in TIME_WAIT state after
1640 // the program was closed and restarted. Not an issue on windows.
1641 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1645 // Set to nonblocking, incoming connections will also inherit this
1646 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1648 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1651 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1652 printf("%s\n", strError.c_str());
1656 // The sockaddr_in structure specifies the address family,
1657 // IP address, and port for the socket that is being bound
1658 struct sockaddr_in sockaddr;
1659 memset(&sockaddr, 0, sizeof(sockaddr));
1660 sockaddr.sin_family = AF_INET;
1661 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1662 sockaddr.sin_port = htons(GetListenPort());
1663 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1665 int nErr = WSAGetLastError();
1666 if (nErr == WSAEADDRINUSE)
1667 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1669 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1670 printf("%s\n", strError.c_str());
1673 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1675 // Listen for incoming connections
1676 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1678 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1679 printf("%s\n", strError.c_str());
1686 void StartNode(void* parg)
1688 if (pnodeLocalHost == NULL)
1689 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1692 // Get local host ip
1693 char pszHostName[1000] = "";
1694 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1696 vector<CAddress> vaddr;
1697 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1698 BOOST_FOREACH (const CAddress &addr, vaddr)
1699 if (addr.GetByte(3) != 127)
1701 addrLocalHost = addr;
1706 // Get local host ip
1707 struct ifaddrs* myaddrs;
1708 if (getifaddrs(&myaddrs) == 0)
1710 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1712 if (ifa->ifa_addr == NULL) continue;
1713 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1714 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1715 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1717 if (ifa->ifa_addr->sa_family == AF_INET)
1719 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1720 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1721 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1723 // Take the first IP that isn't loopback 127.x.x.x
1724 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1725 if (addr.IsValid() && addr.GetByte(3) != 127)
1727 addrLocalHost = addr;
1731 else if (ifa->ifa_addr->sa_family == AF_INET6)
1733 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1734 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1735 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1738 freeifaddrs(myaddrs);
1741 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1743 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1745 // Proxies can't take incoming connections
1746 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1747 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1751 CreateThread(ThreadGetMyExternalIP, NULL);
1758 if (GetBoolArg("-nodnsseed"))
1759 printf("DNS seeding disabled\n");
1761 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1762 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1764 // Map ports with UPnP
1768 // Get addresses from IRC and advertise ours
1769 if (!CreateThread(ThreadIRCSeed, NULL))
1770 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1772 // Send and receive from sockets, accept connections
1773 if (!CreateThread(ThreadSocketHandler, NULL))
1774 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1776 // Initiate outbound connections
1777 if (!CreateThread(ThreadOpenConnections, NULL))
1778 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1781 if (!CreateThread(ThreadMessageHandler, NULL))
1782 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1784 // Generate coins in the background
1785 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1790 printf("StopNode()\n");
1792 nTransactionsUpdated++;
1793 int64 nStart = GetTime();
1794 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1796 || vnThreadsRunning[5] > 0
1800 if (GetTime() - nStart > 20)
1804 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1805 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1806 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1807 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1808 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1809 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1810 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1811 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1827 BOOST_FOREACH(CNode* pnode, vNodes)
1828 if (pnode->hSocket != INVALID_SOCKET)
1829 closesocket(pnode->hSocket);
1830 if (hListenSocket != INVALID_SOCKET)
1831 if (closesocket(hListenSocket) == SOCKET_ERROR)
1832 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1835 // Shutdown Windows Sockets
1840 instance_of_cnetcleanup;