forked from I2P_Developers/i2p.i2p
Tunnels: Count consecutive build timeouts per-pool
Use exploratory paired tunnel after too many timeouts
This commit is contained in:
@@ -77,6 +77,8 @@ abstract class BuildRequestor {
|
||||
/** some randomization is added on to this */
|
||||
private static final int BUILD_MSG_TIMEOUT = 60*1000;
|
||||
|
||||
private static final int MAX_CONSECUTIVE_CLIENT_BUILD_FAILS = 6;
|
||||
|
||||
/**
|
||||
* "paired tunnels" means using a client's own inbound tunnel to receive the
|
||||
* reply for an outbound build request, and using a client's own outbound tunnel
|
||||
@@ -160,18 +162,27 @@ abstract class BuildRequestor {
|
||||
}
|
||||
} else {
|
||||
// building a client tunnel
|
||||
Hash from = settings.getDestination();
|
||||
if (isInbound) {
|
||||
pairedTunnel = mgr.selectOutboundTunnel(from, farEnd);
|
||||
} else {
|
||||
pairedTunnel = mgr.selectInboundTunnel(from, farEnd);
|
||||
if (pairedTunnel != null) {
|
||||
replySKM = ctx.clientManager().getClientSessionKeyManager(from);
|
||||
if (replySKM == null && cfg.getGarlicReplyKeys() != null) {
|
||||
// no client SKM, fall back to expl.
|
||||
pairedTunnel = null;
|
||||
int fails = pool.getConsecutiveBuildTimeouts();
|
||||
if (fails < MAX_CONSECUTIVE_CLIENT_BUILD_FAILS) {
|
||||
Hash from = settings.getDestination();
|
||||
if (isInbound) {
|
||||
pairedTunnel = mgr.selectOutboundTunnel(from, farEnd);
|
||||
} else {
|
||||
pairedTunnel = mgr.selectInboundTunnel(from, farEnd);
|
||||
if (pairedTunnel != null) {
|
||||
replySKM = ctx.clientManager().getClientSessionKeyManager(from);
|
||||
if (replySKM == null && cfg.getGarlicReplyKeys() != null) {
|
||||
// no client SKM, fall back to expl.
|
||||
pairedTunnel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Force using an expl. tunnel as the paired tunnel
|
||||
// This prevents us from being stuck for 10 minutes if the client pool
|
||||
// has exactly one tunnel in the other direction and it's bad
|
||||
if (log.shouldWarn())
|
||||
log.warn(fails + " consecutive build timeouts for " + cfg + ", using exploratory tunnel");
|
||||
}
|
||||
if (pairedTunnel == null) {
|
||||
if (isInbound) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
@@ -47,6 +48,7 @@ public class TunnelPool {
|
||||
private long _lastLifetimeProcessed;
|
||||
private final String _rateName;
|
||||
private final long _firstInstalled;
|
||||
private final AtomicInteger _consecutiveBuildTimeouts = new AtomicInteger();
|
||||
|
||||
private static final int TUNNEL_LIFETIME = 10*60*1000;
|
||||
/** if less than one success in this many, reduce quantity (exploratory only) */
|
||||
@@ -127,6 +129,7 @@ public class TunnelPool {
|
||||
synchronized (_inProgress) {
|
||||
_inProgress.clear();
|
||||
}
|
||||
_consecutiveBuildTimeouts.set(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1200,6 +1203,7 @@ public class TunnelPool {
|
||||
|
||||
/**
|
||||
* Remove from the _inprogress list and call addTunnel() if result is SUCCESS.
|
||||
* Updates consecutive build timeout count.
|
||||
*
|
||||
* @since 0.9.53 added result parameter
|
||||
*/
|
||||
@@ -1213,15 +1217,18 @@ public class TunnelPool {
|
||||
|
||||
switch (result) {
|
||||
case SUCCESS:
|
||||
_consecutiveBuildTimeouts.set(0);
|
||||
addTunnel(cfg);
|
||||
break;
|
||||
|
||||
case REJECT:
|
||||
case BAD_RESPONSE:
|
||||
case DUP_ID:
|
||||
_consecutiveBuildTimeouts.set(0);
|
||||
break;
|
||||
|
||||
case TIMEOUT:
|
||||
_consecutiveBuildTimeouts.incrementAndGet();
|
||||
break;
|
||||
|
||||
case OTHER_FAILURE:
|
||||
@@ -1230,6 +1237,13 @@ public class TunnelPool {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.53
|
||||
*/
|
||||
int getConsecutiveBuildTimeouts() {
|
||||
return _consecutiveBuildTimeouts.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (_settings.isExploratory()) {
|
||||
|
||||
Reference in New Issue
Block a user