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, CAddrDB *pAddrDB)
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));
459 pAddrDB->WriteAddress(addr);
461 CAddrDB().WriteAddress(addr);
466 bool fUpdated = false;
467 CAddress& addrFound = (*it).second;
468 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
470 // Services have been added
471 addrFound.nServices |= addr.nServices;
474 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
475 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
476 if (addrFound.nTime < addr.nTime - nUpdateInterval)
478 // Periodically update most recently seen time
479 addrFound.nTime = addr.nTime;
485 pAddrDB->WriteAddress(addrFound);
487 CAddrDB().WriteAddress(addrFound);
494 void AddressCurrentlyConnected(const CAddress& addr)
496 CRITICAL_BLOCK(cs_mapAddresses)
498 // Only if it's been published already
499 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
500 if (it != mapAddresses.end())
502 CAddress& addrFound = (*it).second;
503 int64 nUpdateInterval = 20 * 60;
504 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
506 // Periodically update most recently seen time
507 addrFound.nTime = GetAdjustedTime();
509 addrdb.WriteAddress(addrFound);
519 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
521 // If the dialog might get closed before the reply comes back,
522 // call this in the destructor so it doesn't get called after it's deleted.
523 CRITICAL_BLOCK(cs_vNodes)
525 BOOST_FOREACH(CNode* pnode, vNodes)
527 CRITICAL_BLOCK(pnode->cs_mapRequests)
529 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
531 CRequestTracker& tracker = (*mi).second;
532 if (tracker.fn == fn && tracker.param1 == param1)
533 pnode->mapRequests.erase(mi++);
549 // Subscription methods for the broadcast and subscription system.
550 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
552 // The subscription system uses a meet-in-the-middle strategy.
553 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
554 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
557 bool AnySubscribed(unsigned int nChannel)
559 if (pnodeLocalHost->IsSubscribed(nChannel))
561 CRITICAL_BLOCK(cs_vNodes)
562 BOOST_FOREACH(CNode* pnode, vNodes)
563 if (pnode->IsSubscribed(nChannel))
568 bool CNode::IsSubscribed(unsigned int nChannel)
570 if (nChannel >= vfSubscribe.size())
572 return vfSubscribe[nChannel];
575 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
577 if (nChannel >= vfSubscribe.size())
580 if (!AnySubscribed(nChannel))
583 CRITICAL_BLOCK(cs_vNodes)
584 BOOST_FOREACH(CNode* pnode, vNodes)
586 pnode->PushMessage("subscribe", nChannel, nHops);
589 vfSubscribe[nChannel] = true;
592 void CNode::CancelSubscribe(unsigned int nChannel)
594 if (nChannel >= vfSubscribe.size())
597 // Prevent from relaying cancel if wasn't subscribed
598 if (!vfSubscribe[nChannel])
600 vfSubscribe[nChannel] = false;
602 if (!AnySubscribed(nChannel))
604 // Relay subscription cancel
605 CRITICAL_BLOCK(cs_vNodes)
606 BOOST_FOREACH(CNode* pnode, vNodes)
608 pnode->PushMessage("sub-cancel", nChannel);
620 CNode* FindNode(unsigned int ip)
622 CRITICAL_BLOCK(cs_vNodes)
624 BOOST_FOREACH(CNode* pnode, vNodes)
625 if (pnode->addr.ip == ip)
631 CNode* FindNode(CAddress addr)
633 CRITICAL_BLOCK(cs_vNodes)
635 BOOST_FOREACH(CNode* pnode, vNodes)
636 if (pnode->addr == addr)
642 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
644 if (addrConnect.ip == addrLocalHost.ip)
647 // Look for an existing connection
648 CNode* pnode = FindNode(addrConnect.ip);
652 pnode->AddRef(nTimeout);
659 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
660 addrConnect.ToString().c_str(),
661 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
662 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
664 CRITICAL_BLOCK(cs_mapAddresses)
665 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
669 if (ConnectSocket(addrConnect, hSocket))
672 printf("connected %s\n", addrConnect.ToString().c_str());
674 // Set to nonblocking
677 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
678 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
680 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
681 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
685 CNode* pnode = new CNode(hSocket, addrConnect, false);
687 pnode->AddRef(nTimeout);
690 CRITICAL_BLOCK(cs_vNodes)
691 vNodes.push_back(pnode);
693 pnode->nTimeConnected = GetTime();
702 void CNode::CloseSocketDisconnect()
705 if (hSocket != INVALID_SOCKET)
708 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
709 printf("disconnecting node %s\n", addr.ToString().c_str());
710 closesocket(hSocket);
711 hSocket = INVALID_SOCKET;
715 void CNode::Cleanup()
717 // All of a nodes broadcasts and subscriptions are automatically torn down
718 // when it goes down, so a node has to stay up to keep its broadcast going.
720 // Cancel subscriptions
721 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
722 if (vfSubscribe[nChannel])
723 CancelSubscribe(nChannel);
738 void ThreadSocketHandler(void* parg)
740 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
743 vnThreadsRunning[0]++;
744 ThreadSocketHandler2(parg);
745 vnThreadsRunning[0]--;
747 catch (std::exception& e) {
748 vnThreadsRunning[0]--;
749 PrintException(&e, "ThreadSocketHandler()");
751 vnThreadsRunning[0]--;
752 throw; // support pthread_cancel()
754 printf("ThreadSocketHandler exiting\n");
757 void ThreadSocketHandler2(void* parg)
759 printf("ThreadSocketHandler started\n");
760 list<CNode*> vNodesDisconnected;
761 int nPrevNodeCount = 0;
768 CRITICAL_BLOCK(cs_vNodes)
770 // Disconnect unused nodes
771 vector<CNode*> vNodesCopy = vNodes;
772 BOOST_FOREACH(CNode* pnode, vNodesCopy)
774 if (pnode->fDisconnect ||
775 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
777 // remove from vNodes
778 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
780 // close socket and cleanup
781 pnode->CloseSocketDisconnect();
784 // hold in disconnected pool until all refs are released
785 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
786 if (pnode->fNetworkNode || pnode->fInbound)
788 vNodesDisconnected.push_back(pnode);
792 // Delete disconnected nodes
793 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
794 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
796 // wait until threads are done using it
797 if (pnode->GetRefCount() <= 0)
799 bool fDelete = false;
800 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
801 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
802 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
803 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
807 vNodesDisconnected.remove(pnode);
813 if (vNodes.size() != nPrevNodeCount)
815 nPrevNodeCount = vNodes.size();
821 // Find which sockets have data to receive
823 struct timeval timeout;
825 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
832 FD_ZERO(&fdsetError);
833 SOCKET hSocketMax = 0;
835 if(hListenSocket != INVALID_SOCKET)
836 FD_SET(hListenSocket, &fdsetRecv);
837 hSocketMax = max(hSocketMax, hListenSocket);
838 CRITICAL_BLOCK(cs_vNodes)
840 BOOST_FOREACH(CNode* pnode, vNodes)
842 if (pnode->hSocket == INVALID_SOCKET)
844 FD_SET(pnode->hSocket, &fdsetRecv);
845 FD_SET(pnode->hSocket, &fdsetError);
846 hSocketMax = max(hSocketMax, pnode->hSocket);
847 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
848 if (!pnode->vSend.empty())
849 FD_SET(pnode->hSocket, &fdsetSend);
853 vnThreadsRunning[0]--;
854 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
855 vnThreadsRunning[0]++;
858 if (nSelect == SOCKET_ERROR)
860 int nErr = WSAGetLastError();
863 printf("socket select error %d\n", nErr);
864 for (int i = 0; i <= hSocketMax; i++)
865 FD_SET(i, &fdsetRecv);
868 FD_ZERO(&fdsetError);
869 Sleep(timeout.tv_usec/1000);
874 // Accept new connections
876 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
878 struct sockaddr_in sockaddr;
879 socklen_t len = sizeof(sockaddr);
880 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
881 CAddress addr(sockaddr);
884 CRITICAL_BLOCK(cs_vNodes)
885 BOOST_FOREACH(CNode* pnode, vNodes)
888 if (hSocket == INVALID_SOCKET)
890 if (WSAGetLastError() != WSAEWOULDBLOCK)
891 printf("socket error accept failed: %d\n", WSAGetLastError());
893 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
895 closesocket(hSocket);
899 printf("accepted connection %s\n", addr.ToString().c_str());
900 CNode* pnode = new CNode(hSocket, addr, true);
902 CRITICAL_BLOCK(cs_vNodes)
903 vNodes.push_back(pnode);
909 // Service each socket
911 vector<CNode*> vNodesCopy;
912 CRITICAL_BLOCK(cs_vNodes)
915 BOOST_FOREACH(CNode* pnode, vNodesCopy)
918 BOOST_FOREACH(CNode* pnode, vNodesCopy)
926 if (pnode->hSocket == INVALID_SOCKET)
928 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
930 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
932 CDataStream& vRecv = pnode->vRecv;
933 unsigned int nPos = vRecv.size();
935 if (nPos > ReceiveBufferSize()) {
936 if (!pnode->fDisconnect)
937 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
938 pnode->CloseSocketDisconnect();
941 // typical socket buffer is 8K-64K
942 char pchBuf[0x10000];
943 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
946 vRecv.resize(nPos + nBytes);
947 memcpy(&vRecv[nPos], pchBuf, nBytes);
948 pnode->nLastRecv = GetTime();
950 else if (nBytes == 0)
952 // socket closed gracefully
953 if (!pnode->fDisconnect)
954 printf("socket closed\n");
955 pnode->CloseSocketDisconnect();
960 int nErr = WSAGetLastError();
961 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
963 if (!pnode->fDisconnect)
964 printf("socket recv error %d\n", nErr);
965 pnode->CloseSocketDisconnect();
975 if (pnode->hSocket == INVALID_SOCKET)
977 if (FD_ISSET(pnode->hSocket, &fdsetSend))
979 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
981 CDataStream& vSend = pnode->vSend;
984 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
987 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
988 pnode->nLastSend = GetTime();
993 int nErr = WSAGetLastError();
994 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
996 printf("socket send error %d\n", nErr);
997 pnode->CloseSocketDisconnect();
1000 if (vSend.size() > SendBufferSize()) {
1001 if (!pnode->fDisconnect)
1002 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1003 pnode->CloseSocketDisconnect();
1010 // Inactivity checking
1012 if (pnode->vSend.empty())
1013 pnode->nLastSendEmpty = GetTime();
1014 if (GetTime() - pnode->nTimeConnected > 60)
1016 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1018 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1019 pnode->fDisconnect = true;
1021 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1023 printf("socket not sending\n");
1024 pnode->fDisconnect = true;
1026 else if (GetTime() - pnode->nLastRecv > 90*60)
1028 printf("socket inactivity timeout\n");
1029 pnode->fDisconnect = true;
1033 CRITICAL_BLOCK(cs_vNodes)
1035 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1052 void ThreadMapPort(void* parg)
1054 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1057 vnThreadsRunning[5]++;
1058 ThreadMapPort2(parg);
1059 vnThreadsRunning[5]--;
1061 catch (std::exception& e) {
1062 vnThreadsRunning[5]--;
1063 PrintException(&e, "ThreadMapPort()");
1065 vnThreadsRunning[5]--;
1066 PrintException(NULL, "ThreadMapPort()");
1068 printf("ThreadMapPort exiting\n");
1071 void ThreadMapPort2(void* parg)
1073 printf("ThreadMapPort started\n");
1076 sprintf(port, "%d", GetListenPort());
1078 const char * rootdescurl = 0;
1079 const char * multicastif = 0;
1080 const char * minissdpdpath = 0;
1081 struct UPNPDev * devlist = 0;
1084 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1086 struct UPNPUrls urls;
1087 struct IGDdatas data;
1090 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1095 string strDesc = "Bitcoin " + FormatFullVersion();
1098 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1099 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1101 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1102 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1104 if(r!=UPNPCOMMAND_SUCCESS)
1105 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1106 port, port, lanaddr, r, strupnperror(r));
1108 printf("UPnP Port Mapping successful.\n");
1110 if (fShutdown || !fUseUPnP)
1112 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1113 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1114 freeUPNPDevlist(devlist); devlist = 0;
1115 FreeUPNPUrls(&urls);
1121 printf("No valid UPnP IGDs found\n");
1122 freeUPNPDevlist(devlist); devlist = 0;
1124 FreeUPNPUrls(&urls);
1126 if (fShutdown || !fUseUPnP)
1133 void MapPort(bool fMapPort)
1135 if (fUseUPnP != fMapPort)
1137 fUseUPnP = fMapPort;
1138 WriteSetting("fUseUPnP", fUseUPnP);
1140 if (fUseUPnP && vnThreadsRunning[5] < 1)
1142 if (!CreateThread(ThreadMapPort, NULL))
1143 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1157 static const char *strDNSSeed[] = {
1159 "bitseed.bitcoin.org.uk",
1160 "dnsseed.bluematt.me",
1163 void DNSAddressSeed()
1169 printf("Loading addresses from DNS seeds (could take a while)\n");
1173 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1174 vector<CAddress> vaddr;
1175 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1177 BOOST_FOREACH (CAddress& addr, vaddr)
1179 if (addr.GetByte(3) != 127)
1182 AddAddress(addr, 0, &addrDB);
1189 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1192 printf("%d addresses found from DNS seeds\n", found);
1197 unsigned int pnSeed[] =
1199 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1200 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1201 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1202 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1203 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1204 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1205 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1206 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1207 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1208 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1209 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1210 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1211 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1212 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1213 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1214 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1215 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1216 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1217 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1218 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1219 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1220 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1221 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1222 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1223 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1224 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1225 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1226 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1227 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1228 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1229 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1230 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1231 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1232 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1233 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1234 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1235 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1236 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1237 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1238 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1243 void ThreadOpenConnections(void* parg)
1245 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1248 vnThreadsRunning[1]++;
1249 ThreadOpenConnections2(parg);
1250 vnThreadsRunning[1]--;
1252 catch (std::exception& e) {
1253 vnThreadsRunning[1]--;
1254 PrintException(&e, "ThreadOpenConnections()");
1256 vnThreadsRunning[1]--;
1257 PrintException(NULL, "ThreadOpenConnections()");
1259 printf("ThreadOpenConnections exiting\n");
1262 void ThreadOpenConnections2(void* parg)
1264 printf("ThreadOpenConnections started\n");
1266 // Connect to specific addresses
1267 if (mapArgs.count("-connect"))
1269 for (int64 nLoop = 0;; nLoop++)
1271 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1273 CAddress addr(strAddr, fAllowDNS);
1275 OpenNetworkConnection(addr);
1276 for (int i = 0; i < 10 && i < nLoop; i++)
1286 // Connect to manually added nodes first
1287 if (mapArgs.count("-addnode"))
1289 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1291 CAddress addr(strAddr, fAllowDNS);
1294 OpenNetworkConnection(addr);
1302 // Initiate network connections
1303 int64 nStart = GetTime();
1306 // Limit outbound connections
1307 vnThreadsRunning[1]--;
1312 CRITICAL_BLOCK(cs_vNodes)
1313 BOOST_FOREACH(CNode* pnode, vNodes)
1314 if (!pnode->fInbound)
1316 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1317 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1318 if (nOutbound < nMaxOutboundConnections)
1324 vnThreadsRunning[1]++;
1328 CRITICAL_BLOCK(cs_mapAddresses)
1330 // Add seed nodes if IRC isn't working
1331 static bool fSeedUsed;
1332 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1333 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1335 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1337 // It'll only connect to one or two seed nodes because once it connects,
1338 // it'll get a pile of addresses with newer timestamps.
1340 addr.ip = pnSeed[i];
1347 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1349 // Disconnect seed nodes
1350 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1351 static int64 nSeedDisconnected;
1352 if (nSeedDisconnected == 0)
1354 nSeedDisconnected = GetTime();
1355 CRITICAL_BLOCK(cs_vNodes)
1356 BOOST_FOREACH(CNode* pnode, vNodes)
1357 if (setSeed.count(pnode->addr.ip))
1358 pnode->fDisconnect = true;
1361 // Keep setting timestamps to 0 so they won't reconnect
1362 if (GetTime() - nSeedDisconnected < 60 * 60)
1364 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1366 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1368 item.second.nTime = 0;
1369 CAddrDB().WriteAddress(item.second);
1378 // Choose an address to connect to based on most recently seen
1380 CAddress addrConnect;
1381 int64 nBest = INT64_MIN;
1383 // Only connect to one address per a.b.?.? range.
1384 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1385 set<unsigned int> setConnected;
1386 CRITICAL_BLOCK(cs_vNodes)
1387 BOOST_FOREACH(CNode* pnode, vNodes)
1388 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1390 CRITICAL_BLOCK(cs_mapAddresses)
1392 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1394 const CAddress& addr = item.second;
1395 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1397 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1398 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1400 // Randomize the order in a deterministic way, putting the standard port first
1401 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1402 if (addr.port != htons(GetDefaultPort()))
1403 nRandomizer += 2 * 60 * 60;
1405 // Last seen Base retry frequency
1414 // 365 days 93 hours
1415 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1417 // Fast reconnect for one hour after last seen
1418 if (nSinceLastSeen < 60 * 60)
1421 // Limit retry frequency
1422 if (nSinceLastTry < nDelay)
1425 // If we have IRC, we'll be notified when they first come online,
1426 // and again every 24 hours by the refresh broadcast.
1427 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1430 // Only try the old stuff if we don't have enough connections
1431 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1434 // If multiple addresses are ready, prioritize by time since
1435 // last seen and time since last tried.
1436 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1445 if (addrConnect.IsValid())
1446 OpenNetworkConnection(addrConnect);
1450 bool OpenNetworkConnection(const CAddress& addrConnect)
1453 // Initiate outbound network connection
1457 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1460 vnThreadsRunning[1]--;
1461 CNode* pnode = ConnectNode(addrConnect);
1462 vnThreadsRunning[1]++;
1467 pnode->fNetworkNode = true;
1479 void ThreadMessageHandler(void* parg)
1481 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1484 vnThreadsRunning[2]++;
1485 ThreadMessageHandler2(parg);
1486 vnThreadsRunning[2]--;
1488 catch (std::exception& e) {
1489 vnThreadsRunning[2]--;
1490 PrintException(&e, "ThreadMessageHandler()");
1492 vnThreadsRunning[2]--;
1493 PrintException(NULL, "ThreadMessageHandler()");
1495 printf("ThreadMessageHandler exiting\n");
1498 void ThreadMessageHandler2(void* parg)
1500 printf("ThreadMessageHandler started\n");
1501 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1504 vector<CNode*> vNodesCopy;
1505 CRITICAL_BLOCK(cs_vNodes)
1507 vNodesCopy = vNodes;
1508 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1512 // Poll the connected nodes for messages
1513 CNode* pnodeTrickle = NULL;
1514 if (!vNodesCopy.empty())
1515 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1516 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1519 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1520 ProcessMessages(pnode);
1525 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1526 SendMessages(pnode, pnode == pnodeTrickle);
1531 CRITICAL_BLOCK(cs_vNodes)
1533 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1537 // Wait and allow messages to bunch up.
1538 // Reduce vnThreadsRunning so StopNode has permission to exit while
1539 // we're sleeping, but we must always check fShutdown after doing this.
1540 vnThreadsRunning[2]--;
1542 if (fRequestShutdown)
1544 vnThreadsRunning[2]++;
1555 bool BindListenPort(string& strError)
1559 addrLocalHost.port = htons(GetListenPort());
1562 // Initialize Windows Sockets
1564 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1565 if (ret != NO_ERROR)
1567 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1568 printf("%s\n", strError.c_str());
1573 // Create socket for listening for incoming connections
1574 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1575 if (hListenSocket == INVALID_SOCKET)
1577 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1578 printf("%s\n", strError.c_str());
1583 // Different way of disabling SIGPIPE on BSD
1584 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1588 // Allow binding if the port is still in TIME_WAIT state after
1589 // the program was closed and restarted. Not an issue on windows.
1590 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1594 // Set to nonblocking, incoming connections will also inherit this
1595 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1597 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1600 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1601 printf("%s\n", strError.c_str());
1605 // The sockaddr_in structure specifies the address family,
1606 // IP address, and port for the socket that is being bound
1607 struct sockaddr_in sockaddr;
1608 memset(&sockaddr, 0, sizeof(sockaddr));
1609 sockaddr.sin_family = AF_INET;
1610 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1611 sockaddr.sin_port = htons(GetListenPort());
1612 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1614 int nErr = WSAGetLastError();
1615 if (nErr == WSAEADDRINUSE)
1616 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1618 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1619 printf("%s\n", strError.c_str());
1622 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1624 // Listen for incoming connections
1625 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1627 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1628 printf("%s\n", strError.c_str());
1635 void StartNode(void* parg)
1637 if (pnodeLocalHost == NULL)
1638 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1641 // Get local host ip
1642 char pszHostName[1000] = "";
1643 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1645 vector<CAddress> vaddr;
1646 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1647 BOOST_FOREACH (const CAddress &addr, vaddr)
1648 if (addr.GetByte(3) != 127)
1650 addrLocalHost = addr;
1655 // Get local host ip
1656 struct ifaddrs* myaddrs;
1657 if (getifaddrs(&myaddrs) == 0)
1659 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1661 if (ifa->ifa_addr == NULL) continue;
1662 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1663 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1664 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1666 if (ifa->ifa_addr->sa_family == AF_INET)
1668 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1669 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1670 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1672 // Take the first IP that isn't loopback 127.x.x.x
1673 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1674 if (addr.IsValid() && addr.GetByte(3) != 127)
1676 addrLocalHost = addr;
1680 else if (ifa->ifa_addr->sa_family == AF_INET6)
1682 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1683 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1684 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1687 freeifaddrs(myaddrs);
1690 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1692 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1694 // Proxies can't take incoming connections
1695 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1696 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1700 CreateThread(ThreadGetMyExternalIP, NULL);
1707 // Map ports with UPnP
1711 // Get addresses from IRC and advertise ours
1712 if (!CreateThread(ThreadIRCSeed, NULL))
1713 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1715 // Send and receive from sockets, accept connections
1716 CreateThread(ThreadSocketHandler, NULL, true);
1718 // Initiate outbound connections
1719 if (!CreateThread(ThreadOpenConnections, NULL))
1720 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1723 if (!CreateThread(ThreadMessageHandler, NULL))
1724 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1726 // Generate coins in the background
1727 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1732 printf("StopNode()\n");
1734 nTransactionsUpdated++;
1735 int64 nStart = GetTime();
1736 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1738 || vnThreadsRunning[5] > 0
1742 if (GetTime() - nStart > 20)
1746 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1747 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1748 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1749 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1750 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1751 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1752 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1768 BOOST_FOREACH(CNode* pnode, vNodes)
1769 if (pnode->hSocket != INVALID_SOCKET)
1770 closesocket(pnode->hSocket);
1771 if (hListenSocket != INVALID_SOCKET)
1772 if (closesocket(hListenSocket) == SOCKET_ERROR)
1773 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1776 // Shutdown Windows Sockets
1781 instance_of_cnetcleanup;