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));
1097 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1098 port, port, lanaddr, 0, "TCP", 0);
1100 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1101 port, port, lanaddr, 0, "TCP", 0, "0");
1103 if(r!=UPNPCOMMAND_SUCCESS)
1104 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1105 port, port, lanaddr, r, strupnperror(r));
1107 printf("UPnP Port Mapping successful.\n");
1109 if (fShutdown || !fUseUPnP)
1111 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1112 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1113 freeUPNPDevlist(devlist); devlist = 0;
1114 FreeUPNPUrls(&urls);
1120 printf("No valid UPnP IGDs found\n");
1121 freeUPNPDevlist(devlist); devlist = 0;
1123 FreeUPNPUrls(&urls);
1125 if (fShutdown || !fUseUPnP)
1132 void MapPort(bool fMapPort)
1134 if (fUseUPnP != fMapPort)
1136 fUseUPnP = fMapPort;
1137 WriteSetting("fUseUPnP", fUseUPnP);
1139 if (fUseUPnP && vnThreadsRunning[5] < 1)
1141 if (!CreateThread(ThreadMapPort, NULL))
1142 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1156 static const char *strDNSSeed[] = {
1158 "bitseed.bitcoin.org.uk",
1159 "dnsseed.bluematt.me",
1162 void DNSAddressSeed()
1168 printf("Loading addresses from DNS seeds (could take a while)\n");
1172 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1173 vector<CAddress> vaddr;
1174 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1176 BOOST_FOREACH (CAddress& addr, vaddr)
1178 if (addr.GetByte(3) != 127)
1181 AddAddress(addr, 0, &addrDB);
1188 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
1191 printf("%d addresses found from DNS seeds\n", found);
1196 unsigned int pnSeed[] =
1198 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1199 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1200 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1201 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1202 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1203 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1204 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1205 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1206 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1207 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1208 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1209 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1210 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1211 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1212 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1213 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1214 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1215 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1216 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1217 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1218 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1219 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1220 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1221 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1222 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1223 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1224 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1225 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1226 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1227 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1228 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1229 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1230 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1231 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1232 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1233 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1234 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1235 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1236 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1237 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1242 void ThreadOpenConnections(void* parg)
1244 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1247 vnThreadsRunning[1]++;
1248 ThreadOpenConnections2(parg);
1249 vnThreadsRunning[1]--;
1251 catch (std::exception& e) {
1252 vnThreadsRunning[1]--;
1253 PrintException(&e, "ThreadOpenConnections()");
1255 vnThreadsRunning[1]--;
1256 PrintException(NULL, "ThreadOpenConnections()");
1258 printf("ThreadOpenConnections exiting\n");
1261 void ThreadOpenConnections2(void* parg)
1263 printf("ThreadOpenConnections started\n");
1265 // Connect to specific addresses
1266 if (mapArgs.count("-connect"))
1268 for (int64 nLoop = 0;; nLoop++)
1270 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1272 CAddress addr(strAddr, fAllowDNS);
1274 OpenNetworkConnection(addr);
1275 for (int i = 0; i < 10 && i < nLoop; i++)
1285 // Connect to manually added nodes first
1286 if (mapArgs.count("-addnode"))
1288 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1290 CAddress addr(strAddr, fAllowDNS);
1293 OpenNetworkConnection(addr);
1301 // Initiate network connections
1302 int64 nStart = GetTime();
1305 // Limit outbound connections
1306 vnThreadsRunning[1]--;
1311 CRITICAL_BLOCK(cs_vNodes)
1312 BOOST_FOREACH(CNode* pnode, vNodes)
1313 if (!pnode->fInbound)
1315 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1316 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1317 if (nOutbound < nMaxOutboundConnections)
1323 vnThreadsRunning[1]++;
1327 CRITICAL_BLOCK(cs_mapAddresses)
1329 // Add seed nodes if IRC isn't working
1330 static bool fSeedUsed;
1331 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1332 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1334 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1336 // It'll only connect to one or two seed nodes because once it connects,
1337 // it'll get a pile of addresses with newer timestamps.
1339 addr.ip = pnSeed[i];
1346 if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1348 // Disconnect seed nodes
1349 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1350 static int64 nSeedDisconnected;
1351 if (nSeedDisconnected == 0)
1353 nSeedDisconnected = GetTime();
1354 CRITICAL_BLOCK(cs_vNodes)
1355 BOOST_FOREACH(CNode* pnode, vNodes)
1356 if (setSeed.count(pnode->addr.ip))
1357 pnode->fDisconnect = true;
1360 // Keep setting timestamps to 0 so they won't reconnect
1361 if (GetTime() - nSeedDisconnected < 60 * 60)
1363 BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1365 if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1367 item.second.nTime = 0;
1368 CAddrDB().WriteAddress(item.second);
1377 // Choose an address to connect to based on most recently seen
1379 CAddress addrConnect;
1380 int64 nBest = INT64_MIN;
1382 // Only connect to one address per a.b.?.? range.
1383 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1384 set<unsigned int> setConnected;
1385 CRITICAL_BLOCK(cs_vNodes)
1386 BOOST_FOREACH(CNode* pnode, vNodes)
1387 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1389 CRITICAL_BLOCK(cs_mapAddresses)
1391 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1393 const CAddress& addr = item.second;
1394 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1396 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1397 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1399 // Randomize the order in a deterministic way, putting the standard port first
1400 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1401 if (addr.port != htons(GetDefaultPort()))
1402 nRandomizer += 2 * 60 * 60;
1404 // Last seen Base retry frequency
1413 // 365 days 93 hours
1414 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1416 // Fast reconnect for one hour after last seen
1417 if (nSinceLastSeen < 60 * 60)
1420 // Limit retry frequency
1421 if (nSinceLastTry < nDelay)
1424 // If we have IRC, we'll be notified when they first come online,
1425 // and again every 24 hours by the refresh broadcast.
1426 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1429 // Only try the old stuff if we don't have enough connections
1430 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1433 // If multiple addresses are ready, prioritize by time since
1434 // last seen and time since last tried.
1435 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1444 if (addrConnect.IsValid())
1445 OpenNetworkConnection(addrConnect);
1449 bool OpenNetworkConnection(const CAddress& addrConnect)
1452 // Initiate outbound network connection
1456 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1459 vnThreadsRunning[1]--;
1460 CNode* pnode = ConnectNode(addrConnect);
1461 vnThreadsRunning[1]++;
1466 pnode->fNetworkNode = true;
1478 void ThreadMessageHandler(void* parg)
1480 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1483 vnThreadsRunning[2]++;
1484 ThreadMessageHandler2(parg);
1485 vnThreadsRunning[2]--;
1487 catch (std::exception& e) {
1488 vnThreadsRunning[2]--;
1489 PrintException(&e, "ThreadMessageHandler()");
1491 vnThreadsRunning[2]--;
1492 PrintException(NULL, "ThreadMessageHandler()");
1494 printf("ThreadMessageHandler exiting\n");
1497 void ThreadMessageHandler2(void* parg)
1499 printf("ThreadMessageHandler started\n");
1500 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1503 vector<CNode*> vNodesCopy;
1504 CRITICAL_BLOCK(cs_vNodes)
1506 vNodesCopy = vNodes;
1507 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1511 // Poll the connected nodes for messages
1512 CNode* pnodeTrickle = NULL;
1513 if (!vNodesCopy.empty())
1514 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1515 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1518 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1519 ProcessMessages(pnode);
1524 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1525 SendMessages(pnode, pnode == pnodeTrickle);
1530 CRITICAL_BLOCK(cs_vNodes)
1532 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1536 // Wait and allow messages to bunch up.
1537 // Reduce vnThreadsRunning so StopNode has permission to exit while
1538 // we're sleeping, but we must always check fShutdown after doing this.
1539 vnThreadsRunning[2]--;
1541 if (fRequestShutdown)
1543 vnThreadsRunning[2]++;
1554 bool BindListenPort(string& strError)
1558 addrLocalHost.port = htons(GetListenPort());
1561 // Initialize Windows Sockets
1563 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1564 if (ret != NO_ERROR)
1566 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1567 printf("%s\n", strError.c_str());
1572 // Create socket for listening for incoming connections
1573 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1574 if (hListenSocket == INVALID_SOCKET)
1576 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1577 printf("%s\n", strError.c_str());
1582 // Different way of disabling SIGPIPE on BSD
1583 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1587 // Allow binding if the port is still in TIME_WAIT state after
1588 // the program was closed and restarted. Not an issue on windows.
1589 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1593 // Set to nonblocking, incoming connections will also inherit this
1594 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1596 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1599 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1600 printf("%s\n", strError.c_str());
1604 // The sockaddr_in structure specifies the address family,
1605 // IP address, and port for the socket that is being bound
1606 struct sockaddr_in sockaddr;
1607 memset(&sockaddr, 0, sizeof(sockaddr));
1608 sockaddr.sin_family = AF_INET;
1609 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1610 sockaddr.sin_port = htons(GetListenPort());
1611 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1613 int nErr = WSAGetLastError();
1614 if (nErr == WSAEADDRINUSE)
1615 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1617 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1618 printf("%s\n", strError.c_str());
1621 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1623 // Listen for incoming connections
1624 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1626 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1627 printf("%s\n", strError.c_str());
1634 void StartNode(void* parg)
1636 if (pnodeLocalHost == NULL)
1637 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1640 // Get local host ip
1641 char pszHostName[1000] = "";
1642 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1644 vector<CAddress> vaddr;
1645 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1646 BOOST_FOREACH (const CAddress &addr, vaddr)
1647 if (addr.GetByte(3) != 127)
1649 addrLocalHost = addr;
1654 // Get local host ip
1655 struct ifaddrs* myaddrs;
1656 if (getifaddrs(&myaddrs) == 0)
1658 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1660 if (ifa->ifa_addr == NULL) continue;
1661 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1662 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1663 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1665 if (ifa->ifa_addr->sa_family == AF_INET)
1667 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1668 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1669 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1671 // Take the first IP that isn't loopback 127.x.x.x
1672 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1673 if (addr.IsValid() && addr.GetByte(3) != 127)
1675 addrLocalHost = addr;
1679 else if (ifa->ifa_addr->sa_family == AF_INET6)
1681 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1682 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1683 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1686 freeifaddrs(myaddrs);
1689 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1691 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1693 // Proxies can't take incoming connections
1694 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1695 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1699 CreateThread(ThreadGetMyExternalIP, NULL);
1706 // Map ports with UPnP
1710 // Get addresses from IRC and advertise ours
1711 if (!CreateThread(ThreadIRCSeed, NULL))
1712 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1714 // Send and receive from sockets, accept connections
1715 CreateThread(ThreadSocketHandler, NULL, true);
1717 // Initiate outbound connections
1718 if (!CreateThread(ThreadOpenConnections, NULL))
1719 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1722 if (!CreateThread(ThreadMessageHandler, NULL))
1723 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1725 // Generate coins in the background
1726 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1731 printf("StopNode()\n");
1733 nTransactionsUpdated++;
1734 int64 nStart = GetTime();
1735 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1737 || vnThreadsRunning[5] > 0
1741 if (GetTime() - nStart > 20)
1745 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1746 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1747 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1748 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1749 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1750 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1751 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1767 BOOST_FOREACH(CNode* pnode, vNodes)
1768 if (pnode->hSocket != INVALID_SOCKET)
1769 closesocket(pnode->hSocket);
1770 if (hListenSocket != INVALID_SOCKET)
1771 if (closesocket(hListenSocket) == SOCKET_ERROR)
1772 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1775 // Shutdown Windows Sockets
1780 instance_of_cnetcleanup;