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;
1078 struct UPNPDev * devlist = 0;
1081 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1083 struct UPNPUrls urls;
1084 struct IGDdatas data;
1087 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1092 string strDesc = "Bitcoin " + FormatFullVersion();
1093 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1094 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1096 if(r!=UPNPCOMMAND_SUCCESS)
1097 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1098 port, port, lanaddr, r, strupnperror(r));
1100 printf("UPnP Port Mapping successful.\n");
1102 if (fShutdown || !fUseUPnP)
1104 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1105 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1106 freeUPNPDevlist(devlist); devlist = 0;
1107 FreeUPNPUrls(&urls);
1113 printf("No valid UPnP IGDs found\n");
1114 freeUPNPDevlist(devlist); devlist = 0;
1116 FreeUPNPUrls(&urls);
1118 if (fShutdown || !fUseUPnP)
1125 void MapPort(bool fMapPort)
1127 if (fUseUPnP != fMapPort)
1129 fUseUPnP = fMapPort;
1130 WriteSetting("fUseUPnP", fUseUPnP);
1132 if (fUseUPnP && vnThreadsRunning[5] < 1)
1134 if (!CreateThread(ThreadMapPort, NULL))
1135 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1139 void MapPort(bool /* unused fMapPort */)
1141 // Intentionally left blank.
1154 static const char *strDNSSeed[] = {
1156 "bitseed.bitcoin.org.uk",
1157 "dnsseed.bluematt.me",
1160 void DNSAddressSeed()
1166 printf("Loading addresses from DNS seeds (could take a while)\n");
1170 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1171 vector<CAddress> vaddr;
1172 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1174 BOOST_FOREACH (CAddress& addr, vaddr)
1176 if (addr.GetByte(3) != 127)
1179 AddAddress(addr, 0, &addrDB);
1186 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1189 printf("%d addresses found from DNS seeds\n", found);
1194 unsigned int pnSeed[] =
1196 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1197 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1198 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1199 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1200 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1201 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1202 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1203 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1204 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1205 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1206 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1207 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1208 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1209 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1210 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1211 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1212 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1213 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1214 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1215 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1216 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1217 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1218 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1219 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1220 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1221 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1222 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1223 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1224 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1225 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1226 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1227 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1228 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1229 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1230 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1231 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1232 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1233 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1234 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1235 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1240 void ThreadOpenConnections(void* parg)
1242 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1245 vnThreadsRunning[1]++;
1246 ThreadOpenConnections2(parg);
1247 vnThreadsRunning[1]--;
1249 catch (std::exception& e) {
1250 vnThreadsRunning[1]--;
1251 PrintException(&e, "ThreadOpenConnections()");
1253 vnThreadsRunning[1]--;
1254 PrintException(NULL, "ThreadOpenConnections()");
1256 printf("ThreadOpenConnections exiting\n");
1259 void ThreadOpenConnections2(void* parg)
1261 printf("ThreadOpenConnections started\n");
1263 // Connect to specific addresses
1264 if (mapArgs.count("-connect"))
1266 for (int64 nLoop = 0;; nLoop++)
1268 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1270 CAddress addr(strAddr, fAllowDNS);
1272 OpenNetworkConnection(addr);
1273 for (int i = 0; i < 10 && i < nLoop; i++)
1283 // Connect to manually added nodes first
1284 if (mapArgs.count("-addnode"))
1286 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1288 CAddress addr(strAddr, fAllowDNS);
1291 OpenNetworkConnection(addr);
1299 // Initiate network connections
1300 int64 nStart = GetTime();
1303 // Limit outbound connections
1304 vnThreadsRunning[1]--;
1309 CRITICAL_BLOCK(cs_vNodes)
1310 BOOST_FOREACH(CNode* pnode, vNodes)
1311 if (!pnode->fInbound)
1313 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1314 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1315 if (nOutbound < nMaxOutboundConnections)
1321 vnThreadsRunning[1]++;
1325 CRITICAL_BLOCK(cs_mapAddresses)
1327 // Add seed nodes if IRC isn't working
1328 static bool fSeedUsed;
1329 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1330 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1332 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1334 // It'll only connect to one or two seed nodes because once it connects,
1335 // it'll get a pile of addresses with newer timestamps.
1337 addr.ip = pnSeed[i];
1344 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1346 // Disconnect seed nodes
1347 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1348 static int64 nSeedDisconnected;
1349 if (nSeedDisconnected == 0)
1351 nSeedDisconnected = GetTime();
1352 CRITICAL_BLOCK(cs_vNodes)
1353 BOOST_FOREACH(CNode* pnode, vNodes)
1354 if (setSeed.count(pnode->addr.ip))
1355 pnode->fDisconnect = true;
1358 // Keep setting timestamps to 0 so they won't reconnect
1359 if (GetTime() - nSeedDisconnected < 60 * 60)
1361 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1363 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1365 item.second.nTime = 0;
1366 CAddrDB().WriteAddress(item.second);
1375 // Choose an address to connect to based on most recently seen
1377 CAddress addrConnect;
1378 int64 nBest = INT64_MIN;
1380 // Only connect to one address per a.b.?.? range.
1381 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1382 set<unsigned int> setConnected;
1383 CRITICAL_BLOCK(cs_vNodes)
1384 BOOST_FOREACH(CNode* pnode, vNodes)
1385 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1387 CRITICAL_BLOCK(cs_mapAddresses)
1389 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1391 const CAddress& addr = item.second;
1392 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1394 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1395 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1397 // Randomize the order in a deterministic way, putting the standard port first
1398 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1399 if (addr.port != htons(GetDefaultPort()))
1400 nRandomizer += 2 * 60 * 60;
1402 // Last seen Base retry frequency
1411 // 365 days 93 hours
1412 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1414 // Fast reconnect for one hour after last seen
1415 if (nSinceLastSeen < 60 * 60)
1418 // Limit retry frequency
1419 if (nSinceLastTry < nDelay)
1422 // If we have IRC, we'll be notified when they first come online,
1423 // and again every 24 hours by the refresh broadcast.
1424 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1427 // Only try the old stuff if we don't have enough connections
1428 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1431 // If multiple addresses are ready, prioritize by time since
1432 // last seen and time since last tried.
1433 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1442 if (addrConnect.IsValid())
1443 OpenNetworkConnection(addrConnect);
1447 bool OpenNetworkConnection(const CAddress& addrConnect)
1450 // Initiate outbound network connection
1454 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1457 vnThreadsRunning[1]--;
1458 CNode* pnode = ConnectNode(addrConnect);
1459 vnThreadsRunning[1]++;
1464 pnode->fNetworkNode = true;
1476 void ThreadMessageHandler(void* parg)
1478 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1481 vnThreadsRunning[2]++;
1482 ThreadMessageHandler2(parg);
1483 vnThreadsRunning[2]--;
1485 catch (std::exception& e) {
1486 vnThreadsRunning[2]--;
1487 PrintException(&e, "ThreadMessageHandler()");
1489 vnThreadsRunning[2]--;
1490 PrintException(NULL, "ThreadMessageHandler()");
1492 printf("ThreadMessageHandler exiting\n");
1495 void ThreadMessageHandler2(void* parg)
1497 printf("ThreadMessageHandler started\n");
1498 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1501 vector<CNode*> vNodesCopy;
1502 CRITICAL_BLOCK(cs_vNodes)
1504 vNodesCopy = vNodes;
1505 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1509 // Poll the connected nodes for messages
1510 CNode* pnodeTrickle = NULL;
1511 if (!vNodesCopy.empty())
1512 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1513 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1516 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1517 ProcessMessages(pnode);
1522 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1523 SendMessages(pnode, pnode == pnodeTrickle);
1528 CRITICAL_BLOCK(cs_vNodes)
1530 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1534 // Wait and allow messages to bunch up.
1535 // Reduce vnThreadsRunning so StopNode has permission to exit while
1536 // we're sleeping, but we must always check fShutdown after doing this.
1537 vnThreadsRunning[2]--;
1539 if (fRequestShutdown)
1541 vnThreadsRunning[2]++;
1552 bool BindListenPort(string& strError)
1556 addrLocalHost.port = htons(GetListenPort());
1559 // Initialize Windows Sockets
1561 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1562 if (ret != NO_ERROR)
1564 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1565 printf("%s\n", strError.c_str());
1570 // Create socket for listening for incoming connections
1571 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1572 if (hListenSocket == INVALID_SOCKET)
1574 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1575 printf("%s\n", strError.c_str());
1580 // Different way of disabling SIGPIPE on BSD
1581 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1585 // Allow binding if the port is still in TIME_WAIT state after
1586 // the program was closed and restarted. Not an issue on windows.
1587 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1591 // Set to nonblocking, incoming connections will also inherit this
1592 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1594 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1597 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1598 printf("%s\n", strError.c_str());
1602 // The sockaddr_in structure specifies the address family,
1603 // IP address, and port for the socket that is being bound
1604 struct sockaddr_in sockaddr;
1605 memset(&sockaddr, 0, sizeof(sockaddr));
1606 sockaddr.sin_family = AF_INET;
1607 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1608 sockaddr.sin_port = htons(GetListenPort());
1609 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1611 int nErr = WSAGetLastError();
1612 if (nErr == WSAEADDRINUSE)
1613 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1615 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1616 printf("%s\n", strError.c_str());
1619 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1621 // Listen for incoming connections
1622 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1624 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1625 printf("%s\n", strError.c_str());
1632 void StartNode(void* parg)
1634 if (pnodeLocalHost == NULL)
1635 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1638 // Get local host ip
1639 char pszHostName[1000] = "";
1640 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1642 vector<CAddress> vaddr;
1643 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1644 BOOST_FOREACH (const CAddress &addr, vaddr)
1645 if (addr.GetByte(3) != 127)
1647 addrLocalHost = addr;
1652 // Get local host ip
1653 struct ifaddrs* myaddrs;
1654 if (getifaddrs(&myaddrs) == 0)
1656 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1658 if (ifa->ifa_addr == NULL) continue;
1659 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1660 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1661 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1663 if (ifa->ifa_addr->sa_family == AF_INET)
1665 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1666 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1667 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1669 // Take the first IP that isn't loopback 127.x.x.x
1670 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1671 if (addr.IsValid() && addr.GetByte(3) != 127)
1673 addrLocalHost = addr;
1677 else if (ifa->ifa_addr->sa_family == AF_INET6)
1679 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1680 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1681 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1684 freeifaddrs(myaddrs);
1687 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1689 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1691 // Proxies can't take incoming connections
1692 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1693 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1697 CreateThread(ThreadGetMyExternalIP, NULL);
1704 // Map ports with UPnP
1708 // Get addresses from IRC and advertise ours
1709 if (!CreateThread(ThreadIRCSeed, NULL))
1710 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1712 // Send and receive from sockets, accept connections
1713 CreateThread(ThreadSocketHandler, NULL, true);
1715 // Initiate outbound connections
1716 if (!CreateThread(ThreadOpenConnections, NULL))
1717 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1720 if (!CreateThread(ThreadMessageHandler, NULL))
1721 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1723 // Generate coins in the background
1724 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1729 printf("StopNode()\n");
1731 nTransactionsUpdated++;
1732 int64 nStart = GetTime();
1733 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1735 || vnThreadsRunning[5] > 0
1739 if (GetTime() - nStart > 20)
1743 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1744 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1745 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1746 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1747 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1748 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1749 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1765 BOOST_FOREACH(CNode* pnode, vNodes)
1766 if (pnode->hSocket != INVALID_SOCKET)
1767 closesocket(pnode->hSocket);
1768 if (hListenSocket != INVALID_SOCKET)
1769 if (closesocket(hListenSocket) == SOCKET_ERROR)
1770 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1773 // Shutdown Windows Sockets
1778 instance_of_cnetcleanup;