diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java index 7b182d105476d0c380aa81a5052673782367235a..92e78d3de270c0ca5b80338a2ee8af3da50f2003 100644 --- a/router/java/src/net/i2p/router/Shitlist.java +++ b/router/java/src/net/i2p/router/Shitlist.java @@ -198,6 +198,7 @@ public class Shitlist { if (transport == null) { // we hate the peer on *any* transport _context.netDb().fail(peer); + _context.tunnelManager().fail(peer); } //_context.tunnelManager().peerFailed(peer); //_context.messageRegistry().peerFailed(peer); diff --git a/router/java/src/net/i2p/router/TunnelManagerFacade.java b/router/java/src/net/i2p/router/TunnelManagerFacade.java index ae54f6077df59275f9c9a2c6294fda7b78af3f72..5e00d7010d60e615391f83d1ad543a8009ea2fe0 100644 --- a/router/java/src/net/i2p/router/TunnelManagerFacade.java +++ b/router/java/src/net/i2p/router/TunnelManagerFacade.java @@ -165,4 +165,7 @@ public interface TunnelManagerFacade extends Service { public TunnelPool getInboundExploratoryPool(); /** for TunnelRenderer in router console */ public TunnelPool getOutboundExploratoryPool(); + + /** @since 0.8.13 */ + public void fail(Hash peer); } diff --git a/router/java/src/net/i2p/router/dummy/DummyTunnelManagerFacade.java b/router/java/src/net/i2p/router/dummy/DummyTunnelManagerFacade.java index b1574738cbb4c1aade3f0c26befc400639f098af..221f2d9e936b48a10364da6f12a53258af5d439b 100644 --- a/router/java/src/net/i2p/router/dummy/DummyTunnelManagerFacade.java +++ b/router/java/src/net/i2p/router/dummy/DummyTunnelManagerFacade.java @@ -70,4 +70,5 @@ public class DummyTunnelManagerFacade implements TunnelManagerFacade { public Map<Hash, TunnelPool> getOutboundClientPools() { return null; } public TunnelPool getInboundExploratoryPool() { return null; } public TunnelPool getOutboundExploratoryPool() { return null; } + public void fail(Hash peer) {} } diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java index c5397580f1842b5060d4bf74c60700787fddfae4..753f931bcb1bfa3640d508353aaf24a7c2cb485b 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -486,8 +486,30 @@ public class TunnelPool { } } - /** This may be called multiple times from TestJob */ - void tunnelFailed(PooledTunnelCreatorConfig cfg) { + /** + * Remove the tunnel and blame all the peers (not necessarily equally). + * This may be called multiple times from TestJob. + */ + void tunnelFailed(TunnelInfo cfg) { + fail(cfg); + tellProfileFailed(cfg); + } + + /** + * Remove the tunnel and blame only one peer. + * This may be called multiple times. + * + * @since 0.8.13 + */ + void tunnelFailed(TunnelInfo cfg, Hash blamePeer) { + fail(cfg); + _context.profileManager().tunnelFailed(blamePeer, 100); + } + + /** + * Remove the tunnel. + */ + private void fail(TunnelInfo cfg) { if (_log.shouldLog(Log.WARN)) _log.warn(toString() + ": Tunnel failed: " + cfg); LeaseSet ls = null; @@ -504,7 +526,6 @@ public class TunnelPool { } _manager.tunnelFailed(); - tellProfileFailed(cfg); _lifetimeProcessed += cfg.getProcessedMessagesCount(); updateRate(); @@ -516,9 +537,11 @@ public class TunnelPool { } } - // Blame all the other peers in the tunnel, with a probability - // inversely related to the tunnel length - private void tellProfileFailed(PooledTunnelCreatorConfig cfg) { + /** + * Blame all the other peers in the tunnel, with a probability + * inversely related to the tunnel length + */ + private void tellProfileFailed(TunnelInfo cfg) { int len = cfg.getLength(); if (len < 2) return; @@ -543,7 +566,7 @@ public class TunnelPool { } } - void updateRate() { + private void updateRate() { long now = _context.clock().now(); long et = now - _lastRateUpdate; if (et > 2*60*1000) { diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java index 8df88c8b0be821d0ff1b07808e30058dc51413a6..56f8a587bd4fbc276330c102c341fd75a9132b73 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java @@ -644,4 +644,57 @@ public class TunnelPoolManager implements TunnelManagerFacade { public TunnelPool getOutboundExploratoryPool() { return _outboundExploratory; } + + /** + * Fail all outbound tunnels with this peer as first hop, + * and all inbound tunnels with this peer as the last hop, + * baecause we can't contact it any more. + * This is most likely to be triggered by an outbound tunnel. + * + * @since 0.8.13 + */ + public void fail(Hash peer) { + if (_outboundExploratory != null) + failTunnelsWithFirstHop(_outboundExploratory, peer); + for (TunnelPool pool : _clientOutboundPools.values()) { + failTunnelsWithFirstHop(pool, peer); + } + if (_inboundExploratory != null) + failTunnelsWithLastHop(_inboundExploratory, peer); + for (TunnelPool pool : _clientInboundPools.values()) { + failTunnelsWithLastHop(pool, peer); + } + } + + /** + * Fail all (outbound) tunnels with this peer as first hop (not counting us) + * + * @since 0.8.13 + */ + private void failTunnelsWithFirstHop(TunnelPool pool, Hash peer) { + for (TunnelInfo tun : pool.listTunnels()) { + int len = tun.getLength(); + if (len > 1 && tun.getPeer(1).equals(peer)) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Removing OB tunnel, first hop shitlisted: " + tun); + pool.tunnelFailed(tun, peer); + } + } + } + + /** + * Fail all (inbound) tunnels with this peer as last hop (not counting us) + * + * @since 0.8.13 + */ + private void failTunnelsWithLastHop(TunnelPool pool, Hash peer) { + for (TunnelInfo tun : pool.listTunnels()) { + int len = tun.getLength(); + if (len > 1 && tun.getPeer(len - 2).equals(peer)) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Removing IB tunnel, prev. hop shitlisted: " + tun); + pool.tunnelFailed(tun, peer); + } + } + } }