From 16d9bfc4172b4f6ce24a3cd1a1cfa3933cd26751 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Fri, 16 Oct 2020 14:05:09 -0400 Subject: [PATCH] Avoid test-before-evict evictions of current peers Outbound peer logic prevents connecting to addresses that we're already connected to, so prevent inadvertent eviction of current peers via test-before-evict by checking this condition and marking current peer's addresses as Good(). Co-authored-by: John Newbery --- src/net.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 11e975c3a9..468358a94d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1999,11 +1999,30 @@ void CConnman::ThreadOpenConnections(const std::vector connect) if (nTries > 100) break; - CAddrInfo addr = addrman.SelectTriedCollision(); + CAddrInfo addr; - // SelectTriedCollision returns an invalid address if it is empty. - if (!fFeeler || !addr.IsValid()) { - addr = addrman.Select(fFeeler); + if (fFeeler) { + // First, try to get a tried table collision address. This returns + // an empty (invalid) address if there are no collisions to try. + addr = addrman.SelectTriedCollision(); + + if (!addr.IsValid()) { + // No tried table collisions. Select a new table address + // for our feeler. + addr = addrman.Select(true); + } else if (AlreadyConnectedToAddress(addr)) { + // If test-before-evict logic would have us connect to a + // peer that we're already connected to, just mark that + // address as Good(). We won't be able to initiate the + // connection anyway, so this avoids inadvertently evicting + // a currently-connected peer. + addrman.Good(addr); + // Select a new table address for our feeler instead. + addr = addrman.Select(true); + } + } else { + // Not a feeler + addr = addrman.Select(); } // Require outbound connections, other than feelers, to be to distinct network groups