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
|
2011-10-25 zzz
|
||||||
* BloomSHA1, DecayingBloomFilter:
|
* BloomSHA1, DecayingBloomFilter:
|
||||||
- Refactor for concurrent, at some small risk of false negatives
|
- Refactor for concurrent, at some small risk of false negatives
|
||||||
|
@@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 1;
|
public final static long BUILD = 2;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
@@ -74,4 +74,16 @@ public interface TunnelInfo {
|
|||||||
public long getVerifiedBytesTransferred();
|
public long getVerifiedBytesTransferred();
|
||||||
/** we know for sure that the given number of bytes were sent down the tunnel fully */
|
/** we know for sure that the given number of bytes were sent down the tunnel fully */
|
||||||
public void incrementVerifiedBytesTransferred(int numBytes);
|
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 volatile long _verifiedBytesTransferred;
|
||||||
private boolean _failed;
|
private boolean _failed;
|
||||||
private int _failures;
|
private int _failures;
|
||||||
|
private boolean _reused;
|
||||||
|
|
||||||
public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound) {
|
public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound) {
|
||||||
this(ctx, length, isInbound, null);
|
this(ctx, length, isInbound, null);
|
||||||
@@ -190,6 +191,18 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
_failures = 0;
|
_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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
// H0:1235-->H1:2345-->H2:2345
|
// H0:1235-->H1:2345-->H2:2345
|
||||||
|
@@ -292,7 +292,7 @@ public class TunnelPool {
|
|||||||
* Used to prevent a zillion of them
|
* Used to prevent a zillion of them
|
||||||
*/
|
*/
|
||||||
boolean needFallback() {
|
boolean needFallback() {
|
||||||
int needed = _settings.getTotalQuantity();
|
int needed = getAdjustedTotalQuantity();
|
||||||
int fallbacks = 0;
|
int fallbacks = 0;
|
||||||
synchronized (_tunnels) {
|
synchronized (_tunnels) {
|
||||||
for (int i = 0; i < _tunnels.size(); i++) {
|
for (int i = 0; i < _tunnels.size(); i++) {
|
||||||
@@ -304,6 +304,45 @@ public class TunnelPool {
|
|||||||
return true;
|
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 */
|
/** list of tunnelInfo instances of tunnels currently being built */
|
||||||
public List listPending() { synchronized (_inProgress) { return new ArrayList(_inProgress); } }
|
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() {
|
void refreshLeaseSet() {
|
||||||
if (_settings.isInbound() && (_settings.getDestination() != null) ) {
|
if (_settings.isInbound() && (_settings.getDestination() != null) ) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
@@ -495,7 +534,7 @@ public class TunnelPool {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
boolean buildFallback() {
|
boolean buildFallback() {
|
||||||
int quantity = _settings.getTotalQuantity();
|
int quantity = getAdjustedTotalQuantity();
|
||||||
int usable = 0;
|
int usable = 0;
|
||||||
synchronized (_tunnels) {
|
synchronized (_tunnels) {
|
||||||
usable = _tunnels.size();
|
usable = _tunnels.size();
|
||||||
@@ -678,7 +717,7 @@ public class TunnelPool {
|
|||||||
if (!isAlive()) {
|
if (!isAlive()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int wanted = getSettings().getTotalQuantity();
|
int wanted = getAdjustedTotalQuantity();
|
||||||
|
|
||||||
boolean allowZeroHop = ((getSettings().getLength() + getSettings().getLengthVariance()) <= 0);
|
boolean allowZeroHop = ((getSettings().getLength() + getSettings().getLengthVariance()) <= 0);
|
||||||
|
|
||||||
@@ -965,10 +1004,30 @@ public class TunnelPool {
|
|||||||
TunnelPoolSettings settings = getSettings();
|
TunnelPoolSettings settings = getSettings();
|
||||||
// peers for new tunnel, including us, ENDPOINT FIRST
|
// peers for new tunnel, including us, ENDPOINT FIRST
|
||||||
List<Hash> peers = null;
|
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) {
|
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()) ) {
|
if ( (peers == null) || (peers.isEmpty()) ) {
|
||||||
// no peers to build the tunnel with, and
|
// no peers to build the tunnel with, and
|
||||||
|
Reference in New Issue
Block a user