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 CNode* pnodeLocalHost = NULL;
49 uint64 nLocalHostNonce = 0;
50 array<int, 10> vnThreadsRunning;
51 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;
1077 struct UPNPDev * devlist = 0;
1080 #ifndef UPNPDISCOVER_SUCCESS
1082 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1086 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 #ifndef UPNPDISCOVER_SUCCESS
1101 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1102 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1105 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1106 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1109 if(r!=UPNPCOMMAND_SUCCESS)
1110 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1111 port, port, lanaddr, r, strupnperror(r));
1113 printf("UPnP Port Mapping successful.\n");
1115 if (fShutdown || !fUseUPnP)
1117 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1118 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1119 freeUPNPDevlist(devlist); devlist = 0;
1120 FreeUPNPUrls(&urls);
1126 printf("No valid UPnP IGDs found\n");
1127 freeUPNPDevlist(devlist); devlist = 0;
1129 FreeUPNPUrls(&urls);
1131 if (fShutdown || !fUseUPnP)
1138 void MapPort(bool fMapPort)
1140 if (fUseUPnP != fMapPort)
1142 fUseUPnP = fMapPort;
1143 WriteSetting("fUseUPnP", fUseUPnP);
1145 if (fUseUPnP && vnThreadsRunning[5] < 1)
1147 if (!CreateThread(ThreadMapPort, NULL))
1148 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1152 void MapPort(bool /* unused fMapPort */)
1154 // Intentionally left blank.
1167 static const char *strDNSSeed[] = {
1169 "bitseed.bitcoin.org.uk",
1170 "dnsseed.bluematt.me",
1173 void DNSAddressSeed()
1179 printf("Loading addresses from DNS seeds (could take a while)\n");
1183 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1184 vector<CAddress> vaddr;
1185 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1187 BOOST_FOREACH (CAddress& addr, vaddr)
1189 if (addr.GetByte(3) != 127)
1192 AddAddress(addr, 0, &addrDB);
1199 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1202 printf("%d addresses found from DNS seeds\n", found);
1207 unsigned int pnSeed[] =
1209 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1210 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1211 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1212 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1213 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1214 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1215 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1216 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1217 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1218 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1219 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1220 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1221 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1222 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1223 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1224 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1225 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1226 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1227 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1228 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1229 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1230 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1231 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1232 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1233 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1234 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1235 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1236 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1237 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1238 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1239 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1240 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1241 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1242 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1243 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1244 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1245 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1246 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1247 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1248 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1253 void ThreadOpenConnections(void* parg)
1255 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1258 vnThreadsRunning[1]++;
1259 ThreadOpenConnections2(parg);
1260 vnThreadsRunning[1]--;
1262 catch (std::exception& e) {
1263 vnThreadsRunning[1]--;
1264 PrintException(&e, "ThreadOpenConnections()");
1266 vnThreadsRunning[1]--;
1267 PrintException(NULL, "ThreadOpenConnections()");
1269 printf("ThreadOpenConnections exiting\n");
1272 void ThreadOpenConnections2(void* parg)
1274 printf("ThreadOpenConnections started\n");
1276 // Connect to specific addresses
1277 if (mapArgs.count("-connect"))
1279 for (int64 nLoop = 0;; nLoop++)
1281 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1283 CAddress addr(strAddr, fAllowDNS);
1285 OpenNetworkConnection(addr);
1286 for (int i = 0; i < 10 && i < nLoop; i++)
1296 // Connect to manually added nodes first
1297 if (mapArgs.count("-addnode"))
1299 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1301 CAddress addr(strAddr, fAllowDNS);
1304 OpenNetworkConnection(addr);
1312 // Initiate network connections
1313 int64 nStart = GetTime();
1316 // Limit outbound connections
1317 vnThreadsRunning[1]--;
1322 CRITICAL_BLOCK(cs_vNodes)
1323 BOOST_FOREACH(CNode* pnode, vNodes)
1324 if (!pnode->fInbound)
1326 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1327 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1328 if (nOutbound < nMaxOutboundConnections)
1334 vnThreadsRunning[1]++;
1338 CRITICAL_BLOCK(cs_mapAddresses)
1340 // Add seed nodes if IRC isn't working
1341 static bool fSeedUsed;
1342 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1343 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1345 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1347 // It'll only connect to one or two seed nodes because once it connects,
1348 // it'll get a pile of addresses with newer timestamps.
1350 addr.ip = pnSeed[i];
1357 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1359 // Disconnect seed nodes
1360 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1361 static int64 nSeedDisconnected;
1362 if (nSeedDisconnected == 0)
1364 nSeedDisconnected = GetTime();
1365 CRITICAL_BLOCK(cs_vNodes)
1366 BOOST_FOREACH(CNode* pnode, vNodes)
1367 if (setSeed.count(pnode->addr.ip))
1368 pnode->fDisconnect = true;
1371 // Keep setting timestamps to 0 so they won't reconnect
1372 if (GetTime() - nSeedDisconnected < 60 * 60)
1374 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1376 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1378 item.second.nTime = 0;
1379 CAddrDB().WriteAddress(item.second);
1388 // Choose an address to connect to based on most recently seen
1390 CAddress addrConnect;
1391 int64 nBest = INT64_MIN;
1393 // Only connect to one address per a.b.?.? range.
1394 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1395 set<unsigned int> setConnected;
1396 CRITICAL_BLOCK(cs_vNodes)
1397 BOOST_FOREACH(CNode* pnode, vNodes)
1398 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1400 CRITICAL_BLOCK(cs_mapAddresses)
1402 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1404 const CAddress& addr = item.second;
1405 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1407 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1408 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1410 // Randomize the order in a deterministic way, putting the standard port first
1411 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1412 if (addr.port != htons(GetDefaultPort()))
1413 nRandomizer += 2 * 60 * 60;
1415 // Last seen Base retry frequency
1424 // 365 days 93 hours
1425 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1427 // Fast reconnect for one hour after last seen
1428 if (nSinceLastSeen < 60 * 60)
1431 // Limit retry frequency
1432 if (nSinceLastTry < nDelay)
1435 // If we have IRC, we'll be notified when they first come online,
1436 // and again every 24 hours by the refresh broadcast.
1437 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1440 // Only try the old stuff if we don't have enough connections
1441 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1444 // If multiple addresses are ready, prioritize by time since
1445 // last seen and time since last tried.
1446 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1455 if (addrConnect.IsValid())
1456 OpenNetworkConnection(addrConnect);
1460 bool OpenNetworkConnection(const CAddress& addrConnect)
1463 // Initiate outbound network connection
1467 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1470 vnThreadsRunning[1]--;
1471 CNode* pnode = ConnectNode(addrConnect);
1472 vnThreadsRunning[1]++;
1477 pnode->fNetworkNode = true;
1489 void ThreadMessageHandler(void* parg)
1491 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1494 vnThreadsRunning[2]++;
1495 ThreadMessageHandler2(parg);
1496 vnThreadsRunning[2]--;
1498 catch (std::exception& e) {
1499 vnThreadsRunning[2]--;
1500 PrintException(&e, "ThreadMessageHandler()");
1502 vnThreadsRunning[2]--;
1503 PrintException(NULL, "ThreadMessageHandler()");
1505 printf("ThreadMessageHandler exiting\n");
1508 void ThreadMessageHandler2(void* parg)
1510 printf("ThreadMessageHandler started\n");
1511 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1514 vector<CNode*> vNodesCopy;
1515 CRITICAL_BLOCK(cs_vNodes)
1517 vNodesCopy = vNodes;
1518 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1522 // Poll the connected nodes for messages
1523 CNode* pnodeTrickle = NULL;
1524 if (!vNodesCopy.empty())
1525 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1526 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1529 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1530 ProcessMessages(pnode);
1535 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1536 SendMessages(pnode, pnode == pnodeTrickle);
1541 CRITICAL_BLOCK(cs_vNodes)
1543 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1547 // Wait and allow messages to bunch up.
1548 // Reduce vnThreadsRunning so StopNode has permission to exit while
1549 // we're sleeping, but we must always check fShutdown after doing this.
1550 vnThreadsRunning[2]--;
1552 if (fRequestShutdown)
1554 vnThreadsRunning[2]++;
1565 bool BindListenPort(string& strError)
1569 addrLocalHost.port = htons(GetListenPort());
1572 // Initialize Windows Sockets
1574 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1575 if (ret != NO_ERROR)
1577 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1578 printf("%s\n", strError.c_str());
1583 // Create socket for listening for incoming connections
1584 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1585 if (hListenSocket == INVALID_SOCKET)
1587 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1588 printf("%s\n", strError.c_str());
1593 // Different way of disabling SIGPIPE on BSD
1594 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1598 // Allow binding if the port is still in TIME_WAIT state after
1599 // the program was closed and restarted. Not an issue on windows.
1600 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1604 // Set to nonblocking, incoming connections will also inherit this
1605 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1607 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1610 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1611 printf("%s\n", strError.c_str());
1615 // The sockaddr_in structure specifies the address family,
1616 // IP address, and port for the socket that is being bound
1617 struct sockaddr_in sockaddr;
1618 memset(&sockaddr, 0, sizeof(sockaddr));
1619 sockaddr.sin_family = AF_INET;
1620 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1621 sockaddr.sin_port = htons(GetListenPort());
1622 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1624 int nErr = WSAGetLastError();
1625 if (nErr == WSAEADDRINUSE)
1626 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1628 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1629 printf("%s\n", strError.c_str());
1632 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1634 // Listen for incoming connections
1635 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1637 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1638 printf("%s\n", strError.c_str());
1645 void StartNode(void* parg)
1647 if (pnodeLocalHost == NULL)
1648 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1651 // Get local host ip
1652 char pszHostName[1000] = "";
1653 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1655 vector<CAddress> vaddr;
1656 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1657 BOOST_FOREACH (const CAddress &addr, vaddr)
1658 if (addr.GetByte(3) != 127)
1660 addrLocalHost = addr;
1665 // Get local host ip
1666 struct ifaddrs* myaddrs;
1667 if (getifaddrs(&myaddrs) == 0)
1669 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1671 if (ifa->ifa_addr == NULL) continue;
1672 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1673 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1674 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1676 if (ifa->ifa_addr->sa_family == AF_INET)
1678 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1679 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1680 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1682 // Take the first IP that isn't loopback 127.x.x.x
1683 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1684 if (addr.IsValid() && addr.GetByte(3) != 127)
1686 addrLocalHost = addr;
1690 else if (ifa->ifa_addr->sa_family == AF_INET6)
1692 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1693 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1694 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1697 freeifaddrs(myaddrs);
1700 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1702 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1704 // Proxies can't take incoming connections
1705 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1706 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1710 CreateThread(ThreadGetMyExternalIP, NULL);
1717 // Map ports with UPnP
1721 // Get addresses from IRC and advertise ours
1722 if (!CreateThread(ThreadIRCSeed, NULL))
1723 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1725 // Send and receive from sockets, accept connections
1726 CreateThread(ThreadSocketHandler, NULL, true);
1728 // Initiate outbound connections
1729 if (!CreateThread(ThreadOpenConnections, NULL))
1730 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1733 if (!CreateThread(ThreadMessageHandler, NULL))
1734 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1736 // Generate coins in the background
1737 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1742 printf("StopNode()\n");
1744 nTransactionsUpdated++;
1745 int64 nStart = GetTime();
1746 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1748 || vnThreadsRunning[5] > 0
1752 if (GetTime() - nStart > 20)
1756 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1757 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1758 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1759 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1760 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1761 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1762 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1778 BOOST_FOREACH(CNode* pnode, vNodes)
1779 if (pnode->hSocket != INVALID_SOCKET)
1780 closesocket(pnode->hSocket);
1781 if (hListenSocket != INVALID_SOCKET)
1782 if (closesocket(hListenSocket) == SOCKET_ERROR)
1783 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1786 // Shutdown Windows Sockets
1791 instance_of_cnetcleanup;