From 4291450f3704813a1a1fb2dd98856ef795f0efab Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Thu, 26 Nov 2015 23:30:18 +0000
Subject: [PATCH] make method private fix timeout message add client sink
 pinger

---
 apps/sam/java/src/net/i2p/sam/SAMHandler.java | 10 ++++--
 .../java/src/net/i2p/sam/SAMv3Handler.java    |  2 +-
 .../src/net/i2p/sam/client/SAMStreamSink.java | 34 +++++++++++++++++++
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/apps/sam/java/src/net/i2p/sam/SAMHandler.java b/apps/sam/java/src/net/i2p/sam/SAMHandler.java
index 3a1f4aaa7c..e2bcb84fb7 100644
--- a/apps/sam/java/src/net/i2p/sam/SAMHandler.java
+++ b/apps/sam/java/src/net/i2p/sam/SAMHandler.java
@@ -102,7 +102,10 @@ abstract class SAMHandler implements Runnable, Handler {
         }
     }
     
-    static public void writeBytes(ByteBuffer data, SocketChannel out) throws IOException {
+    /**
+     *  Caller must synch
+     */
+    private static void writeBytes(ByteBuffer data, SocketChannel out) throws IOException {
         while (data.hasRemaining()) out.write(data);           
         out.socket().getOutputStream().flush();
     }
@@ -132,7 +135,10 @@ abstract class SAMHandler implements Runnable, Handler {
         }
     }
 
-    /** @return success */
+    /**
+     * Unsynchronized, use with caution
+     * @return success
+     */
     public static boolean writeString(String str, SocketChannel out)
     {
     	try {
diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java b/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java
index ff17f07b80..9cc4a500c7 100644
--- a/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java
+++ b/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java
@@ -315,7 +315,7 @@ class SAMv3Handler extends SAMv1Handler
 							} else if (_lastPing < 0) {
 								if (_log.shouldWarn())
 									_log.warn("2nd timeout");
-								writeString("XXX STATUS RESULT=I2P_ERROR MESSAGE=\"command timeout, bye\"\n");
+								writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"command timeout, bye\"\n");
 								break;
 							} else {
 								// don't clear buffer, don't send ping,
diff --git a/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java b/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java
index fedd469981..b582fa8069 100644
--- a/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java
+++ b/apps/sam/java/src/net/i2p/sam/client/SAMStreamSink.java
@@ -15,6 +15,7 @@ import gnu.getopt.Getopt;
 import net.i2p.I2PAppContext;
 import net.i2p.data.Base32;
 import net.i2p.data.DataHelper;
+import net.i2p.util.I2PAppThread;
 import net.i2p.util.Log;
 import net.i2p.util.VersionComparator;
 
@@ -35,6 +36,7 @@ public class SAMStreamSink {
     private String _conOptions;
     private SAMReader _reader, _reader2;
     private boolean _isV3;
+    private boolean _isV32;
     private String _v3ID;
     //private boolean _dead;
     /** Connection id (Integer) to peer (Flooder) */
@@ -127,6 +129,11 @@ public class SAMStreamSink {
                 throw new IOException("handshake failed");
             if (_log.shouldLog(Log.DEBUG))
                 _log.debug("Handshake complete.  we are " + ourDest);
+            if (_isV32) {
+                _log.debug("Starting pinger");
+                Thread t = new Pinger(out);
+                t.start();
+            }
             if (_isV3 && mode != V1DG && mode != V1RAW) {
                 Socket sock2 = connect(isSSL);
                 out = sock2.getOutputStream();
@@ -146,6 +153,32 @@ public class SAMStreamSink {
             _log.error("Unable to connect to SAM at " + _samHost + ":" + _samPort, e);
         }
     }
+
+    private static class Pinger extends I2PAppThread {
+        private final OutputStream _out;
+
+        public Pinger(OutputStream out) {
+            super("SAM Sink Pinger");
+            setDaemon(true);
+            _out = out;
+        }
+
+        public void run() {
+            while (true) {
+                try {
+                    Thread.sleep(127*1000);
+                    synchronized(_out) {
+                        _out.write(DataHelper.getASCII("PING " + System.currentTimeMillis() + '\n'));
+                        _out.flush();
+                    }
+                } catch (InterruptedException ie) {
+                    break;
+                } catch (IOException ioe) {
+                    break;
+                }
+            }
+        }
+    }
     
     private class SinkEventHandler extends SAMEventHandler {
 
@@ -353,6 +386,7 @@ public class SAMStreamSink {
                 _isV3 = VersionComparator.comp(hisVersion, "3") >= 0;
                 String dest;
                 if (_isV3) {
+                    _isV32 = VersionComparator.comp(hisVersion, "3.2") >= 0;
                     // we use the filename as the name in sam.keys
                     // and read it in ourselves
                     File keys = new File("sam.keys");
-- 
GitLab