1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17 #include <miniupnpc/miniwget.h>
18 #include <miniupnpc/miniupnpc.h>
19 #include <miniupnpc/upnpcommands.h>
20 #include <miniupnpc/upnperrors.h>
24 using namespace boost;
26 static const int MAX_OUTBOUND_CONNECTIONS = 8;
28 void ThreadMessageHandler2(void* parg);
29 void ThreadSocketHandler2(void* parg);
30 void ThreadOpenConnections2(void* parg);
32 void ThreadMapPort2(void* parg);
34 bool OpenNetworkConnection(const CAddress& addrConnect);
41 // Global state variables
44 bool fAllowDNS = false;
45 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
46 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
47 CNode* pnodeLocalHost = NULL;
48 uint64 nLocalHostNonce = 0;
49 array<int, 10> vnThreadsRunning;
50 SOCKET hListenSocket = INVALID_SOCKET;
52 vector<CNode*> vNodes;
53 CCriticalSection cs_vNodes;
54 map<vector<unsigned char>, CAddress> mapAddresses;
55 CCriticalSection cs_mapAddresses;
56 map<CInv, CDataStream> mapRelay;
57 deque<pair<int64, CInv> > vRelayExpiration;
58 CCriticalSection cs_mapRelay;
59 map<CInv, int64> mapAlreadyAskedFor;
62 int fUseProxy = false;
63 int nConnectTimeout = 5000;
64 CAddress addrProxy("127.0.0.1",9050);
69 unsigned short GetListenPort()
71 return (unsigned short)(GetArg("-port", GetDefaultPort()));
74 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
76 // Filter out duplicate requests
77 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
79 pindexLastGetBlocksBegin = pindexBegin;
80 hashLastGetBlocksEnd = hashEnd;
82 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
89 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
91 hSocketRet = INVALID_SOCKET;
93 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
94 if (hSocket == INVALID_SOCKET)
98 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
101 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
102 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
105 u_long fNonblock = 1;
106 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
108 int fFlags = fcntl(hSocket, F_GETFL, 0);
109 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
112 closesocket(hSocket);
117 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
119 // WSAEINVAL is here because some legacy version of winsock uses it
120 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
122 struct timeval timeout;
123 timeout.tv_sec = nTimeout / 1000;
124 timeout.tv_usec = (nTimeout % 1000) * 1000;
128 FD_SET(hSocket, &fdset);
129 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
132 printf("connection timeout\n");
133 closesocket(hSocket);
136 if (nRet == SOCKET_ERROR)
138 printf("select() for connection failed: %i\n",WSAGetLastError());
139 closesocket(hSocket);
142 socklen_t nRetSize = sizeof(nRet);
144 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
146 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
149 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
150 closesocket(hSocket);
155 printf("connect() failed after select(): %s\n",strerror(nRet));
156 closesocket(hSocket);
161 else if (WSAGetLastError() != WSAEISCONN)
166 printf("connect() failed: %i\n",WSAGetLastError());
167 closesocket(hSocket);
173 this isn't even strictly necessary
174 CNode::ConnectNode immediately turns the socket back to non-blocking
175 but we'll turn it back to blocking just in case
179 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
181 fFlags = fcntl(hSocket, F_GETFL, 0);
182 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
185 closesocket(hSocket);
191 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
192 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
193 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
194 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
195 char* pszSocks4 = pszSocks4IP;
196 int nSize = sizeof(pszSocks4IP);
198 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
201 closesocket(hSocket);
202 return error("Error sending to proxy");
205 if (recv(hSocket, pchRet, 8, 0) != 8)
207 closesocket(hSocket);
208 return error("Error reading proxy response");
210 if (pchRet[1] != 0x5a)
212 closesocket(hSocket);
213 if (pchRet[1] != 0x5b)
214 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
217 printf("proxy connected %s\n", addrConnect.ToString().c_str());
220 hSocketRet = hSocket;
224 // portDefault is in host order
225 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
230 int port = portDefault;
233 strlcpy(psz, pszName, sizeof(psz));
236 char* pszColon = strrchr(psz+1,':');
237 char *pszPortEnd = NULL;
238 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
239 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
241 if (psz[0] == '[' && pszColon[-1] == ']')
243 // Future: enable IPv6 colon-notation inside []
250 if (port < 0 || port > USHRT_MAX)
255 unsigned int addrIP = inet_addr(pszHost);
256 if (addrIP != INADDR_NONE)
258 // valid IP address passed
259 vaddr.push_back(CAddress(addrIP, port, nServices));
266 struct hostent* phostent = gethostbyname(pszHost);
270 if (phostent->h_addrtype != AF_INET)
273 char** ppAddr = phostent->h_addr_list;
274 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
276 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
278 vaddr.push_back(addr);
282 return (vaddr.size() > 0);
285 // portDefault is in host order
286 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
288 vector<CAddress> vaddr;
289 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
295 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
298 if (!ConnectSocket(addrConnect, hSocket))
299 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
301 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
304 while (RecvLine(hSocket, strLine))
306 if (strLine.empty()) // HTTP response is separated from headers by blank line
310 if (!RecvLine(hSocket, strLine))
312 closesocket(hSocket);
315 if (pszKeyword == NULL)
317 if (strLine.find(pszKeyword) != -1)
319 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
323 closesocket(hSocket);
324 if (strLine.find("<") != -1)
325 strLine = strLine.substr(0, strLine.find("<"));
326 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
327 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
328 strLine.resize(strLine.size()-1);
329 CAddress addr(strLine,0,true);
330 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
331 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
337 closesocket(hSocket);
338 return error("GetMyExternalIP() : connection closed");
341 // We now get our external IP from the IRC server first and only use this as a backup
342 bool GetMyExternalIP(unsigned int& ipRet)
344 CAddress addrConnect;
346 const char* pszKeyword;
351 for (int nLookup = 0; nLookup <= 1; nLookup++)
352 for (int nHost = 1; nHost <= 2; nHost++)
354 // We should be phasing out our use of sites like these. If we need
355 // replacements, we should ask for volunteers to put this simple
356 // php file on their webserver that prints the client IP:
357 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
360 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
364 CAddress addrIP("checkip.dyndns.org", 80, true);
365 if (addrIP.IsValid())
366 addrConnect = addrIP;
369 pszGet = "GET / HTTP/1.1\r\n"
370 "Host: checkip.dyndns.org\r\n"
371 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
372 "Connection: close\r\n"
375 pszKeyword = "Address:";
379 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
383 CAddress addrIP("www.showmyip.com", 80, true);
384 if (addrIP.IsValid())
385 addrConnect = addrIP;
388 pszGet = "GET /simple/ HTTP/1.1\r\n"
389 "Host: www.showmyip.com\r\n"
390 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
391 "Connection: close\r\n"
394 pszKeyword = NULL; // Returns just IP address
397 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
404 void ThreadGetMyExternalIP(void* parg)
406 // Wait for IRC to get it first
407 if (!GetBoolArg("-noirc"))
409 for (int i = 0; i < 2 * 60; i++)
412 if (fGotExternalIP || fShutdown)
417 // Fallback in case IRC fails to get it
418 if (GetMyExternalIP(addrLocalHost.ip))
420 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
421 if (addrLocalHost.IsRoutable())
423 // If we already connected to a few before we had our IP, go back and addr them.
424 // setAddrKnown automatically filters any duplicate sends.
425 CAddress addr(addrLocalHost);
426 addr.nTime = GetAdjustedTime();
427 CRITICAL_BLOCK(cs_vNodes)
428 BOOST_FOREACH(CNode* pnode, vNodes)
429 pnode->PushAddress(addr);
438 bool AddAddress(CAddress addr, int64 nTimePenalty)
440 if (!addr.IsRoutable())
442 if (addr.ip == addrLocalHost.ip)
444 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
445 CRITICAL_BLOCK(cs_mapAddresses)
447 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
448 if (it == mapAddresses.end())
451 printf("AddAddress(%s)\n", addr.ToString().c_str());
452 mapAddresses.insert(make_pair(addr.GetKey(), addr));
453 CAddrDB().WriteAddress(addr);
458 bool fUpdated = false;
459 CAddress& addrFound = (*it).second;
460 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
462 // Services have been added
463 addrFound.nServices |= addr.nServices;
466 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
467 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
468 if (addrFound.nTime < addr.nTime - nUpdateInterval)
470 // Periodically update most recently seen time
471 addrFound.nTime = addr.nTime;
475 CAddrDB().WriteAddress(addrFound);
481 void AddressCurrentlyConnected(const CAddress& addr)
483 CRITICAL_BLOCK(cs_mapAddresses)
485 // Only if it's been published already
486 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
487 if (it != mapAddresses.end())
489 CAddress& addrFound = (*it).second;
490 int64 nUpdateInterval = 20 * 60;
491 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
493 // Periodically update most recently seen time
494 addrFound.nTime = GetAdjustedTime();
496 addrdb.WriteAddress(addrFound);
506 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
508 // If the dialog might get closed before the reply comes back,
509 // call this in the destructor so it doesn't get called after it's deleted.
510 CRITICAL_BLOCK(cs_vNodes)
512 BOOST_FOREACH(CNode* pnode, vNodes)
514 CRITICAL_BLOCK(pnode->cs_mapRequests)
516 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
518 CRequestTracker& tracker = (*mi).second;
519 if (tracker.fn == fn && tracker.param1 == param1)
520 pnode->mapRequests.erase(mi++);
536 // Subscription methods for the broadcast and subscription system.
537 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
539 // The subscription system uses a meet-in-the-middle strategy.
540 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
541 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
544 bool AnySubscribed(unsigned int nChannel)
546 if (pnodeLocalHost->IsSubscribed(nChannel))
548 CRITICAL_BLOCK(cs_vNodes)
549 BOOST_FOREACH(CNode* pnode, vNodes)
550 if (pnode->IsSubscribed(nChannel))
555 bool CNode::IsSubscribed(unsigned int nChannel)
557 if (nChannel >= vfSubscribe.size())
559 return vfSubscribe[nChannel];
562 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
564 if (nChannel >= vfSubscribe.size())
567 if (!AnySubscribed(nChannel))
570 CRITICAL_BLOCK(cs_vNodes)
571 BOOST_FOREACH(CNode* pnode, vNodes)
573 pnode->PushMessage("subscribe", nChannel, nHops);
576 vfSubscribe[nChannel] = true;
579 void CNode::CancelSubscribe(unsigned int nChannel)
581 if (nChannel >= vfSubscribe.size())
584 // Prevent from relaying cancel if wasn't subscribed
585 if (!vfSubscribe[nChannel])
587 vfSubscribe[nChannel] = false;
589 if (!AnySubscribed(nChannel))
591 // Relay subscription cancel
592 CRITICAL_BLOCK(cs_vNodes)
593 BOOST_FOREACH(CNode* pnode, vNodes)
595 pnode->PushMessage("sub-cancel", nChannel);
607 CNode* FindNode(unsigned int ip)
609 CRITICAL_BLOCK(cs_vNodes)
611 BOOST_FOREACH(CNode* pnode, vNodes)
612 if (pnode->addr.ip == ip)
618 CNode* FindNode(CAddress addr)
620 CRITICAL_BLOCK(cs_vNodes)
622 BOOST_FOREACH(CNode* pnode, vNodes)
623 if (pnode->addr == addr)
629 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
631 if (addrConnect.ip == addrLocalHost.ip)
634 // Look for an existing connection
635 CNode* pnode = FindNode(addrConnect.ip);
639 pnode->AddRef(nTimeout);
646 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
647 addrConnect.ToString().c_str(),
648 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
649 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
651 CRITICAL_BLOCK(cs_mapAddresses)
652 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
656 if (ConnectSocket(addrConnect, hSocket))
659 printf("connected %s\n", addrConnect.ToString().c_str());
661 // Set to nonblocking
664 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
665 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
667 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
668 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
672 CNode* pnode = new CNode(hSocket, addrConnect, false);
674 pnode->AddRef(nTimeout);
677 CRITICAL_BLOCK(cs_vNodes)
678 vNodes.push_back(pnode);
680 pnode->nTimeConnected = GetTime();
689 void CNode::CloseSocketDisconnect()
692 if (hSocket != INVALID_SOCKET)
695 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
696 printf("disconnecting node %s\n", addr.ToString().c_str());
697 closesocket(hSocket);
698 hSocket = INVALID_SOCKET;
702 void CNode::Cleanup()
704 // All of a nodes broadcasts and subscriptions are automatically torn down
705 // when it goes down, so a node has to stay up to keep its broadcast going.
707 // Cancel subscriptions
708 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
709 if (vfSubscribe[nChannel])
710 CancelSubscribe(nChannel);
725 void ThreadSocketHandler(void* parg)
727 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
730 vnThreadsRunning[0]++;
731 ThreadSocketHandler2(parg);
732 vnThreadsRunning[0]--;
734 catch (std::exception& e) {
735 vnThreadsRunning[0]--;
736 PrintException(&e, "ThreadSocketHandler()");
738 vnThreadsRunning[0]--;
739 throw; // support pthread_cancel()
741 printf("ThreadSocketHandler exiting\n");
744 void ThreadSocketHandler2(void* parg)
746 printf("ThreadSocketHandler started\n");
747 list<CNode*> vNodesDisconnected;
748 int nPrevNodeCount = 0;
755 CRITICAL_BLOCK(cs_vNodes)
757 // Disconnect unused nodes
758 vector<CNode*> vNodesCopy = vNodes;
759 BOOST_FOREACH(CNode* pnode, vNodesCopy)
761 if (pnode->fDisconnect ||
762 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
764 // remove from vNodes
765 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
767 // close socket and cleanup
768 pnode->CloseSocketDisconnect();
771 // hold in disconnected pool until all refs are released
772 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
773 if (pnode->fNetworkNode || pnode->fInbound)
775 vNodesDisconnected.push_back(pnode);
779 // Delete disconnected nodes
780 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
781 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
783 // wait until threads are done using it
784 if (pnode->GetRefCount() <= 0)
786 bool fDelete = false;
787 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
788 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
789 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
790 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
794 vNodesDisconnected.remove(pnode);
800 if (vNodes.size() != nPrevNodeCount)
802 nPrevNodeCount = vNodes.size();
808 // Find which sockets have data to receive
810 struct timeval timeout;
812 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
819 FD_ZERO(&fdsetError);
820 SOCKET hSocketMax = 0;
822 if(hListenSocket != INVALID_SOCKET)
823 FD_SET(hListenSocket, &fdsetRecv);
824 hSocketMax = max(hSocketMax, hListenSocket);
825 CRITICAL_BLOCK(cs_vNodes)
827 BOOST_FOREACH(CNode* pnode, vNodes)
829 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
831 FD_SET(pnode->hSocket, &fdsetRecv);
832 FD_SET(pnode->hSocket, &fdsetError);
833 hSocketMax = max(hSocketMax, pnode->hSocket);
834 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
835 if (!pnode->vSend.empty())
836 FD_SET(pnode->hSocket, &fdsetSend);
840 vnThreadsRunning[0]--;
841 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
842 vnThreadsRunning[0]++;
845 if (nSelect == SOCKET_ERROR)
847 int nErr = WSAGetLastError();
850 printf("socket select error %d\n", nErr);
851 for (int i = 0; i <= hSocketMax; i++)
852 FD_SET(i, &fdsetRecv);
855 FD_ZERO(&fdsetError);
856 Sleep(timeout.tv_usec/1000);
861 // Accept new connections
863 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
865 struct sockaddr_in sockaddr;
866 socklen_t len = sizeof(sockaddr);
867 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
868 CAddress addr(sockaddr);
871 CRITICAL_BLOCK(cs_vNodes)
872 BOOST_FOREACH(CNode* pnode, vNodes)
875 if (hSocket == INVALID_SOCKET)
877 if (WSAGetLastError() != WSAEWOULDBLOCK)
878 printf("socket error accept failed: %d\n", WSAGetLastError());
880 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
882 closesocket(hSocket);
886 printf("accepted connection %s\n", addr.ToString().c_str());
887 CNode* pnode = new CNode(hSocket, addr, true);
889 CRITICAL_BLOCK(cs_vNodes)
890 vNodes.push_back(pnode);
896 // Service each socket
898 vector<CNode*> vNodesCopy;
899 CRITICAL_BLOCK(cs_vNodes)
902 BOOST_FOREACH(CNode* pnode, vNodesCopy)
905 BOOST_FOREACH(CNode* pnode, vNodesCopy)
913 if (pnode->hSocket == INVALID_SOCKET)
915 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
917 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
919 CDataStream& vRecv = pnode->vRecv;
920 unsigned int nPos = vRecv.size();
922 if (nPos > ReceiveBufferSize()) {
923 if (!pnode->fDisconnect)
924 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
925 pnode->CloseSocketDisconnect();
928 // typical socket buffer is 8K-64K
929 char pchBuf[0x10000];
930 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
933 vRecv.resize(nPos + nBytes);
934 memcpy(&vRecv[nPos], pchBuf, nBytes);
935 pnode->nLastRecv = GetTime();
937 else if (nBytes == 0)
939 // socket closed gracefully
940 if (!pnode->fDisconnect)
941 printf("socket closed\n");
942 pnode->CloseSocketDisconnect();
947 int nErr = WSAGetLastError();
948 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
950 if (!pnode->fDisconnect)
951 printf("socket recv error %d\n", nErr);
952 pnode->CloseSocketDisconnect();
962 if (pnode->hSocket == INVALID_SOCKET)
964 if (FD_ISSET(pnode->hSocket, &fdsetSend))
966 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
968 CDataStream& vSend = pnode->vSend;
971 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
974 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
975 pnode->nLastSend = GetTime();
980 int nErr = WSAGetLastError();
981 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
983 printf("socket send error %d\n", nErr);
984 pnode->CloseSocketDisconnect();
987 if (vSend.size() > SendBufferSize()) {
988 if (!pnode->fDisconnect)
989 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
990 pnode->CloseSocketDisconnect();
997 // Inactivity checking
999 if (pnode->vSend.empty())
1000 pnode->nLastSendEmpty = GetTime();
1001 if (GetTime() - pnode->nTimeConnected > 60)
1003 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1005 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1006 pnode->fDisconnect = true;
1008 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1010 printf("socket not sending\n");
1011 pnode->fDisconnect = true;
1013 else if (GetTime() - pnode->nLastRecv > 90*60)
1015 printf("socket inactivity timeout\n");
1016 pnode->fDisconnect = true;
1020 CRITICAL_BLOCK(cs_vNodes)
1022 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1039 void ThreadMapPort(void* parg)
1041 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1044 vnThreadsRunning[5]++;
1045 ThreadMapPort2(parg);
1046 vnThreadsRunning[5]--;
1048 catch (std::exception& e) {
1049 vnThreadsRunning[5]--;
1050 PrintException(&e, "ThreadMapPort()");
1052 vnThreadsRunning[5]--;
1053 PrintException(NULL, "ThreadMapPort()");
1055 printf("ThreadMapPort exiting\n");
1058 void ThreadMapPort2(void* parg)
1060 printf("ThreadMapPort started\n");
1063 sprintf(port, "%d", GetListenPort());
1065 const char * rootdescurl = 0;
1066 const char * multicastif = 0;
1067 const char * minissdpdpath = 0;
1068 struct UPNPDev * devlist = 0;
1071 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1073 struct UPNPUrls urls;
1074 struct IGDdatas data;
1077 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1084 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1085 port, port, lanaddr, 0, "TCP", 0);
1087 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1088 port, port, lanaddr, 0, "TCP", 0, "0");
1090 if(r!=UPNPCOMMAND_SUCCESS)
1091 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1092 port, port, lanaddr, r, strupnperror(r));
1094 printf("UPnP Port Mapping successful.\n");
1096 if (fShutdown || !fUseUPnP)
1098 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1099 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1100 freeUPNPDevlist(devlist); devlist = 0;
1101 FreeUPNPUrls(&urls);
1107 printf("No valid UPnP IGDs found\n");
1108 freeUPNPDevlist(devlist); devlist = 0;
1110 FreeUPNPUrls(&urls);
1112 if (fShutdown || !fUseUPnP)
1119 void MapPort(bool fMapPort)
1121 if (fUseUPnP != fMapPort)
1123 fUseUPnP = fMapPort;
1124 WriteSetting("fUseUPnP", fUseUPnP);
1126 if (fUseUPnP && vnThreadsRunning[5] < 1)
1128 if (!CreateThread(ThreadMapPort, NULL))
1129 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1143 static const char *strDNSSeed[] = {
1145 "bitseed.bitcoin.org.uk",
1146 "dnsseed.bluematt.me",
1149 void DNSAddressSeed()
1155 printf("Loading addresses from DNS seeds (could take a while)\n");
1157 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1158 vector<CAddress> vaddr;
1159 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1161 BOOST_FOREACH (CAddress& addr, vaddr)
1163 if (addr.GetByte(3) != 127)
1174 printf("%d addresses found from DNS seeds\n", found);
1179 unsigned int pnSeed[] =
1181 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1182 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1183 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1184 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1185 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1186 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1187 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1188 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1189 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1190 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1191 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1192 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1193 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1194 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1195 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1196 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1197 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1198 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1199 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1200 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1201 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1202 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1203 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1204 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1205 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1206 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1207 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1208 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1209 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1210 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1211 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1212 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1213 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1214 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1215 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1216 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1217 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1218 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1219 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1220 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1225 void ThreadOpenConnections(void* parg)
1227 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1230 vnThreadsRunning[1]++;
1231 ThreadOpenConnections2(parg);
1232 vnThreadsRunning[1]--;
1234 catch (std::exception& e) {
1235 vnThreadsRunning[1]--;
1236 PrintException(&e, "ThreadOpenConnections()");
1238 vnThreadsRunning[1]--;
1239 PrintException(NULL, "ThreadOpenConnections()");
1241 printf("ThreadOpenConnections exiting\n");
1244 void ThreadOpenConnections2(void* parg)
1246 printf("ThreadOpenConnections started\n");
1248 // Connect to specific addresses
1249 if (mapArgs.count("-connect"))
1251 for (int64 nLoop = 0;; nLoop++)
1253 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1255 CAddress addr(strAddr, fAllowDNS);
1257 OpenNetworkConnection(addr);
1258 for (int i = 0; i < 10 && i < nLoop; i++)
1268 // Connect to manually added nodes first
1269 if (mapArgs.count("-addnode"))
1271 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1273 CAddress addr(strAddr, fAllowDNS);
1276 OpenNetworkConnection(addr);
1284 // Initiate network connections
1285 int64 nStart = GetTime();
1288 // Limit outbound connections
1289 vnThreadsRunning[1]--;
1294 CRITICAL_BLOCK(cs_vNodes)
1295 BOOST_FOREACH(CNode* pnode, vNodes)
1296 if (!pnode->fInbound)
1298 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1299 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1300 if (nOutbound < nMaxOutboundConnections)
1306 vnThreadsRunning[1]++;
1310 CRITICAL_BLOCK(cs_mapAddresses)
1312 // Add seed nodes if IRC isn't working
1313 static bool fSeedUsed;
1314 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1315 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1317 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1319 // It'll only connect to one or two seed nodes because once it connects,
1320 // it'll get a pile of addresses with newer timestamps.
1322 addr.ip = pnSeed[i];
1329 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1331 // Disconnect seed nodes
1332 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1333 static int64 nSeedDisconnected;
1334 if (nSeedDisconnected == 0)
1336 nSeedDisconnected = GetTime();
1337 CRITICAL_BLOCK(cs_vNodes)
1338 BOOST_FOREACH(CNode* pnode, vNodes)
1339 if (setSeed.count(pnode->addr.ip))
1340 pnode->fDisconnect = true;
1343 // Keep setting timestamps to 0 so they won't reconnect
1344 if (GetTime() - nSeedDisconnected < 60 * 60)
1346 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1348 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1350 item.second.nTime = 0;
1351 CAddrDB().WriteAddress(item.second);
1360 // Choose an address to connect to based on most recently seen
1362 CAddress addrConnect;
1363 int64 nBest = INT64_MIN;
1365 // Only connect to one address per a.b.?.? range.
1366 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1367 set<unsigned int> setConnected;
1368 CRITICAL_BLOCK(cs_vNodes)
1369 BOOST_FOREACH(CNode* pnode, vNodes)
1370 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1372 CRITICAL_BLOCK(cs_mapAddresses)
1374 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1376 const CAddress& addr = item.second;
1377 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1379 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1380 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1382 // Randomize the order in a deterministic way, putting the standard port first
1383 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1384 if (addr.port != htons(GetDefaultPort()))
1385 nRandomizer += 2 * 60 * 60;
1387 // Last seen Base retry frequency
1396 // 365 days 93 hours
1397 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1399 // Fast reconnect for one hour after last seen
1400 if (nSinceLastSeen < 60 * 60)
1403 // Limit retry frequency
1404 if (nSinceLastTry < nDelay)
1407 // If we have IRC, we'll be notified when they first come online,
1408 // and again every 24 hours by the refresh broadcast.
1409 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1412 // Only try the old stuff if we don't have enough connections
1413 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1416 // If multiple addresses are ready, prioritize by time since
1417 // last seen and time since last tried.
1418 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1427 if (addrConnect.IsValid())
1428 OpenNetworkConnection(addrConnect);
1432 bool OpenNetworkConnection(const CAddress& addrConnect)
1435 // Initiate outbound network connection
1439 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1442 vnThreadsRunning[1]--;
1443 CNode* pnode = ConnectNode(addrConnect);
1444 vnThreadsRunning[1]++;
1449 pnode->fNetworkNode = true;
1461 void ThreadMessageHandler(void* parg)
1463 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1466 vnThreadsRunning[2]++;
1467 ThreadMessageHandler2(parg);
1468 vnThreadsRunning[2]--;
1470 catch (std::exception& e) {
1471 vnThreadsRunning[2]--;
1472 PrintException(&e, "ThreadMessageHandler()");
1474 vnThreadsRunning[2]--;
1475 PrintException(NULL, "ThreadMessageHandler()");
1477 printf("ThreadMessageHandler exiting\n");
1480 void ThreadMessageHandler2(void* parg)
1482 printf("ThreadMessageHandler started\n");
1483 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1486 vector<CNode*> vNodesCopy;
1487 CRITICAL_BLOCK(cs_vNodes)
1489 vNodesCopy = vNodes;
1490 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1494 // Poll the connected nodes for messages
1495 CNode* pnodeTrickle = NULL;
1496 if (!vNodesCopy.empty())
1497 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1498 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1501 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1502 ProcessMessages(pnode);
1507 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1508 SendMessages(pnode, pnode == pnodeTrickle);
1513 CRITICAL_BLOCK(cs_vNodes)
1515 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1519 // Wait and allow messages to bunch up.
1520 // Reduce vnThreadsRunning so StopNode has permission to exit while
1521 // we're sleeping, but we must always check fShutdown after doing this.
1522 vnThreadsRunning[2]--;
1524 if (fRequestShutdown)
1526 vnThreadsRunning[2]++;
1537 bool BindListenPort(string& strError)
1541 addrLocalHost.port = htons(GetListenPort());
1544 // Initialize Windows Sockets
1546 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1547 if (ret != NO_ERROR)
1549 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1550 printf("%s\n", strError.c_str());
1555 // Create socket for listening for incoming connections
1556 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1557 if (hListenSocket == INVALID_SOCKET)
1559 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1560 printf("%s\n", strError.c_str());
1565 // Different way of disabling SIGPIPE on BSD
1566 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1570 // Allow binding if the port is still in TIME_WAIT state after
1571 // the program was closed and restarted. Not an issue on windows.
1572 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1576 // Set to nonblocking, incoming connections will also inherit this
1577 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1579 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1582 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1583 printf("%s\n", strError.c_str());
1587 // The sockaddr_in structure specifies the address family,
1588 // IP address, and port for the socket that is being bound
1589 struct sockaddr_in sockaddr;
1590 memset(&sockaddr, 0, sizeof(sockaddr));
1591 sockaddr.sin_family = AF_INET;
1592 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1593 sockaddr.sin_port = htons(GetListenPort());
1594 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1596 int nErr = WSAGetLastError();
1597 if (nErr == WSAEADDRINUSE)
1598 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1600 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1601 printf("%s\n", strError.c_str());
1604 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1606 // Listen for incoming connections
1607 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1609 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1610 printf("%s\n", strError.c_str());
1617 void StartNode(void* parg)
1619 if (pnodeLocalHost == NULL)
1620 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1623 // Get local host ip
1624 char pszHostName[1000] = "";
1625 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1627 vector<CAddress> vaddr;
1628 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1629 BOOST_FOREACH (const CAddress &addr, vaddr)
1630 if (addr.GetByte(3) != 127)
1632 addrLocalHost = addr;
1637 // Get local host ip
1638 struct ifaddrs* myaddrs;
1639 if (getifaddrs(&myaddrs) == 0)
1641 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1643 if (ifa->ifa_addr == NULL) continue;
1644 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1645 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1646 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1648 if (ifa->ifa_addr->sa_family == AF_INET)
1650 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1651 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1652 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1654 // Take the first IP that isn't loopback 127.x.x.x
1655 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1656 if (addr.IsValid() && addr.GetByte(3) != 127)
1658 addrLocalHost = addr;
1662 else if (ifa->ifa_addr->sa_family == AF_INET6)
1664 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1665 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1666 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1669 freeifaddrs(myaddrs);
1672 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1674 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1676 // Proxies can't take incoming connections
1677 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1678 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1682 CreateThread(ThreadGetMyExternalIP, NULL);
1689 // Map ports with UPnP
1693 // Get addresses from IRC and advertise ours
1694 if (!CreateThread(ThreadIRCSeed, NULL))
1695 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1697 // Send and receive from sockets, accept connections
1698 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1700 // Initiate outbound connections
1701 if (!CreateThread(ThreadOpenConnections, NULL))
1702 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1705 if (!CreateThread(ThreadMessageHandler, NULL))
1706 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1708 // Generate coins in the background
1709 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1714 printf("StopNode()\n");
1716 nTransactionsUpdated++;
1717 int64 nStart = GetTime();
1718 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1720 || vnThreadsRunning[5] > 0
1724 if (GetTime() - nStart > 20)
1728 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1729 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1730 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1731 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1732 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1733 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1734 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1750 BOOST_FOREACH(CNode* pnode, vNodes)
1751 if (pnode->hSocket != INVALID_SOCKET)
1752 closesocket(pnode->hSocket);
1753 if (hListenSocket != INVALID_SOCKET)
1754 if (closesocket(hListenSocket) == SOCKET_ERROR)
1755 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1758 // Shutdown Windows Sockets
1763 instance_of_cnetcleanup;