- When a peer is shitlisted, fail all our tunnels where

that peer is the adjacent hop. In particular this
      will remove outbound tunnels when we can't contact
      the first hop, and enable quicker recovery.
This commit is contained in:
zzz
2012-01-18 02:01:59 +00:00
parent 6e5d53dbde
commit a4a1ed4357
5 changed files with 88 additions and 7 deletions

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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) {}
}

View File

@@ -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) {

View File

@@ -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);
}
}
}
}