From 9007db1485fabb3b09bff802ed018f68c994c8e3 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 3 Nov 2013 15:26:21 +0000 Subject: [PATCH] Expire wasUnreachable entries, so inbound tunnel build failures don't escalate and the peer doesn't have a severe penalty in the CapacityCalculator forever. This may fix the tunnel build problems that started in -10. Or not. --- history.txt | 10 +++ .../src/net/i2p/router/RouterVersion.java | 2 +- .../i2p/router/transport/TransportImpl.java | 62 ++++++++++++++----- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/history.txt b/history.txt index 0c4f8587e8..e523cfb42f 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,13 @@ +2013-11-03 zzz + * NetDB: Allow store of leaseset as long as one lease has not expired + * Transport: + - Expire wasUnreachable entries, so inbound tunnel build failures + don't escalate + - Add network status to event log + +2013-11-01 zzz + * Transport: Fix GeoIPv6 (ticket #1096) + 2013-10-31 zzz * i2psnark: Always verify file lengths at startup (ticket #1099) * Transports: Increase threshold for idle timeout reduction diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index f5c9264549..43dca92409 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 20; + public final static long BUILD = 21; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index 19873cc6d4..89b6cbeda7 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -61,11 +61,14 @@ public abstract class TransportImpl implements Transport { protected final RouterContext _context; /** map from routerIdentHash to timestamp (Long) that the peer was last unreachable */ private final Map _unreachableEntries; - private final Set _wasUnreachableEntries; + private final Map _wasUnreachableEntries; private final Set _localAddresses; /** global router ident -> IP */ private static final Map _IPMap; + private static final long UNREACHABLE_PERIOD = 5*60*1000; + private static final long WAS_UNREACHABLE_PERIOD = 30*60*1000; + static { long maxMemory = SystemVersion.getMaxMemory(); long min = 512; @@ -97,8 +100,8 @@ public abstract class TransportImpl implements Transport { _sendPool = new ArrayBlockingQueue(8); else _sendPool = null; - _unreachableEntries = new HashMap(16); - _wasUnreachableEntries = new ConcurrentHashSet(16); + _unreachableEntries = new HashMap(32); + _wasUnreachableEntries = new HashMap(32); _localAddresses = new ConcurrentHashSet(4); _context.simpleScheduler().addPeriodicEvent(new CleanupUnreachable(), 2 * UNREACHABLE_PERIOD, UNREACHABLE_PERIOD / 2); } @@ -701,8 +704,6 @@ public abstract class TransportImpl implements Transport { public boolean isBacklogged(Hash dest) { return false; } public boolean isEstablished(Hash dest) { return false; } - private static final long UNREACHABLE_PERIOD = 5*60*1000; - public boolean isUnreachable(Hash peer) { long now = _context.clock().now(); synchronized (_unreachableEntries) { @@ -718,12 +719,17 @@ public abstract class TransportImpl implements Transport { } /** called when we can't reach a peer */ - /** This isn't very useful since it is cleared when they contact us */ public void markUnreachable(Hash peer) { - long now = _context.clock().now(); + short status = _context.commSystem().getReachabilityStatus(); + if (status == CommSystemFacade.STATUS_DISCONNECTED || + status == CommSystemFacade.STATUS_HOSED) + return; + Long now = Long.valueOf(_context.clock().now()); synchronized (_unreachableEntries) { - _unreachableEntries.put(peer, Long.valueOf(now)); + // This isn't very useful since it is cleared when they contact us + _unreachableEntries.put(peer, now); } + // This is not cleared when they contact us markWasUnreachable(peer, true); } @@ -748,29 +754,53 @@ public abstract class TransportImpl implements Transport { iter.remove(); } } + synchronized (_wasUnreachableEntries) { + for (Iterator iter = _wasUnreachableEntries.values().iterator(); iter.hasNext(); ) { + Long when = iter.next(); + if (when.longValue() + WAS_UNREACHABLE_PERIOD < now) + iter.remove(); + } + } } } /** * Was the peer UNreachable (outbound only) the last time we tried it? - * This is NOT reset if the peer contacts us and it is never expired. + * This is NOT reset if the peer contacts us. */ public boolean wasUnreachable(Hash peer) { - if (_wasUnreachableEntries.contains(peer)) - return true; + long now = _context.clock().now(); + synchronized (_wasUnreachableEntries) { + Long when = _wasUnreachableEntries.get(peer); + if (when != null) { + if (when.longValue() + WAS_UNREACHABLE_PERIOD < now) { + _unreachableEntries.remove(peer); + return false; + } else { + return true; + } + } + } RouterInfo ri = _context.netDb().lookupRouterInfoLocally(peer); if (ri == null) return false; return null == ri.getTargetAddress(this.getStyle()); } + /** * Maintain the WasUnreachable list */ - public void markWasUnreachable(Hash peer, boolean yes) { - if (yes) - _wasUnreachableEntries.add(peer); - else - _wasUnreachableEntries.remove(peer); + private void markWasUnreachable(Hash peer, boolean yes) { + if (yes) { + Long now = Long.valueOf(_context.clock().now()); + synchronized (_wasUnreachableEntries) { + _wasUnreachableEntries.put(peer, now); + } + } else { + synchronized (_wasUnreachableEntries) { + _wasUnreachableEntries.remove(peer); + } + } if (_log.shouldLog(Log.INFO)) _log.info(this.getStyle() + " setting wasUnreachable to " + yes + " for " + peer, yes ? new Exception() : null);