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.
14 // This file can be downloaded as a part of the Windows Platform SDK
15 // and is required for Bitcoin binaries to work properly on versions
16 // of Windows before XP. If you are doing builds of Bitcoin for
17 // public release, you should uncomment this line.
18 //#include <WSPiApi.h>
22 #include <miniupnpc/miniwget.h>
23 #include <miniupnpc/miniupnpc.h>
24 #include <miniupnpc/upnpcommands.h>
25 #include <miniupnpc/upnperrors.h>
29 using namespace boost;
31 static const int MAX_OUTBOUND_CONNECTIONS = 8;
33 void ThreadMessageHandler2(void* parg);
34 void ThreadSocketHandler2(void* parg);
35 void ThreadOpenConnections2(void* parg);
37 void ThreadMapPort2(void* parg);
39 bool OpenNetworkConnection(const CAddress& addrConnect);
46 // Global state variables
49 bool fAllowDNS = false;
50 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
51 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
52 CNode* pnodeLocalHost = NULL;
53 uint64 nLocalHostNonce = 0;
54 array<int, 10> vnThreadsRunning;
55 SOCKET hListenSocket = INVALID_SOCKET;
57 vector<CNode*> vNodes;
58 CCriticalSection cs_vNodes;
59 map<vector<unsigned char>, CAddress> mapAddresses;
60 CCriticalSection cs_mapAddresses;
61 map<CInv, CDataStream> mapRelay;
62 deque<pair<int64, CInv> > vRelayExpiration;
63 CCriticalSection cs_mapRelay;
64 map<CInv, int64> mapAlreadyAskedFor;
67 int fUseProxy = false;
68 int nConnectTimeout = 5000;
69 CAddress addrProxy("127.0.0.1",9050);
74 unsigned short GetListenPort()
76 return (unsigned short)(GetArg("-port", GetDefaultPort()));
79 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
81 // Filter out duplicate requests
82 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
84 pindexLastGetBlocksBegin = pindexBegin;
85 hashLastGetBlocksEnd = hashEnd;
87 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
94 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
96 hSocketRet = INVALID_SOCKET;
98 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
99 if (hSocket == INVALID_SOCKET)
103 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
106 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
107 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
110 u_long fNonblock = 1;
111 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
113 int fFlags = fcntl(hSocket, F_GETFL, 0);
114 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
117 closesocket(hSocket);
122 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
124 // WSAEINVAL is here because some legacy version of winsock uses it
125 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
127 struct timeval timeout;
128 timeout.tv_sec = nTimeout / 1000;
129 timeout.tv_usec = (nTimeout % 1000) * 1000;
133 FD_SET(hSocket, &fdset);
134 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
137 printf("connection timeout\n");
138 closesocket(hSocket);
141 if (nRet == SOCKET_ERROR)
143 printf("select() for connection failed: %i\n",WSAGetLastError());
144 closesocket(hSocket);
147 socklen_t nRetSize = sizeof(nRet);
149 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
151 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
154 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
155 closesocket(hSocket);
160 printf("connect() failed after select(): %s\n",strerror(nRet));
161 closesocket(hSocket);
166 else if (WSAGetLastError() != WSAEISCONN)
171 printf("connect() failed: %i\n",WSAGetLastError());
172 closesocket(hSocket);
178 this isn't even strictly necessary
179 CNode::ConnectNode immediately turns the socket back to non-blocking
180 but we'll turn it back to blocking just in case
184 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
186 fFlags = fcntl(hSocket, F_GETFL, 0);
187 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
190 closesocket(hSocket);
196 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
197 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
198 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
199 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
200 char* pszSocks4 = pszSocks4IP;
201 int nSize = sizeof(pszSocks4IP);
203 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
206 closesocket(hSocket);
207 return error("Error sending to proxy");
210 if (recv(hSocket, pchRet, 8, 0) != 8)
212 closesocket(hSocket);
213 return error("Error reading proxy response");
215 if (pchRet[1] != 0x5a)
217 closesocket(hSocket);
218 if (pchRet[1] != 0x5b)
219 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
222 printf("proxy connected %s\n", addrConnect.ToString().c_str());
225 hSocketRet = hSocket;
229 // portDefault is in host order
230 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
235 int port = portDefault;
238 strlcpy(psz, pszName, sizeof(psz));
241 char* pszColon = strrchr(psz+1,':');
242 char *pszPortEnd = NULL;
243 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
244 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
246 if (psz[0] == '[' && pszColon[-1] == ']')
248 // Future: enable IPv6 colon-notation inside []
255 if (port < 0 || port > USHRT_MAX)
260 unsigned int addrIP = inet_addr(pszHost);
261 if (addrIP != INADDR_NONE)
263 // valid IP address passed
264 vaddr.push_back(CAddress(addrIP, port, nServices));
271 struct hostent* phostent = gethostbyname(pszHost);
275 if (phostent->h_addrtype != AF_INET)
278 char** ppAddr = phostent->h_addr_list;
279 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
281 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
283 vaddr.push_back(addr);
287 return (vaddr.size() > 0);
290 // portDefault is in host order
291 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
293 vector<CAddress> vaddr;
294 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
300 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
303 if (!ConnectSocket(addrConnect, hSocket))
304 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
306 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
309 while (RecvLine(hSocket, strLine))
311 if (strLine.empty()) // HTTP response is separated from headers by blank line
315 if (!RecvLine(hSocket, strLine))
317 closesocket(hSocket);
320 if (pszKeyword == NULL)
322 if (strLine.find(pszKeyword) != -1)
324 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
328 closesocket(hSocket);
329 if (strLine.find("<") != -1)
330 strLine = strLine.substr(0, strLine.find("<"));
331 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
332 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
333 strLine.resize(strLine.size()-1);
334 CAddress addr(strLine,0,true);
335 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
336 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
342 closesocket(hSocket);
343 return error("GetMyExternalIP() : connection closed");
346 // We now get our external IP from the IRC server first and only use this as a backup
347 bool GetMyExternalIP(unsigned int& ipRet)
349 CAddress addrConnect;
351 const char* pszKeyword;
356 for (int nLookup = 0; nLookup <= 1; nLookup++)
357 for (int nHost = 1; nHost <= 2; nHost++)
359 // We should be phasing out our use of sites like these. If we need
360 // replacements, we should ask for volunteers to put this simple
361 // php file on their webserver that prints the client IP:
362 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
365 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
369 CAddress addrIP("checkip.dyndns.org", 80, true);
370 if (addrIP.IsValid())
371 addrConnect = addrIP;
374 pszGet = "GET / HTTP/1.1\r\n"
375 "Host: checkip.dyndns.org\r\n"
376 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
377 "Connection: close\r\n"
380 pszKeyword = "Address:";
384 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
388 CAddress addrIP("www.showmyip.com", 80, true);
389 if (addrIP.IsValid())
390 addrConnect = addrIP;
393 pszGet = "GET /simple/ HTTP/1.1\r\n"
394 "Host: www.showmyip.com\r\n"
395 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
396 "Connection: close\r\n"
399 pszKeyword = NULL; // Returns just IP address
402 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
409 void ThreadGetMyExternalIP(void* parg)
411 // Wait for IRC to get it first
412 if (!GetBoolArg("-noirc"))
414 for (int i = 0; i < 2 * 60; i++)
417 if (fGotExternalIP || fShutdown)
422 // Fallback in case IRC fails to get it
423 if (GetMyExternalIP(addrLocalHost.ip))
425 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
426 if (addrLocalHost.IsRoutable())
428 // If we already connected to a few before we had our IP, go back and addr them.
429 // setAddrKnown automatically filters any duplicate sends.
430 CAddress addr(addrLocalHost);
431 addr.nTime = GetAdjustedTime();
432 CRITICAL_BLOCK(cs_vNodes)
433 BOOST_FOREACH(CNode* pnode, vNodes)
434 pnode->PushAddress(addr);
443 bool AddAddress(CAddress addr, int64 nTimePenalty)
445 if (!addr.IsRoutable())
447 if (addr.ip == addrLocalHost.ip)
449 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
450 CRITICAL_BLOCK(cs_mapAddresses)
452 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
453 if (it == mapAddresses.end())
456 printf("AddAddress(%s)\n", addr.ToString().c_str());
457 mapAddresses.insert(make_pair(addr.GetKey(), addr));
458 CAddrDB().WriteAddress(addr);
463 bool fUpdated = false;
464 CAddress& addrFound = (*it).second;
465 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
467 // Services have been added
468 addrFound.nServices |= addr.nServices;
471 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
472 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
473 if (addrFound.nTime < addr.nTime - nUpdateInterval)
475 // Periodically update most recently seen time
476 addrFound.nTime = addr.nTime;
480 CAddrDB().WriteAddress(addrFound);
486 void AddressCurrentlyConnected(const CAddress& addr)
488 CRITICAL_BLOCK(cs_mapAddresses)
490 // Only if it's been published already
491 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
492 if (it != mapAddresses.end())
494 CAddress& addrFound = (*it).second;
495 int64 nUpdateInterval = 20 * 60;
496 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
498 // Periodically update most recently seen time
499 addrFound.nTime = GetAdjustedTime();
501 addrdb.WriteAddress(addrFound);
511 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
513 // If the dialog might get closed before the reply comes back,
514 // call this in the destructor so it doesn't get called after it's deleted.
515 CRITICAL_BLOCK(cs_vNodes)
517 BOOST_FOREACH(CNode* pnode, vNodes)
519 CRITICAL_BLOCK(pnode->cs_mapRequests)
521 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
523 CRequestTracker& tracker = (*mi).second;
524 if (tracker.fn == fn && tracker.param1 == param1)
525 pnode->mapRequests.erase(mi++);
541 // Subscription methods for the broadcast and subscription system.
542 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
544 // The subscription system uses a meet-in-the-middle strategy.
545 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
546 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
549 bool AnySubscribed(unsigned int nChannel)
551 if (pnodeLocalHost->IsSubscribed(nChannel))
553 CRITICAL_BLOCK(cs_vNodes)
554 BOOST_FOREACH(CNode* pnode, vNodes)
555 if (pnode->IsSubscribed(nChannel))
560 bool CNode::IsSubscribed(unsigned int nChannel)
562 if (nChannel >= vfSubscribe.size())
564 return vfSubscribe[nChannel];
567 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
569 if (nChannel >= vfSubscribe.size())
572 if (!AnySubscribed(nChannel))
575 CRITICAL_BLOCK(cs_vNodes)
576 BOOST_FOREACH(CNode* pnode, vNodes)
578 pnode->PushMessage("subscribe", nChannel, nHops);
581 vfSubscribe[nChannel] = true;
584 void CNode::CancelSubscribe(unsigned int nChannel)
586 if (nChannel >= vfSubscribe.size())
589 // Prevent from relaying cancel if wasn't subscribed
590 if (!vfSubscribe[nChannel])
592 vfSubscribe[nChannel] = false;
594 if (!AnySubscribed(nChannel))
596 // Relay subscription cancel
597 CRITICAL_BLOCK(cs_vNodes)
598 BOOST_FOREACH(CNode* pnode, vNodes)
600 pnode->PushMessage("sub-cancel", nChannel);
612 CNode* FindNode(unsigned int ip)
614 CRITICAL_BLOCK(cs_vNodes)
616 BOOST_FOREACH(CNode* pnode, vNodes)
617 if (pnode->addr.ip == ip)
623 CNode* FindNode(CAddress addr)
625 CRITICAL_BLOCK(cs_vNodes)
627 BOOST_FOREACH(CNode* pnode, vNodes)
628 if (pnode->addr == addr)
634 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
636 if (addrConnect.ip == addrLocalHost.ip)
639 // Look for an existing connection
640 CNode* pnode = FindNode(addrConnect.ip);
644 pnode->AddRef(nTimeout);
651 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
652 addrConnect.ToString().c_str(),
653 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
654 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
656 CRITICAL_BLOCK(cs_mapAddresses)
657 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
661 if (ConnectSocket(addrConnect, hSocket))
664 printf("connected %s\n", addrConnect.ToString().c_str());
666 // Set to nonblocking
669 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
670 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
672 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
673 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
677 CNode* pnode = new CNode(hSocket, addrConnect, false);
679 pnode->AddRef(nTimeout);
682 CRITICAL_BLOCK(cs_vNodes)
683 vNodes.push_back(pnode);
685 pnode->nTimeConnected = GetTime();
694 void CNode::CloseSocketDisconnect()
697 if (hSocket != INVALID_SOCKET)
700 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
701 printf("disconnecting node %s\n", addr.ToString().c_str());
702 closesocket(hSocket);
703 hSocket = INVALID_SOCKET;
707 void CNode::Cleanup()
709 // All of a nodes broadcasts and subscriptions are automatically torn down
710 // when it goes down, so a node has to stay up to keep its broadcast going.
712 // Cancel subscriptions
713 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
714 if (vfSubscribe[nChannel])
715 CancelSubscribe(nChannel);
730 void ThreadSocketHandler(void* parg)
732 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
735 vnThreadsRunning[0]++;
736 ThreadSocketHandler2(parg);
737 vnThreadsRunning[0]--;
739 catch (std::exception& e) {
740 vnThreadsRunning[0]--;
741 PrintException(&e, "ThreadSocketHandler()");
743 vnThreadsRunning[0]--;
744 throw; // support pthread_cancel()
746 printf("ThreadSocketHandler exiting\n");
749 void ThreadSocketHandler2(void* parg)
751 printf("ThreadSocketHandler started\n");
752 list<CNode*> vNodesDisconnected;
753 int nPrevNodeCount = 0;
760 CRITICAL_BLOCK(cs_vNodes)
762 // Disconnect unused nodes
763 vector<CNode*> vNodesCopy = vNodes;
764 BOOST_FOREACH(CNode* pnode, vNodesCopy)
766 if (pnode->fDisconnect ||
767 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
769 // remove from vNodes
770 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
772 // close socket and cleanup
773 pnode->CloseSocketDisconnect();
776 // hold in disconnected pool until all refs are released
777 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
778 if (pnode->fNetworkNode || pnode->fInbound)
780 vNodesDisconnected.push_back(pnode);
784 // Delete disconnected nodes
785 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
786 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
788 // wait until threads are done using it
789 if (pnode->GetRefCount() <= 0)
791 bool fDelete = false;
792 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
793 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
794 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
795 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
799 vNodesDisconnected.remove(pnode);
805 if (vNodes.size() != nPrevNodeCount)
807 nPrevNodeCount = vNodes.size();
813 // Find which sockets have data to receive
815 struct timeval timeout;
817 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
824 FD_ZERO(&fdsetError);
825 SOCKET hSocketMax = 0;
827 if(hListenSocket != INVALID_SOCKET)
828 FD_SET(hListenSocket, &fdsetRecv);
829 hSocketMax = max(hSocketMax, hListenSocket);
830 CRITICAL_BLOCK(cs_vNodes)
832 BOOST_FOREACH(CNode* pnode, vNodes)
834 if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0)
836 FD_SET(pnode->hSocket, &fdsetRecv);
837 FD_SET(pnode->hSocket, &fdsetError);
838 hSocketMax = max(hSocketMax, pnode->hSocket);
839 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
840 if (!pnode->vSend.empty())
841 FD_SET(pnode->hSocket, &fdsetSend);
845 vnThreadsRunning[0]--;
846 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
847 vnThreadsRunning[0]++;
850 if (nSelect == SOCKET_ERROR)
852 int nErr = WSAGetLastError();
855 printf("socket select error %d\n", nErr);
856 for (int i = 0; i <= hSocketMax; i++)
857 FD_SET(i, &fdsetRecv);
860 FD_ZERO(&fdsetError);
861 Sleep(timeout.tv_usec/1000);
866 // Accept new connections
868 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
870 struct sockaddr_in sockaddr;
871 socklen_t len = sizeof(sockaddr);
872 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
873 CAddress addr(sockaddr);
876 CRITICAL_BLOCK(cs_vNodes)
877 BOOST_FOREACH(CNode* pnode, vNodes)
880 if (hSocket == INVALID_SOCKET)
882 if (WSAGetLastError() != WSAEWOULDBLOCK)
883 printf("socket error accept failed: %d\n", WSAGetLastError());
885 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
887 closesocket(hSocket);
891 printf("accepted connection %s\n", addr.ToString().c_str());
892 CNode* pnode = new CNode(hSocket, addr, true);
894 CRITICAL_BLOCK(cs_vNodes)
895 vNodes.push_back(pnode);
901 // Service each socket
903 vector<CNode*> vNodesCopy;
904 CRITICAL_BLOCK(cs_vNodes)
907 BOOST_FOREACH(CNode* pnode, vNodesCopy)
910 BOOST_FOREACH(CNode* pnode, vNodesCopy)
918 if (pnode->hSocket == INVALID_SOCKET)
920 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
922 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
924 CDataStream& vRecv = pnode->vRecv;
925 unsigned int nPos = vRecv.size();
927 if (nPos > ReceiveBufferSize()) {
928 if (!pnode->fDisconnect)
929 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
930 pnode->CloseSocketDisconnect();
933 // typical socket buffer is 8K-64K
934 char pchBuf[0x10000];
935 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
938 vRecv.resize(nPos + nBytes);
939 memcpy(&vRecv[nPos], pchBuf, nBytes);
940 pnode->nLastRecv = GetTime();
942 else if (nBytes == 0)
944 // socket closed gracefully
945 if (!pnode->fDisconnect)
946 printf("socket closed\n");
947 pnode->CloseSocketDisconnect();
952 int nErr = WSAGetLastError();
953 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
955 if (!pnode->fDisconnect)
956 printf("socket recv error %d\n", nErr);
957 pnode->CloseSocketDisconnect();
967 if (pnode->hSocket == INVALID_SOCKET)
969 if (FD_ISSET(pnode->hSocket, &fdsetSend))
971 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
973 CDataStream& vSend = pnode->vSend;
976 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
979 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
980 pnode->nLastSend = GetTime();
985 int nErr = WSAGetLastError();
986 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
988 printf("socket send error %d\n", nErr);
989 pnode->CloseSocketDisconnect();
992 if (vSend.size() > SendBufferSize()) {
993 if (!pnode->fDisconnect)
994 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
995 pnode->CloseSocketDisconnect();
1002 // Inactivity checking
1004 if (pnode->vSend.empty())
1005 pnode->nLastSendEmpty = GetTime();
1006 if (GetTime() - pnode->nTimeConnected > 60)
1008 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1010 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1011 pnode->fDisconnect = true;
1013 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1015 printf("socket not sending\n");
1016 pnode->fDisconnect = true;
1018 else if (GetTime() - pnode->nLastRecv > 90*60)
1020 printf("socket inactivity timeout\n");
1021 pnode->fDisconnect = true;
1025 CRITICAL_BLOCK(cs_vNodes)
1027 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1044 void ThreadMapPort(void* parg)
1046 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1049 vnThreadsRunning[5]++;
1050 ThreadMapPort2(parg);
1051 vnThreadsRunning[5]--;
1053 catch (std::exception& e) {
1054 vnThreadsRunning[5]--;
1055 PrintException(&e, "ThreadMapPort()");
1057 vnThreadsRunning[5]--;
1058 PrintException(NULL, "ThreadMapPort()");
1060 printf("ThreadMapPort exiting\n");
1063 void ThreadMapPort2(void* parg)
1065 printf("ThreadMapPort started\n");
1068 sprintf(port, "%d", GetListenPort());
1070 const char * rootdescurl = 0;
1071 const char * multicastif = 0;
1072 const char * minissdpdpath = 0;
1073 struct UPNPDev * devlist = 0;
1076 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1078 struct UPNPUrls urls;
1079 struct IGDdatas data;
1082 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1089 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1090 port, port, lanaddr, 0, "TCP", 0);
1092 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1093 port, port, lanaddr, 0, "TCP", 0, "0");
1095 if(r!=UPNPCOMMAND_SUCCESS)
1096 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1097 port, port, lanaddr, r, strupnperror(r));
1099 printf("UPnP Port Mapping successful.\n");
1101 if (fShutdown || !fUseUPnP)
1103 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1104 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1105 freeUPNPDevlist(devlist); devlist = 0;
1106 FreeUPNPUrls(&urls);
1112 printf("No valid UPnP IGDs found\n");
1113 freeUPNPDevlist(devlist); devlist = 0;
1115 FreeUPNPUrls(&urls);
1117 if (fShutdown || !fUseUPnP)
1124 void MapPort(bool fMapPort)
1126 if (fUseUPnP != fMapPort)
1128 fUseUPnP = fMapPort;
1129 WriteSetting("fUseUPnP", fUseUPnP);
1131 if (fUseUPnP && vnThreadsRunning[5] < 1)
1133 if (!CreateThread(ThreadMapPort, NULL))
1134 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1148 static const char *strDNSSeed[] = {
1150 "bitseed.bitcoin.org.uk",
1151 "dnsseed.bluematt.me",
1154 void DNSAddressSeed()
1160 printf("Loading addresses from DNS seeds (could take a while)\n");
1162 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1163 vector<CAddress> vaddr;
1164 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1166 BOOST_FOREACH (CAddress& addr, vaddr)
1168 if (addr.GetByte(3) != 127)
1179 printf("%d addresses found from DNS seeds\n", found);
1184 unsigned int pnSeed[] =
1186 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1187 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1188 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1189 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1190 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1191 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1192 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1193 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1194 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1195 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1196 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1197 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1198 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1199 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1200 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1201 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1202 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1203 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1204 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1205 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1206 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1207 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1208 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1209 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1210 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1211 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1212 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1213 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1214 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1215 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1216 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1217 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1218 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1219 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1220 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1221 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1222 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1223 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1224 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1225 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1230 void ThreadOpenConnections(void* parg)
1232 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1235 vnThreadsRunning[1]++;
1236 ThreadOpenConnections2(parg);
1237 vnThreadsRunning[1]--;
1239 catch (std::exception& e) {
1240 vnThreadsRunning[1]--;
1241 PrintException(&e, "ThreadOpenConnections()");
1243 vnThreadsRunning[1]--;
1244 PrintException(NULL, "ThreadOpenConnections()");
1246 printf("ThreadOpenConnections exiting\n");
1249 void ThreadOpenConnections2(void* parg)
1251 printf("ThreadOpenConnections started\n");
1253 // Connect to specific addresses
1254 if (mapArgs.count("-connect"))
1256 for (int64 nLoop = 0;; nLoop++)
1258 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1260 CAddress addr(strAddr, fAllowDNS);
1262 OpenNetworkConnection(addr);
1263 for (int i = 0; i < 10 && i < nLoop; i++)
1273 // Connect to manually added nodes first
1274 if (mapArgs.count("-addnode"))
1276 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1278 CAddress addr(strAddr, fAllowDNS);
1281 OpenNetworkConnection(addr);
1289 // Initiate network connections
1290 int64 nStart = GetTime();
1293 // Limit outbound connections
1294 vnThreadsRunning[1]--;
1299 CRITICAL_BLOCK(cs_vNodes)
1300 BOOST_FOREACH(CNode* pnode, vNodes)
1301 if (!pnode->fInbound)
1303 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1304 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1305 if (nOutbound < nMaxOutboundConnections)
1311 vnThreadsRunning[1]++;
1315 CRITICAL_BLOCK(cs_mapAddresses)
1317 // Add seed nodes if IRC isn't working
1318 static bool fSeedUsed;
1319 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1320 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1322 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1324 // It'll only connect to one or two seed nodes because once it connects,
1325 // it'll get a pile of addresses with newer timestamps.
1327 addr.ip = pnSeed[i];
1334 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1336 // Disconnect seed nodes
1337 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1338 static int64 nSeedDisconnected;
1339 if (nSeedDisconnected == 0)
1341 nSeedDisconnected = GetTime();
1342 CRITICAL_BLOCK(cs_vNodes)
1343 BOOST_FOREACH(CNode* pnode, vNodes)
1344 if (setSeed.count(pnode->addr.ip))
1345 pnode->fDisconnect = true;
1348 // Keep setting timestamps to 0 so they won't reconnect
1349 if (GetTime() - nSeedDisconnected < 60 * 60)
1351 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1353 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1355 item.second.nTime = 0;
1356 CAddrDB().WriteAddress(item.second);
1365 // Choose an address to connect to based on most recently seen
1367 CAddress addrConnect;
1368 int64 nBest = INT64_MIN;
1370 // Only connect to one address per a.b.?.? range.
1371 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1372 set<unsigned int> setConnected;
1373 CRITICAL_BLOCK(cs_vNodes)
1374 BOOST_FOREACH(CNode* pnode, vNodes)
1375 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1377 CRITICAL_BLOCK(cs_mapAddresses)
1379 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1381 const CAddress& addr = item.second;
1382 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1384 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1385 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1387 // Randomize the order in a deterministic way, putting the standard port first
1388 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1389 if (addr.port != htons(GetDefaultPort()))
1390 nRandomizer += 2 * 60 * 60;
1392 // Last seen Base retry frequency
1401 // 365 days 93 hours
1402 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1404 // Fast reconnect for one hour after last seen
1405 if (nSinceLastSeen < 60 * 60)
1408 // Limit retry frequency
1409 if (nSinceLastTry < nDelay)
1412 // If we have IRC, we'll be notified when they first come online,
1413 // and again every 24 hours by the refresh broadcast.
1414 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1417 // Only try the old stuff if we don't have enough connections
1418 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1421 // If multiple addresses are ready, prioritize by time since
1422 // last seen and time since last tried.
1423 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1432 if (addrConnect.IsValid())
1433 OpenNetworkConnection(addrConnect);
1437 bool OpenNetworkConnection(const CAddress& addrConnect)
1440 // Initiate outbound network connection
1444 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1447 vnThreadsRunning[1]--;
1448 CNode* pnode = ConnectNode(addrConnect);
1449 vnThreadsRunning[1]++;
1454 pnode->fNetworkNode = true;
1466 void ThreadMessageHandler(void* parg)
1468 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1471 vnThreadsRunning[2]++;
1472 ThreadMessageHandler2(parg);
1473 vnThreadsRunning[2]--;
1475 catch (std::exception& e) {
1476 vnThreadsRunning[2]--;
1477 PrintException(&e, "ThreadMessageHandler()");
1479 vnThreadsRunning[2]--;
1480 PrintException(NULL, "ThreadMessageHandler()");
1482 printf("ThreadMessageHandler exiting\n");
1485 void ThreadMessageHandler2(void* parg)
1487 printf("ThreadMessageHandler started\n");
1488 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1491 vector<CNode*> vNodesCopy;
1492 CRITICAL_BLOCK(cs_vNodes)
1494 vNodesCopy = vNodes;
1495 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1499 // Poll the connected nodes for messages
1500 CNode* pnodeTrickle = NULL;
1501 if (!vNodesCopy.empty())
1502 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1503 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1506 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1507 ProcessMessages(pnode);
1512 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1513 SendMessages(pnode, pnode == pnodeTrickle);
1518 CRITICAL_BLOCK(cs_vNodes)
1520 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1524 // Wait and allow messages to bunch up.
1525 // Reduce vnThreadsRunning so StopNode has permission to exit while
1526 // we're sleeping, but we must always check fShutdown after doing this.
1527 vnThreadsRunning[2]--;
1529 if (fRequestShutdown)
1531 vnThreadsRunning[2]++;
1542 bool BindListenPort(string& strError)
1546 addrLocalHost.port = htons(GetListenPort());
1549 // Initialize Windows Sockets
1551 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1552 if (ret != NO_ERROR)
1554 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1555 printf("%s\n", strError.c_str());
1560 // Create socket for listening for incoming connections
1561 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1562 if (hListenSocket == INVALID_SOCKET)
1564 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1565 printf("%s\n", strError.c_str());
1570 // Different way of disabling SIGPIPE on BSD
1571 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1575 // Allow binding if the port is still in TIME_WAIT state after
1576 // the program was closed and restarted. Not an issue on windows.
1577 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1581 // Set to nonblocking, incoming connections will also inherit this
1582 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1584 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1587 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1588 printf("%s\n", strError.c_str());
1592 // The sockaddr_in structure specifies the address family,
1593 // IP address, and port for the socket that is being bound
1594 struct sockaddr_in sockaddr;
1595 memset(&sockaddr, 0, sizeof(sockaddr));
1596 sockaddr.sin_family = AF_INET;
1597 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1598 sockaddr.sin_port = htons(GetListenPort());
1599 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1601 int nErr = WSAGetLastError();
1602 if (nErr == WSAEADDRINUSE)
1603 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1605 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1606 printf("%s\n", strError.c_str());
1609 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1611 // Listen for incoming connections
1612 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1614 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1615 printf("%s\n", strError.c_str());
1622 void StartNode(void* parg)
1624 if (pnodeLocalHost == NULL)
1625 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1628 // Get local host ip
1629 char pszHostName[1000] = "";
1630 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1632 vector<CAddress> vaddr;
1633 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1634 BOOST_FOREACH (const CAddress &addr, vaddr)
1635 if (addr.GetByte(3) != 127)
1637 addrLocalHost = addr;
1642 // Get local host ip
1643 struct ifaddrs* myaddrs;
1644 if (getifaddrs(&myaddrs) == 0)
1646 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1648 if (ifa->ifa_addr == NULL) continue;
1649 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1650 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1651 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1653 if (ifa->ifa_addr->sa_family == AF_INET)
1655 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1656 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1657 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1659 // Take the first IP that isn't loopback 127.x.x.x
1660 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1661 if (addr.IsValid() && addr.GetByte(3) != 127)
1663 addrLocalHost = addr;
1667 else if (ifa->ifa_addr->sa_family == AF_INET6)
1669 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1670 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1671 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1674 freeifaddrs(myaddrs);
1677 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1679 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1681 // Proxies can't take incoming connections
1682 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1683 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1687 CreateThread(ThreadGetMyExternalIP, NULL);
1694 // Map ports with UPnP
1698 // Get addresses from IRC and advertise ours
1699 if (!CreateThread(ThreadIRCSeed, NULL))
1700 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1702 // Send and receive from sockets, accept connections
1703 pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
1705 // Initiate outbound connections
1706 if (!CreateThread(ThreadOpenConnections, NULL))
1707 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1710 if (!CreateThread(ThreadMessageHandler, NULL))
1711 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1713 // Generate coins in the background
1714 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1719 printf("StopNode()\n");
1721 nTransactionsUpdated++;
1722 int64 nStart = GetTime();
1723 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1725 || vnThreadsRunning[5] > 0
1729 if (GetTime() - nStart > 20)
1733 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1734 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1735 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1736 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1737 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1738 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1739 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1755 BOOST_FOREACH(CNode* pnode, vNodes)
1756 if (pnode->hSocket != INVALID_SOCKET)
1757 closesocket(pnode->hSocket);
1758 if (hListenSocket != INVALID_SOCKET)
1759 if (closesocket(hListenSocket) == SOCKET_ERROR)
1760 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1763 // Shutdown Windows Sockets
1768 instance_of_cnetcleanup;