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 bool fUpdated = false;
448 CAddress addrFound = addr;
450 CRITICAL_BLOCK(cs_mapAddresses)
452 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
453 if (it == mapAddresses.end())
456 printf("AddAddress(%s)\n", addr.ToString().c_str());
457 mapAddresses.insert(make_pair(addr.GetKey(), addr));
463 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;
480 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
482 // Thread 1: begin db transaction (locks inside-db-mutex)
483 // then AddAddress (locks cs_mapAddresses)
484 // Thread 2: AddAddress (locks cs_mapAddresses)
485 // ... then db operation hangs waiting for inside-db-mutex
489 pAddrDB->WriteAddress(addrFound);
491 CAddrDB().WriteAddress(addrFound);
496 void AddressCurrentlyConnected(const CAddress& addr)
498 CRITICAL_BLOCK(cs_mapAddresses)
500 // Only if it's been published already
501 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
502 if (it != mapAddresses.end())
504 CAddress& addrFound = (*it).second;
505 int64 nUpdateInterval = 20 * 60;
506 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
508 // Periodically update most recently seen time
509 addrFound.nTime = GetAdjustedTime();
511 addrdb.WriteAddress(addrFound);
521 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
523 // If the dialog might get closed before the reply comes back,
524 // call this in the destructor so it doesn't get called after it's deleted.
525 CRITICAL_BLOCK(cs_vNodes)
527 BOOST_FOREACH(CNode* pnode, vNodes)
529 CRITICAL_BLOCK(pnode->cs_mapRequests)
531 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
533 CRequestTracker& tracker = (*mi).second;
534 if (tracker.fn == fn && tracker.param1 == param1)
535 pnode->mapRequests.erase(mi++);
551 // Subscription methods for the broadcast and subscription system.
552 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
554 // The subscription system uses a meet-in-the-middle strategy.
555 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
556 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
559 bool AnySubscribed(unsigned int nChannel)
561 if (pnodeLocalHost->IsSubscribed(nChannel))
563 CRITICAL_BLOCK(cs_vNodes)
564 BOOST_FOREACH(CNode* pnode, vNodes)
565 if (pnode->IsSubscribed(nChannel))
570 bool CNode::IsSubscribed(unsigned int nChannel)
572 if (nChannel >= vfSubscribe.size())
574 return vfSubscribe[nChannel];
577 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
579 if (nChannel >= vfSubscribe.size())
582 if (!AnySubscribed(nChannel))
585 CRITICAL_BLOCK(cs_vNodes)
586 BOOST_FOREACH(CNode* pnode, vNodes)
588 pnode->PushMessage("subscribe", nChannel, nHops);
591 vfSubscribe[nChannel] = true;
594 void CNode::CancelSubscribe(unsigned int nChannel)
596 if (nChannel >= vfSubscribe.size())
599 // Prevent from relaying cancel if wasn't subscribed
600 if (!vfSubscribe[nChannel])
602 vfSubscribe[nChannel] = false;
604 if (!AnySubscribed(nChannel))
606 // Relay subscription cancel
607 CRITICAL_BLOCK(cs_vNodes)
608 BOOST_FOREACH(CNode* pnode, vNodes)
610 pnode->PushMessage("sub-cancel", nChannel);
622 CNode* FindNode(unsigned int ip)
624 CRITICAL_BLOCK(cs_vNodes)
626 BOOST_FOREACH(CNode* pnode, vNodes)
627 if (pnode->addr.ip == ip)
633 CNode* FindNode(CAddress addr)
635 CRITICAL_BLOCK(cs_vNodes)
637 BOOST_FOREACH(CNode* pnode, vNodes)
638 if (pnode->addr == addr)
644 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
646 if (addrConnect.ip == addrLocalHost.ip)
649 // Look for an existing connection
650 CNode* pnode = FindNode(addrConnect.ip);
654 pnode->AddRef(nTimeout);
661 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
662 addrConnect.ToString().c_str(),
663 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
664 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
666 CRITICAL_BLOCK(cs_mapAddresses)
667 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
671 if (ConnectSocket(addrConnect, hSocket))
674 printf("connected %s\n", addrConnect.ToString().c_str());
676 // Set to nonblocking
679 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
680 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
682 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
683 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
687 CNode* pnode = new CNode(hSocket, addrConnect, false);
689 pnode->AddRef(nTimeout);
692 CRITICAL_BLOCK(cs_vNodes)
693 vNodes.push_back(pnode);
695 pnode->nTimeConnected = GetTime();
704 void CNode::CloseSocketDisconnect()
707 if (hSocket != INVALID_SOCKET)
710 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
711 printf("disconnecting node %s\n", addr.ToString().c_str());
712 closesocket(hSocket);
713 hSocket = INVALID_SOCKET;
717 void CNode::Cleanup()
719 // All of a nodes broadcasts and subscriptions are automatically torn down
720 // when it goes down, so a node has to stay up to keep its broadcast going.
722 // Cancel subscriptions
723 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
724 if (vfSubscribe[nChannel])
725 CancelSubscribe(nChannel);
740 void ThreadSocketHandler(void* parg)
742 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
745 vnThreadsRunning[0]++;
746 ThreadSocketHandler2(parg);
747 vnThreadsRunning[0]--;
749 catch (std::exception& e) {
750 vnThreadsRunning[0]--;
751 PrintException(&e, "ThreadSocketHandler()");
753 vnThreadsRunning[0]--;
754 throw; // support pthread_cancel()
756 printf("ThreadSocketHandler exiting\n");
759 void ThreadSocketHandler2(void* parg)
761 printf("ThreadSocketHandler started\n");
762 list<CNode*> vNodesDisconnected;
763 int nPrevNodeCount = 0;
770 CRITICAL_BLOCK(cs_vNodes)
772 // Disconnect unused nodes
773 vector<CNode*> vNodesCopy = vNodes;
774 BOOST_FOREACH(CNode* pnode, vNodesCopy)
776 if (pnode->fDisconnect ||
777 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
779 // remove from vNodes
780 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
782 // close socket and cleanup
783 pnode->CloseSocketDisconnect();
786 // hold in disconnected pool until all refs are released
787 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
788 if (pnode->fNetworkNode || pnode->fInbound)
790 vNodesDisconnected.push_back(pnode);
794 // Delete disconnected nodes
795 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
796 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
798 // wait until threads are done using it
799 if (pnode->GetRefCount() <= 0)
801 bool fDelete = false;
802 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
803 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
804 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
805 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
809 vNodesDisconnected.remove(pnode);
815 if (vNodes.size() != nPrevNodeCount)
817 nPrevNodeCount = vNodes.size();
823 // Find which sockets have data to receive
825 struct timeval timeout;
827 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
834 FD_ZERO(&fdsetError);
835 SOCKET hSocketMax = 0;
837 if(hListenSocket != INVALID_SOCKET)
838 FD_SET(hListenSocket, &fdsetRecv);
839 hSocketMax = max(hSocketMax, hListenSocket);
840 CRITICAL_BLOCK(cs_vNodes)
842 BOOST_FOREACH(CNode* pnode, vNodes)
844 if (pnode->hSocket == INVALID_SOCKET)
846 FD_SET(pnode->hSocket, &fdsetRecv);
847 FD_SET(pnode->hSocket, &fdsetError);
848 hSocketMax = max(hSocketMax, pnode->hSocket);
849 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
850 if (!pnode->vSend.empty())
851 FD_SET(pnode->hSocket, &fdsetSend);
855 vnThreadsRunning[0]--;
856 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
857 vnThreadsRunning[0]++;
860 if (nSelect == SOCKET_ERROR)
862 int nErr = WSAGetLastError();
865 printf("socket select error %d\n", nErr);
866 for (int i = 0; i <= hSocketMax; i++)
867 FD_SET(i, &fdsetRecv);
870 FD_ZERO(&fdsetError);
871 Sleep(timeout.tv_usec/1000);
876 // Accept new connections
878 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
880 struct sockaddr_in sockaddr;
881 socklen_t len = sizeof(sockaddr);
882 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
883 CAddress addr(sockaddr);
886 CRITICAL_BLOCK(cs_vNodes)
887 BOOST_FOREACH(CNode* pnode, vNodes)
890 if (hSocket == INVALID_SOCKET)
892 if (WSAGetLastError() != WSAEWOULDBLOCK)
893 printf("socket error accept failed: %d\n", WSAGetLastError());
895 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
897 closesocket(hSocket);
901 printf("accepted connection %s\n", addr.ToString().c_str());
902 CNode* pnode = new CNode(hSocket, addr, true);
904 CRITICAL_BLOCK(cs_vNodes)
905 vNodes.push_back(pnode);
911 // Service each socket
913 vector<CNode*> vNodesCopy;
914 CRITICAL_BLOCK(cs_vNodes)
917 BOOST_FOREACH(CNode* pnode, vNodesCopy)
920 BOOST_FOREACH(CNode* pnode, vNodesCopy)
928 if (pnode->hSocket == INVALID_SOCKET)
930 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
932 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
934 CDataStream& vRecv = pnode->vRecv;
935 unsigned int nPos = vRecv.size();
937 if (nPos > ReceiveBufferSize()) {
938 if (!pnode->fDisconnect)
939 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
940 pnode->CloseSocketDisconnect();
943 // typical socket buffer is 8K-64K
944 char pchBuf[0x10000];
945 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
948 vRecv.resize(nPos + nBytes);
949 memcpy(&vRecv[nPos], pchBuf, nBytes);
950 pnode->nLastRecv = GetTime();
952 else if (nBytes == 0)
954 // socket closed gracefully
955 if (!pnode->fDisconnect)
956 printf("socket closed\n");
957 pnode->CloseSocketDisconnect();
962 int nErr = WSAGetLastError();
963 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
965 if (!pnode->fDisconnect)
966 printf("socket recv error %d\n", nErr);
967 pnode->CloseSocketDisconnect();
977 if (pnode->hSocket == INVALID_SOCKET)
979 if (FD_ISSET(pnode->hSocket, &fdsetSend))
981 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
983 CDataStream& vSend = pnode->vSend;
986 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
989 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
990 pnode->nLastSend = GetTime();
995 int nErr = WSAGetLastError();
996 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
998 printf("socket send error %d\n", nErr);
999 pnode->CloseSocketDisconnect();
1002 if (vSend.size() > SendBufferSize()) {
1003 if (!pnode->fDisconnect)
1004 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1005 pnode->CloseSocketDisconnect();
1012 // Inactivity checking
1014 if (pnode->vSend.empty())
1015 pnode->nLastSendEmpty = GetTime();
1016 if (GetTime() - pnode->nTimeConnected > 60)
1018 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1020 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1021 pnode->fDisconnect = true;
1023 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1025 printf("socket not sending\n");
1026 pnode->fDisconnect = true;
1028 else if (GetTime() - pnode->nLastRecv > 90*60)
1030 printf("socket inactivity timeout\n");
1031 pnode->fDisconnect = true;
1035 CRITICAL_BLOCK(cs_vNodes)
1037 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1054 void ThreadMapPort(void* parg)
1056 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1059 vnThreadsRunning[5]++;
1060 ThreadMapPort2(parg);
1061 vnThreadsRunning[5]--;
1063 catch (std::exception& e) {
1064 vnThreadsRunning[5]--;
1065 PrintException(&e, "ThreadMapPort()");
1067 vnThreadsRunning[5]--;
1068 PrintException(NULL, "ThreadMapPort()");
1070 printf("ThreadMapPort exiting\n");
1073 void ThreadMapPort2(void* parg)
1075 printf("ThreadMapPort started\n");
1078 sprintf(port, "%d", GetListenPort());
1080 const char * rootdescurl = 0;
1081 const char * multicastif = 0;
1082 const char * minissdpdpath = 0;
1084 struct UPNPDev * devlist = 0;
1087 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1089 struct UPNPUrls urls;
1090 struct IGDdatas data;
1093 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1098 string strDesc = "Bitcoin " + FormatFullVersion();
1099 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1100 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1102 if(r!=UPNPCOMMAND_SUCCESS)
1103 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1104 port, port, lanaddr, r, strupnperror(r));
1106 printf("UPnP Port Mapping successful.\n");
1108 if (fShutdown || !fUseUPnP)
1110 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1111 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1112 freeUPNPDevlist(devlist); devlist = 0;
1113 FreeUPNPUrls(&urls);
1119 printf("No valid UPnP IGDs found\n");
1120 freeUPNPDevlist(devlist); devlist = 0;
1122 FreeUPNPUrls(&urls);
1124 if (fShutdown || !fUseUPnP)
1131 void MapPort(bool fMapPort)
1133 if (fUseUPnP != fMapPort)
1135 fUseUPnP = fMapPort;
1136 WriteSetting("fUseUPnP", fUseUPnP);
1138 if (fUseUPnP && vnThreadsRunning[5] < 1)
1140 if (!CreateThread(ThreadMapPort, NULL))
1141 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1145 void MapPort(bool /* unused fMapPort */)
1147 // Intentionally left blank.
1160 static const char *strDNSSeed[] = {
1162 "bitseed.bitcoin.org.uk",
1163 "dnsseed.bluematt.me",
1166 void DNSAddressSeed()
1172 printf("Loading addresses from DNS seeds (could take a while)\n");
1176 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1177 vector<CAddress> vaddr;
1178 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1180 BOOST_FOREACH (CAddress& addr, vaddr)
1182 if (addr.GetByte(3) != 127)
1185 AddAddress(addr, 0, &addrDB);
1192 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1195 printf("%d addresses found from DNS seeds\n", found);
1200 unsigned int pnSeed[] =
1202 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1203 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1204 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1205 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1206 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1207 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1208 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1209 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1210 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1211 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1212 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1213 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1214 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1215 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1216 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1217 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1218 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1219 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1220 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1221 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1222 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1223 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1224 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1225 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1226 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1227 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1228 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1229 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1230 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1231 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1232 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1233 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1234 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1235 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1236 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1237 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1238 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1239 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1240 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1241 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1242 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1243 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1244 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1245 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1246 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1247 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1248 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1249 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1250 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1251 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1252 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1253 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1254 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1255 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1256 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1257 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1258 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1259 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1260 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1261 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1262 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1263 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1264 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1265 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1270 void ThreadOpenConnections(void* parg)
1272 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1275 vnThreadsRunning[1]++;
1276 ThreadOpenConnections2(parg);
1277 vnThreadsRunning[1]--;
1279 catch (std::exception& e) {
1280 vnThreadsRunning[1]--;
1281 PrintException(&e, "ThreadOpenConnections()");
1283 vnThreadsRunning[1]--;
1284 PrintException(NULL, "ThreadOpenConnections()");
1286 printf("ThreadOpenConnections exiting\n");
1289 void ThreadOpenConnections2(void* parg)
1291 printf("ThreadOpenConnections started\n");
1293 // Connect to specific addresses
1294 if (mapArgs.count("-connect"))
1296 for (int64 nLoop = 0;; nLoop++)
1298 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1300 CAddress addr(strAddr, fAllowDNS);
1302 OpenNetworkConnection(addr);
1303 for (int i = 0; i < 10 && i < nLoop; i++)
1313 // Connect to manually added nodes first
1314 if (mapArgs.count("-addnode"))
1316 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1318 CAddress addr(strAddr, fAllowDNS);
1321 OpenNetworkConnection(addr);
1329 // Initiate network connections
1330 int64 nStart = GetTime();
1333 // Limit outbound connections
1334 vnThreadsRunning[1]--;
1339 CRITICAL_BLOCK(cs_vNodes)
1340 BOOST_FOREACH(CNode* pnode, vNodes)
1341 if (!pnode->fInbound)
1343 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1344 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1345 if (nOutbound < nMaxOutboundConnections)
1351 vnThreadsRunning[1]++;
1355 CRITICAL_BLOCK(cs_mapAddresses)
1357 // Add seed nodes if IRC isn't working
1358 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1359 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1361 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1363 // It'll only connect to one or two seed nodes because once it connects,
1364 // it'll get a pile of addresses with newer timestamps.
1365 // Seed nodes are given a random 'last seen time' of between one and two
1367 const int64 nOneWeek = 7*24*60*60;
1369 addr.ip = pnSeed[i];
1370 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1378 // Choose an address to connect to based on most recently seen
1380 CAddress addrConnect;
1381 int64 nBest = INT64_MIN;
1383 // Only connect to one address per a.b.?.? range.
1384 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1385 set<unsigned int> setConnected;
1386 CRITICAL_BLOCK(cs_vNodes)
1387 BOOST_FOREACH(CNode* pnode, vNodes)
1388 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1390 CRITICAL_BLOCK(cs_mapAddresses)
1392 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1394 const CAddress& addr = item.second;
1395 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1397 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1398 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1400 // Randomize the order in a deterministic way, putting the standard port first
1401 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1402 if (addr.port != htons(GetDefaultPort()))
1403 nRandomizer += 2 * 60 * 60;
1405 // Last seen Base retry frequency
1414 // 365 days 93 hours
1415 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1417 // Fast reconnect for one hour after last seen
1418 if (nSinceLastSeen < 60 * 60)
1421 // Limit retry frequency
1422 if (nSinceLastTry < nDelay)
1425 // If we have IRC, we'll be notified when they first come online,
1426 // and again every 24 hours by the refresh broadcast.
1427 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1430 // Only try the old stuff if we don't have enough connections
1431 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1434 // If multiple addresses are ready, prioritize by time since
1435 // last seen and time since last tried.
1436 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1445 if (addrConnect.IsValid())
1446 OpenNetworkConnection(addrConnect);
1450 bool OpenNetworkConnection(const CAddress& addrConnect)
1453 // Initiate outbound network connection
1457 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1460 vnThreadsRunning[1]--;
1461 CNode* pnode = ConnectNode(addrConnect);
1462 vnThreadsRunning[1]++;
1467 pnode->fNetworkNode = true;
1479 void ThreadMessageHandler(void* parg)
1481 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1484 vnThreadsRunning[2]++;
1485 ThreadMessageHandler2(parg);
1486 vnThreadsRunning[2]--;
1488 catch (std::exception& e) {
1489 vnThreadsRunning[2]--;
1490 PrintException(&e, "ThreadMessageHandler()");
1492 vnThreadsRunning[2]--;
1493 PrintException(NULL, "ThreadMessageHandler()");
1495 printf("ThreadMessageHandler exiting\n");
1498 void ThreadMessageHandler2(void* parg)
1500 printf("ThreadMessageHandler started\n");
1501 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1504 vector<CNode*> vNodesCopy;
1505 CRITICAL_BLOCK(cs_vNodes)
1507 vNodesCopy = vNodes;
1508 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1512 // Poll the connected nodes for messages
1513 CNode* pnodeTrickle = NULL;
1514 if (!vNodesCopy.empty())
1515 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1516 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1519 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1520 ProcessMessages(pnode);
1525 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1526 SendMessages(pnode, pnode == pnodeTrickle);
1531 CRITICAL_BLOCK(cs_vNodes)
1533 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1537 // Wait and allow messages to bunch up.
1538 // Reduce vnThreadsRunning so StopNode has permission to exit while
1539 // we're sleeping, but we must always check fShutdown after doing this.
1540 vnThreadsRunning[2]--;
1542 if (fRequestShutdown)
1544 vnThreadsRunning[2]++;
1555 bool BindListenPort(string& strError)
1559 addrLocalHost.port = htons(GetListenPort());
1562 // Initialize Windows Sockets
1564 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1565 if (ret != NO_ERROR)
1567 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1568 printf("%s\n", strError.c_str());
1573 // Create socket for listening for incoming connections
1574 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1575 if (hListenSocket == INVALID_SOCKET)
1577 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1578 printf("%s\n", strError.c_str());
1583 // Different way of disabling SIGPIPE on BSD
1584 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1588 // Allow binding if the port is still in TIME_WAIT state after
1589 // the program was closed and restarted. Not an issue on windows.
1590 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1594 // Set to nonblocking, incoming connections will also inherit this
1595 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1597 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1600 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1601 printf("%s\n", strError.c_str());
1605 // The sockaddr_in structure specifies the address family,
1606 // IP address, and port for the socket that is being bound
1607 struct sockaddr_in sockaddr;
1608 memset(&sockaddr, 0, sizeof(sockaddr));
1609 sockaddr.sin_family = AF_INET;
1610 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1611 sockaddr.sin_port = htons(GetListenPort());
1612 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1614 int nErr = WSAGetLastError();
1615 if (nErr == WSAEADDRINUSE)
1616 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1618 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1619 printf("%s\n", strError.c_str());
1622 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1624 // Listen for incoming connections
1625 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1627 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1628 printf("%s\n", strError.c_str());
1635 void StartNode(void* parg)
1637 if (pnodeLocalHost == NULL)
1638 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1641 // Get local host ip
1642 char pszHostName[1000] = "";
1643 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1645 vector<CAddress> vaddr;
1646 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1647 BOOST_FOREACH (const CAddress &addr, vaddr)
1648 if (addr.GetByte(3) != 127)
1650 addrLocalHost = addr;
1655 // Get local host ip
1656 struct ifaddrs* myaddrs;
1657 if (getifaddrs(&myaddrs) == 0)
1659 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1661 if (ifa->ifa_addr == NULL) continue;
1662 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1663 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1664 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1666 if (ifa->ifa_addr->sa_family == AF_INET)
1668 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1669 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1670 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1672 // Take the first IP that isn't loopback 127.x.x.x
1673 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1674 if (addr.IsValid() && addr.GetByte(3) != 127)
1676 addrLocalHost = addr;
1680 else if (ifa->ifa_addr->sa_family == AF_INET6)
1682 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1683 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1684 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1687 freeifaddrs(myaddrs);
1690 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1692 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1694 // Proxies can't take incoming connections
1695 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1696 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1700 CreateThread(ThreadGetMyExternalIP, NULL);
1707 // Map ports with UPnP
1711 // Get addresses from IRC and advertise ours
1712 if (!CreateThread(ThreadIRCSeed, NULL))
1713 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1715 // Send and receive from sockets, accept connections
1716 CreateThread(ThreadSocketHandler, NULL);
1718 // Initiate outbound connections
1719 if (!CreateThread(ThreadOpenConnections, NULL))
1720 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1723 if (!CreateThread(ThreadMessageHandler, NULL))
1724 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1726 // Generate coins in the background
1727 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1732 printf("StopNode()\n");
1734 nTransactionsUpdated++;
1735 int64 nStart = GetTime();
1736 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1738 || vnThreadsRunning[5] > 0
1742 if (GetTime() - nStart > 20)
1746 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1747 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1748 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1749 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1750 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1751 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1752 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1768 BOOST_FOREACH(CNode* pnode, vNodes)
1769 if (pnode->hSocket != INVALID_SOCKET)
1770 closesocket(pnode->hSocket);
1771 if (hListenSocket != INVALID_SOCKET)
1772 if (closesocket(hListenSocket) == SOCKET_ERROR)
1773 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1776 // Shutdown Windows Sockets
1781 instance_of_cnetcleanup;