2004-12-14 jrandom

* Reenable the probabalistic drop on the TCP queues to deal with good old
      fashioned bandwidth limiting.  However, by default the probability is
      rigged to reserve 0% of the queue free - meaning we just aggressively
      fail messages in the queue if we're transferring too slowly.  That
      reservation factor can be increased with 'tcp.queueFreeFactor=0.25'
      (or whatever) and the drop code can be disabled with the parameter
      'tcp.dropProbabalistically=false'.
    * Still penalize a peer on tunnel failure, but don't immediately drop
      their capacity to 0.
    * More aggressively ACK duplicates
    * Randomize the timestamper period
    * Display the clock skew on the connection logs when a peer sends it.
    * Allow the timestamper to fix skews of up to 10 minutes
    * Logging
This commit is contained in:
jrandom
2004-12-14 11:54:39 +00:00
committed by zzz
parent 9e16bc203a
commit b2f183fc17
11 changed files with 78 additions and 27 deletions

View File

@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.109 $ $Date: 2004/12/11 04:26:24 $";
public final static String ID = "$Revision: 1.110 $ $Date: 2004/12/13 08:45:52 $";
public final static String VERSION = "0.4.2.3";
public final static long BUILD = 3;
public final static long BUILD = 4;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@@ -95,10 +95,10 @@ public class CapacityCalculator extends Calculator {
if (curFailed != null)
failed = curFailed.getCurrentEventCount() + curFailed.getLastEventCount();
if (failed > 0) {
if ( (period <= 10*60*1000) && (curFailed.getCurrentEventCount() > 0) )
return 0.0d; // their tunnels have failed in the last 0-10 minutes
else
val -= failed * stretch;
//if ( (period <= 10*60*1000) && (curFailed.getCurrentEventCount() > 0) )
// return 0.0d; // their tunnels have failed in the last 0-10 minutes
//else
val -= failed * stretch;
}
if ( (period <= 10*60*1000) && (curRejected.getCurrentEventCount() + curRejected.getLastEventCount() > 0) ) {

View File

@@ -177,6 +177,8 @@ public class TransportManager implements TransportEventListener {
}
private List orderBids(HashSet bids, OutNetMessage msg) {
if (bids.size() <= 1)
return new ArrayList(bids);
// db messages should go as fast as possible, while the others
// should use as little bandwidth as possible.
I2NPMessage message = msg.getMessage();

View File

@@ -410,12 +410,13 @@ public class ConnectionBuilder {
RouterInfo peer = new RouterInfo();
peer.readBytes(_rawIn);
int status = (int)_rawIn.read() & 0xFF;
boolean ok = validateStatus(status);
if (!ok) return false;
Properties props = DataHelper.readProperties(_rawIn);
// ignore these now
boolean ok = validateStatus(status, props);
if (!ok) return false;
Hash readHash = new Hash();
readHash.readBytes(_rawIn);
@@ -564,12 +565,13 @@ public class ConnectionBuilder {
RouterInfo peer = new RouterInfo();
peer.readBytes(_rawIn);
int status = (int)_rawIn.read() & 0xFF;
boolean ok = validateStatus(status);
if (!ok) return false;
Properties props = DataHelper.readProperties(_rawIn);
// ignore these now
boolean ok = validateStatus(status, props);
if (!ok) return false;
Signature sig = new Signature();
sig.readBytes(_rawIn);
@@ -620,7 +622,7 @@ public class ConnectionBuilder {
*
* @return true if ok, false if fail()ed
*/
private boolean validateStatus(int status) {
private boolean validateStatus(int status, Properties props) {
switch (status) {
case -1: // EOF
fail("Error reading the status from "
@@ -636,7 +638,7 @@ public class ConnectionBuilder {
case ConnectionHandler.STATUS_SKEWED:
fail("According to "
+ _target.getIdentity().calculateHash().toBase64().substring(0,6)
+ ", our clock is off");
+ ", our clock is off (they think it is " + props.getProperty("SKEW") + ")");
return false;
case ConnectionHandler.STATUS_SIGNATURE_FAILED: // (only for new sessions)
fail("Signature failure talking to "

View File

@@ -185,7 +185,7 @@ public class TCPConnection {
}
private boolean shouldDropProbabalistically() {
return Boolean.valueOf(_context.getProperty("tcp.dropProbabalistically", "false")).booleanValue();
return Boolean.valueOf(_context.getProperty("tcp.dropProbabalistically", "true")).booleanValue();
}
/**
@@ -210,12 +210,34 @@ public class TCPConnection {
long sendRate = getSendRate();
long bytesSendableUntilFirstExpire = sendRate * (earliestExpiration - _context.clock().now()) / 1000;
// try to keep the queue less than half full
long excessQueued = bytesQueued - (bytesSendableUntilFirstExpire/2);
// pretend that instead of being able to push bytesSendableUntilFirstExpire,
// that we can only push a fraction of that amount, causing us to probabalistically
// drop more than is necessary (leaving a fraction of the queue 'free' for bursts)
long excessQueued = (long)(bytesQueued - ((double)bytesSendableUntilFirstExpire * (1.0-getQueueFreeFactor())));
if ( (excessQueued > 0) && (_pendingMessages.size() > 1) && (_transport != null) )
locked_probabalisticDrop(excessQueued);
}
/**
* by default, try to keep the queue completely full, but this can be overridden
* with the property 'tcp.queueFreeFactor'
*
*/
public static final double DEFAULT_QUEUE_FREE_FACTOR = 0.0;
private double getQueueFreeFactor() {
String factor = _context.getProperty("tcp.queueFreeFactor");
if (factor != null) {
try {
return Double.parseDouble(factor);
} catch (NumberFormatException nfe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid tcp.queueFreeFactor [" + factor + "]", nfe);
}
}
return DEFAULT_QUEUE_FREE_FACTOR;
}
/** how many Bps we are sending data to the peer (or 2KBps if we don't know) */
public long getSendRate() {
if (_sendRate == null) return 2*1024;