Tunnels: Reimplement, re-enable using tunnel builds as a tunnel test,

but without ooming
disabled in 2009 because of ooms
This commit is contained in:
zzz
2022-01-25 09:10:00 -05:00
parent 21f5f7c148
commit b9f53069bb
3 changed files with 85 additions and 1 deletions

View File

@@ -240,7 +240,14 @@ abstract class BuildRequestor {
return false;
}
//cfg.setPairedTunnel(pairedTunnel);
// store the ID of the paired GW so we can credit/blame the paired tunnel,
// see TunnelPool.updatePairedProfile()
if (pairedTunnel.getLength() > 1) {
TunnelId gw = pairedTunnel.isInbound() ?
pairedTunnel.getReceiveTunnelId(0) :
pairedTunnel.getSendTunnelId(0);
cfg.setPairedGW(gw);
}
//long beforeDispatch = System.currentTimeMillis();
if (cfg.isInbound()) {

View File

@@ -3,6 +3,7 @@ package net.i2p.router.tunnel.pool;
import java.util.Properties;
import net.i2p.data.Hash;
import net.i2p.data.TunnelId;
import net.i2p.router.RouterContext;
import net.i2p.router.tunnel.TunnelCreatorConfig;
@@ -11,6 +12,8 @@ import net.i2p.router.tunnel.TunnelCreatorConfig;
*/
public class PooledTunnelCreatorConfig extends TunnelCreatorConfig {
private final TunnelPool _pool;
// we don't store the config, that leads to OOM
private TunnelId _pairedGW;
/**
* Creates a new instance of PooledTunnelCreatorConfig
@@ -73,4 +76,22 @@ public class PooledTunnelCreatorConfig extends TunnelCreatorConfig {
* @return non-null
*/
public TunnelPool getTunnelPool() { return _pool; }
/**
* The ID of the gateway of the paired tunnel used to send/receive the build request
*
* @param gw for paired inbound, the GW rcv tunnel ID; for paired outbound, the GW send tunnel ID.
* @since 0.9.53
*/
public void setPairedGW(TunnelId gw) { _pairedGW = gw; }
/**
* The ID of the gateway of the paired tunnel used to send/receive the build request
*
* @return for paired inbound, the GW rcv tunnel ID; for paired outbound, the GW send tunnel ID.
* null if not previously set
* @since 0.9.53
*/
public TunnelId getPairedGW() { return _pairedGW; }
}

View File

@@ -264,6 +264,9 @@ public class TunnelPool {
return rv;
}
/**
* @param gatewayId for inbound, the GW rcv tunnel ID; for outbound, the GW send tunnel ID.
*/
public TunnelInfo getTunnel(TunnelId gatewayId) {
synchronized (_tunnels) {
for (int i = 0; i < _tunnels.size(); i++) {
@@ -1219,16 +1222,19 @@ public class TunnelPool {
case SUCCESS:
_consecutiveBuildTimeouts.set(0);
addTunnel(cfg);
updatePairedProfile(cfg, true);
break;
case REJECT:
case BAD_RESPONSE:
case DUP_ID:
_consecutiveBuildTimeouts.set(0);
updatePairedProfile(cfg, true);
break;
case TIMEOUT:
_consecutiveBuildTimeouts.incrementAndGet();
updatePairedProfile(cfg, false);
break;
case OTHER_FAILURE:
@@ -1244,6 +1250,56 @@ public class TunnelPool {
return _consecutiveBuildTimeouts.get();
}
/**
* Update the paired tunnel profiles by treating the build as a tunnel test
*
* @param cfg the build for this tunnel, to lookup the paired tunnel
* @param success did the paired tunnel pass the message through
* @since 0.9.53
*/
private void updatePairedProfile(PooledTunnelCreatorConfig cfg, boolean success) {
// will be null if paired tunnel is 0-hop
TunnelId pairedGW = cfg.getPairedGW();
if (pairedGW == null)
return;
if (!success) {
// don't blame the paired tunnel for exploratory build failures
if (_settings.isExploratory())
return;
// don't blame the paired tunnel if there might be some other problem
if (getConsecutiveBuildTimeouts() > 3)
return;
}
TunnelPool pool;
PooledTunnelCreatorConfig paired = null;
if (!_settings.isExploratory()) {
Hash dest = _settings.getDestination();
if (_settings.isInbound())
pool = _manager.getOutboundPool(dest);
else
pool = _manager.getInboundPool(dest);
if (pool != null)
paired = (PooledTunnelCreatorConfig) pool.getTunnel(pairedGW);
}
if (paired == null) { // not found or exploratory
if (_settings.isInbound())
pool = _manager.getOutboundExploratoryPool();
else
pool = _manager.getInboundExploratoryPool();
paired = (PooledTunnelCreatorConfig) pool.getTunnel(pairedGW);
}
if (paired != null && paired.getLength() > 1) {
//_log.info("Updating paired cfg, success? " + success + ' ' + paired);
if (success) {
long requestedOn = cfg.getExpiration() - 10*60*1000;
int rtt = (int) (_context.clock().now() - requestedOn);
paired.testSuccessful(rtt);
} else {
paired.tunnelFailed();
}
}
}
@Override
public String toString() {
if (_settings.isExploratory()) {