* Streaming: Limit amount of slow-start exponential growth

This commit is contained in:
zzz
2012-08-27 20:36:24 +00:00
parent 9099937119
commit f8bc6f8612
3 changed files with 25 additions and 8 deletions

View File

@ -100,6 +100,8 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
private static final boolean DEFAULT_ANSWER_PINGS = true;
private static final int DEFAULT_INACTIVITY_TIMEOUT = 90*1000;
private static final int DEFAULT_INACTIVITY_ACTION = INACTIVITY_ACTION_SEND;
private static final int DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR = 1;
private static final int DEFAULT_SLOW_START_GROWTH_RATE_FACTOR = 1;
/**
@ -327,8 +329,10 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
setInactivityTimeout(getInt(opts, PROP_INACTIVITY_TIMEOUT, DEFAULT_INACTIVITY_TIMEOUT));
setInactivityAction(getInt(opts, PROP_INACTIVITY_ACTION, DEFAULT_INACTIVITY_ACTION));
setInboundBufferSize(getMaxMessageSize() * (Connection.MAX_WINDOW_SIZE + 2));
setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR, 1));
setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR, 1));
setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR,
DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR));
setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR,
DEFAULT_SLOW_START_GROWTH_RATE_FACTOR));
// overrides default in super()
setConnectTimeout(getInt(opts, PROP_CONNECT_TIMEOUT, Connection.DISCONNECT_TIMEOUT));
setAnswerPings(getBool(opts, PROP_ANSWER_PINGS, DEFAULT_ANSWER_PINGS));
@ -378,9 +382,11 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
setInactivityAction(getInt(opts, PROP_INACTIVITY_ACTION, DEFAULT_INACTIVITY_ACTION));
setInboundBufferSize(getMaxMessageSize() * (Connection.MAX_WINDOW_SIZE + 2));
if (opts.contains(PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR))
setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR, 2));
setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR,
DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR));
if (opts.contains(PROP_SLOW_START_GROWTH_RATE_FACTOR))
setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR, 2));
setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR,
DEFAULT_SLOW_START_GROWTH_RATE_FACTOR));
if (opts.containsKey(PROP_CONNECT_TIMEOUT))
// wow 5 minutes!!! FIXME!!
// overrides default in super()

View File

@ -23,6 +23,8 @@ import net.i2p.util.SimpleTimer;
class ConnectionPacketHandler {
private final I2PAppContext _context;
private final Log _log;
public static final int MAX_SLOW_START_WINDOW = 24;
public ConnectionPacketHandler(I2PAppContext context) {
_context = context;
@ -367,9 +369,16 @@ class ConnectionPacketHandler {
// grow acked/N times (where N = the slow start factor)
// always grow at least 1
int factor = con.getOptions().getSlowStartGrowthRateFactor();
if (factor <= 1)
newWindowSize += acked;
else if (acked < factor)
if (factor <= 1) {
// above a certain point, don't grow exponentially
// as it often leads to a big packet loss (30-50) all at once that
// takes quite a while (a minute or more) to recover from,
// especially if crypto tags are lost
if (newWindowSize >= MAX_SLOW_START_WINDOW)
newWindowSize++;
else
newWindowSize = Math.min(MAX_SLOW_START_WINDOW, newWindowSize + acked);
} else if (acked < factor)
newWindowSize++;
else
newWindowSize += acked / factor;

View File

@ -31,7 +31,7 @@ class TCBShare {
private static final double RTT_DAMPENING = 0.75;
private static final double WDW_DAMPENING = 0.75;
private static final int MAX_RTT = ((int) Connection.MAX_RESEND_DELAY) / 2;
private static final int MAX_WINDOW_SIZE = Connection.MAX_WINDOW_SIZE / 4;
private static final int MAX_WINDOW_SIZE = ConnectionPacketHandler.MAX_SLOW_START_WINDOW;
public TCBShare(I2PAppContext ctx, SimpleTimer2 timer) {
_context = ctx;
@ -45,6 +45,7 @@ class TCBShare {
_cleaner.cancel();
}
/** retrieve from cache */
public void updateOptsFromShare(Connection con) {
Destination dest = con.getRemotePeer();
if (dest == null)
@ -65,6 +66,7 @@ class TCBShare {
opts.setWindowSize(e.getWindowSize());
}
/** store to cache */
public void updateShareOpts(Connection con) {
Destination dest = con.getRemotePeer();
if (dest == null)