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"
14 #include "clientversion.h"
15 #include "primitives/transaction.h"
16 #include "ui_interface.h"
25 #include <miniupnpc/miniupnpc.h>
26 #include <miniupnpc/miniwget.h>
27 #include <miniupnpc/upnpcommands.h>
28 #include <miniupnpc/upnperrors.h>
31 #include <boost/filesystem.hpp>
32 #include <boost/thread.hpp>
34 // Dump addresses to peers.dat every 15 minutes (900s)
35 #define DUMP_ADDRESSES_INTERVAL 900
37 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
38 #define MSG_NOSIGNAL 0
41 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
42 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
44 #ifndef PROTECTION_LEVEL_UNRESTRICTED
45 #define PROTECTION_LEVEL_UNRESTRICTED 10
47 #ifndef IPV6_PROTECTION_LEVEL
48 #define IPV6_PROTECTION_LEVEL 23
52 using namespace boost;
56 const int MAX_OUTBOUND_CONNECTIONS = 8;
62 ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
67 // Global state variables
69 bool fDiscover = true;
71 uint64_t nLocalServices = NODE_NETWORK;
72 CCriticalSection cs_mapLocalHost;
73 map<CNetAddr, LocalServiceInfo> mapLocalHost;
74 static bool vfReachable[NET_MAX] = {};
75 static bool vfLimited[NET_MAX] = {};
76 static CNode* pnodeLocalHost = NULL;
77 uint64_t nLocalHostNonce = 0;
78 static std::vector<ListenSocket> vhListenSocket;
80 int nMaxConnections = 125;
81 bool fAddressesInitialized = false;
83 vector<CNode*> vNodes;
84 CCriticalSection cs_vNodes;
85 map<CInv, CDataStream> mapRelay;
86 deque<pair<int64_t, CInv> > vRelayExpiration;
87 CCriticalSection cs_mapRelay;
88 limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
90 static deque<string> vOneShots;
91 CCriticalSection cs_vOneShots;
93 set<CNetAddr> setservAddNodeAddresses;
94 CCriticalSection cs_setservAddNodeAddresses;
96 vector<std::string> vAddedNodes;
97 CCriticalSection cs_vAddedNodes;
99 NodeId nLastNodeId = 0;
100 CCriticalSection cs_nLastNodeId;
102 static CSemaphore *semOutbound = NULL;
104 // Signals for message handling
105 static CNodeSignals g_signals;
106 CNodeSignals& GetNodeSignals() { return g_signals; }
108 void AddOneShot(string strDest)
111 vOneShots.push_back(strDest);
114 unsigned short GetListenPort()
116 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
119 // find 'best' local address for a particular peer
120 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
126 int nBestReachability = -1;
128 LOCK(cs_mapLocalHost);
129 for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
131 int nScore = (*it).second.nScore;
132 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
133 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
135 addr = CService((*it).first, (*it).second.nPort);
136 nBestReachability = nReachability;
141 return nBestScore >= 0;
144 // get best local address for a particular peer as a CAddress
145 // Otherwise, return the unroutable 0.0.0.0 but filled in with
146 // the normal parameters, since the IP may be changed to a useful
148 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
150 CAddress ret(CService("0.0.0.0",GetListenPort()),0);
152 if (GetLocal(addr, paddrPeer))
154 ret = CAddress(addr);
156 ret.nServices = nLocalServices;
157 ret.nTime = GetAdjustedTime();
161 bool RecvLine(SOCKET hSocket, string& strLine)
167 int nBytes = recv(hSocket, &c, 1, 0);
175 if (strLine.size() >= 9000)
178 else if (nBytes <= 0)
180 boost::this_thread::interruption_point();
183 int nErr = WSAGetLastError();
184 if (nErr == WSAEMSGSIZE)
186 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
192 if (!strLine.empty())
197 LogPrint("net", "socket closed\n");
203 int nErr = WSAGetLastError();
204 LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
211 int GetnScore(const CService& addr)
213 LOCK(cs_mapLocalHost);
214 if (mapLocalHost.count(addr) == LOCAL_NONE)
216 return mapLocalHost[addr].nScore;
219 // Is our peer's addrLocal potentially useful as an external IP source?
220 bool IsPeerAddrLocalGood(CNode *pnode)
222 return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
223 !IsLimited(pnode->addrLocal.GetNetwork());
226 // pushes our own address to a peer
227 void AdvertizeLocal(CNode *pnode)
229 if (fListen && pnode->fSuccessfullyConnected)
231 CAddress addrLocal = GetLocalAddress(&pnode->addr);
232 // If discovery is enabled, sometimes give our peer the address it
233 // tells us that it sees us as in case it has a better idea of our
234 // address than we do.
235 if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
236 GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
238 addrLocal.SetIP(pnode->addrLocal);
240 if (addrLocal.IsRoutable())
242 pnode->PushAddress(addrLocal);
247 void SetReachable(enum Network net, bool fFlag)
249 LOCK(cs_mapLocalHost);
250 vfReachable[net] = fFlag;
251 if (net == NET_IPV6 && fFlag)
252 vfReachable[NET_IPV4] = true;
255 // learn a new local address
256 bool AddLocal(const CService& addr, int nScore)
258 if (!addr.IsRoutable())
261 if (!fDiscover && nScore < LOCAL_MANUAL)
267 LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
270 LOCK(cs_mapLocalHost);
271 bool fAlready = mapLocalHost.count(addr) > 0;
272 LocalServiceInfo &info = mapLocalHost[addr];
273 if (!fAlready || nScore >= info.nScore) {
274 info.nScore = nScore + (fAlready ? 1 : 0);
275 info.nPort = addr.GetPort();
277 SetReachable(addr.GetNetwork());
283 bool AddLocal(const CNetAddr &addr, int nScore)
285 return AddLocal(CService(addr, GetListenPort()), nScore);
288 /** Make a particular network entirely off-limits (no automatic connects to it) */
289 void SetLimited(enum Network net, bool fLimited)
291 if (net == NET_UNROUTABLE)
293 LOCK(cs_mapLocalHost);
294 vfLimited[net] = fLimited;
297 bool IsLimited(enum Network net)
299 LOCK(cs_mapLocalHost);
300 return vfLimited[net];
303 bool IsLimited(const CNetAddr &addr)
305 return IsLimited(addr.GetNetwork());
308 /** vote for a local address */
309 bool SeenLocal(const CService& addr)
312 LOCK(cs_mapLocalHost);
313 if (mapLocalHost.count(addr) == 0)
315 mapLocalHost[addr].nScore++;
321 /** check whether a given address is potentially local */
322 bool IsLocal(const CService& addr)
324 LOCK(cs_mapLocalHost);
325 return mapLocalHost.count(addr) > 0;
328 /** check whether a given network is one we can probably connect to */
329 bool IsReachable(enum Network net)
331 LOCK(cs_mapLocalHost);
332 return vfReachable[net] && !vfLimited[net];
335 /** check whether a given address is in a network we can probably connect to */
336 bool IsReachable(const CNetAddr& addr)
338 enum Network net = addr.GetNetwork();
339 return IsReachable(net);
342 void AddressCurrentlyConnected(const CService& addr)
344 addrman.Connected(addr);
348 uint64_t CNode::nTotalBytesRecv = 0;
349 uint64_t CNode::nTotalBytesSent = 0;
350 CCriticalSection CNode::cs_totalBytesRecv;
351 CCriticalSection CNode::cs_totalBytesSent;
353 CNode* FindNode(const CNetAddr& ip)
356 BOOST_FOREACH(CNode* pnode, vNodes)
357 if ((CNetAddr)pnode->addr == ip)
362 CNode* FindNode(const std::string& addrName)
365 BOOST_FOREACH(CNode* pnode, vNodes)
366 if (pnode->addrName == addrName)
371 CNode* FindNode(const CService& addr)
374 BOOST_FOREACH(CNode* pnode, vNodes)
375 if ((CService)pnode->addr == addr)
380 CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
382 if (pszDest == NULL) {
383 if (IsLocal(addrConnect))
386 // Look for an existing connection
387 CNode* pnode = FindNode((CService)addrConnect);
396 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
397 pszDest ? pszDest : addrConnect.ToString(),
398 pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
402 bool proxyConnectionFailed = false;
403 if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
404 ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
406 addrman.Attempt(addrConnect);
409 CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
414 vNodes.push_back(pnode);
417 pnode->nTimeConnected = GetTime();
420 } else if (!proxyConnectionFailed) {
421 // If connecting to the node failed, and failure is not caused by a problem connecting to
422 // the proxy, mark this as an attempt.
423 addrman.Attempt(addrConnect);
429 void CNode::CloseSocketDisconnect()
432 if (hSocket != INVALID_SOCKET)
434 LogPrint("net", "disconnecting peer=%d\n", id);
435 CloseSocket(hSocket);
438 // in case this fails, we'll empty the recv buffer when the CNode is deleted
439 TRY_LOCK(cs_vRecvMsg, lockRecv);
444 void CNode::PushVersion()
446 int nBestHeight = g_signals.GetHeight().get_value_or(0);
448 /// when NTP implemented, change to just nTime = GetAdjustedTime()
449 int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
450 CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
451 CAddress addrMe = GetLocalAddress(&addr);
452 GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
454 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
456 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
457 PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
458 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
465 std::map<CNetAddr, int64_t> CNode::setBanned;
466 CCriticalSection CNode::cs_setBanned;
468 void CNode::ClearBanned()
473 bool CNode::IsBanned(CNetAddr ip)
475 bool fResult = false;
478 std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
479 if (i != setBanned.end())
481 int64_t t = (*i).second;
489 bool CNode::Ban(const CNetAddr &addr) {
490 int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
493 if (setBanned[addr] < banTime)
494 setBanned[addr] = banTime;
500 std::vector<CSubNet> CNode::vWhitelistedRange;
501 CCriticalSection CNode::cs_vWhitelistedRange;
503 bool CNode::IsWhitelistedRange(const CNetAddr &addr) {
504 LOCK(cs_vWhitelistedRange);
505 BOOST_FOREACH(const CSubNet& subnet, vWhitelistedRange) {
506 if (subnet.Match(addr))
512 void CNode::AddWhitelistedRange(const CSubNet &subnet) {
513 LOCK(cs_vWhitelistedRange);
514 vWhitelistedRange.push_back(subnet);
518 #define X(name) stats.name = name
519 void CNode::copyStats(CNodeStats &stats)
521 stats.nodeid = this->GetId();
535 // It is common for nodes with good ping times to suddenly become lagged,
536 // due to a new block arriving or other large transfer.
537 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
538 // since pingtime does not update until the ping is complete, which might take a while.
539 // So, if a ping is taking an unusually long time in flight,
540 // the caller can immediately detect that this is happening.
541 int64_t nPingUsecWait = 0;
542 if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
543 nPingUsecWait = GetTimeMicros() - nPingUsecStart;
546 // 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 :)
547 stats.dPingTime = (((double)nPingUsecTime) / 1e6);
548 stats.dPingWait = (((double)nPingUsecWait) / 1e6);
550 // Leave string empty if addrLocal invalid (not filled in yet)
551 stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
555 // requires LOCK(cs_vRecvMsg)
556 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
560 // get current incomplete message, or create a new one
561 if (vRecvMsg.empty() ||
562 vRecvMsg.back().complete())
563 vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
565 CNetMessage& msg = vRecvMsg.back();
567 // absorb network data
570 handled = msg.readHeader(pch, nBytes);
572 handled = msg.readData(pch, nBytes);
581 msg.nTime = GetTimeMicros();
587 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
589 // copy data to temporary parsing buffer
590 unsigned int nRemaining = 24 - nHdrPos;
591 unsigned int nCopy = std::min(nRemaining, nBytes);
593 memcpy(&hdrbuf[nHdrPos], pch, nCopy);
596 // if header incomplete, exit
600 // deserialize to CMessageHeader
604 catch (const std::exception &) {
608 // reject messages larger than MAX_SIZE
609 if (hdr.nMessageSize > MAX_SIZE)
612 // switch state to reading message data
618 int CNetMessage::readData(const char *pch, unsigned int nBytes)
620 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
621 unsigned int nCopy = std::min(nRemaining, nBytes);
623 if (vRecv.size() < nDataPos + nCopy) {
624 // Allocate up to 256 KiB ahead, but never more than the total message size.
625 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
628 memcpy(&vRecv[nDataPos], pch, nCopy);
642 // requires LOCK(cs_vSend)
643 void SocketSendData(CNode *pnode)
645 std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
647 while (it != pnode->vSendMsg.end()) {
648 const CSerializeData &data = *it;
649 assert(data.size() > pnode->nSendOffset);
650 int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
652 pnode->nLastSend = GetTime();
653 pnode->nSendBytes += nBytes;
654 pnode->nSendOffset += nBytes;
655 pnode->RecordBytesSent(nBytes);
656 if (pnode->nSendOffset == data.size()) {
657 pnode->nSendOffset = 0;
658 pnode->nSendSize -= data.size();
661 // could not send full message; stop sending more
667 int nErr = WSAGetLastError();
668 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
670 LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
671 pnode->CloseSocketDisconnect();
674 // couldn't send anything at all
679 if (it == pnode->vSendMsg.end()) {
680 assert(pnode->nSendOffset == 0);
681 assert(pnode->nSendSize == 0);
683 pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
686 static list<CNode*> vNodesDisconnected;
688 void ThreadSocketHandler()
690 unsigned int nPrevNodeCount = 0;
698 // Disconnect unused nodes
699 vector<CNode*> vNodesCopy = vNodes;
700 BOOST_FOREACH(CNode* pnode, vNodesCopy)
702 if (pnode->fDisconnect ||
703 (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
705 // remove from vNodes
706 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
708 // release outbound grant (if any)
709 pnode->grantOutbound.Release();
711 // close socket and cleanup
712 pnode->CloseSocketDisconnect();
714 // hold in disconnected pool until all refs are released
715 if (pnode->fNetworkNode || pnode->fInbound)
717 vNodesDisconnected.push_back(pnode);
722 // Delete disconnected nodes
723 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
724 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
726 // wait until threads are done using it
727 if (pnode->GetRefCount() <= 0)
729 bool fDelete = false;
731 TRY_LOCK(pnode->cs_vSend, lockSend);
734 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
737 TRY_LOCK(pnode->cs_inventory, lockInv);
745 vNodesDisconnected.remove(pnode);
751 if(vNodes.size() != nPrevNodeCount) {
752 nPrevNodeCount = vNodes.size();
753 uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
757 // Find which sockets have data to receive
759 struct timeval timeout;
761 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
768 FD_ZERO(&fdsetError);
769 SOCKET hSocketMax = 0;
770 bool have_fds = false;
772 BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
773 FD_SET(hListenSocket.socket, &fdsetRecv);
774 hSocketMax = max(hSocketMax, hListenSocket.socket);
780 BOOST_FOREACH(CNode* pnode, vNodes)
782 if (pnode->hSocket == INVALID_SOCKET)
784 FD_SET(pnode->hSocket, &fdsetError);
785 hSocketMax = max(hSocketMax, pnode->hSocket);
788 // Implement the following logic:
789 // * If there is data to send, select() for sending data. As this only
790 // happens when optimistic write failed, we choose to first drain the
791 // write buffer in this case before receiving more. This avoids
792 // needlessly queueing received data, if the remote peer is not themselves
793 // receiving data. This means properly utilizing TCP flow control signalling.
794 // * Otherwise, if there is no (complete) message in the receive buffer,
795 // or there is space left in the buffer, select() for receiving data.
796 // * (if neither of the above applies, there is certainly one message
797 // in the receiver buffer ready to be processed).
798 // Together, that means that at least one of the following is always possible,
799 // so we don't deadlock:
800 // * We send some data.
801 // * We wait for data to be received (and disconnect after timeout).
802 // * We process a message in the buffer (message handler thread).
804 TRY_LOCK(pnode->cs_vSend, lockSend);
805 if (lockSend && !pnode->vSendMsg.empty()) {
806 FD_SET(pnode->hSocket, &fdsetSend);
811 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
813 pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
814 pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
815 FD_SET(pnode->hSocket, &fdsetRecv);
820 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
821 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
822 boost::this_thread::interruption_point();
824 if (nSelect == SOCKET_ERROR)
828 int nErr = WSAGetLastError();
829 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
830 for (unsigned int i = 0; i <= hSocketMax; i++)
831 FD_SET(i, &fdsetRecv);
834 FD_ZERO(&fdsetError);
835 MilliSleep(timeout.tv_usec/1000);
839 // Accept new connections
841 BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket)
843 if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
845 struct sockaddr_storage sockaddr;
846 socklen_t len = sizeof(sockaddr);
847 SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
851 if (hSocket != INVALID_SOCKET)
852 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
853 LogPrintf("Warning: Unknown socket family\n");
855 bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
858 BOOST_FOREACH(CNode* pnode, vNodes)
863 if (hSocket == INVALID_SOCKET)
865 int nErr = WSAGetLastError();
866 if (nErr != WSAEWOULDBLOCK)
867 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
869 else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
871 CloseSocket(hSocket);
873 else if (CNode::IsBanned(addr) && !whitelisted)
875 LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
876 CloseSocket(hSocket);
880 CNode* pnode = new CNode(hSocket, addr, "", true);
882 pnode->fWhitelisted = whitelisted;
886 vNodes.push_back(pnode);
893 // Service each socket
895 vector<CNode*> vNodesCopy;
899 BOOST_FOREACH(CNode* pnode, vNodesCopy)
902 BOOST_FOREACH(CNode* pnode, vNodesCopy)
904 boost::this_thread::interruption_point();
909 if (pnode->hSocket == INVALID_SOCKET)
911 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
913 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
917 // typical socket buffer is 8K-64K
918 char pchBuf[0x10000];
919 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
922 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
923 pnode->CloseSocketDisconnect();
924 pnode->nLastRecv = GetTime();
925 pnode->nRecvBytes += nBytes;
926 pnode->RecordBytesRecv(nBytes);
928 else if (nBytes == 0)
930 // socket closed gracefully
931 if (!pnode->fDisconnect)
932 LogPrint("net", "socket closed\n");
933 pnode->CloseSocketDisconnect();
938 int nErr = WSAGetLastError();
939 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
941 if (!pnode->fDisconnect)
942 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
943 pnode->CloseSocketDisconnect();
953 if (pnode->hSocket == INVALID_SOCKET)
955 if (FD_ISSET(pnode->hSocket, &fdsetSend))
957 TRY_LOCK(pnode->cs_vSend, lockSend);
959 SocketSendData(pnode);
963 // Inactivity checking
965 int64_t nTime = GetTime();
966 if (nTime - pnode->nTimeConnected > 60)
968 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
970 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->id);
971 pnode->fDisconnect = true;
973 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
975 LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
976 pnode->fDisconnect = true;
978 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
980 LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
981 pnode->fDisconnect = true;
983 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
985 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
986 pnode->fDisconnect = true;
992 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1007 void ThreadMapPort()
1009 std::string port = strprintf("%u", GetListenPort());
1010 const char * multicastif = 0;
1011 const char * minissdpdpath = 0;
1012 struct UPNPDev * devlist = 0;
1015 #ifndef UPNPDISCOVER_SUCCESS
1017 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1021 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1024 struct UPNPUrls urls;
1025 struct IGDdatas data;
1028 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1032 char externalIPAddress[40];
1033 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1034 if(r != UPNPCOMMAND_SUCCESS)
1035 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1038 if(externalIPAddress[0])
1040 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1041 AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1044 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1048 string strDesc = "Bitcoin " + FormatFullVersion();
1052 #ifndef UPNPDISCOVER_SUCCESS
1054 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1055 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1058 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1059 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1062 if(r!=UPNPCOMMAND_SUCCESS)
1063 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1064 port, port, lanaddr, r, strupnperror(r));
1066 LogPrintf("UPnP Port Mapping successful.\n");;
1068 MilliSleep(20*60*1000); // Refresh every 20 minutes
1071 catch (boost::thread_interrupted)
1073 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1074 LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
1075 freeUPNPDevlist(devlist); devlist = 0;
1076 FreeUPNPUrls(&urls);
1080 LogPrintf("No valid UPnP IGDs found\n");
1081 freeUPNPDevlist(devlist); devlist = 0;
1083 FreeUPNPUrls(&urls);
1087 void MapPort(bool fUseUPnP)
1089 static boost::thread* upnp_thread = NULL;
1094 upnp_thread->interrupt();
1095 upnp_thread->join();
1098 upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1100 else if (upnp_thread) {
1101 upnp_thread->interrupt();
1102 upnp_thread->join();
1111 // Intentionally left blank.
1120 void ThreadDNSAddressSeed()
1122 // goal: only query DNS seeds if address need is acute
1123 if ((addrman.size() > 0) &&
1124 (!GetBoolArg("-forcednsseed", false))) {
1125 MilliSleep(11 * 1000);
1128 if (vNodes.size() >= 2) {
1129 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1134 const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1137 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1139 BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1140 if (HaveNameProxy()) {
1141 AddOneShot(seed.host);
1143 vector<CNetAddr> vIPs;
1144 vector<CAddress> vAdd;
1145 if (LookupHost(seed.host.c_str(), vIPs))
1147 BOOST_FOREACH(CNetAddr& ip, vIPs)
1149 int nOneDay = 24*3600;
1150 CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1151 addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1152 vAdd.push_back(addr);
1156 addrman.Add(vAdd, CNetAddr(seed.name, true));
1160 LogPrintf("%d addresses found from DNS seeds\n", found);
1174 void DumpAddresses()
1176 int64_t nStart = GetTimeMillis();
1181 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1182 addrman.size(), GetTimeMillis() - nStart);
1185 void static ProcessOneShot()
1190 if (vOneShots.empty())
1192 strDest = vOneShots.front();
1193 vOneShots.pop_front();
1196 CSemaphoreGrant grant(*semOutbound, true);
1198 if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1199 AddOneShot(strDest);
1203 void ThreadOpenConnections()
1205 // Connect to specific addresses
1206 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1208 for (int64_t nLoop = 0;; nLoop++)
1211 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1214 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1215 for (int i = 0; i < 10 && i < nLoop; i++)
1224 // Initiate network connections
1225 int64_t nStart = GetTime();
1232 CSemaphoreGrant grant(*semOutbound);
1233 boost::this_thread::interruption_point();
1235 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1236 if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1237 static bool done = false;
1239 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1240 addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
1246 // Choose an address to connect to based on most recently seen
1248 CAddress addrConnect;
1250 // Only connect out to one peer per network group (/16 for IPv4).
1251 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1253 set<vector<unsigned char> > setConnected;
1256 BOOST_FOREACH(CNode* pnode, vNodes) {
1257 if (!pnode->fInbound) {
1258 setConnected.insert(pnode->addr.GetGroup());
1264 int64_t nANow = GetAdjustedTime();
1269 // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1270 CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1272 // if we selected an invalid address, restart
1273 if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1276 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1277 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1278 // already-connected network ranges, ...) before trying new addrman addresses.
1283 if (IsLimited(addr))
1286 // only consider very recently tried nodes after 30 failed attempts
1287 if (nANow - addr.nLastTry < 600 && nTries < 30)
1290 // do not allow non-default ports, unless after 50 invalid addresses selected already
1291 if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1298 if (addrConnect.IsValid())
1299 OpenNetworkConnection(addrConnect, &grant);
1303 void ThreadOpenAddedConnections()
1306 LOCK(cs_vAddedNodes);
1307 vAddedNodes = mapMultiArgs["-addnode"];
1310 if (HaveNameProxy()) {
1312 list<string> lAddresses(0);
1314 LOCK(cs_vAddedNodes);
1315 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1316 lAddresses.push_back(strAddNode);
1318 BOOST_FOREACH(string& strAddNode, lAddresses) {
1320 CSemaphoreGrant grant(*semOutbound);
1321 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1324 MilliSleep(120000); // Retry every 2 minutes
1328 for (unsigned int i = 0; true; i++)
1330 list<string> lAddresses(0);
1332 LOCK(cs_vAddedNodes);
1333 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1334 lAddresses.push_back(strAddNode);
1337 list<vector<CService> > lservAddressesToAdd(0);
1338 BOOST_FOREACH(string& strAddNode, lAddresses)
1340 vector<CService> vservNode(0);
1341 if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1343 lservAddressesToAdd.push_back(vservNode);
1345 LOCK(cs_setservAddNodeAddresses);
1346 BOOST_FOREACH(CService& serv, vservNode)
1347 setservAddNodeAddresses.insert(serv);
1351 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1352 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1355 BOOST_FOREACH(CNode* pnode, vNodes)
1356 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1357 BOOST_FOREACH(CService& addrNode, *(it))
1358 if (pnode->addr == addrNode)
1360 it = lservAddressesToAdd.erase(it);
1365 BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1367 CSemaphoreGrant grant(*semOutbound);
1368 OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1371 MilliSleep(120000); // Retry every 2 minutes
1375 // if successful, this moves the passed grant to the constructed node
1376 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
1379 // Initiate outbound network connection
1381 boost::this_thread::interruption_point();
1383 if (IsLocal(addrConnect) ||
1384 FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1385 FindNode(addrConnect.ToStringIPPort()))
1387 } else if (FindNode(pszDest))
1390 CNode* pnode = ConnectNode(addrConnect, pszDest);
1391 boost::this_thread::interruption_point();
1396 grantOutbound->MoveTo(pnode->grantOutbound);
1397 pnode->fNetworkNode = true;
1399 pnode->fOneShot = true;
1405 void ThreadMessageHandler()
1407 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1410 vector<CNode*> vNodesCopy;
1413 vNodesCopy = vNodes;
1414 BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1419 // Poll the connected nodes for messages
1420 CNode* pnodeTrickle = NULL;
1421 if (!vNodesCopy.empty())
1422 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1426 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1428 if (pnode->fDisconnect)
1433 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1436 if (!g_signals.ProcessMessages(pnode))
1437 pnode->CloseSocketDisconnect();
1439 if (pnode->nSendSize < SendBufferSize())
1441 if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1448 boost::this_thread::interruption_point();
1452 TRY_LOCK(pnode->cs_vSend, lockSend);
1454 g_signals.SendMessages(pnode, pnode == pnodeTrickle);
1456 boost::this_thread::interruption_point();
1461 BOOST_FOREACH(CNode* pnode, vNodesCopy)
1475 bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted)
1480 // Create socket for listening for incoming connections
1481 struct sockaddr_storage sockaddr;
1482 socklen_t len = sizeof(sockaddr);
1483 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1485 strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
1486 LogPrintf("%s\n", strError);
1490 SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1491 if (hListenSocket == INVALID_SOCKET)
1493 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1494 LogPrintf("%s\n", strError);
1500 // Different way of disabling SIGPIPE on BSD
1501 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1503 // Allow binding if the port is still in TIME_WAIT state after
1504 // the program was closed and restarted. Not an issue on windows!
1505 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1508 // Set to non-blocking, incoming connections will also inherit this
1509 if (!SetSocketNonBlocking(hListenSocket, true)) {
1510 strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1511 LogPrintf("%s\n", strError);
1515 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1516 // and enable it by default or not. Try to enable it, if possible.
1517 if (addrBind.IsIPv6()) {
1520 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1522 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1526 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1527 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1531 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1533 int nErr = WSAGetLastError();
1534 if (nErr == WSAEADDRINUSE)
1535 strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
1537 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
1538 LogPrintf("%s\n", strError);
1539 CloseSocket(hListenSocket);
1542 LogPrintf("Bound to %s\n", addrBind.ToString());
1544 // Listen for incoming connections
1545 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1547 strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1548 LogPrintf("%s\n", strError);
1549 CloseSocket(hListenSocket);
1553 vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
1555 if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
1556 AddLocal(addrBind, LOCAL_BIND);
1561 void static Discover(boost::thread_group& threadGroup)
1567 // Get local host IP
1568 char pszHostName[256] = "";
1569 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1571 vector<CNetAddr> vaddr;
1572 if (LookupHost(pszHostName, vaddr))
1574 BOOST_FOREACH (const CNetAddr &addr, vaddr)
1576 if (AddLocal(addr, LOCAL_IF))
1577 LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
1582 // Get local host ip
1583 struct ifaddrs* myaddrs;
1584 if (getifaddrs(&myaddrs) == 0)
1586 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1588 if (ifa->ifa_addr == NULL) continue;
1589 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1590 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1591 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1592 if (ifa->ifa_addr->sa_family == AF_INET)
1594 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1595 CNetAddr addr(s4->sin_addr);
1596 if (AddLocal(addr, LOCAL_IF))
1597 LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1599 else if (ifa->ifa_addr->sa_family == AF_INET6)
1601 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1602 CNetAddr addr(s6->sin6_addr);
1603 if (AddLocal(addr, LOCAL_IF))
1604 LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1607 freeifaddrs(myaddrs);
1612 void StartNode(boost::thread_group& threadGroup)
1614 uiInterface.InitMessage(_("Loading addresses..."));
1615 // Load addresses for peers.dat
1616 int64_t nStart = GetTimeMillis();
1619 if (!adb.Read(addrman))
1620 LogPrintf("Invalid or missing peers.dat; recreating\n");
1622 LogPrintf("Loaded %i addresses from peers.dat %dms\n",
1623 addrman.size(), GetTimeMillis() - nStart);
1624 fAddressesInitialized = true;
1626 if (semOutbound == NULL) {
1627 // initialize semaphore
1628 int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
1629 semOutbound = new CSemaphore(nMaxOutbound);
1632 if (pnodeLocalHost == NULL)
1633 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1635 Discover(threadGroup);
1641 if (!GetBoolArg("-dnsseed", true))
1642 LogPrintf("DNS seeding disabled\n");
1644 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1646 // Map ports with UPnP
1647 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
1649 // Send and receive from sockets, accept connections
1650 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1652 // Initiate outbound connections from -addnode
1653 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1655 // Initiate outbound connections
1656 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1659 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1661 // Dump network addresses
1662 threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, DUMP_ADDRESSES_INTERVAL * 1000));
1667 LogPrintf("StopNode()\n");
1670 for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1671 semOutbound->post();
1673 if (fAddressesInitialized)
1676 fAddressesInitialized = false;
1690 BOOST_FOREACH(CNode* pnode, vNodes)
1691 if (pnode->hSocket != INVALID_SOCKET)
1692 CloseSocket(pnode->hSocket);
1693 BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
1694 if (hListenSocket.socket != INVALID_SOCKET)
1695 if (!CloseSocket(hListenSocket.socket))
1696 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
1698 // clean up some globals (to help leak detection)
1699 BOOST_FOREACH(CNode *pnode, vNodes)
1701 BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1704 vNodesDisconnected.clear();
1705 vhListenSocket.clear();
1708 delete pnodeLocalHost;
1709 pnodeLocalHost = NULL;
1712 // Shutdown Windows Sockets
1717 instance_of_cnetcleanup;
1725 void RelayTransaction(const CTransaction& tx)
1727 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1730 RelayTransaction(tx, ss);
1733 void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
1735 CInv inv(MSG_TX, tx.GetHash());
1738 // Expire old relay messages
1739 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1741 mapRelay.erase(vRelayExpiration.front().second);
1742 vRelayExpiration.pop_front();
1745 // Save original serialized message so newer versions are preserved
1746 mapRelay.insert(std::make_pair(inv, ss));
1747 vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1750 BOOST_FOREACH(CNode* pnode, vNodes)
1752 if(!pnode->fRelayTxes)
1754 LOCK(pnode->cs_filter);
1757 if (pnode->pfilter->IsRelevantAndUpdate(tx))
1758 pnode->PushInventory(inv);
1760 pnode->PushInventory(inv);
1764 void CNode::RecordBytesRecv(uint64_t bytes)
1766 LOCK(cs_totalBytesRecv);
1767 nTotalBytesRecv += bytes;
1770 void CNode::RecordBytesSent(uint64_t bytes)
1772 LOCK(cs_totalBytesSent);
1773 nTotalBytesSent += bytes;
1776 uint64_t CNode::GetTotalBytesRecv()
1778 LOCK(cs_totalBytesRecv);
1779 return nTotalBytesRecv;
1782 uint64_t CNode::GetTotalBytesSent()
1784 LOCK(cs_totalBytesSent);
1785 return nTotalBytesSent;
1788 void CNode::Fuzz(int nChance)
1790 if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
1791 if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
1796 // xor a random byte with a random value:
1797 if (!ssSend.empty()) {
1798 CDataStream::size_type pos = GetRand(ssSend.size());
1799 ssSend[pos] ^= (unsigned char)(GetRand(256));
1803 // delete a random byte:
1804 if (!ssSend.empty()) {
1805 CDataStream::size_type pos = GetRand(ssSend.size());
1806 ssSend.erase(ssSend.begin()+pos);
1810 // insert a random byte at a random position
1812 CDataStream::size_type pos = GetRand(ssSend.size());
1813 char ch = (char)GetRand(256);
1814 ssSend.insert(ssSend.begin()+pos, ch);
1818 // Chance of more than one change half the time:
1819 // (more changes exponentially less likely):
1829 pathAddr = GetDataDir() / "peers.dat";
1832 bool CAddrDB::Write(const CAddrMan& addr)
1834 // Generate random temporary filename
1835 unsigned short randv = 0;
1836 GetRandBytes((unsigned char*)&randv, sizeof(randv));
1837 std::string tmpfn = strprintf("peers.dat.%04x", randv);
1839 // serialize addresses, checksum data up to that point, then append csum
1840 CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
1841 ssPeers << FLATDATA(Params().MessageStart());
1843 uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
1846 // open temp output file, and associate with CAutoFile
1847 boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
1848 FILE *file = fopen(pathTmp.string().c_str(), "wb");
1849 CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
1850 if (fileout.IsNull())
1851 return error("%s : Failed to open file %s", __func__, pathTmp.string());
1853 // Write and commit header, data
1857 catch (std::exception &e) {
1858 return error("%s : Serialize or I/O error - %s", __func__, e.what());
1860 FileCommit(fileout.Get());
1863 // replace existing peers.dat, if any, with new peers.dat.XXXX
1864 if (!RenameOver(pathTmp, pathAddr))
1865 return error("%s : Rename-into-place failed", __func__);
1870 bool CAddrDB::Read(CAddrMan& addr)
1872 // open input file, and associate with CAutoFile
1873 FILE *file = fopen(pathAddr.string().c_str(), "rb");
1874 CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
1875 if (filein.IsNull())
1876 return error("%s : Failed to open file %s", __func__, pathAddr.string());
1878 // use file size to size memory buffer
1879 int fileSize = boost::filesystem::file_size(pathAddr);
1880 int dataSize = fileSize - sizeof(uint256);
1881 // Don't try to resize to a negative number if file is small
1884 vector<unsigned char> vchData;
1885 vchData.resize(dataSize);
1888 // read data and checksum from file
1890 filein.read((char *)&vchData[0], dataSize);
1893 catch (std::exception &e) {
1894 return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1898 CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
1900 // verify stored checksum matches input data
1901 uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
1902 if (hashIn != hashTmp)
1903 return error("%s : Checksum mismatch, data corrupted", __func__);
1905 unsigned char pchMsgTmp[4];
1907 // de-serialize file header (network specific magic number) and ..
1908 ssPeers >> FLATDATA(pchMsgTmp);
1910 // ... verify the network matches ours
1911 if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
1912 return error("%s : Invalid network magic number", __func__);
1914 // de-serialize address data into one CAddrMan object
1917 catch (std::exception &e) {
1918 return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1924 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
1925 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
1927 CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000)
1930 hSocket = hSocketIn;
1931 nRecvVersion = INIT_PROTO_VERSION;
1936 nTimeConnected = GetTime();
1938 addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
1941 fWhitelisted = false;
1943 fClient = false; // set by version message
1944 fInbound = fInboundIn;
1945 fNetworkNode = false;
1946 fSuccessfullyConnected = false;
1947 fDisconnect = false;
1952 nStartingHeight = -1;
1955 setInventoryKnown.max_size(SendBufferSize() / 1000);
1956 pfilter = new CBloomFilter();
1960 fPingQueued = false;
1963 LOCK(cs_nLastNodeId);
1968 LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
1970 LogPrint("net", "Added connection peer=%d\n", id);
1972 // Be shy and don't send version until we hear
1973 if (hSocket != INVALID_SOCKET && !fInbound)
1976 GetNodeSignals().InitializeNode(GetId(), this);
1981 CloseSocket(hSocket);
1986 GetNodeSignals().FinalizeNode(GetId());
1989 void CNode::AskFor(const CInv& inv)
1991 if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
1993 // We're using mapAskFor as a priority queue,
1994 // the key is the earliest time the request can be sent
1995 int64_t nRequestTime;
1996 limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
1997 if (it != mapAlreadyAskedFor.end())
1998 nRequestTime = it->second;
2001 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id);
2003 // Make sure not to reuse time indexes to keep things in the same order
2004 int64_t nNow = GetTimeMicros() - 1000000;
2005 static int64_t nLastTime;
2007 nNow = std::max(nNow, nLastTime);
2010 // Each retry is 2 minutes after the last
2011 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2012 if (it != mapAlreadyAskedFor.end())
2013 mapAlreadyAskedFor.update(it, nRequestTime);
2015 mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2016 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2019 void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
2021 ENTER_CRITICAL_SECTION(cs_vSend);
2022 assert(ssSend.size() == 0);
2023 ssSend << CMessageHeader(pszCommand, 0);
2024 LogPrint("net", "sending: %s ", pszCommand);
2027 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
2031 LEAVE_CRITICAL_SECTION(cs_vSend);
2033 LogPrint("net", "(aborted)\n");
2036 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
2038 // The -*messagestest options are intentionally not documented in the help message,
2039 // since they are only used during development to debug the networking code and are
2040 // not intended for end-users.
2041 if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2043 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2047 if (mapArgs.count("-fuzzmessagestest"))
2048 Fuzz(GetArg("-fuzzmessagestest", 10));
2050 if (ssSend.size() == 0)
2054 unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
2055 memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
2058 uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
2059 unsigned int nChecksum = 0;
2060 memcpy(&nChecksum, &hash, sizeof(nChecksum));
2061 assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
2062 memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
2064 LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
2066 std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
2067 ssSend.GetAndClear(*it);
2068 nSendSize += (*it).size();
2070 // If write queue empty, attempt "optimistic write"
2071 if (it == vSendMsg.begin())
2072 SocketSendData(this);
2074 LEAVE_CRITICAL_SECTION(cs_vSend);