From 772d0beac3db580e3b80b0843c0239b6b3adefc9 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Thu, 23 Apr 2015 15:34:24 +0000
Subject: [PATCH] Streaming: Don't wait too long to send a dup ACK, so the
 other side isn't stuck forever at a window size of 1. Cleanups, log tweaks,
 javadocs

---
 .../i2p/client/streaming/impl/ConnectionOptions.java   | 10 +++++++++-
 .../client/streaming/impl/ConnectionPacketHandler.java |  7 +++++--
 .../net/i2p/client/streaming/impl/PacketHandler.java   |  4 ++--
 3 files changed, 16 insertions(+), 5 deletions(-)

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 b6e1bc3657..84a94a3e7b 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
@@ -546,7 +546,11 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
      * @return round trip time estimate in ms
      */
     public synchronized int getRTT() { return _rtt; }
-    public void setRTT(int ms) { 
+
+    /**
+     *  not public, use updateRTT()
+     */
+    private void setRTT(int ms) { 
         synchronized (_trend) {
             _trend[0] = _trend[1];
             _trend[1] = _trend[2];
@@ -569,6 +573,7 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
 
     /** used in TCB @since 0.9.8 */
     synchronized int getRTTDev() { return _rttDev; }
+
     private synchronized void setRTTDev(int rttDev) { _rttDev = rttDev; }
     
     /** 
@@ -619,6 +624,9 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
         }
     }
     
+    /**
+     *  @param measuredValue must be positive
+     */
     public synchronized void updateRTT(int measuredValue) {
         switch(_initState) {
         case INIT:
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionPacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionPacketHandler.java
index 998ede4a3c..f907c308ca 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionPacketHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionPacketHandler.java
@@ -194,7 +194,10 @@ class ConnectionPacketHandler {
                     _log.info(String.format("%s congestion.. dup packet %s ackDelay %d lastSend %s ago",
                                     con, packet, ackDelay, DataHelper.formatDuration(now - lastSendTime)));
                 
-                final long nextSendTime = lastSendTime + ackDelay;
+                // If this is longer than his RTO, he will always retransmit, and
+                // will be stuck at a window size of 1 forever. So we take the minimum
+                // of the ackDelay and half our estimated RTT to be sure.
+                final long nextSendTime = lastSendTime + Math.min(ackDelay, con.getOptions().getRTT() / 2);
                 if (nextSendTime <= now) {
                     if (_log.shouldLog(Log.DEBUG)) 
                         _log.debug("immediate ack");
@@ -203,7 +206,7 @@ class ConnectionPacketHandler {
                 } else {
                     final long delay = nextSendTime - now;
                     if (_log.shouldLog(Log.DEBUG)) 
-                        _log.debug("scheduling ack in "+delay);
+                        _log.debug("scheduling ack in " + delay);
                     _context.simpleTimer2().addEvent(new AckDup(con), delay);
                 }
 
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketHandler.java
index 1eb63a663f..500e62d565 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketHandler.java
@@ -114,7 +114,7 @@ class PacketHandler {
     
     private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss.SSS");
 
-    /** logs to System.out, and router log at debug level */
+    /** logs to router log at debug level */
     void displayPacket(Packet packet, String prefix, String suffix) {
         StringBuilder buf = new StringBuilder(256);
         synchronized (_fmt) {
@@ -125,7 +125,7 @@ class PacketHandler {
         if (suffix != null)
             buf.append(" ").append(suffix);
         String str = buf.toString();
-        System.out.println(str);
+        //System.out.println(str);
         _log.debug(str);
     }
     
-- 
GitLab