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.
13 #include <miniupnpc/miniwget.h>
14 #include <miniupnpc/miniupnpc.h>
15 #include <miniupnpc/upnpcommands.h>
16 #include <miniupnpc/upnperrors.h>
20 using namespace boost;
22 static const int MAX_OUTBOUND_CONNECTIONS = 8;
24 void ThreadMessageHandler2(void* parg);
25 void ThreadSocketHandler2(void* parg);
26 void ThreadOpenConnections2(void* parg);
28 void ThreadMapPort2(void* parg);
30 bool OpenNetworkConnection(const CAddress& addrConnect);
37 // Global state variables
40 bool fAllowDNS = false;
41 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
42 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
43 CNode* pnodeLocalHost = NULL;
44 uint64 nLocalHostNonce = 0;
45 array<int, 10> vnThreadsRunning;
46 SOCKET hListenSocket = INVALID_SOCKET;
48 vector<CNode*> vNodes;
49 CCriticalSection cs_vNodes;
50 map<vector<unsigned char>, CAddress> mapAddresses;
51 CCriticalSection cs_mapAddresses;
52 map<CInv, CDataStream> mapRelay;
53 deque<pair<int64, CInv> > vRelayExpiration;
54 CCriticalSection cs_mapRelay;
55 map<CInv, int64> mapAlreadyAskedFor;
58 int fUseProxy = false;
59 int nConnectTimeout = 5000;
60 CAddress addrProxy("127.0.0.1",9050);
65 unsigned short GetListenPort()
67 return (unsigned short)(GetArg("-port", GetDefaultPort()));
70 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
72 // Filter out duplicate requests
73 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
75 pindexLastGetBlocksBegin = pindexBegin;
76 hashLastGetBlocksEnd = hashEnd;
78 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
85 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
87 hSocketRet = INVALID_SOCKET;
89 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
90 if (hSocket == INVALID_SOCKET)
94 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
97 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
98 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
101 u_long fNonblock = 1;
102 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
104 int fFlags = fcntl(hSocket, F_GETFL, 0);
105 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
108 closesocket(hSocket);
113 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
115 // WSAEINVAL is here because some legacy version of winsock uses it
116 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
118 struct timeval timeout;
119 timeout.tv_sec = nTimeout / 1000;
120 timeout.tv_usec = (nTimeout % 1000) * 1000;
124 FD_SET(hSocket, &fdset);
125 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
128 printf("connection timeout\n");
129 closesocket(hSocket);
132 if (nRet == SOCKET_ERROR)
134 printf("select() for connection failed: %i\n",WSAGetLastError());
135 closesocket(hSocket);
138 socklen_t nRetSize = sizeof(nRet);
140 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
142 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
145 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
146 closesocket(hSocket);
151 printf("connect() failed after select(): %i\n",nRet);
152 closesocket(hSocket);
157 else if (WSAGetLastError() != WSAEISCONN)
162 printf("connect() failed: %i\n",WSAGetLastError());
163 closesocket(hSocket);
169 this isn't even strictly necessary
170 CNode::ConnectNode immediately turns the socket back to non-blocking
171 but we'll turn it back to blocking just in case
175 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
177 fFlags = fcntl(hSocket, F_GETFL, 0);
178 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
181 closesocket(hSocket);
187 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
188 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
189 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
190 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
191 char* pszSocks4 = pszSocks4IP;
192 int nSize = sizeof(pszSocks4IP);
194 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
197 closesocket(hSocket);
198 return error("Error sending to proxy");
201 if (recv(hSocket, pchRet, 8, 0) != 8)
203 closesocket(hSocket);
204 return error("Error reading proxy response");
206 if (pchRet[1] != 0x5a)
208 closesocket(hSocket);
209 if (pchRet[1] != 0x5b)
210 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
213 printf("proxy connected %s\n", addrConnect.ToString().c_str());
216 hSocketRet = hSocket;
220 // portDefault is in host order
221 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
226 int port = portDefault;
229 strlcpy(psz, pszName, sizeof(psz));
232 char* pszColon = strrchr(psz+1,':');
233 char *pszPortEnd = NULL;
234 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
235 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
237 if (psz[0] == '[' && pszColon[-1] == ']')
239 // Future: enable IPv6 colon-notation inside []
246 if (port < 0 || port > USHRT_MAX)
251 unsigned int addrIP = inet_addr(pszHost);
252 if (addrIP != INADDR_NONE)
254 // valid IP address passed
255 vaddr.push_back(CAddress(addrIP, port, nServices));
262 struct hostent* phostent = gethostbyname(pszHost);
266 if (phostent->h_addrtype != AF_INET)
269 char** ppAddr = phostent->h_addr_list;
270 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
272 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
274 vaddr.push_back(addr);
278 return (vaddr.size() > 0);
281 // portDefault is in host order
282 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
284 vector<CAddress> vaddr;
285 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
291 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
294 if (!ConnectSocket(addrConnect, hSocket))
295 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
297 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
300 while (RecvLine(hSocket, strLine))
302 if (strLine.empty()) // HTTP response is separated from headers by blank line
306 if (!RecvLine(hSocket, strLine))
308 closesocket(hSocket);
311 if (pszKeyword == NULL)
313 if (strLine.find(pszKeyword) != -1)
315 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
319 closesocket(hSocket);
320 if (strLine.find("<") != -1)
321 strLine = strLine.substr(0, strLine.find("<"));
322 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
323 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
324 strLine.resize(strLine.size()-1);
325 CAddress addr(strLine,0,true);
326 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
327 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
333 closesocket(hSocket);
334 return error("GetMyExternalIP() : connection closed");
337 // We now get our external IP from the IRC server first and only use this as a backup
338 bool GetMyExternalIP(unsigned int& ipRet)
340 CAddress addrConnect;
342 const char* pszKeyword;
347 for (int nLookup = 0; nLookup <= 1; nLookup++)
348 for (int nHost = 1; nHost <= 2; nHost++)
350 // We should be phasing out our use of sites like these. If we need
351 // replacements, we should ask for volunteers to put this simple
352 // php file on their webserver that prints the client IP:
353 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
356 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
360 CAddress addrIP("checkip.dyndns.org", 80, true);
361 if (addrIP.IsValid())
362 addrConnect = addrIP;
365 pszGet = "GET / HTTP/1.1\r\n"
366 "Host: checkip.dyndns.org\r\n"
367 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
368 "Connection: close\r\n"
371 pszKeyword = "Address:";
375 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
379 CAddress addrIP("www.showmyip.com", 80, true);
380 if (addrIP.IsValid())
381 addrConnect = addrIP;
384 pszGet = "GET /simple/ HTTP/1.1\r\n"
385 "Host: www.showmyip.com\r\n"
386 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
387 "Connection: close\r\n"
390 pszKeyword = NULL; // Returns just IP address
393 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
400 void ThreadGetMyExternalIP(void* parg)
402 // Wait for IRC to get it first
403 if (!GetBoolArg("-noirc"))
405 for (int i = 0; i < 2 * 60; i++)
408 if (fGotExternalIP || fShutdown)
413 // Fallback in case IRC fails to get it
414 if (GetMyExternalIP(addrLocalHost.ip))
416 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
417 if (addrLocalHost.IsRoutable())
419 // If we already connected to a few before we had our IP, go back and addr them.
420 // setAddrKnown automatically filters any duplicate sends.
421 CAddress addr(addrLocalHost);
422 addr.nTime = GetAdjustedTime();
423 CRITICAL_BLOCK(cs_vNodes)
424 BOOST_FOREACH(CNode* pnode, vNodes)
425 pnode->PushAddress(addr);
434 bool AddAddress(CAddress addr, int64 nTimePenalty)
436 if (!addr.IsRoutable())
438 if (addr.ip == addrLocalHost.ip)
440 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
441 CRITICAL_BLOCK(cs_mapAddresses)
443 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
444 if (it == mapAddresses.end())
447 printf("AddAddress(%s)\n", addr.ToString().c_str());
448 mapAddresses.insert(make_pair(addr.GetKey(), addr));
449 CAddrDB().WriteAddress(addr);
454 bool fUpdated = false;
455 CAddress& addrFound = (*it).second;
456 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
458 // Services have been added
459 addrFound.nServices |= addr.nServices;
462 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
463 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
464 if (addrFound.nTime < addr.nTime - nUpdateInterval)
466 // Periodically update most recently seen time
467 addrFound.nTime = addr.nTime;
471 CAddrDB().WriteAddress(addrFound);
477 void AddressCurrentlyConnected(const CAddress& addr)
479 CRITICAL_BLOCK(cs_mapAddresses)
481 // Only if it's been published already
482 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
483 if (it != mapAddresses.end())
485 CAddress& addrFound = (*it).second;
486 int64 nUpdateInterval = 20 * 60;
487 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
489 // Periodically update most recently seen time
490 addrFound.nTime = GetAdjustedTime();
492 addrdb.WriteAddress(addrFound);
502 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
504 // If the dialog might get closed before the reply comes back,
505 // call this in the destructor so it doesn't get called after it's deleted.
506 CRITICAL_BLOCK(cs_vNodes)
508 BOOST_FOREACH(CNode* pnode, vNodes)
510 CRITICAL_BLOCK(pnode->cs_mapRequests)
512 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
514 CRequestTracker& tracker = (*mi).second;
515 if (tracker.fn == fn && tracker.param1 == param1)
516 pnode->mapRequests.erase(mi++);
532 // Subscription methods for the broadcast and subscription system.
533 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
535 // The subscription system uses a meet-in-the-middle strategy.
536 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
537 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
540 bool AnySubscribed(unsigned int nChannel)
542 if (pnodeLocalHost->IsSubscribed(nChannel))
544 CRITICAL_BLOCK(cs_vNodes)
545 BOOST_FOREACH(CNode* pnode, vNodes)
546 if (pnode->IsSubscribed(nChannel))
551 bool CNode::IsSubscribed(unsigned int nChannel)
553 if (nChannel >= vfSubscribe.size())
555 return vfSubscribe[nChannel];
558 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
560 if (nChannel >= vfSubscribe.size())
563 if (!AnySubscribed(nChannel))
566 CRITICAL_BLOCK(cs_vNodes)
567 BOOST_FOREACH(CNode* pnode, vNodes)
569 pnode->PushMessage("subscribe", nChannel, nHops);
572 vfSubscribe[nChannel] = true;
575 void CNode::CancelSubscribe(unsigned int nChannel)
577 if (nChannel >= vfSubscribe.size())
580 // Prevent from relaying cancel if wasn't subscribed
581 if (!vfSubscribe[nChannel])
583 vfSubscribe[nChannel] = false;
585 if (!AnySubscribed(nChannel))
587 // Relay subscription cancel
588 CRITICAL_BLOCK(cs_vNodes)
589 BOOST_FOREACH(CNode* pnode, vNodes)
591 pnode->PushMessage("sub-cancel", nChannel);
603 CNode* FindNode(unsigned int ip)
605 CRITICAL_BLOCK(cs_vNodes)
607 BOOST_FOREACH(CNode* pnode, vNodes)
608 if (pnode->addr.ip == ip)
614 CNode* FindNode(CAddress addr)
616 CRITICAL_BLOCK(cs_vNodes)
618 BOOST_FOREACH(CNode* pnode, vNodes)
619 if (pnode->addr == addr)
625 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
627 if (addrConnect.ip == addrLocalHost.ip)
630 // Look for an existing connection
631 CNode* pnode = FindNode(addrConnect.ip);
635 pnode->AddRef(nTimeout);
642 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
643 addrConnect.ToString().c_str(),
644 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
645 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
647 CRITICAL_BLOCK(cs_mapAddresses)
648 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
652 if (ConnectSocket(addrConnect, hSocket))
655 printf("connected %s\n", addrConnect.ToString().c_str());
657 // Set to nonblocking
660 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
661 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
663 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
664 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
668 CNode* pnode = new CNode(hSocket, addrConnect, false);
670 pnode->AddRef(nTimeout);
673 CRITICAL_BLOCK(cs_vNodes)
674 vNodes.push_back(pnode);
676 pnode->nTimeConnected = GetTime();
685 void CNode::CloseSocketDisconnect()
688 if (hSocket != INVALID_SOCKET)
691 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
692 printf("disconnecting node %s\n", addr.ToString().c_str());
693 closesocket(hSocket);
694 hSocket = INVALID_SOCKET;
698 void CNode::Cleanup()
700 // All of a nodes broadcasts and subscriptions are automatically torn down
701 // when it goes down, so a node has to stay up to keep its broadcast going.
703 // Cancel subscriptions
704 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
705 if (vfSubscribe[nChannel])
706 CancelSubscribe(nChannel);
721 void ThreadSocketHandler(void* parg)
723 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
726 vnThreadsRunning[0]++;
727 ThreadSocketHandler2(parg);
728 vnThreadsRunning[0]--;
730 catch (std::exception& e) {
731 vnThreadsRunning[0]--;
732 PrintException(&e, "ThreadSocketHandler()");
734 vnThreadsRunning[0]--;
735 throw; // support pthread_cancel()
737 printf("ThreadSocketHandler exiting\n");
740 void ThreadSocketHandler2(void* parg)
742 printf("ThreadSocketHandler started\n");
743 list<CNode*> vNodesDisconnected;
744 int nPrevNodeCount = 0;
751 CRITICAL_BLOCK(cs_vNodes)
753 // Disconnect unused nodes
754 vector<CNode*> vNodesCopy = vNodes;
755 BOOST_FOREACH(CNode* pnode, vNodesCopy)
757 if (pnode->fDisconnect ||
758 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
760 // remove from vNodes
761 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
763 // close socket and cleanup
764 pnode->CloseSocketDisconnect();
767 // hold in disconnected pool until all refs are released
768 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
769 if (pnode->fNetworkNode || pnode->fInbound)
771 vNodesDisconnected.push_back(pnode);
775 // Delete disconnected nodes
776 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
777 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
779 // wait until threads are done using it
780 if (pnode->GetRefCount() <= 0)
782 bool fDelete = false;
783 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
784 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
785 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
786 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
790 vNodesDisconnected.remove(pnode);
796 if (vNodes.size() != nPrevNodeCount)
798 nPrevNodeCount = vNodes.size();
804 // Find which sockets have data to receive
806 struct timeval timeout;
808 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
815 FD_ZERO(&fdsetError);
816 SOCKET hSocketMax = 0;
818 if(hListenSocket != INVALID_SOCKET)
819 FD_SET(hListenSocket, &fdsetRecv);
820 hSocketMax = max(hSocketMax, hListenSocket);
821 CRITICAL_BLOCK(cs_vNodes)
823 BOOST_FOREACH(CNode* pnode, vNodes)
825 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
827 FD_SET(pnode->hSocket, &fdsetRecv);
828 FD_SET(pnode->hSocket, &fdsetError);
829 hSocketMax = max(hSocketMax, pnode->hSocket);
830 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
831 if (!pnode->vSend.empty())
832 FD_SET(pnode->hSocket, &fdsetSend);
836 vnThreadsRunning[0]--;
837 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
838 vnThreadsRunning[0]++;
841 if (nSelect == SOCKET_ERROR)
843 int nErr = WSAGetLastError();
846 printf("socket select error %d\n", nErr);
847 for (int i = 0; i <= hSocketMax; i++)
848 FD_SET(i, &fdsetRecv);
851 FD_ZERO(&fdsetError);
852 Sleep(timeout.tv_usec/1000);
857 // Accept new connections
859 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
861 struct sockaddr_in sockaddr;
862 socklen_t len = sizeof(sockaddr);
863 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
864 CAddress addr(sockaddr);
867 CRITICAL_BLOCK(cs_vNodes)
868 BOOST_FOREACH(CNode* pnode, vNodes)
871 if (hSocket == INVALID_SOCKET)
873 if (WSAGetLastError() != WSAEWOULDBLOCK)
874 printf("socket error accept failed: %d\n", WSAGetLastError());
876 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
878 closesocket(hSocket);
882 printf("accepted connection %s\n", addr.ToString().c_str());
883 CNode* pnode = new CNode(hSocket, addr, true);
885 CRITICAL_BLOCK(cs_vNodes)
886 vNodes.push_back(pnode);
892 // Service each socket
894 vector<CNode*> vNodesCopy;
895 CRITICAL_BLOCK(cs_vNodes)
898 BOOST_FOREACH(CNode* pnode, vNodesCopy)
901 BOOST_FOREACH(CNode* pnode, vNodesCopy)
909 if (pnode->hSocket == INVALID_SOCKET)
911 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
913 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
915 CDataStream& vRecv = pnode->vRecv;
916 unsigned int nPos = vRecv.size();
918 if (nPos > 1000*GetArg("-maxreceivebuffer", 10*1000)) {
919 if (!pnode->fDisconnect)
920 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
921 pnode->CloseSocketDisconnect();
924 // typical socket buffer is 8K-64K
925 char pchBuf[0x10000];
926 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
929 vRecv.resize(nPos + nBytes);
930 memcpy(&vRecv[nPos], pchBuf, nBytes);
931 pnode->nLastRecv = GetTime();
933 else if (nBytes == 0)
935 // socket closed gracefully
936 if (!pnode->fDisconnect)
937 printf("socket closed\n");
938 pnode->CloseSocketDisconnect();
943 int nErr = WSAGetLastError();
944 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
946 if (!pnode->fDisconnect)
947 printf("socket recv error %d\n", nErr);
948 pnode->CloseSocketDisconnect();
958 if (pnode->hSocket == INVALID_SOCKET)
960 if (FD_ISSET(pnode->hSocket, &fdsetSend))
962 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
964 CDataStream& vSend = pnode->vSend;
967 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
970 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
971 pnode->nLastSend = GetTime();
976 int nErr = WSAGetLastError();
977 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
979 printf("socket send error %d\n", nErr);
980 pnode->CloseSocketDisconnect();
983 if (vSend.size() > 1000*GetArg("-maxsendbuffer", 10*1000)) {
984 if (!pnode->fDisconnect)
985 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
986 pnode->CloseSocketDisconnect();
993 // Inactivity checking
995 if (pnode->vSend.empty())
996 pnode->nLastSendEmpty = GetTime();
997 if (GetTime() - pnode->nTimeConnected > 60)
999 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1001 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1002 pnode->fDisconnect = true;
1004 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1006 printf("socket not sending\n");
1007 pnode->fDisconnect = true;
1009 else if (GetTime() - pnode->nLastRecv > 90*60)
1011 printf("socket inactivity timeout\n");
1012 pnode->fDisconnect = true;
1016 CRITICAL_BLOCK(cs_vNodes)
1018 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1035 void ThreadMapPort(void* parg)
1037 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1040 vnThreadsRunning[5]++;
1041 ThreadMapPort2(parg);
1042 vnThreadsRunning[5]--;
1044 catch (std::exception& e) {
1045 vnThreadsRunning[5]--;
1046 PrintException(&e, "ThreadMapPort()");
1048 vnThreadsRunning[5]--;
1049 PrintException(NULL, "ThreadMapPort()");
1051 printf("ThreadMapPort exiting\n");
1054 void ThreadMapPort2(void* parg)
1056 printf("ThreadMapPort started\n");
1059 sprintf(port, "%d", GetListenPort());
1061 const char * rootdescurl = 0;
1062 const char * multicastif = 0;
1063 const char * minissdpdpath = 0;
1064 struct UPNPDev * devlist = 0;
1067 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1069 struct UPNPUrls urls;
1070 struct IGDdatas data;
1073 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1080 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1081 port, port, lanaddr, 0, "TCP", 0);
1083 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1084 port, port, lanaddr, 0, "TCP", 0, "0");
1086 if(r!=UPNPCOMMAND_SUCCESS)
1087 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1088 port, port, lanaddr, r, strupnperror(r));
1090 printf("UPnP Port Mapping successful.\n");
1092 if (fShutdown || !fUseUPnP)
1094 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1095 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1096 freeUPNPDevlist(devlist); devlist = 0;
1097 FreeUPNPUrls(&urls);
1103 printf("No valid UPnP IGDs found\n");
1104 freeUPNPDevlist(devlist); devlist = 0;
1106 FreeUPNPUrls(&urls);
1108 if (fShutdown || !fUseUPnP)
1115 void MapPort(bool fMapPort)
1117 if (fUseUPnP != fMapPort)
1119 fUseUPnP = fMapPort;
1120 WriteSetting("fUseUPnP", fUseUPnP);
1122 if (fUseUPnP && vnThreadsRunning[5] < 1)
1124 if (!CreateThread(ThreadMapPort, NULL))
1125 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1139 static const char *strDNSSeed[] = {
1141 "bitseed.bitcoin.org.uk",
1142 "dnsseed.bluematt.me",
1145 void DNSAddressSeed()
1149 printf("Loading addresses from DNS seeds (could take a while)\n");
1151 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1152 vector<CAddress> vaddr;
1153 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1155 BOOST_FOREACH (CAddress& addr, vaddr)
1157 if (addr.GetByte(3) != 127)
1167 printf("%d addresses found from DNS seeds\n", found);
1172 unsigned int pnSeed[] =
1174 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1175 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1176 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1177 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1178 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1179 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1180 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1181 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1182 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1183 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1184 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1185 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1186 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1187 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1188 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1189 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1190 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1191 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1192 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1193 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1194 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1195 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1196 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1197 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1198 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1199 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1200 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1201 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1202 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1203 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1204 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1205 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1206 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1207 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1208 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1209 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1210 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1211 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1212 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1213 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1218 void ThreadOpenConnections(void* parg)
1220 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1223 vnThreadsRunning[1]++;
1224 ThreadOpenConnections2(parg);
1225 vnThreadsRunning[1]--;
1227 catch (std::exception& e) {
1228 vnThreadsRunning[1]--;
1229 PrintException(&e, "ThreadOpenConnections()");
1231 vnThreadsRunning[1]--;
1232 PrintException(NULL, "ThreadOpenConnections()");
1234 printf("ThreadOpenConnections exiting\n");
1237 void ThreadOpenConnections2(void* parg)
1239 printf("ThreadOpenConnections started\n");
1241 // Connect to specific addresses
1242 if (mapArgs.count("-connect"))
1244 for (int64 nLoop = 0;; nLoop++)
1246 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1248 CAddress addr(strAddr, fAllowDNS);
1250 OpenNetworkConnection(addr);
1251 for (int i = 0; i < 10 && i < nLoop; i++)
1261 // Connect to manually added nodes first
1262 if (mapArgs.count("-addnode"))
1264 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1266 CAddress addr(strAddr, fAllowDNS);
1269 OpenNetworkConnection(addr);
1277 // Initiate network connections
1278 int64 nStart = GetTime();
1281 // Limit outbound connections
1282 vnThreadsRunning[1]--;
1287 CRITICAL_BLOCK(cs_vNodes)
1288 BOOST_FOREACH(CNode* pnode, vNodes)
1289 if (!pnode->fInbound)
1291 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1292 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1293 if (nOutbound < nMaxOutboundConnections)
1299 vnThreadsRunning[1]++;
1303 CRITICAL_BLOCK(cs_mapAddresses)
1305 // Add seed nodes if IRC isn't working
1306 static bool fSeedUsed;
1307 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1308 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1310 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1312 // It'll only connect to one or two seed nodes because once it connects,
1313 // it'll get a pile of addresses with newer timestamps.
1315 addr.ip = pnSeed[i];
1322 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1324 // Disconnect seed nodes
1325 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1326 static int64 nSeedDisconnected;
1327 if (nSeedDisconnected == 0)
1329 nSeedDisconnected = GetTime();
1330 CRITICAL_BLOCK(cs_vNodes)
1331 BOOST_FOREACH(CNode* pnode, vNodes)
1332 if (setSeed.count(pnode->addr.ip))
1333 pnode->fDisconnect = true;
1336 // Keep setting timestamps to 0 so they won't reconnect
1337 if (GetTime() - nSeedDisconnected < 60 * 60)
1339 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1341 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1343 item.second.nTime = 0;
1344 CAddrDB().WriteAddress(item.second);
1353 // Choose an address to connect to based on most recently seen
1355 CAddress addrConnect;
1356 int64 nBest = INT64_MIN;
1358 // Only connect to one address per a.b.?.? range.
1359 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1360 set<unsigned int> setConnected;
1361 CRITICAL_BLOCK(cs_vNodes)
1362 BOOST_FOREACH(CNode* pnode, vNodes)
1363 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1365 CRITICAL_BLOCK(cs_mapAddresses)
1367 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1369 const CAddress& addr = item.second;
1370 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1372 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1373 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1375 // Randomize the order in a deterministic way, putting the standard port first
1376 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1377 if (addr.port != htons(GetDefaultPort()))
1378 nRandomizer += 2 * 60 * 60;
1380 // Last seen Base retry frequency
1389 // 365 days 93 hours
1390 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1392 // Fast reconnect for one hour after last seen
1393 if (nSinceLastSeen < 60 * 60)
1396 // Limit retry frequency
1397 if (nSinceLastTry < nDelay)
1400 // If we have IRC, we'll be notified when they first come online,
1401 // and again every 24 hours by the refresh broadcast.
1402 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1405 // Only try the old stuff if we don't have enough connections
1406 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1409 // If multiple addresses are ready, prioritize by time since
1410 // last seen and time since last tried.
1411 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1420 if (addrConnect.IsValid())
1421 OpenNetworkConnection(addrConnect);
1425 bool OpenNetworkConnection(const CAddress& addrConnect)
1428 // Initiate outbound network connection
1432 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1435 vnThreadsRunning[1]--;
1436 CNode* pnode = ConnectNode(addrConnect);
1437 vnThreadsRunning[1]++;
1442 pnode->fNetworkNode = true;
1454 void ThreadMessageHandler(void* parg)
1456 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1459 vnThreadsRunning[2]++;
1460 ThreadMessageHandler2(parg);
1461 vnThreadsRunning[2]--;
1463 catch (std::exception& e) {
1464 vnThreadsRunning[2]--;
1465 PrintException(&e, "ThreadMessageHandler()");
1467 vnThreadsRunning[2]--;
1468 PrintException(NULL, "ThreadMessageHandler()");
1470 printf("ThreadMessageHandler exiting\n");
1473 void ThreadMessageHandler2(void* parg)
1475 printf("ThreadMessageHandler started\n");
1476 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1479 vector<CNode*> vNodesCopy;
1480 CRITICAL_BLOCK(cs_vNodes)
1482 vNodesCopy = vNodes;
1483 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1487 // Poll the connected nodes for messages
1488 CNode* pnodeTrickle = NULL;
1489 if (!vNodesCopy.empty())
1490 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1491 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1494 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1495 ProcessMessages(pnode);
1500 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1501 SendMessages(pnode, pnode == pnodeTrickle);
1506 CRITICAL_BLOCK(cs_vNodes)
1508 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1512 // Wait and allow messages to bunch up.
1513 // Reduce vnThreadsRunning so StopNode has permission to exit while
1514 // we're sleeping, but we must always check fShutdown after doing this.
1515 vnThreadsRunning[2]--;
1517 if (fRequestShutdown)
1519 vnThreadsRunning[2]++;
1530 bool BindListenPort(string& strError)
1534 addrLocalHost.port = htons(GetListenPort());
1537 // Initialize Windows Sockets
1539 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1540 if (ret != NO_ERROR)
1542 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1543 printf("%s\n", strError.c_str());
1548 // Create socket for listening for incoming connections
1549 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1550 if (hListenSocket == INVALID_SOCKET)
1552 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1553 printf("%s\n", strError.c_str());
1558 // Different way of disabling SIGPIPE on BSD
1559 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1563 // Allow binding if the port is still in TIME_WAIT state after
1564 // the program was closed and restarted. Not an issue on windows.
1565 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1569 // Set to nonblocking, incoming connections will also inherit this
1570 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1572 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1575 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1576 printf("%s\n", strError.c_str());
1580 // The sockaddr_in structure specifies the address family,
1581 // IP address, and port for the socket that is being bound
1582 struct sockaddr_in sockaddr;
1583 memset(&sockaddr, 0, sizeof(sockaddr));
1584 sockaddr.sin_family = AF_INET;
1585 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1586 sockaddr.sin_port = htons(GetListenPort());
1587 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1589 int nErr = WSAGetLastError();
1590 if (nErr == WSAEADDRINUSE)
1591 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1593 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1594 printf("%s\n", strError.c_str());
1597 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1599 // Listen for incoming connections
1600 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1602 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1603 printf("%s\n", strError.c_str());
1610 void StartNode(void* parg)
1612 if (pnodeLocalHost == NULL)
1613 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1616 // Get local host ip
1617 char pszHostName[1000] = "";
1618 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1620 vector<CAddress> vaddr;
1621 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1622 BOOST_FOREACH (const CAddress &addr, vaddr)
1623 if (addr.GetByte(3) != 127)
1625 addrLocalHost = addr;
1630 // Get local host ip
1631 struct ifaddrs* myaddrs;
1632 if (getifaddrs(&myaddrs) == 0)
1634 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1636 if (ifa->ifa_addr == NULL) continue;
1637 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1638 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1639 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1641 if (ifa->ifa_addr->sa_family == AF_INET)
1643 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1644 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1645 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1647 // Take the first IP that isn't loopback 127.x.x.x
1648 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1649 if (addr.IsValid() && addr.GetByte(3) != 127)
1651 addrLocalHost = addr;
1655 else if (ifa->ifa_addr->sa_family == AF_INET6)
1657 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1658 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1659 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1662 freeifaddrs(myaddrs);
1665 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1667 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1669 // Proxies can't take incoming connections
1670 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1671 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1675 CreateThread(ThreadGetMyExternalIP, NULL);
1682 // Map ports with UPnP
1686 // Get addresses from IRC and advertise ours
1687 if (!CreateThread(ThreadIRCSeed, NULL))
1688 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1690 // Send and receive from sockets, accept connections
1691 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1693 // Initiate outbound connections
1694 if (!CreateThread(ThreadOpenConnections, NULL))
1695 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1698 if (!CreateThread(ThreadMessageHandler, NULL))
1699 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1701 // Generate coins in the background
1702 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1707 printf("StopNode()\n");
1709 nTransactionsUpdated++;
1710 int64 nStart = GetTime();
1711 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1713 || vnThreadsRunning[5] > 0
1717 if (GetTime() - nStart > 20)
1721 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1722 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1723 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1724 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1725 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1726 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1727 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1743 BOOST_FOREACH(CNode* pnode, vNodes)
1744 if (pnode->hSocket != INVALID_SOCKET)
1745 closesocket(pnode->hSocket);
1746 if (hListenSocket != INVALID_SOCKET)
1747 if (closesocket(hListenSocket) == SOCKET_ERROR)
1748 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1751 // Shutdown Windows Sockets
1756 instance_of_cnetcleanup;