From a4e28b3d1e5c95eb0c87f144851cd65048c3e0bc Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Wed, 21 Oct 2015 23:52:29 +0000 Subject: Set TCP_NODELAY on P2P sockets. Nagle appears to be a significant contributor to latency now that the static sleeps are gone. Most of our messages are relatively large compared to IP + TCP so I do not expect this to create enormous overhead. This may also reduce traffic burstyness somewhat. --- src/net.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 87c4f0af0..58b946f4a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -963,6 +963,15 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { return; } + // According to the internet TCP_NODELAY is not carried into accepted sockets + // on all platforms. Set it again here just to be sure. + int set = 1; +#ifdef WIN32 + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int)); +#else + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); +#endif + if (CNode::IsBanned(addr) && !whitelisted) { LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); @@ -1790,8 +1799,11 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste // Allow binding if the port is still in TIME_WAIT state after // the program was closed and restarted. setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); + // Disable Nagle's algorithm + setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int)); #else setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int)); + setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int)); #endif // Set to non-blocking, incoming connections will also inherit this -- cgit v1.2.3 From 872fee3fccc8b33b9af0a401b5f85ac5504b57eb Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 2 Sep 2015 17:03:27 +0200 Subject: Introduce -maxuploadtarget * -maxuploadtarget can be set in MiB * if - ( time-left-in-24h-cycle / 600 * MAX_BLOCK_SIZE ) has reach, stop serve blocks older than one week and filtered blocks * no action if limit has reached, no guarantee that the target will not be surpassed * add outbound limit informations to rpc getnettotals --- src/net.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 58b946f4a..e18e8d0e2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -12,6 +12,7 @@ #include "addrman.h" #include "chainparams.h" #include "clientversion.h" +#include "consensus/consensus.h" #include "crypto/common.h" #include "hash.h" #include "primitives/transaction.h" @@ -326,6 +327,11 @@ uint64_t CNode::nTotalBytesSent = 0; CCriticalSection CNode::cs_totalBytesRecv; CCriticalSection CNode::cs_totalBytesSent; +uint64_t CNode::nMaxOutboundLimit = 0; +uint64_t CNode::nMaxOutboundTotalBytesSentInCycle = 0; +uint64_t CNode::nMaxOutboundTimeframe = 60*60*24; //1 day +uint64_t CNode::nMaxOutboundCycleStartTime = 0; + CNode* FindNode(const CNetAddr& ip) { LOCK(cs_vNodes); @@ -2083,6 +2089,94 @@ void CNode::RecordBytesSent(uint64_t bytes) { LOCK(cs_totalBytesSent); nTotalBytesSent += bytes; + + uint64_t now = GetTime(); + if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now) + { + // timeframe expired, reset cycle + nMaxOutboundCycleStartTime = now; + nMaxOutboundTotalBytesSentInCycle = 0; + } + + // TODO, exclude whitebind peers + nMaxOutboundTotalBytesSentInCycle += bytes; +} + +void CNode::SetMaxOutboundTarget(uint64_t limit) +{ + LOCK(cs_totalBytesSent); + uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE; + nMaxOutboundLimit = limit; + + if (limit < recommendedMinimum) + LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\n.", nMaxOutboundLimit, recommendedMinimum); +} + +uint64_t CNode::GetMaxOutboundTarget() +{ + LOCK(cs_totalBytesSent); + return nMaxOutboundLimit; +} + +uint64_t CNode::GetMaxOutboundTimeframe() +{ + LOCK(cs_totalBytesSent); + return nMaxOutboundTimeframe; +} + +uint64_t CNode::GetMaxOutboundTimeLeftInCycle() +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundLimit == 0) + return 0; + + if (nMaxOutboundCycleStartTime == 0) + return nMaxOutboundTimeframe; + + uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe; + uint64_t now = GetTime(); + return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime(); +} + +void CNode::SetMaxOutboundTimeframe(uint64_t timeframe) +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundTimeframe != timeframe) + { + // reset measure-cycle in case of changing + // the timeframe + nMaxOutboundCycleStartTime = GetTime(); + } + nMaxOutboundTimeframe = timeframe; +} + +bool CNode::OutboundTargetReached(bool historicalBlockServingLimit) +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundLimit == 0) + return false; + + if (historicalBlockServingLimit) + { + // keep a large enought buffer to at least relay each block once + uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle(); + uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE; + if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) + return true; + } + else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) + return true; + + return false; +} + +uint64_t CNode::GetOutboundTargetBytesLeft() +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundLimit == 0) + return 0; + + return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle; } uint64_t CNode::GetTotalBytesRecv() -- cgit v1.2.3 From 8f4e67f152a9625a1c66c20de00679286b2c187c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 25 Aug 2015 20:12:08 +0200 Subject: net: Automatically create hidden service, listen on Tor Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket API, to create and destroy 'ephemeral' hidden services programmatically. https://stem.torproject.org/api/control.html#stem.control.Controller.create_ephemeral_hidden_service This means that if Tor is running (and proper authorization is available), bitcoin automatically creates a hidden service to listen on, without user manual configuration. This will positively affect the number of available .onion nodes. - When the node is started, connect to Tor through control socket - Send `ADD_ONION` command - First time: - Make it create a hidden service key - Save the key in the data directory for later usage - Make it redirect port 8333 to the local port 8333 (or whatever port we're listening on). - Keep control socket connection open for as long node is running. The hidden service will (by default) automatically go away when the connection is closed. --- src/net.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index e18e8d0e2..9d01f2557 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -216,6 +216,7 @@ void AdvertizeLocal(CNode *pnode) } if (addrLocal.IsRoutable()) { + LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal.ToString()); pnode->PushAddress(addrLocal); } } -- cgit v1.2.3 From 09c1ae1c01076f64fe0654f371200668306e5e18 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 8 Sep 2015 17:48:45 +0200 Subject: torcontrol improvements and fixes - Force AUTHCOOKIE size to be 32 bytes: This provides protection against an attack where a process pretends to be Tor and uses the cookie authentication method to nab arbitrary files such as the wallet - torcontrol logging - fix cookie auth - add HASHEDPASSWORD auth, fix fd leak when fwrite() fails - better error reporting when cookie file is not ok - better init/shutdown flow - stop advertizing service when disconnected from tor control port - COOKIE->SAFECOOKIE auth --- src/net.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 9d01f2557..ada4a1bb6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -263,6 +263,14 @@ bool AddLocal(const CNetAddr &addr, int nScore) return AddLocal(CService(addr, GetListenPort()), nScore); } +bool RemoveLocal(const CService& addr) +{ + LOCK(cs_mapLocalHost); + LogPrintf("RemoveLocal(%s)\n", addr.ToString()); + mapLocalHost.erase(addr); + return true; +} + /** Make a particular network entirely off-limits (no automatic connects to it) */ void SetLimited(enum Network net, bool fLimited) { -- cgit v1.2.3 From b27e81f115e67bffee2c35c1c96082879160f6e1 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 6 Nov 2015 00:05:06 +0100 Subject: [net] Cleanup maxuploadtarget * log: nMaxOutboundLimit is in bytes * log: Hide misleading -maxuploadtarget=0 warning * qa : Minor cleanup to maxuploadtarget rpc tests * net: Use DEFAULT_MAX_UPLOAD_TARGET = 0 --- src/net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index ada4a1bb6..1ea50b249 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2117,8 +2117,8 @@ void CNode::SetMaxOutboundTarget(uint64_t limit) uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE; nMaxOutboundLimit = limit; - if (limit < recommendedMinimum) - LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\n.", nMaxOutboundLimit, recommendedMinimum); + if (limit > 0 && limit < recommendedMinimum) + LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit, recommendedMinimum); } uint64_t CNode::GetMaxOutboundTarget() -- cgit v1.2.3 From 4044f07d1c5eacb0ec732f1232489aa77fb7bb3b Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Sat, 14 Nov 2015 04:44:15 -0800 Subject: Add blocksonly mode --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 1ea50b249..a62e875f8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -460,7 +460,7 @@ void CNode::PushVersion() else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, strSubVersion, nBestHeight, true); + nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", false)); } -- cgit v1.2.3 From 71a2683f4b526b17adf317733b0aa18ffacecfdc Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Sat, 14 Nov 2015 05:10:59 -0800 Subject: Use DEFAULT_BLOCKSONLY and DEFAULT_WHITELISTALWAYSRELAY constants --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index a62e875f8..000eefc85 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -460,7 +460,7 @@ void CNode::PushVersion() else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", false)); + nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)); } -- cgit v1.2.3 From 08843ed99843078acb10eecda2045d5f0f1c2b4f Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 20 Nov 2015 18:51:44 -0500 Subject: Add relaytxes status to getpeerinfo --- src/net.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 000eefc85..cff4c5450 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -617,6 +617,7 @@ void CNode::copyStats(CNodeStats &stats) { stats.nodeid = this->GetId(); X(nServices); + X(fRelayTxes); X(nLastSend); X(nLastRecv); X(nTimeConnected); -- cgit v1.2.3 From 5029698186445bf3cd69d0e720f019c472661bff Mon Sep 17 00:00:00 2001 From: kazcw Date: Wed, 16 Jul 2014 14:31:41 -0700 Subject: prevent peer flooding request queue for an inv mapAlreadyAskedFor does not keep track of which peer has a request queued for a particular tx. As a result, a peer can blind a node to a tx indefinitely by sending many invs for the same tx, and then never replying to getdatas for it. Each inv received will be placed 2 minutes farther back in mapAlreadyAskedFor, so a short message containing 10 invs would render that tx unavailable for 20 minutes. This is fixed by disallowing a peer from having more than one entry for a particular inv in mapAlreadyAskedFor at a time. --- src/net.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index cff4c5450..04119e9dd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2410,6 +2410,10 @@ void CNode::AskFor(const CInv& inv) { if (mapAskFor.size() > MAPASKFOR_MAX_SZ) return; + // a peer may not occupy multiple positions in an inv's request queue + if (!setAskFor.insert(inv.hash).second) + return; + // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64_t nRequestTime; -- cgit v1.2.3 From ebb25f4c23adbcb55796c402bafd6064a136f16f Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Mon, 23 Nov 2015 01:54:23 +0000 Subject: Limit setAskFor and retire requested entries only when a getdata returns. The setAskFor duplicate elimination was too eager and removed entries when we still had no getdata response, allowing the peer to keep INVing and not responding. --- src/net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 04119e9dd..a8b6ca9c5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2408,9 +2408,9 @@ CNode::~CNode() void CNode::AskFor(const CInv& inv) { - if (mapAskFor.size() > MAPASKFOR_MAX_SZ) + if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ) return; - // a peer may not occupy multiple positions in an inv's request queue + // a peer may not have multiple non-responded queue positions for a single inv item if (!setAskFor.insert(inv.hash).second) return; -- cgit v1.2.3 From b966aa836a3bc5bfa1314248258308f0026d41bb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 27 Jun 2015 19:21:41 +0000 Subject: Constrain constant values to a single location in code --- src/net.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index cff4c5450..abc7cbb8f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -521,12 +521,11 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti banEntry.banReason = banReason; if (bantimeoffset <= 0) { - bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban + bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); sinceUnixEpoch = false; } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; - LOCK(cs_setBanned); if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) setBanned[subNet] = banEntry; @@ -1414,7 +1413,7 @@ void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute if ((addrman.size() > 0) && - (!GetBoolArg("-forcednsseed", false))) { + (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { MilliSleep(11 * 1000); LOCK(cs_vNodes); @@ -2337,8 +2336,8 @@ bool CAddrDB::Read(CAddrMan& addr) return true; } -unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } -unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } +unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); } +unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); } CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), -- cgit v1.2.3 From ec73ef37eccfeda76de55c4ff93ea54d4e69e1ec Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Thu, 26 Nov 2015 05:25:30 +0000 Subject: Replace setInventoryKnown with a rolling bloom filter. Mruset setInventoryKnown was reduced to a remarkably small 1000 entries as a side effect of sendbuffer size reductions in 2012. This removes setInventoryKnown filtering from merkleBlock responses because false positives there are especially unattractive and also because I'm not sure if there aren't race conditions around the relay pool that would cause some transactions there to be suppressed. (Also, ProcessGetData was accessing setInventoryKnown without taking the required lock.) --- src/net.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index abc7cbb8f..fc8fa30ee 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2342,7 +2342,7 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(SendBufferSize() / 1000) + setInventoryKnown(50000, 0.000001) { nServices = 0; hSocket = hSocketIn; @@ -2369,6 +2369,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nSendOffset = 0; hashContinue = uint256(); nStartingHeight = -1; + setInventoryKnown.reset(); fGetAddr = false; fRelayTxes = false; pfilter = new CBloomFilter(); -- cgit v1.2.3 From 6b849350ab074a7ccb80ecbef387f59e1271ded6 Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Sun, 29 Nov 2015 01:52:51 -0800 Subject: Rename setInventoryKnown filterInventoryKnown --- src/net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index fc8fa30ee..59c0faac2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2342,7 +2342,7 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(50000, 0.000001) + filterInventoryKnown(50000, 0.000001) { nServices = 0; hSocket = hSocketIn; @@ -2369,7 +2369,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nSendOffset = 0; hashContinue = uint256(); nStartingHeight = -1; - setInventoryKnown.reset(); + filterInventoryKnown.reset(); fGetAddr = false; fRelayTxes = false; pfilter = new CBloomFilter(); -- cgit v1.2.3 From ca188c629e90fd90b533f43d769348d6a42d24b9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 25 Aug 2015 16:30:31 +0200 Subject: log bytes recv/sent per command --- src/net.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index a8aa97fee..649c6134d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -67,6 +67,15 @@ namespace { }; } +//immutable thread safe array of allowed commands for logging inbound traffic +const static std::string logAllowIncomingMsgCmds[] = { + "version", "addr", "inv", "getdata", "merkleblock", + "getblocks", "getheaders", "tx", "headers", "block", + "getaddr", "mempool", "ping", "pong", "alert", "notfound", + "filterload", "filteradd", "filterclear", "reject"}; + +const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; + // // Global state variables // @@ -627,7 +636,9 @@ void CNode::copyStats(CNodeStats &stats) X(fInbound); X(nStartingHeight); X(nSendBytes); + X(mapSendBytesPerMsgCmd); X(nRecvBytes); + X(mapRecvBytesPerMsgCmd); X(fWhitelisted); // It is common for nodes with good ping times to suddenly become lagged, @@ -682,6 +693,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) nBytes -= handled; if (msg.complete()) { + + //store received bytes per message command + //to prevent a memory DOS, only allow valid commands + mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand); + if (i == mapRecvBytesPerMsgCmd.end()) + i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); + assert(i != mapRecvBytesPerMsgCmd.end()); + i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE; + msg.nTime = GetTimeMicros(); messageHandlerCondition.notify_one(); } @@ -2378,6 +2398,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits::max(); + for (unsigned int i = 0; i < sizeof(logAllowIncomingMsgCmds)/sizeof(logAllowIncomingMsgCmds[0]); i++) + mapRecvBytesPerMsgCmd[logAllowIncomingMsgCmds[i]] = 0; + mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; { LOCK(cs_nLastNodeId); @@ -2457,7 +2480,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend) LogPrint("net", "(aborted)\n"); } -void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) +void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend) { // The -*messagestest options are intentionally not documented in the help message, // since they are only used during development to debug the networking code and are @@ -2480,6 +2503,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); + //log total amount of bytes per command + mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE; + // Set the checksum uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); unsigned int nChecksum = 0; -- cgit v1.2.3 From e3bc5e0e927af14bd34cc30cfdf11cacbb346262 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 7 Dec 2015 15:15:12 +0100 Subject: net: Account for `sendheaders` `verack` messages Looks like these were forgotten in #6589. --- src/net.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 649c6134d..159d44cba 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -72,7 +72,8 @@ const static std::string logAllowIncomingMsgCmds[] = { "version", "addr", "inv", "getdata", "merkleblock", "getblocks", "getheaders", "tx", "headers", "block", "getaddr", "mempool", "ping", "pong", "alert", "notfound", - "filterload", "filteradd", "filterclear", "reject"}; + "filterload", "filteradd", "filterclear", "reject", + "sendheaders", "verack"}; const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; -- cgit v1.2.3 From 9bbe71b641e2fc985daf127988a14a67c99da50a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 7 Dec 2015 15:31:32 +0100 Subject: net: Add and document network messages in protocol.h - Avoids string typos (by making the compiler check) - Makes it easier to grep for handling/generation of a certain message type - Refer directly to documentation by following the symbol in IDE - Move list of valid message types to protocol.cpp: protocol.cpp is a more appropriate place for this, and having the array there makes it easier to keep things consistent. --- src/net.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index 159d44cba..c5e7ece79 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -67,14 +67,6 @@ namespace { }; } -//immutable thread safe array of allowed commands for logging inbound traffic -const static std::string logAllowIncomingMsgCmds[] = { - "version", "addr", "inv", "getdata", "merkleblock", - "getblocks", "getheaders", "tx", "headers", "block", - "getaddr", "mempool", "ping", "pong", "alert", "notfound", - "filterload", "filteradd", "filterclear", "reject", - "sendheaders", "verack"}; - const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; // @@ -469,7 +461,7 @@ void CNode::PushVersion() LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); - PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)); } @@ -2399,8 +2391,8 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits::max(); - for (unsigned int i = 0; i < sizeof(logAllowIncomingMsgCmds)/sizeof(logAllowIncomingMsgCmds[0]); i++) - mapRecvBytesPerMsgCmd[logAllowIncomingMsgCmds[i]] = 0; + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) + mapRecvBytesPerMsgCmd[msg] = 0; mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; { -- cgit v1.2.3 From 5400ef6bcb9d243b2b21697775aa6491115420f3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 8 Apr 2015 11:20:00 -0700 Subject: Replace trickle nodes with per-node/message Poisson delays We used to have a trickle node, a node which was chosen in each iteration of the send loop that was privileged and allowed to send out queued up non-time critical messages. Since the removal of the fixed sleeps in the network code, this resulted in fast and attackable treatment of such broadcasts. This pull request changes the 3 remaining trickle use cases by random delays: * Local address broadcast (while also removing the the wiping of the seen filter) * Address relay * Inv relay (for transactions; blocks are always relayed immediately) The code is based on older commits by Patrick Strateman. --- src/net.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index c5e7ece79..e0d96a2dc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -36,6 +36,8 @@ #include #include +#include + // Dump addresses to peers.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 @@ -1733,11 +1735,6 @@ void ThreadMessageHandler() } } - // Poll the connected nodes for messages - CNode* pnodeTrickle = NULL; - if (!vNodesCopy.empty()) - pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; - bool fSleep = true; BOOST_FOREACH(CNode* pnode, vNodesCopy) @@ -1768,7 +1765,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted); + g_signals.SendMessages(pnode); } boost::this_thread::interruption_point(); } @@ -2384,6 +2381,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nStartingHeight = -1; filterInventoryKnown.reset(); fGetAddr = false; + nNextLocalAddrSend = 0; + nNextAddrSend = 0; + nNextInvSend = 0; fRelayTxes = false; pfilter = new CBloomFilter(); nPingNonceSent = 0; @@ -2634,3 +2634,7 @@ void DumpBanlist() LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); } + +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { + return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); +} -- cgit v1.2.3 From fa24439ff3d8ab5b9efaf66ef4dae6713b88cb35 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 13 Dec 2015 17:58:29 +0100 Subject: Bump copyright headers to 2015 --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index e5659efc0..48a181dee 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From a5a0831458d8290c1e7591cf32a529669b613d86 Mon Sep 17 00:00:00 2001 From: 21E14 <21xe14@gmail.com> Date: Tue, 29 Dec 2015 22:42:27 -0500 Subject: Double semicolon cleanup. --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/net.cpp') diff --git a/src/net.cpp b/src/net.cpp index e0d96a2dc..2ad20ac22 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1370,7 +1370,7 @@ void ThreadMapPort() LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); else - LogPrintf("UPnP Port Mapping successful.\n");; + LogPrintf("UPnP Port Mapping successful.\n"); MilliSleep(20*60*1000); // Refresh every 20 minutes } -- cgit v1.2.3