From 43a82bdd292dad89c23c3bb657ad2e22e30c1345 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sat, 26 Dec 2020 12:01:25 +0330 Subject: [PATCH 1/9] merge bitcoin#20769: fixes "advertised address where nobody is listening" --- src/init.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index f57dd4a5e0eea..d52ab19225c17 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1256,6 +1256,11 @@ bool AppInitParameterInteraction(const ArgsManager& args) return InitError(Untranslated("Cannot set -bind or -whitebind together with -listen=0")); } + // if listen=0, then disallow listenonion=1 + if (!args.GetBoolArg("-listen", DEFAULT_LISTEN) && args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) { + return InitError(Untranslated("Cannot set -listen=0 together with -listenonion=1")); + } + // Make sure enough file descriptors are available int nBind = std::max(nUserBind, size_t(1)); nUserMaxConnections = args.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); From 6f8c730f35e4d4d1e3199192613e357e39030654 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 25 Mar 2024 15:54:04 +0000 Subject: [PATCH 2/9] merge bitcoin#19499: Make timeout mockable and type safe, speed up test --- src/net.cpp | 32 ++++++++++++++------------ src/net.h | 16 ++++++------- src/net_processing.cpp | 5 ++-- src/qt/guiutil.cpp | 4 +++- src/qt/guiutil.h | 2 +- src/qt/rpcconsole.cpp | 14 +++++------ src/qt/rpcconsole.h | 5 ++-- src/rpc/net.cpp | 4 ++-- src/test/denialofservice_tests.cpp | 2 +- src/test/util/net.h | 2 +- test/functional/p2p_timeouts.py | 26 +++++++++++++-------- test/functional/test_framework/util.py | 8 +++---- 12 files changed, 66 insertions(+), 54 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 499fd05f91818..db93469f94839 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -660,8 +660,8 @@ void CNode::copyStats(CNodeStats &stats, const std::vector &m_asmap) } else { stats.fRelayTxes = false; } - X(nLastSend); - X(nLastRecv); + X(m_last_send); + X(m_last_recv); X(nLastTXTime); X(nLastBlockTime); X(nTimeConnected); @@ -710,7 +710,7 @@ bool CNode::ReceiveMsgBytes(Span msg_bytes, bool& complete) // TODO: use mocktime here after bitcoin#19499 is backported const auto time = std::chrono::microseconds(GetTimeMicros()); LOCK(cs_vRecv); - nLastRecv = std::chrono::duration_cast(time).count(); + m_last_recv = std::chrono::duration_cast(time); nRecvBytes += msg_bytes.size(); while (msg_bytes.size() > 0) { // absorb network data @@ -881,7 +881,7 @@ size_t CConnman::SocketSendData(CNode& node) nBytes = send(node.hSocket, reinterpret_cast(data.data()) + node.nSendOffset, data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); } if (nBytes > 0) { - node.nLastSend = GetTimeSeconds(); + node.m_last_send = GetTime(); node.nSendBytes += nBytes; node.nSendOffset += nBytes; nSentSize += nBytes; @@ -1524,31 +1524,33 @@ void CConnman::CalculateNumConnectionsChangedStats() statsClient.gauge("peers.torConnections", torNodes, 1.0f); } -bool CConnman::ShouldRunInactivityChecks(const CNode& node, int64_t now) const +bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const { - return node.nTimeConnected + m_peer_connect_timeout < now; + return std::chrono::seconds{node.nTimeConnected} + m_peer_connect_timeout < now; } bool CConnman::InactivityCheck(const CNode& node) const { - // Use non-mockable system time (otherwise these timers will pop when we - // use setmocktime in the tests). - int64_t now = GetTimeSeconds(); + // Tests that see disconnects after using mocktime can start nodes with a + // large timeout. For example, -peertimeout=999999999. + const auto now{GetTime()}; + const auto last_send{node.m_last_send.load()}; + const auto last_recv{node.m_last_recv.load()}; if (!ShouldRunInactivityChecks(node, now)) return false; - if (node.nLastRecv == 0 || node.nLastSend == 0) { - LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d peer=%d\n", m_peer_connect_timeout, node.nLastRecv != 0, node.nLastSend != 0, node.GetId()); + if (last_recv.count() == 0 || last_send.count() == 0) { + LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d peer=%d\n", count_seconds(m_peer_connect_timeout), last_recv.count() != 0, last_send.count() != 0, node.GetId()); return true; } - if (now > node.nLastSend + TIMEOUT_INTERVAL) { - LogPrint(BCLog::NET, "socket sending timeout: %is peer=%d\n", now - node.nLastSend, node.GetId()); + if (now > last_send + TIMEOUT_INTERVAL) { + LogPrint(BCLog::NET, "socket sending timeout: %is peer=%d\n", count_seconds(now - last_send), node.GetId()); return true; } - if (now > node.nLastRecv + TIMEOUT_INTERVAL) { - LogPrint(BCLog::NET, "socket receive timeout: %is peer=%d\n", now - node.nLastRecv, node.GetId()); + if (now > last_recv + TIMEOUT_INTERVAL) { + LogPrint(BCLog::NET, "socket receive timeout: %is peer=%d\n", count_seconds(now - last_recv), node.GetId()); return true; } diff --git a/src/net.h b/src/net.h index 72a329fceee57..e506033e7a63a 100644 --- a/src/net.h +++ b/src/net.h @@ -63,7 +63,7 @@ static const bool DEFAULT_WHITELISTRELAY = true; static const bool DEFAULT_WHITELISTFORCERELAY = false; /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ -static const int TIMEOUT_INTERVAL = 20 * 60; +static constexpr std::chrono::minutes TIMEOUT_INTERVAL{20}; /** Time to wait since nTimeConnected before disconnecting a probe node. **/ static const int PROBE_WAIT_INTERVAL = 5; /** Minimum time between warnings printed to log. */ @@ -275,8 +275,8 @@ class CNodeStats NodeId nodeid; ServiceFlags nServices; bool fRelayTxes; - int64_t nLastSend; - int64_t nLastRecv; + std::chrono::seconds m_last_send; + std::chrono::seconds m_last_recv; int64_t nLastTXTime; int64_t nLastBlockTime; int64_t nTimeConnected; @@ -459,8 +459,8 @@ class CNode uint64_t nRecvBytes GUARDED_BY(cs_vRecv){0}; - std::atomic nLastSend{0}; - std::atomic nLastRecv{0}; + std::atomic m_last_send{0s}; + std::atomic m_last_recv{0s}; //! Unix epoch time at peer connection, in seconds. const int64_t nTimeConnected; std::atomic nTimeOffset{0}; @@ -926,7 +926,7 @@ friend class CNode; m_msgproc = connOptions.m_msgproc; nSendBufferMaxSize = connOptions.nSendBufferMaxSize; nReceiveFloodSize = connOptions.nReceiveFloodSize; - m_peer_connect_timeout = connOptions.m_peer_connect_timeout; + m_peer_connect_timeout = std::chrono::seconds{connOptions.m_peer_connect_timeout}; { LOCK(cs_totalBytesSent); nMaxOutboundLimit = connOptions.nMaxOutboundLimit; @@ -1235,7 +1235,7 @@ friend class CNode; void SetAsmap(std::vector asmap) { addrman.m_asmap = std::move(asmap); } /** Return true if we should disconnect the peer for failing an inactivity check. */ - bool ShouldRunInactivityChecks(const CNode& node, int64_t secs_now) const; + bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const; private: struct ListenSocket { @@ -1351,7 +1351,7 @@ friend class CNode; uint64_t nMaxOutboundLimit GUARDED_BY(cs_totalBytesSent); // P2P timeout in seconds - int64_t m_peer_connect_timeout; + std::chrono::seconds m_peer_connect_timeout; // Whitelisted ranges. Any node connecting from these is automatically // whitelisted (as well as those connecting to whitelisted binds). diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 77e551eb2893b..c0cc232942e91 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -5063,9 +5063,10 @@ void PeerManagerImpl::CheckForStaleTipAndEvictPeers() void PeerManagerImpl::MaybeSendPing(CNode& node_to, Peer& peer, std::chrono::microseconds now) { - if (m_connman.ShouldRunInactivityChecks(node_to, std::chrono::duration_cast(now).count()) && + if (m_connman.ShouldRunInactivityChecks(node_to, std::chrono::duration_cast(now)) && peer.m_ping_nonce_sent && - now > peer.m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL}) { + now > peer.m_ping_start.load() + TIMEOUT_INTERVAL) + { // The ping timeout is using mocktime. To disable the check during // testing, increase -peertimeout. LogPrint(BCLog::NET, "ping timeout: %fs peer=%d\n", 0.000001 * count_microseconds(now - peer.m_ping_start.load()), peer.m_id); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index d6fb85473bba1..5cc1bed563b5c 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -23,6 +23,7 @@ #include