From bae6844e5d74cf6b34618b9a1a2b02d196e8c72b Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 10 Nov 2023 16:35:00 +0000 Subject: [PATCH] NetDB: Lookup handler/throttler fixes (Gitlab #468) --- ...FloodfillDatabaseLookupMessageHandler.java | 28 ++++------------ .../FloodfillNetworkDatabaseFacade.java | 2 +- .../networkdb/kademlia/LookupThrottler.java | 32 +++++++++++++------ 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java index bbb7b52794..bb9a9b4374 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java @@ -35,10 +35,7 @@ public class FloodfillDatabaseLookupMessageHandler implements HandlerJobBuilder _log = context.logManager().getLog(FloodfillDatabaseLookupMessageHandler.class); _context.statManager().createRateStat("netDb.lookupsReceived", "How many netDb lookups have we received?", "NetworkDatabase", new long[] { 60*60*1000l }); _context.statManager().createRateStat("netDb.lookupsDropped", "How many netDb lookups did we drop due to throttling?", "NetworkDatabase", new long[] { 60*60*1000l }); - _context.statManager().createRateStat("netDb.lookupsDroppedDueToPriorBan", "How many netDb lookups did we drop due to having a prior ban?", "NetworkDatabase", new long[] { 60*60*1000l }); _context.statManager().createRateStat("netDb.nonFFLookupsDropped", "How many netDb lookups did we drop due to us not being a floodfill?", "NetworkDatabase", new long[] { 60*60*1000l }); - _context.statManager().createRateStat("netDb.repeatedLookupsDropped", "How many netDb lookups are coming in faster than we want?", "NetworkDatabase", new long[] { 60*60*1000l }); - _context.statManager().createRateStat("netDb.repeatedBurstLookupsDropped", "How many netDb lookups did we drop due to burst throttling?", "NetworkDatabase", new long[] { 60*60*1000l }); // following are for ../HDLMJ _context.statManager().createRateStat("netDb.lookupsHandled", "How many netDb lookups have we handled?", "NetworkDatabase", new long[] { 60 * 60 * 1000l }); @@ -65,17 +62,10 @@ public class FloodfillDatabaseLookupMessageHandler implements HandlerJobBuilder _context.statManager().addRateData("netDb.lookupsReceived", 1); DatabaseLookupMessage dlm = (DatabaseLookupMessage)receivedMessage; - boolean isBanned = dlm.getFrom() != null - && (_context.banlist().isBanlistedForever(dlm.getFrom()) - || _context.banlist().isBanlisted(dlm.getFrom())); - if (isBanned) { - _context.statManager().addRateData("netDb.lookupsDroppedDueToPriorBan", 1); - return null; - } - boolean ourRI = dlm.getSearchKey() != null && dlm.getSearchKey().equals(_context.routerHash()); - if (!_context.netDb().floodfillEnabled() && (dlm.getReplyTunnel() == null && !ourRI)) { + if (dlm.getSearchType() == DatabaseLookupMessage.Type.EXPL && + !_context.netDb().floodfillEnabled()) { if (_log.shouldLog(Log.WARN)) - _log.warn("[dbid: " + _facade._dbid + _log.warn("[dbid: " + _facade + "] Dropping " + dlm.getSearchType() + " lookup request for " + dlm.getSearchKey() + " (we are not a floodfill), reply was to: " @@ -83,20 +73,14 @@ public class FloodfillDatabaseLookupMessageHandler implements HandlerJobBuilder _context.statManager().addRateData("netDb.nonFFLookupsDropped", 1); return null; } + if (!_facade.shouldThrottleLookup(dlm.getFrom(), dlm.getReplyTunnel()) - || _context.routerHash().equals(dlm.getFrom())) { + || _context.routerHash().equals(dlm.getSearchKey())) { Job j = new HandleFloodfillDatabaseLookupMessageJob(_context, dlm, from, fromHash, _msgIDBloomXor); - // if (false) { - // // might as well inline it, all the heavy lifting is queued up in later jobs, - // if necessary - // j.runJob(); - // return null; - // } else { return j; - // } } else { if (_log.shouldLog(Log.WARN)) - _log.warn("[dbid: " + _facade._dbid + _log.warn("[dbid: " + _facade + "] Dropping " + dlm.getSearchType() + " lookup request for " + dlm.getSearchKey() + " (throttled), reply was to: " + dlm.getFrom() diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java index e11d97bb34..7530530d6c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java @@ -108,7 +108,7 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad isFF = false; } else { isFF = _context.getBooleanProperty(FloodfillMonitorJob.PROP_FLOODFILL_PARTICIPANT); - _lookupThrottler = new LookupThrottler(); + _lookupThrottler = new LookupThrottler(this); } long down = _context.router().getEstimatedDowntime(); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/LookupThrottler.java b/router/java/src/net/i2p/router/networkdb/kademlia/LookupThrottler.java index 9d43c78c78..f63fa96d13 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/LookupThrottler.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/LookupThrottler.java @@ -19,17 +19,28 @@ class LookupThrottler { private final ObjectCounter<ReplyTunnel> counter; /** the id of this is -1 */ private static final TunnelId DUMMY_ID = new TunnelId(); - /** 30 seems like plenty, possibly too many, maybe dial this down again next release(2.4.0)*/ - private final int MAX_LOOKUPS; // DEFAULT=20 - private final long CLEAN_TIME; // DEFAULT=3*60*1000 - LookupThrottler() { - MAX_LOOKUPS = 14; - CLEAN_TIME = 2*60*1000; - this.counter = new ObjectCounter<ReplyTunnel>(); - SimpleTimer2.getInstance().addPeriodicEvent(new Cleaner(), CLEAN_TIME); + private static final int DEFAULT_MAX_LOOKUPS = 14; + private static final int DEFAULT_MAX_NON_FF_LOOKUPS = 3; + private static final long DEFAULT_CLEAN_TIME = 2*60*1000; + private final int MAX_LOOKUPS; + private final int MAX_NON_FF_LOOKUPS; + private final long CLEAN_TIME; + private final FloodfillNetworkDatabaseFacade _facade; + private int _max; + + LookupThrottler(FloodfillNetworkDatabaseFacade facade) { + this(facade, DEFAULT_MAX_LOOKUPS, DEFAULT_MAX_NON_FF_LOOKUPS, DEFAULT_CLEAN_TIME); } - LookupThrottler(int maxlookups, long cleanTime) { + + /** + * @param maxlookups when floodfill + * @param maxnonfflookups when not floodfill + * @since 0.9.60 + */ + LookupThrottler(FloodfillNetworkDatabaseFacade facade, int maxlookups, int maxnonfflookups, long cleanTime) { + _facade = facade; MAX_LOOKUPS = maxlookups; + MAX_NON_FF_LOOKUPS = maxnonfflookups; CLEAN_TIME = cleanTime; this.counter = new ObjectCounter<ReplyTunnel>(); SimpleTimer2.getInstance().addPeriodicEvent(new Cleaner(), CLEAN_TIME); @@ -41,12 +52,13 @@ class LookupThrottler { * @param id null if for direct lookups */ boolean shouldThrottle(Hash key, TunnelId id) { - return this.counter.increment(new ReplyTunnel(key, id)) > MAX_LOOKUPS; + return this.counter.increment(new ReplyTunnel(key, id)) > _max; } private class Cleaner implements SimpleTimer.TimedEvent { public void timeReached() { LookupThrottler.this.counter.clear(); + _max = _facade.floodfillEnabled() ? MAX_LOOKUPS : MAX_NON_FF_LOOKUPS; } } -- GitLab