* Tunnels:

- Restore and implement lengthOverride()
    - Adjust quantity override
This commit is contained in:
zzz
2011-10-31 21:13:01 +00:00
parent a3a1110b41
commit bf0947ee82
5 changed files with 89 additions and 23 deletions

View File

@@ -5,7 +5,11 @@
- Don't exceed high cap limit between reorgs
- Reduce max reorg cycle time
- Reduce new bonus values
- Fix rare NSEE thx sponge
* SSU: Increase threshold for incremented cost
* Tunnels:
- Restore and implement lengthOverride()
- Adjust quantity override
2011-10-29 zzz
* BuildHandler: Add router.buildHandlerThreads config setting

View File

@@ -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 = 4;
public final static long BUILD = 5;
/** for example "-test" */
public final static String EXTRA = "";

View File

@@ -19,7 +19,7 @@ public class TunnelPoolSettings {
//private int _duration;
private int _length;
private int _lengthVariance;
//private int _lengthOverride;
private int _lengthOverride;
private boolean _isInbound;
private boolean _isExploratory;
private boolean _allowZeroHop;
@@ -60,6 +60,7 @@ public class TunnelPoolSettings {
//_duration = DEFAULT_DURATION;
_length = DEFAULT_LENGTH;
_lengthVariance = DEFAULT_LENGTH_VARIANCE;
_lengthOverride = -1;
_allowZeroHop = DEFAULT_ALLOW_ZERO_HOP;
_IPRestriction = DEFAULT_IP_RESTRICTION;
_unknownOptions = new Properties();
@@ -87,8 +88,16 @@ public class TunnelPoolSettings {
// public int getRebuildPeriod() { return _rebuildPeriod; }
// public void setRebuildPeriod(int periodMs) { _rebuildPeriod = periodMs; }
/** how many remote hops should be in the tunnel */
/**
* How many remote hops should be in the tunnel NOT including us
* @return 0 to 7
*/
public int getLength() { return _length; }
/**
* How many remote hops should be in the tunnel NOT including us
* @param length 0 to 7 (not enforced here)
*/
public void setLength(int length) { _length = length; }
/** if there are no tunnels to build with, will this pool allow 0 hop tunnels? */
@@ -104,10 +113,20 @@ public class TunnelPoolSettings {
public int getLengthVariance() { return _lengthVariance; }
public void setLengthVariance(int variance) { _lengthVariance = variance; }
/* UNUSED Set to a nonzero value to override the length setting */
//public int getLengthOverride() { return _lengthOverride; }
//public void setLengthOverride(int variance) { _lengthOverride = variance; }
/**
* A temporary length to be used due to network conditions.
* If less than zero, the standard length should be used.
* Unused until 0.8.11
*/
public int getLengthOverride() { return _lengthOverride; }
/**
* A temporary length to be used due to network conditions.
* If less than zero, the standard length will be used.
* Unused until 0.8.11
*/
public void setLengthOverride(int length) { _lengthOverride = length; }
/** is this an inbound tunnel? */
public boolean isInbound() { return _isInbound; }
public void setIsInbound(boolean isInbound) { _isInbound = isInbound; }

View File

@@ -47,11 +47,10 @@ public abstract class TunnelPeerSelector {
*/
protected int getLength(RouterContext ctx, TunnelPoolSettings settings) {
int length = settings.getLength();
//int override = settings.getLengthOverride();
//if (override != 0)
// length = override;
//else if (settings.getLengthVariance() != 0) {
if (settings.getLengthVariance() != 0) {
int override = settings.getLengthOverride();
if (override >= 0) {
length = override;
} else if (settings.getLengthVariance() != 0) {
int skew = settings.getLengthVariance();
if (skew > 0)
length += ctx.random().nextInt(skew+1);

View File

@@ -43,7 +43,12 @@ public class TunnelPool {
private long _lastRateUpdate;
private long _lastLifetimeProcessed;
private final String _rateName;
private static final int TUNNEL_LIFETIME = 10*60*1000;
/** if less than one success in this many, reduce quantity (exploratory only) */
private static final int BUILD_TRIES_QUANTITY_OVERRIDE = 12;
/** if less than one success in this many, reduce length (exploratory only) */
private static final int BUILD_TRIES_LENGTH_OVERRIDE = 18;
TunnelPool(RouterContext ctx, TunnelPoolManager mgr, TunnelPoolSettings settings, TunnelPeerSelector sel) {
_context = ctx;
@@ -322,19 +327,16 @@ public class TunnelPool {
RateStat r = _context.statManager().getRate("tunnel.buildExploratoryReject");
RateStat s = _context.statManager().getRate("tunnel.buildExploratorySuccess");
if (e != null && r != null && s != null) {
// 60 min was too long - is 10 min too short?
// By not adding in previous period, this gives us a burst every
// 10 min - is that good or bad?
Rate er = e.getRate(10*60*1000);
Rate rr = r.getRate(10*60*1000);
Rate sr = s.getRate(10*60*1000);
if (er != null && rr != null && sr != null) {
long ec = er.getCurrentEventCount();
long rc = rr.getCurrentEventCount();
long sc = sr.getCurrentEventCount();
long ec = er.getCurrentEventCount() + er.getLastEventCount();
long rc = rr.getCurrentEventCount() + rr.getLastEventCount();
long sc = sr.getCurrentEventCount() + sr.getLastEventCount();
long tot = ec + rc + sc;
if (tot >= 10) {
if (1000 * sc / tot <= 1000 / 10)
if (tot >= BUILD_TRIES_QUANTITY_OVERRIDE) {
if (1000 * sc / tot <= 1000 / BUILD_TRIES_QUANTITY_OVERRIDE)
rv--;
}
}
@@ -343,6 +345,43 @@ public class TunnelPool {
return rv;
}
/**
* Shorten the length when under extreme stress, else clear the override.
* We only do this for exploratory tunnels, since we have to build a fallback
* if we run out. It's much better to have a shorter tunnel than a fallback.
*
* @since 0.8.11
*/
private void setLengthOverride() {
if (!_settings.isExploratory())
return;
int len = _settings.getLength();
if (len > 1) {
RateStat e = _context.statManager().getRate("tunnel.buildExploratoryExpire");
RateStat r = _context.statManager().getRate("tunnel.buildExploratoryReject");
RateStat s = _context.statManager().getRate("tunnel.buildExploratorySuccess");
if (e != null && r != null && s != null) {
Rate er = e.getRate(10*60*1000);
Rate rr = r.getRate(10*60*1000);
Rate sr = s.getRate(10*60*1000);
if (er != null && rr != null && sr != null) {
long ec = er.getCurrentEventCount() + er.getLastEventCount();
long rc = rr.getCurrentEventCount() + rr.getLastEventCount();
long sc = sr.getCurrentEventCount() + sr.getLastEventCount();
long tot = ec + rc + sc;
if (tot >= BUILD_TRIES_LENGTH_OVERRIDE) {
if (1000 * sc / tot <= 1000 / BUILD_TRIES_LENGTH_OVERRIDE)
_settings.setLengthOverride(len - 1);
return;
}
}
}
}
// disable
_settings.setLengthOverride(-1);
}
/** list of tunnelInfo instances of tunnels currently being built */
public List listPending() { synchronized (_inProgress) { return new ArrayList(_inProgress); } }
@@ -1008,15 +1047,18 @@ public class TunnelPool {
long expiration = now + TunnelPoolSettings.DEFAULT_DURATION;
if (!forceZeroHop) {
int len = settings.getLength();
int len = settings.getLengthOverride();
if (len < 0)
len = settings.getLength();
if (len > 0 && _context.random().nextBoolean()) {
// look for a tunnel to reuse, if the right length and expiring soon
// ignore variance for now.
len++; // us
synchronized (_tunnels) {
for (TunnelInfo ti : _tunnels) {
if (ti.getLength() == len && ti.getExpiration() < now + 3*60*1000 && !ti.wasReused()) {
if (ti.getLength() >= len && ti.getExpiration() < now + 3*60*1000 && !ti.wasReused()) {
ti.setReused();
len = ti.getLength();
peers = new ArrayList(len);
// peers list is ordered endpoint first, but cfg.getPeer() is ordered gateway first
for (int i = len - 1; i >= 0; i--) {
@@ -1026,8 +1068,10 @@ public class TunnelPool {
}
}
}
if (peers == null)
if (peers == null) {
setLengthOverride();
peers = _peerSelector.selectPeers(_context, settings);
}
if ( (peers == null) || (peers.isEmpty()) ) {
// no peers to build the tunnel with, and