1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #if defined(HAVE_CONFIG_H)
7 #include "config/bitcoin-config.h"
13 #include "chainparams.h"
15 #include "ui_interface.h"
24 #include <miniupnpc/miniupnpc.h>
25 #include <miniupnpc/miniwget.h>
26 #include <miniupnpc/upnpcommands.h>
27 #include <miniupnpc/upnperrors.h>
30 #include <boost/filesystem.hpp>
32 // Dump addresses to peers.dat every 15 minutes (900s)
33 #define DUMP_ADDRESSES_INTERVAL 900
35 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
36 #define MSG_NOSIGNAL 0
39 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
40 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
42 #ifndef PROTECTION_LEVEL_UNRESTRICTED
43 #define PROTECTION_LEVEL_UNRESTRICTED 10
45 #ifndef IPV6_PROTECTION_LEVEL
46 #define IPV6_PROTECTION_LEVEL 23
51 using namespace boost;
54 const int MAX_OUTBOUND_CONNECTIONS = 8;
60 ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
65 // Global state variables
67 bool fDiscover = true;
69 uint64_t nLocalServices = NODE_NETWORK;
70 CCriticalSection cs_mapLocalHost;
71 map<CNetAddr, LocalServiceInfo> mapLocalHost;
72 static bool vfReachable[NET_MAX] = {};
73 static bool vfLimited[NET_MAX] = {};
74 static CNode* pnodeLocalHost = NULL;
75 static CNode* pnodeSync = NULL;
76 uint64_t nLocalHostNonce = 0;
77 static std::vector<ListenSocket> vhListenSocket;
79 int nMaxConnections = 125;
81 vector<CNode*> vNodes;
82 CCriticalSection cs_vNodes;
83 map<CInv, CDataStream> mapRelay;
84 deque<pair<int64_t, CInv> > vRelayExpiration;
85 CCriticalSection cs_mapRelay;
86 limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
88 static deque<string> vOneShots;
89 CCriticalSection cs_vOneShots;
91 set<CNetAddr> setservAddNodeAddresses;
92 CCriticalSection cs_setservAddNodeAddresses;
94 vector<std::string> vAddedNodes;
95 CCriticalSection cs_vAddedNodes;
97 NodeId nLastNodeId = 0;
98 CCriticalSection cs_nLastNodeId;
100 static CSemaphore *semOutbound = NULL;
102 // Signals for message handling
103 static CNodeSignals g_signals;
104 CNodeSignals& GetNodeSignals() { return g_signals; }
106 void AddOneShot(string strDest)
109 vOneShots.push_back(strDest);
112 unsigned short GetListenPort()
114 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
117 // find 'best' local address for a particular peer
118 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
124 int nBestReachability = -1;
126 LOCK(cs_mapLocalHost);
127 for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
129 int nScore = (*it).second.nScore;
130 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
131 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
133 addr = CService((*it).first, (*it).second.nPort);
134 nBestReachability = nReachability;
139 return nBestScore >= 0;
142 // get best local address for a particular peer as a CAddress
143 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
145 CAddress ret(CService("0.0.0.0",0),0);
147 if (GetLocal(addr, paddrPeer))
149 ret = CAddress(addr);
150 ret.nServices = nLocalServices;
151 ret.nTime = GetAdjustedTime();
156 bool RecvLine(SOCKET hSocket, string& strLine)
162 int nBytes = recv(hSocket, &c, 1, 0);
170 if (strLine.size() >= 9000)
173 else if (nBytes <= 0)
175 boost::this_thread::interruption_point();
178 int nErr = WSAGetLastError();
179 if (nErr == WSAEMSGSIZE)
181 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
187 if (!strLine.empty())
192 LogPrint("net", "socket closed\n");
198 int nErr = WSAGetLastError();
199 LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
206 // used when scores of local addresses may have changed
207 // pushes better local address to peers
208 void static AdvertizeLocal()
211 BOOST_FOREACH(CNode* pnode, vNodes)
213 if (pnode->fSuccessfullyConnected)
215 CAddress addrLocal = GetLocalAddress(&pnode->addr);
216 if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
218 pnode->PushAddress(addrLocal);
219 pnode->addrLocal = addrLocal;
225 void SetReachable(enum Network net, bool fFlag)
227 LOCK(cs_mapLocalHost);
228 vfReachable[net] = fFlag;
229 if (net == NET_IPV6 && fFlag)
230 vfReachable[NET_IPV4] = true;
233 // learn a new local address
234 bool AddLocal(const CService& addr, int nScore)
236 if (!addr.IsRoutable())
239 if (!fDiscover && nScore < LOCAL_MANUAL)
245 LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
248 LOCK(cs_mapLocalHost);
249 bool fAlready = mapLocalHost.count(addr) > 0;
250 LocalServiceInfo &info = mapLocalHost[addr];
251 if (!fAlready || nScore >= info.nScore) {
252 info.nScore = nScore + (fAlready ? 1 : 0);
253 info.nPort = addr.GetPort();
255 SetReachable(addr.GetNetwork());
263 bool AddLocal(const CNetAddr &addr, int nScore)
265 return AddLocal(CService(addr, GetListenPort()), nScore);
268 /** Make a particular network entirely off-limits (no automatic connects to it) */
269 void SetLimited(enum Network net, bool fLimited)
271 if (net == NET_UNROUTABLE)
273 LOCK(cs_mapLocalHost);
274 vfLimited[net] = fLimited;
277 bool IsLimited(enum Network net)
279 LOCK(cs_mapLocalHost);
280 return vfLimited[net];
283 bool IsLimited(const CNetAddr &addr)
285 return IsLimited(addr.GetNetwork());
288 /** vote for a local address */
289 bool SeenLocal(const CService& addr)
292 LOCK(cs_mapLocalHost);
293 if (mapLocalHost.count(addr) == 0)
295 mapLocalHost[addr].nScore++;
303 /** check whether a given address is potentially local */
304 bool IsLocal(const CService& addr)
306 LOCK(cs_mapLocalHost);
307 return mapLocalHost.count(addr) > 0;
310 /** check whether a given network is one we can probably connect to */
311 bool IsReachable(enum Network net)
313 LOCK(cs_mapLocalHost);
314 return vfReachable[net] && !vfLimited[net];
317 /** check whether a given address is in a network we can probably connect to */
318 bool IsReachable(const CNetAddr& addr)
320 enum Network net = addr.GetNetwork();
321 return IsReachable(net);
324 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
327 if (!ConnectSocket(addrConnect, hSocket))
328 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString());
330 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
333 while (RecvLine(hSocket, strLine))
335 if (strLine.empty()) // HTTP response is separated from headers by blank line
339 if (!RecvLine(hSocket, strLine))
341 CloseSocket(hSocket);
344 if (pszKeyword == NULL)
346 if (strLine.find(pszKeyword) != string::npos)
348 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
352 CloseSocket(hSocket);
353 if (strLine.find("<") != string::npos)
354 strLine = strLine.substr(0, strLine.find("<"));
355 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
356 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
357 strLine.resize(strLine.size()-1);
358 CService addr(strLine,0,true);
359 LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine, addr.ToString());
360 if (!addr.IsValid() || !addr.IsRoutable())
366 CloseSocket(hSocket);
367 return error("GetMyExternalIP() : connection closed");
370 bool GetMyExternalIP(CNetAddr& ipRet)
372 CService addrConnect;
374 const char* pszKeyword;
376 for (int nLookup = 0; nLookup <= 1; nLookup++)
377 for (int nHost = 1; nHost <= 1; nHost++)
379 // We should be phasing out our use of sites like these. If we need
380 // replacements, we should ask for volunteers to put this simple
381 // php file on their web server that prints the client IP:
382 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
385 addrConnect = CService("91.198.22.70", 80); // checkip.dyndns.org
389 CService addrIP("checkip.dyndns.org", 80, true);
390 if (addrIP.IsValid())
391 addrConnect = addrIP;
394 pszGet = "GET / HTTP/1.1\r\n"
395 "Host: checkip.dyndns.org\r\n"
396 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
397 "Connection: close\r\n"
400 pszKeyword = "Address:";
403 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
410 void ThreadGetMyExternalIP()
412 CNetAddr addrLocalHost;
413 if (GetMyExternalIP(addrLocalHost))
415 LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP());
416 AddLocal(addrLocalHost, LOCAL_HTTP);
424 void AddressCurrentlyConnected(const CService& addr)
426 addrman.Connected(addr);
432 uint64_t CNode::nTotalBytesRecv = 0;
433 uint64_t CNode::nTotalBytesSent = 0;
434 CCriticalSection CNode::cs_totalBytesRecv;
435 CCriticalSection CNode::cs_totalBytesSent;
437 CNode* FindNode(const CNetAddr& ip)
440 BOOST_FOREACH(CNode* pnode, vNodes)
441 if ((CNetAddr)pnode->addr == ip)
446 CNode* FindNode(const std::string& addrName)
449 BOOST_FOREACH(CNode* pnode, vNodes)
450 if (pnode->addrName == addrName)
455 CNode* FindNode(const CService& addr)
458 BOOST_FOREACH(CNode* pnode, vNodes)
459 if ((CService)pnode->addr == addr)
464 CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
466 if (pszDest == NULL) {
467 if (IsLocal(addrConnect))
470 // Look for an existing connection
471 CNode* pnode = FindNode((CService)addrConnect);
480 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
481 pszDest ? pszDest : addrConnect.ToString(),
482 pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
486 if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
488 addrman.Attempt(addrConnect);
490 // Set to non-blocking
491 if (!SetSocketNonBlocking(hSocket, true))
492 LogPrintf("ConnectNode: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
495 CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
500 vNodes.push_back(pnode);
503 pnode->nTimeConnected = GetTime();
511 void CNode::CloseSocketDisconnect()
514 if (hSocket != INVALID_SOCKET)
516 LogPrint("net", "disconnecting peer=%d\n", id);
517 CloseSocket(hSocket);
520 // in case this fails, we'll empty the recv buffer when the CNode is deleted
521 TRY_LOCK(cs_vRecvMsg, lockRecv);
525 // if this was the sync node, we'll need a new one
526 if (this == pnodeSync)
530 void CNode::PushVersion()
532 int nBestHeight = g_signals.GetHeight().get_value_or(0);
534 /// when NTP implemented, change to just nTime = GetAdjustedTime()
535 int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
536 CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
537 CAddress addrMe = GetLocalAddress(&addr);
538 GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
540 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
542 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
543 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
544 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
551 std::map<CNetAddr, int64_t> CNode::setBanned;
552 CCriticalSection CNode::cs_setBanned;
554 void CNode::ClearBanned()
559 bool CNode::IsBanned(CNetAddr ip)
561 bool fResult = false;
564 std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
565 if (i != setBanned.end())
567 int64_t t = (*i).second;
575 bool CNode::Ban(const CNetAddr &addr) {
576 int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
579 if (setBanned[addr] < banTime)
580 setBanned[addr] = banTime;
586 std::vector<CSubNet> CNode::vWhitelistedRange;
587 CCriticalSection CNode::cs_vWhitelistedRange;
589 bool CNode::IsWhitelistedRange(const CNetAddr &addr) {
590 LOCK(cs_vWhitelistedRange);
591 BOOST_FOREACH(const CSubNet& subnet, vWhitelistedRange) {
592 if (subnet.Match(addr))
598 void CNode::AddWhitelistedRange(const CSubNet &subnet) {
599 LOCK(cs_vWhitelistedRange);
600 vWhitelistedRange.push_back(subnet);
604 #define X(name) stats.name = name
605 void CNode::copyStats(CNodeStats &stats)
607 stats.nodeid = this->GetId();
620 stats.fSyncNode = (this == pnodeSync);
622 // It is common for nodes with good ping times to suddenly become lagged,
623 // due to a new block arriving or other large transfer.
624 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
625 // since pingtime does not update until the ping is complete, which might take a while.
626 // So, if a ping is taking an unusually long time in flight,
627 // the caller can immediately detect that this is happening.
628 int64_t nPingUsecWait = 0;
629 if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
630 nPingUsecWait = GetTimeMicros() - nPingUsecStart;
633 // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
634 stats.dPingTime = (((double)nPingUsecTime) / 1e6);
635 stats.dPingWait = (((double)nPingUsecWait) / 1e6);
637 // Leave string empty if addrLocal invalid (not filled in yet)
638 stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
642 // requires LOCK(cs_vRecvMsg)
643 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
647 // get current incomplete message, or create a new one
648 if (vRecvMsg.empty() ||
649 vRecvMsg.back().complete())
650 vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
652 CNetMessage& msg = vRecvMsg.back();
654 // absorb network data
657 handled = msg.readHeader(pch, nBytes);
659 handled = msg.readData(pch, nBytes);
668 msg.nTime = GetTimeMicros();
674 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
676 // copy data to temporary parsing buffer
677 unsigned int nRemaining = 24 - nHdrPos;
678 unsigned int nCopy = std::min(nRemaining, nBytes);
680 memcpy(&hdrbuf[nHdrPos], pch, nCopy);
683 // if header incomplete, exit
687 // deserialize to CMessageHeader
691 catch (std::exception &e) {
695 // reject messages larger than MAX_SIZE
696 if (hdr.nMessageSize > MAX_SIZE)
699 // switch state to reading message data
705 int CNetMessage::readData(const char *pch, unsigned int nBytes)
707 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
708 unsigned int nCopy = std::min(nRemaining, nBytes);
710 if (vRecv.size() < nDataPos + nCopy) {
711 // Allocate up to 256 KiB ahead, but never more than the total message size.
712 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
715 memcpy(&vRecv[nDataPos], pch, nCopy);
729 // requires LOCK(cs_vSend)
730 void SocketSendData(CNode *pnode)
732 std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
734 while (it != pnode->vSendMsg.end()) {
735 const CSerializeData &data = *it;
736 assert(data.size() > pnode->nSendOffset);
737 int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
739 pnode->nLastSend = GetTime();
740 pnode->nSendBytes += nBytes;
741 pnode->nSendOffset += nBytes;
742 pnode->RecordBytesSent(nBytes);
743 if (pnode->nSendOffset == data.size()) {
744 pnode->nSendOffset = 0;
745 pnode->nSendSize -= data.size();
748 // could not send full message; stop sending more
754 int nErr = WSAGetLastError();
755 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
757 LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
758 pnode->CloseSocketDisconnect();
761 // couldn't send anything at all
766 if (it == pnode->vSendMsg.end()) {
767 assert(pnode->nSendOffset == 0);
768 assert(pnode->nSendSize == 0);
770 pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
773 static list<CNode*> vNodesDisconnected;
775 void ThreadSocketHandler()
777 unsigned int nPrevNodeCount = 0;
785 // Disconnect unused nodes
786 vector<CNode*> vNodesCopy = vNodes;
787 BOOST_FOREACH(CNode* pnode, vNodesCopy)
789 if (pnode->fDisconnect ||
790 (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
792 // remove from vNodes
793 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
795 // release outbound grant (if any)
796 pnode->grantOutbound.Release();
798 // close socket and cleanup
799 pnode->CloseSocketDisconnect();
801 // hold in disconnected pool until all refs are released
802 if (pnode->fNetworkNode || pnode->fInbound)
804 vNodesDisconnected.push_back(pnode);
809 // Delete disconnected nodes
810 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
811 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
813 // wait until threads are done using it
814 if (pnode->GetRefCount() <= 0)
816 bool fDelete = false;
818 TRY_LOCK(pnode->cs_vSend, lockSend);
821 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
824 TRY_LOCK(pnode->cs_inventory, lockInv);
832 vNodesDisconnected.remove(pnode);
838 if(vNodes.size() != nPrevNodeCount) {
839 nPrevNodeCount = vNodes.size();
840 uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
844 // Find which sockets have data to receive
846 struct timeval timeout;
848 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
855 FD_ZERO(&fdsetError);
856 SOCKET hSocketMax = 0;
857 bool have_fds = false;
859 BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
860 FD_SET(hListenSocket.socket, &fdsetRecv);
861 hSocketMax = max(hSocketMax, hListenSocket.socket);
867 BOOST_FOREACH(CNode* pnode, vNodes)
869 if (pnode->hSocket == INVALID_SOCKET)
871 FD_SET(pnode->hSocket, &fdsetError);
872 hSocketMax = max(hSocketMax, pnode->hSocket);
875 // Implement the following logic:
876 // * If there is data to send, select() for sending data. As this only
877 // happens when optimistic write failed, we choose to first drain the
878 // write buffer in this case before receiving more. This avoids
879 // needlessly queueing received data, if the remote peer is not themselves
880 // receiving data. This means properly utilizing TCP flow control signalling.
881 // * Otherwise, if there is no (complete) message in the receive buffer,
882 // or there is space left in the buffer, select() for receiving data.
883 // * (if neither of the above applies, there is certainly one message
884 // in the receiver buffer ready to be processed).
885 // Together, that means that at least one of the following is always possible,
886 // so we don't deadlock:
887 // * We send some data.
888 // * We wait for data to be received (and disconnect after timeout).
889 // * We process a message in the buffer (message handler thread).
891 TRY_LOCK(pnode->cs_vSend, lockSend);
892 if (lockSend && !pnode->vSendMsg.empty()) {
893 FD_SET(pnode->hSocket, &fdsetSend);
898 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
900 pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
901 pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
902 FD_SET(pnode->hSocket, &fdsetRecv);
907 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
908 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
909 boost::this_thread::interruption_point();
911 if (nSelect == SOCKET_ERROR)
915 int nErr = WSAGetLastError();
916 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
917 for (unsigned int i = 0; i <= hSocketMax; i++)
918 FD_SET(i, &fdsetRecv);
921 FD_ZERO(&fdsetError);
922 MilliSleep(timeout.tv_usec/1000);
926 // Accept new connections
928 BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket)
930 if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
932 struct sockaddr_storage sockaddr;
933 socklen_t len = sizeof(sockaddr);
934 SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
938 if (hSocket != INVALID_SOCKET)
939 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
940 LogPrintf("Warning: Unknown socket family\n");
942 bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
945 BOOST_FOREACH(CNode* pnode, vNodes)
950 if (hSocket == INVALID_SOCKET)
952 int nErr = WSAGetLastError();
953 if (nErr != WSAEWOULDBLOCK)
954 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
956 else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
958 CloseSocket(hSocket);
960 else if (CNode::IsBanned(addr) && !whitelisted)
962 LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
963 CloseSocket(hSocket);
967 CNode* pnode = new CNode(hSocket, addr, "", true);
969 pnode->fWhitelisted = whitelisted;
973 vNodes.push_back(pnode);
980 // Service each socket
982 vector<CNode*> vNodesCopy;
986 BOOST_FOREACH(CNode* pnode, vNodesCopy)
989 BOOST_FOREACH(CNode* pnode, vNodesCopy)
991 boost::this_thread::interruption_point();
996 if (pnode->hSocket == INVALID_SOCKET)
998 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
1000 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1004 // typical socket buffer is 8K-64K
1005 char pchBuf[0x10000];
1006 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1009 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
1010 pnode->CloseSocketDisconnect();
1011 pnode->nLastRecv = GetTime();
1012 pnode->nRecvBytes += nBytes;
1013 pnode->RecordBytesRecv(nBytes);
1015 else if (nBytes == 0)
1017 // socket closed gracefully
1018 if (!pnode->fDisconnect)
1019 LogPrint("net", "socket closed\n");
1020 pnode->CloseSocketDisconnect();
1022 else if (nBytes < 0)
1025 int nErr = WSAGetLastError();
1026 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1028 if (!pnode->fDisconnect)
1029 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1030 pnode->CloseSocketDisconnect();
1040 if (pnode->hSocket == INVALID_SOCKET)
1042 if (FD_ISSET(pnode->hSocket, &fdsetSend))
1044 TRY_LOCK(pnode->cs_vSend, lockSend);
1046 SocketSendData(pnode);
1050 // Inactivity checking
1052 int64_t nTime = GetTime();
1053 if (nTime - pnode->nTimeConnected > 60)
1055 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1057 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->id);
1058 pnode->fDisconnect = true;
1060 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1062 LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1063 pnode->fDisconnect = true;
1065 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1067 LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1068 pnode->fDisconnect = true;
1070 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
1072 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1073 pnode->fDisconnect = true;
1079 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1096 void ThreadMapPort()
1098 std::string port = strprintf("%u", GetListenPort());
1099 const char * multicastif = 0;
1100 const char * minissdpdpath = 0;
1101 struct UPNPDev * devlist = 0;
1104 #ifndef UPNPDISCOVER_SUCCESS
1106 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1110 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1113 struct UPNPUrls urls;
1114 struct IGDdatas data;
1117 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1121 char externalIPAddress[40];
1122 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1123 if(r != UPNPCOMMAND_SUCCESS)
1124 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1127 if(externalIPAddress[0])
1129 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1130 AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1133 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1137 string strDesc = "Bitcoin " + FormatFullVersion();
1141 #ifndef UPNPDISCOVER_SUCCESS
1143 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1144 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1147 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1148 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1151 if(r!=UPNPCOMMAND_SUCCESS)
1152 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1153 port, port, lanaddr, r, strupnperror(r));
1155 LogPrintf("UPnP Port Mapping successful.\n");;
1157 MilliSleep(20*60*1000); // Refresh every 20 minutes
1160 catch (boost::thread_interrupted)
1162 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1163 LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
1164 freeUPNPDevlist(devlist); devlist = 0;
1165 FreeUPNPUrls(&urls);
1169 LogPrintf("No valid UPnP IGDs found\n");
1170 freeUPNPDevlist(devlist); devlist = 0;
1172 FreeUPNPUrls(&urls);
1176 void MapPort(bool fUseUPnP)
1178 static boost::thread* upnp_thread = NULL;
1183 upnp_thread->interrupt();
1184 upnp_thread->join();
1187 upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1189 else if (upnp_thread) {
1190 upnp_thread->interrupt();
1191 upnp_thread->join();
1200 // Intentionally left blank.
1209 void ThreadDNSAddressSeed()
1211 // goal: only query DNS seeds if address need is acute
1212 if ((addrman.size() > 0) &&
1213 (!GetBoolArg("-forcednsseed", false))) {
1214 MilliSleep(11 * 1000);
1217 if (vNodes.size() >= 2) {
1218 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1223 const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1226 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1228 BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1229 if (HaveNameProxy()) {
1230 AddOneShot(seed.host);
1232 vector<CNetAddr> vIPs;
1233 vector<CAddress> vAdd;
1234 if (LookupHost(seed.host.c_str(), vIPs))
1236 BOOST_FOREACH(CNetAddr& ip, vIPs)
1238 int nOneDay = 24*3600;
1239 CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1240 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1241 vAdd.push_back(addr);
1245 addrman.Add(vAdd, CNetAddr(seed.name, true));
1249 LogPrintf("%d addresses found from DNS seeds\n", found);
1263 void DumpAddresses()
1265 int64_t nStart = GetTimeMillis();
1270 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1271 addrman.size(), GetTimeMillis() - nStart);
1274 void static ProcessOneShot()
1279 if (vOneShots.empty())
1281 strDest = vOneShots.front();
1282 vOneShots.pop_front();
1285 CSemaphoreGrant grant(*semOutbound, true);
1287 if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1288 AddOneShot(strDest);
1292 void ThreadOpenConnections()
1294 // Connect to specific addresses
1295 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1297 for (int64_t nLoop = 0;; nLoop++)
1300 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1303 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1304 for (int i = 0; i < 10 && i < nLoop; i++)
1313 // Initiate network connections
1314 int64_t nStart = GetTime();
1321 CSemaphoreGrant grant(*semOutbound);
1322 boost::this_thread::interruption_point();
1324 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1325 if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1326 static bool done = false;
1328 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1329 addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
1335 // Choose an address to connect to based on most recently seen
1337 CAddress addrConnect;
1339 // Only connect out to one peer per network group (/16 for IPv4).
1340 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1342 set<vector<unsigned char> > setConnected;
1345 BOOST_FOREACH(CNode* pnode, vNodes) {
1346 if (!pnode->fInbound) {
1347 setConnected.insert(pnode->addr.GetGroup());
1353 int64_t nANow = GetAdjustedTime();
1358 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1359 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1361 // if we selected an invalid address, restart
1362 if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1365 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1366 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1367 // already-connected network ranges, ...) before trying new addrman addresses.
1372 if (IsLimited(addr))
1375 // only consider very recently tried nodes after 30 failed attempts
1376 if (nANow - addr.nLastTry < 600 && nTries < 30)
1379 // do not allow non-default ports, unless after 50 invalid addresses selected already
1380 if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1387 if (addrConnect.IsValid())
1388 OpenNetworkConnection(addrConnect, &grant);
1392 void ThreadOpenAddedConnections()
1395 LOCK(cs_vAddedNodes);
1396 vAddedNodes = mapMultiArgs["-addnode"];
1399 if (HaveNameProxy()) {
1401 list<string> lAddresses(0);
1403 LOCK(cs_vAddedNodes);
1404 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1405 lAddresses.push_back(strAddNode);
1407 BOOST_FOREACH(string& strAddNode, lAddresses) {
1409 CSemaphoreGrant grant(*semOutbound);
1410 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1413 MilliSleep(120000); // Retry every 2 minutes
1417 for (unsigned int i = 0; true; i++)
1419 list<string> lAddresses(0);
1421 LOCK(cs_vAddedNodes);
1422 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1423 lAddresses.push_back(strAddNode);
1426 list<vector<CService> > lservAddressesToAdd(0);
1427 BOOST_FOREACH(string& strAddNode, lAddresses)
1429 vector<CService> vservNode(0);
1430 if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1432 lservAddressesToAdd.push_back(vservNode);
1434 LOCK(cs_setservAddNodeAddresses);
1435 BOOST_FOREACH(CService& serv, vservNode)
1436 setservAddNodeAddresses.insert(serv);
1440 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1441 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1444 BOOST_FOREACH(CNode* pnode, vNodes)
1445 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1446 BOOST_FOREACH(CService& addrNode, *(it))
1447 if (pnode->addr == addrNode)
1449 it = lservAddressesToAdd.erase(it);
1454 BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1456 CSemaphoreGrant grant(*semOutbound);
1457 OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1460 MilliSleep(120000); // Retry every 2 minutes
1464 // if successful, this moves the passed grant to the constructed node
1465 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
1468 // Initiate outbound network connection
1470 boost::this_thread::interruption_point();
1472 if (IsLocal(addrConnect) ||
1473 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1474 FindNode(addrConnect.ToStringIPPort()))
1476 } else if (FindNode(pszDest))
1479 CNode* pnode = ConnectNode(addrConnect, pszDest);
1480 boost::this_thread::interruption_point();
1485 grantOutbound->MoveTo(pnode->grantOutbound);
1486 pnode->fNetworkNode = true;
1488 pnode->fOneShot = true;
1494 // for now, use a very simple selection metric: the node from which we received
1496 static int64_t NodeSyncScore(const CNode *pnode) {
1497 return pnode->nLastRecv;
1500 void static StartSync(const vector<CNode*> &vNodes) {
1501 CNode *pnodeNewSync = NULL;
1502 int64_t nBestScore = 0;
1504 int nBestHeight = g_signals.GetHeight().get_value_or(0);
1506 // Iterate over all nodes
1507 BOOST_FOREACH(CNode* pnode, vNodes) {
1508 // check preconditions for allowing a sync
1509 if (!pnode->fClient && !pnode->fOneShot &&
1510 !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1511 (pnode->nStartingHeight > (nBestHeight - 144)) &&
1512 (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1513 // if ok, compare node's score with the best so far
1514 int64_t nScore = NodeSyncScore(pnode);
1515 if (pnodeNewSync == NULL || nScore > nBestScore) {
1516 pnodeNewSync = pnode;
1517 nBestScore = nScore;
1521 // if a new sync candidate was found, start sync!
1523 pnodeNewSync->fStartSync = true;
1524 pnodeSync = pnodeNewSync;
1528 void ThreadMessageHandler()
1530 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1533 bool fHaveSyncNode = false;
1535 vector<CNode*> vNodesCopy;
1538 vNodesCopy = vNodes;
1539 BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1541 if (pnode == pnodeSync)
1542 fHaveSyncNode = true;
1547 StartSync(vNodesCopy);
1549 // Poll the connected nodes for messages
1550 CNode* pnodeTrickle = NULL;
1551 if (!vNodesCopy.empty())
1552 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1556 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1558 if (pnode->fDisconnect)
1563 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1566 if (!g_signals.ProcessMessages(pnode))
1567 pnode->CloseSocketDisconnect();
1569 if (pnode->nSendSize < SendBufferSize())
1571 if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1578 boost::this_thread::interruption_point();
1582 TRY_LOCK(pnode->cs_vSend, lockSend);
1584 g_signals.SendMessages(pnode, pnode == pnodeTrickle);
1586 boost::this_thread::interruption_point();
1591 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1605 bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted)
1610 // Create socket for listening for incoming connections
1611 struct sockaddr_storage sockaddr;
1612 socklen_t len = sizeof(sockaddr);
1613 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1615 strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
1616 LogPrintf("%s\n", strError);
1620 SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1621 if (hListenSocket == INVALID_SOCKET)
1623 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1624 LogPrintf("%s\n", strError);
1630 // Different way of disabling SIGPIPE on BSD
1631 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1633 // Allow binding if the port is still in TIME_WAIT state after
1634 // the program was closed and restarted. Not an issue on windows!
1635 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1638 // Set to non-blocking, incoming connections will also inherit this
1639 if (!SetSocketNonBlocking(hListenSocket, true)) {
1640 strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1641 LogPrintf("%s\n", strError);
1645 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1646 // and enable it by default or not. Try to enable it, if possible.
1647 if (addrBind.IsIPv6()) {
1650 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1652 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1656 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1657 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1661 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1663 int nErr = WSAGetLastError();
1664 if (nErr == WSAEADDRINUSE)
1665 strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
1667 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
1668 LogPrintf("%s\n", strError);
1669 CloseSocket(hListenSocket);
1672 LogPrintf("Bound to %s\n", addrBind.ToString());
1674 // Listen for incoming connections
1675 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1677 strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1678 LogPrintf("%s\n", strError);
1679 CloseSocket(hListenSocket);
1683 vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
1685 if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
1686 AddLocal(addrBind, LOCAL_BIND);
1691 void static Discover(boost::thread_group& threadGroup)
1697 // Get local host IP
1698 char pszHostName[1000] = "";
1699 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1701 vector<CNetAddr> vaddr;
1702 if (LookupHost(pszHostName, vaddr))
1704 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1706 AddLocal(addr, LOCAL_IF);
1711 // Get local host ip
1712 struct ifaddrs* myaddrs;
1713 if (getifaddrs(&myaddrs) == 0)
1715 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1717 if (ifa->ifa_addr == NULL) continue;
1718 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1719 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1720 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1721 if (ifa->ifa_addr->sa_family == AF_INET)
1723 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1724 CNetAddr addr(s4->sin_addr);
1725 if (AddLocal(addr, LOCAL_IF))
1726 LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString());
1728 else if (ifa->ifa_addr->sa_family == AF_INET6)
1730 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1731 CNetAddr addr(s6->sin6_addr);
1732 if (AddLocal(addr, LOCAL_IF))
1733 LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString());
1736 freeifaddrs(myaddrs);
1740 // Don't use external IPv4 discovery, when -onlynet="IPv6"
1741 if (!IsLimited(NET_IPV4))
1742 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP));
1745 void StartNode(boost::thread_group& threadGroup)
1747 if (semOutbound == NULL) {
1748 // initialize semaphore
1749 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
1750 semOutbound = new CSemaphore(nMaxOutbound);
1753 if (pnodeLocalHost == NULL)
1754 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1756 Discover(threadGroup);
1762 if (!GetBoolArg("-dnsseed", true))
1763 LogPrintf("DNS seeding disabled\n");
1765 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1767 // Map ports with UPnP
1768 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
1770 // Send and receive from sockets, accept connections
1771 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1773 // Initiate outbound connections from -addnode
1774 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1776 // Initiate outbound connections
1777 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1780 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1782 // Dump network addresses
1783 threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, DUMP_ADDRESSES_INTERVAL * 1000));
1788 LogPrintf("StopNode()\n");
1791 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1792 semOutbound->post();
1807 BOOST_FOREACH(CNode* pnode, vNodes)
1808 if (pnode->hSocket != INVALID_SOCKET)
1809 CloseSocket(pnode->hSocket);
1810 BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
1811 if (hListenSocket.socket != INVALID_SOCKET)
1812 if (!CloseSocket(hListenSocket.socket))
1813 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
1815 // clean up some globals (to help leak detection)
1816 BOOST_FOREACH(CNode *pnode, vNodes)
1818 BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1821 vNodesDisconnected.clear();
1822 vhListenSocket.clear();
1825 delete pnodeLocalHost;
1826 pnodeLocalHost = NULL;
1829 // Shutdown Windows Sockets
1834 instance_of_cnetcleanup;
1842 void RelayTransaction(const CTransaction& tx)
1844 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1847 RelayTransaction(tx, ss);
1850 void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
1852 CInv inv(MSG_TX, tx.GetHash());
1855 // Expire old relay messages
1856 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1858 mapRelay.erase(vRelayExpiration.front().second);
1859 vRelayExpiration.pop_front();
1862 // Save original serialized message so newer versions are preserved
1863 mapRelay.insert(std::make_pair(inv, ss));
1864 vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1867 BOOST_FOREACH(CNode* pnode, vNodes)
1869 if(!pnode->fRelayTxes)
1871 LOCK(pnode->cs_filter);
1874 if (pnode->pfilter->IsRelevantAndUpdate(tx))
1875 pnode->PushInventory(inv);
1877 pnode->PushInventory(inv);
1881 void CNode::RecordBytesRecv(uint64_t bytes)
1883 LOCK(cs_totalBytesRecv);
1884 nTotalBytesRecv += bytes;
1887 void CNode::RecordBytesSent(uint64_t bytes)
1889 LOCK(cs_totalBytesSent);
1890 nTotalBytesSent += bytes;
1893 uint64_t CNode::GetTotalBytesRecv()
1895 LOCK(cs_totalBytesRecv);
1896 return nTotalBytesRecv;
1899 uint64_t CNode::GetTotalBytesSent()
1901 LOCK(cs_totalBytesSent);
1902 return nTotalBytesSent;
1905 void CNode::Fuzz(int nChance)
1907 if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
1908 if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
1913 // xor a random byte with a random value:
1914 if (!ssSend.empty()) {
1915 CDataStream::size_type pos = GetRand(ssSend.size());
1916 ssSend[pos] ^= (unsigned char)(GetRand(256));
1920 // delete a random byte:
1921 if (!ssSend.empty()) {
1922 CDataStream::size_type pos = GetRand(ssSend.size());
1923 ssSend.erase(ssSend.begin()+pos);
1927 // insert a random byte at a random position
1929 CDataStream::size_type pos = GetRand(ssSend.size());
1930 char ch = (char)GetRand(256);
1931 ssSend.insert(ssSend.begin()+pos, ch);
1935 // Chance of more than one change half the time:
1936 // (more changes exponentially less likely):
1946 pathAddr = GetDataDir() / "peers.dat";
1949 bool CAddrDB::Write(const CAddrMan& addr)
1951 // Generate random temporary filename
1952 unsigned short randv = 0;
1953 GetRandBytes((unsigned char*)&randv, sizeof(randv));
1954 std::string tmpfn = strprintf("peers.dat.%04x", randv);
1956 // serialize addresses, checksum data up to that point, then append csum
1957 CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
1958 ssPeers << FLATDATA(Params().MessageStart());
1960 uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
1963 // open temp output file, and associate with CAutoFile
1964 boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
1965 FILE *file = fopen(pathTmp.string().c_str(), "wb");
1966 CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
1968 return error("%s : Failed to open file %s", __func__, pathTmp.string());
1970 // Write and commit header, data
1974 catch (std::exception &e) {
1975 return error("%s : Serialize or I/O error - %s", __func__, e.what());
1977 FileCommit(fileout);
1980 // replace existing peers.dat, if any, with new peers.dat.XXXX
1981 if (!RenameOver(pathTmp, pathAddr))
1982 return error("%s : Rename-into-place failed", __func__);
1987 bool CAddrDB::Read(CAddrMan& addr)
1989 // open input file, and associate with CAutoFile
1990 FILE *file = fopen(pathAddr.string().c_str(), "rb");
1991 CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
1993 return error("%s : Failed to open file %s", __func__, pathAddr.string());
1995 // use file size to size memory buffer
1996 int fileSize = boost::filesystem::file_size(pathAddr);
1997 int dataSize = fileSize - sizeof(uint256);
1998 // Don't try to resize to a negative number if file is small
2001 vector<unsigned char> vchData;
2002 vchData.resize(dataSize);
2005 // read data and checksum from file
2007 filein.read((char *)&vchData[0], dataSize);
2010 catch (std::exception &e) {
2011 return error("%s : Deserialize or I/O error - %s", __func__, e.what());
2015 CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
2017 // verify stored checksum matches input data
2018 uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
2019 if (hashIn != hashTmp)
2020 return error("%s : Checksum mismatch, data corrupted", __func__);
2022 unsigned char pchMsgTmp[4];
2024 // de-serialize file header (network specific magic number) and ..
2025 ssPeers >> FLATDATA(pchMsgTmp);
2027 // ... verify the network matches ours
2028 if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2029 return error("%s : Invalid network magic number", __func__);
2031 // de-serialize address data into one CAddrMan object
2034 catch (std::exception &e) {
2035 return error("%s : Deserialize or I/O error - %s", __func__, e.what());