diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/Connection.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/Connection.java index efc3717f3..474e89bc3 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/Connection.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/Connection.java @@ -1495,8 +1495,12 @@ class Connection { if (newWindowSize <= 0) newWindowSize = 1; - // setRTT has its own ceiling - //getOptions().setRTT(getOptions().getRTT() + 10*1000); + // The timeout for _this_ packet will be doubled below, but we also + // need to double the RTO for the _next_ packets. + // See RFC 6298 section 5 item 5.5 + // This prevents being stuck at a window size of 1, retransmitting every packet, + // never updating the RTT or RTO. + getOptions().doubleRTO(); getOptions().setWindowSize(newWindowSize); if (_log.shouldLog(Log.INFO)) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionOptions.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionOptions.java index 6979f3abe..aab7eb5dc 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionOptions.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionOptions.java @@ -607,6 +607,19 @@ class ConnectionOptions extends I2PSocketOptionsImpl { _rto = (int)Connection.MAX_RESEND_DELAY; } + /** + * Double the RTO (after congestion). + * See RFC 6298 section 5 item 5.5 + * + * @since 0.9.33 + */ + synchronized void doubleRTO() { + // we don't need to switch on _initState, _rto is set in constructor + _rto *= 2; + if (_rto > Connection.MAX_RESEND_DELAY) + _rto = (int)Connection.MAX_RESEND_DELAY; + } + /** * If we have 3 consecutive rtt increases, we are trending upwards (1), or if we have * 3 consecutive rtt decreases, we are trending downwards (-1), else we're stable.