forked from I2P_Developers/i2p.i2p
* Tunnels:
- Reduce exploratory tunnel quantity if build success rate is very low, but may disable this later - Try rebuilding same tunnel (some of the time)
This commit is contained in:
18
history.txt
18
history.txt
@@ -1,3 +1,21 @@
|
||||
2011-10-28 zzz
|
||||
* BuildHandler: Move inbound request handling to its own thread(s)
|
||||
(ticket #542, see also http://zzz.i2p/topics/996)
|
||||
* CapacityCalculator: Small boost for connected peers, new peers, and
|
||||
same-country peers; deduct for recently-unreachable peers
|
||||
* DecayingBloomFilter: Whups fix NPE from previous checkin if log=INFO
|
||||
* NTCP: Reduce min idle time
|
||||
* SSU:
|
||||
- Increase default max connections again
|
||||
- Reduce min idle time
|
||||
- Separate out introducer pinger from introducer selection
|
||||
so it can be run separately and more often
|
||||
- Only ping introducers if we need them
|
||||
* Tunnels:
|
||||
- Reduce exploratory tunnel quantity if build success rate
|
||||
is very low, but may disable this later
|
||||
- Try rebuilding same tunnel (some of the time)
|
||||
|
||||
2011-10-25 zzz
|
||||
* BloomSHA1, DecayingBloomFilter:
|
||||
- Refactor for concurrent, at some small risk of false negatives
|
||||
|
@@ -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 = 1;
|
||||
public final static long BUILD = 2;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
@@ -74,4 +74,16 @@ public interface TunnelInfo {
|
||||
public long getVerifiedBytesTransferred();
|
||||
/** we know for sure that the given number of bytes were sent down the tunnel fully */
|
||||
public void incrementVerifiedBytesTransferred(int numBytes);
|
||||
|
||||
/**
|
||||
* Did we reuse this tunnel?
|
||||
* @since 0.8.11
|
||||
*/
|
||||
public boolean wasReused();
|
||||
|
||||
/**
|
||||
* Note that we reused this tunnel
|
||||
* @since 0.8.11
|
||||
*/
|
||||
public void setReused();
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
||||
private volatile long _verifiedBytesTransferred;
|
||||
private boolean _failed;
|
||||
private int _failures;
|
||||
private boolean _reused;
|
||||
|
||||
public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound) {
|
||||
this(ctx, length, isInbound, null);
|
||||
@@ -190,6 +191,18 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
||||
_failures = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Did we reuse this tunnel?
|
||||
* @since 0.8.11
|
||||
*/
|
||||
public boolean wasReused() { return _reused; }
|
||||
|
||||
/**
|
||||
* Note that we reused this tunnel
|
||||
* @since 0.8.11
|
||||
*/
|
||||
public void setReused() { _reused = true; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// H0:1235-->H1:2345-->H2:2345
|
||||
|
@@ -292,7 +292,7 @@ public class TunnelPool {
|
||||
* Used to prevent a zillion of them
|
||||
*/
|
||||
boolean needFallback() {
|
||||
int needed = _settings.getTotalQuantity();
|
||||
int needed = getAdjustedTotalQuantity();
|
||||
int fallbacks = 0;
|
||||
synchronized (_tunnels) {
|
||||
for (int i = 0; i < _tunnels.size(); i++) {
|
||||
@@ -304,6 +304,45 @@ public class TunnelPool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return settings.getTotalQuantity, unless this is an exploratory tunnel
|
||||
* AND exploratory build success rate is less than 1/10, AND total settings
|
||||
* is greater than 1. Otherwise subtract 1 to help prevent congestion collapse,
|
||||
* and prevent really unintegrated routers from working too hard.
|
||||
* We only do this for exploratory as different clients could have different
|
||||
* length settings. Although I guess inbound and outbound exploratory
|
||||
* could be different too, and inbound is harder...
|
||||
*
|
||||
* @since 0.8.11
|
||||
*/
|
||||
private int getAdjustedTotalQuantity() {
|
||||
int rv = _settings.getTotalQuantity();
|
||||
if (_settings.isExploratory() && rv > 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) {
|
||||
// 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 tot = ec + rc + sc;
|
||||
if (tot >= 10) {
|
||||
if (1000 * sc / tot <= 1000 / 10)
|
||||
rv--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** list of tunnelInfo instances of tunnels currently being built */
|
||||
public List listPending() { synchronized (_inProgress) { return new ArrayList(_inProgress); } }
|
||||
|
||||
@@ -475,7 +514,7 @@ public class TunnelPool {
|
||||
}
|
||||
}
|
||||
|
||||
/** noop for outbound */
|
||||
/** noop for outbound and exploratory */
|
||||
void refreshLeaseSet() {
|
||||
if (_settings.isInbound() && (_settings.getDestination() != null) ) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@@ -495,7 +534,7 @@ public class TunnelPool {
|
||||
*
|
||||
*/
|
||||
boolean buildFallback() {
|
||||
int quantity = _settings.getTotalQuantity();
|
||||
int quantity = getAdjustedTotalQuantity();
|
||||
int usable = 0;
|
||||
synchronized (_tunnels) {
|
||||
usable = _tunnels.size();
|
||||
@@ -678,7 +717,7 @@ public class TunnelPool {
|
||||
if (!isAlive()) {
|
||||
return 0;
|
||||
}
|
||||
int wanted = getSettings().getTotalQuantity();
|
||||
int wanted = getAdjustedTotalQuantity();
|
||||
|
||||
boolean allowZeroHop = ((getSettings().getLength() + getSettings().getLengthVariance()) <= 0);
|
||||
|
||||
@@ -965,10 +1004,30 @@ public class TunnelPool {
|
||||
TunnelPoolSettings settings = getSettings();
|
||||
// peers for new tunnel, including us, ENDPOINT FIRST
|
||||
List<Hash> peers = null;
|
||||
long expiration = _context.clock().now() + TunnelPoolSettings.DEFAULT_DURATION;
|
||||
long now = _context.clock().now();
|
||||
long expiration = now + TunnelPoolSettings.DEFAULT_DURATION;
|
||||
|
||||
if (!forceZeroHop) {
|
||||
peers = _peerSelector.selectPeers(_context, settings);
|
||||
int 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()) {
|
||||
ti.setReused();
|
||||
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--) {
|
||||
peers.add(ti.getPeer(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (peers == null)
|
||||
peers = _peerSelector.selectPeers(_context, settings);
|
||||
|
||||
if ( (peers == null) || (peers.isEmpty()) ) {
|
||||
// no peers to build the tunnel with, and
|
||||
|
Reference in New Issue
Block a user