From e151ef74e10a8de1f8690300cf8a8d7f24a8a0fb Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Mon, 16 Feb 2009 19:42:28 +0000
Subject: [PATCH]     * Streaming lib: Plug timer leak, don't send keepalives  
     after close, don't disconnect hard after close

---
 .../net/i2p/client/streaming/Connection.java  | 25 +++++++++++++------
 .../client/streaming/ConnectionHandler.java   |  3 ++-
 .../src/net/i2p/client/streaming/Packet.java  |  2 ++
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
index 3beed8c8f..6b99fdc00 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
@@ -839,6 +839,8 @@ public class Connection {
             setFuzz(5*1000); // sloppy timer, don't reschedule unless at least 5s later
         }
         public void timeReached() {
+            if (_log.shouldLog(Log.DEBUG))
+                _log.debug("Fire inactivity timer on " + Connection.this.toString());
             // uh, nothing more to do...
             if (!_connected) {
                 if (_log.shouldLog(Log.DEBUG)) _log.debug("Inactivity timeout reached, but we are already closed");
@@ -864,6 +866,9 @@ public class Connection {
             // if one of us can't talk...
             // No - not true - data and acks are still going back and forth.
             // Prevent zombie connections by keeping the inactivity timer.
+            // Not sure why... receiving a close but never sending one?
+            // If so we can probably re-enable this for _closeSentOn.
+            // For further investigation...
             //if ( (_closeSentOn > 0) || (_closeReceivedOn > 0) ) {
             //    if (_log.shouldLog(Log.DEBUG)) _log.debug("Inactivity timeout reached, but we are closing");
             //    return;
@@ -873,15 +878,17 @@ public class Connection {
             
             // bugger it, might as well do the hard work now
             switch (_options.getInactivityAction()) {
-                case ConnectionOptions.INACTIVITY_ACTION_SEND:
-                    if (_log.shouldLog(Log.WARN))
-                        _log.warn("Sending some data due to inactivity");
-                    _receiver.send(null, 0, 0, true);
-                    break;
                 case ConnectionOptions.INACTIVITY_ACTION_NOOP:
                     if (_log.shouldLog(Log.WARN))
                         _log.warn("Inactivity timer expired, but we aint doin' shit");
                     break;
+                case ConnectionOptions.INACTIVITY_ACTION_SEND:
+                    if (_closeSentOn <= 0 && _closeReceivedOn <= 0) {
+                        if (_log.shouldLog(Log.WARN))
+                            _log.warn("Sending some data due to inactivity");
+                        _receiver.send(null, 0, 0, true);
+                        break;
+                    } // else fall through
                 case ConnectionOptions.INACTIVITY_ACTION_DISCONNECT:
                     // fall through
                 default:
@@ -897,7 +904,9 @@ public class Connection {
                     
                     _inputStream.streamErrorOccurred(new IOException("Inactivity timeout"));
                     _outputStream.streamErrorOccurred(new IOException("Inactivity timeout"));
-                    disconnect(false);
+                    // Clean disconnect if we have already scheduled one
+                    // (generally because we already sent a close)
+                    disconnect(_disconnectScheduledOn >= 0);
                     break;
             }
         }
@@ -1046,7 +1055,9 @@ public class Connection {
             if (_packet.getAckTime() > 0) 
                 return false;
             
-            if (_resetSent || _resetReceived) {
+            if (_resetSent || _resetReceived || !_connected) {
+                if(_log.shouldLog(Log.WARN) && (!_resetSent) && (!_resetReceived))
+                     _log.warn("??? no resets but not connected: " + _packet); // don't think this is possible
                 _packet.cancelled();
                 return false;
             }
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
index d468372ec..b96eaea63 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
@@ -71,7 +71,8 @@ class ConnectionHandler {
         if (!_active) {
             if (_log.shouldLog(Log.WARN))
                 _log.warn("Dropping new SYN request, as we're not listening");
-            sendReset(packet);
+            if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE))
+                sendReset(packet);
             return;
         }
         if (_log.shouldLog(Log.DEBUG))
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Packet.java b/apps/streaming/java/src/net/i2p/client/streaming/Packet.java
index 9d4177256..8fc0f02fa 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/Packet.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/Packet.java
@@ -41,6 +41,8 @@ import net.i2p.util.Log;
  * <li>{@link #FLAG_DELAY_REQUESTED}: 2 byte integer</li>
  * <li>{@link #FLAG_MAX_PACKET_SIZE_INCLUDED}: 2 byte integer</li>
  * <li>{@link #FLAG_PROFILE_INTERACTIVE}: no option data</li>
+ * <li>{@link #FLAG_ECHO}: no option data</li>
+ * <li>{@link #FLAG_NO_ACK}: no option data</li>
  * </ol>
  *
  * <p>If the signature is included, it uses the Destination's DSA key 
-- 
GitLab