From 98277d3b646cb163de319ccb977f49a8c7c158f3 Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Wed, 21 Dec 2005 12:04:54 +0000
Subject: [PATCH] 2005-12-21  jrandom     * Adjusted I2PSnark's usage of the
 streaming lib (tweaking it for BT's       behavior)     * Fixed the I2PSnark
 bug that would lose track of live peers

---
 .../src/org/klomp/snark/I2PSnarkUtil.java     |  4 ++
 .../java/src/org/klomp/snark/Peer.java        | 19 +++++--
 .../org/klomp/snark/PeerConnectionOut.java    | 11 +++-
 .../src/org/klomp/snark/PeerCoordinator.java  | 54 ++++++++++---------
 .../src/org/klomp/snark/SnarkManager.java     | 14 ++++-
 .../org/klomp/snark/web/I2PSnarkServlet.java  | 24 +++++----
 .../i2p/syndie/sml/ThreadedHTMLRenderer.java  |  7 ++-
 history.txt                                   | 13 ++++-
 .../src/net/i2p/router/RouterVersion.java     |  4 +-
 9 files changed, 101 insertions(+), 49 deletions(-)

diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
index 4651cbdfba..a53ade392f 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
@@ -90,6 +90,10 @@ public class I2PSnarkUtil {
             }
             if (opts.getProperty("inbound.nickname") == null)
                 opts.setProperty("inbound.nickname", "I2PSnark");
+            if (opts.getProperty("i2p.streaming.inactivityTimeout") == null)
+                opts.setProperty("i2p.streaming.inactivityTimeout", "90000");
+            if (opts.getProperty("i2p.streaming.inactivityAction") == null)
+                opts.setProperty("i2p.streaming.inactivityAction", "1");
             _manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, opts);
         }
         return (_manager != null);
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Peer.java b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
index 0dbd23bbb6..f4aadec54b 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Peer.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
@@ -105,9 +105,9 @@ public class Peer implements Comparable
   public String toString()
   {
     if (peerID != null)
-      return peerID.toString() + _id;
+      return peerID.toString() + ' ' + _id;
     else
-      return "[unknown id]" + _id;
+      return "[unknown id] " + _id;
   }
 
   /**
@@ -115,7 +115,7 @@ public class Peer implements Comparable
    */
   public int hashCode()
   {
-    return peerID.hashCode();
+    return peerID.hashCode() ^ (2 << _id);
   }
 
   /**
@@ -127,7 +127,7 @@ public class Peer implements Comparable
     if (o instanceof Peer)
       {
         Peer p = (Peer)o;
-        return peerID.equals(p.peerID);
+        return _id == p._id && peerID.equals(p.peerID);
       }
     else
       return false;
@@ -139,7 +139,14 @@ public class Peer implements Comparable
   public int compareTo(Object o)
   {
     Peer p = (Peer)o;
-    return peerID.compareTo(p.peerID);
+    int rv = peerID.compareTo(p.peerID);
+    if (rv == 0) {
+        if (_id > p._id) return 1;
+        else if (_id < p._id) return -1;
+        else return 0;
+    } else {
+        return rv;
+    }
   }
 
   /**
@@ -208,6 +215,7 @@ public class Peer implements Comparable
         // Use this thread for running the incomming connection.
         // The outgoing connection creates its own Thread.
         out.startup();
+        Thread.currentThread().setName("Snark reader from " + peerID);
         s.in.run();
       }
     catch(IOException eofe)
@@ -226,6 +234,7 @@ public class Peer implements Comparable
     finally
       {
         if (deregister) listener.disconnected(this);
+        disconnect();
       }
   }
 
diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java
index 3cb9e1b9fb..aef4d4016d 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java
@@ -56,7 +56,7 @@ class PeerConnectionOut implements Runnable
   }
   
   public void startup() {
-    thread = new I2PThread(this, "Snark sender " + _id);
+    thread = new I2PThread(this, "Snark sender " + _id + ": " + peer);
     thread.start();
   }
 
@@ -82,7 +82,7 @@ class PeerConnectionOut implements Runnable
                         dout.flush();
                         
                         // Wait till more data arrives.
-                        sendQueue.wait();
+                        sendQueue.wait(60*1000);
                       }
                     catch (InterruptedException ie)
                       {
@@ -185,6 +185,13 @@ class PeerConnectionOut implements Runnable
         sendQueue.clear();
         sendQueue.notify();
       }
+    if (dout != null) {
+        try {
+            dout.close();
+        } catch (IOException ioe) {
+            _log.warn("Error closing the stream to " + peer, ioe);
+        }
+    }
   }
 
   /**
diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java
index 1d69709010..a8cf9aa1e2 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java
@@ -179,7 +179,7 @@ public class PeerCoordinator implements PeerListener
   }
 
   public void connected(Peer peer)
-  {
+  { 
     if (halted)
       {
         peer.disconnect(false);
@@ -283,34 +283,36 @@ public class PeerCoordinator implements PeerListener
     // At the start are the peers that have us unchoked at the end the
     // other peer that are interested, but are choking us.
     List interested = new LinkedList();
-    Iterator it = peers.iterator();
-    while (it.hasNext())
-      {
-        Peer peer = (Peer)it.next();
-        boolean remove = false;
-        if (uploaders < MAX_UPLOADERS
-            && peer.isChoking()
-            && peer.isInterested())
+    synchronized (peers) {
+        Iterator it = peers.iterator();
+        while (it.hasNext())
           {
-            if (!peer.isChoked())
-              interested.add(0, peer);
-            else
-              interested.add(peer);
+            Peer peer = (Peer)it.next();
+            boolean remove = false;
+            if (uploaders < MAX_UPLOADERS
+                && peer.isChoking()
+                && peer.isInterested())
+              {
+                if (!peer.isChoked())
+                  interested.add(0, peer);
+                else
+                  interested.add(peer);
+              }
           }
-      }
 
-    while (uploaders < MAX_UPLOADERS && interested.size() > 0)
-      {
-        Peer peer = (Peer)interested.remove(0);
-        if (_log.shouldLog(Log.DEBUG))
-          _log.debug("Unchoke: " + peer);
-        peer.setChoking(false);
-        uploaders++;
-        // Put peer back at the end of the list.
-        peers.remove(peer);
-        peers.add(peer);
-        peerCount = peers.size();
-      }
+        while (uploaders < MAX_UPLOADERS && interested.size() > 0)
+          {
+            Peer peer = (Peer)interested.remove(0);
+            if (_log.shouldLog(Log.DEBUG))
+              _log.debug("Unchoke: " + peer);
+            peer.setChoking(false);
+            uploaders++;
+            // Put peer back at the end of the list.
+            peers.remove(peer);
+            peers.add(peer);
+            peerCount = peers.size();
+          }
+    }
   }
 
   public byte[] getBitMap()
diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index 83c485479e..405e3785e8 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -28,6 +28,9 @@ public class SnarkManager implements Snark.CompleteListener {
     public static final String PROP_EEP_HOST = "i2psnark.eepHost";
     public static final String PROP_EEP_PORT = "i2psnark.eepPort";
     public static final String PROP_DIR = "i2psnark.dir";
+
+    public static final String PROP_AUTO_START = "i2snark.autoStart";
+    public static final String DEFAULT_AUTO_START = "true";
     
     private SnarkManager() {
         _snarks = new HashMap();
@@ -59,7 +62,9 @@ public class SnarkManager implements Snark.CompleteListener {
         }
     }
     
-    public boolean shouldAutoStart() { return true; }
+    public boolean shouldAutoStart() {
+        return Boolean.valueOf(_config.getProperty(PROP_AUTO_START, DEFAULT_AUTO_START+"")).booleanValue();
+    }
     private int getStartupDelayMinutes() { return 1; }
     public File getDataDir() { 
         String dir = _config.getProperty(PROP_DIR);
@@ -91,6 +96,8 @@ public class SnarkManager implements Snark.CompleteListener {
             _config.setProperty(PROP_EEP_PORT, "4444");
         if (!_config.containsKey(PROP_DIR))
             _config.setProperty(PROP_DIR, "i2psnark");
+        if (!_config.containsKey(PROP_AUTO_START))
+            _config.setProperty(PROP_AUTO_START, DEFAULT_AUTO_START);
         updateConfig();
     }
     
@@ -226,6 +233,11 @@ public class SnarkManager implements Snark.CompleteListener {
                 changed = true;
             }
         }
+        if (shouldAutoStart() != autoStart) {
+            _config.setProperty(PROP_AUTO_START, autoStart + "");
+            addMessage("Adjusted autostart to " + autoStart);
+            changed = true;
+        }
         if (changed) {
             saveConfig();
         } else {
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index a9a6852965..5f690fc690 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -469,15 +469,15 @@ public class I2PSnarkServlet extends HttpServlet {
         boolean autoStart = _manager.shouldAutoStart();
         int seedPct = 0;
        
-        out.write("<span class=\"snarkConfig\">\n");
         out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
+        out.write("<span class=\"snarkConfig\"><hr />\n");
         out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\n");
-        out.write("<hr /><span class=\"snarkConfigTitle\">Configuration:</span><br />\n");
+        out.write("<span class=\"snarkConfigTitle\">Configuration:</span><br />\n");
         out.write("Data directory: <input type=\"text\" size=\"40\" name=\"dataDir\" value=\"" + dataDir + "\" ");
         out.write("title=\"Directory to store torrents and data\" disabled=\"true\" /><br />\n");
         out.write("Auto start: <input type=\"checkbox\" name=\"autoStart\" value=\"true\" " 
                   + (autoStart ? "checked " : "") 
-                  + "title=\"If true, automatically start torrents that are added\" disabled=\"true\" />");
+                  + "title=\"If true, automatically start torrents that are added\" />");
         //Auto add: <input type="checkbox" name="autoAdd" value="true" title="If true, automatically add torrents that are found in the data directory" />
         //Auto stop: <input type="checkbox" name="autoStop" value="true" title="If true, automatically stop torrents that are removed from the data directory" />
         //out.write("<br />\n");
@@ -496,14 +496,14 @@ public class I2PSnarkServlet extends HttpServlet {
             out.write("<option value=\"150\">150%</option>\n\t");
         out.write("</select><br />\n");
         
-        out.write("<hr />\n");
+        //out.write("<hr />\n");
         out.write("EepProxy host: <input type=\"text\" name=\"eepHost\" value=\""
                   + I2PSnarkUtil.instance().getEepProxyHost() + "\" size=\"15\" /> ");
-        out.write("EepProxy port: <input type=\"text\" name=\"eepPort\" value=\""
-                  + I2PSnarkUtil.instance().getEepProxyPort() + "\" size=\"5\" /> <br />\n");
+        out.write("port: <input type=\"text\" name=\"eepPort\" value=\""
+                  + I2PSnarkUtil.instance().getEepProxyPort() + "\" size=\"5\" /><br />\n");
         out.write("I2CP host: <input type=\"text\" name=\"i2cpHost\" value=\"" 
                   + I2PSnarkUtil.instance().getI2CPHost() + "\" size=\"15\" /> ");
-        out.write("I2CP port: <input type=\"text\" name=\"i2cpPort\" value=\"" +
+        out.write("port: <input type=\"text\" name=\"i2cpPort\" value=\"" +
                   + I2PSnarkUtil.instance().getI2CPPort() + "\" size=\"5\" /> <br />\n");
         StringBuffer opts = new StringBuffer(64);
         Map options = new TreeMap(I2PSnarkUtil.instance().getI2CPOptions());
@@ -512,10 +512,11 @@ public class I2PSnarkServlet extends HttpServlet {
             String val = (String)options.get(key);
             opts.append(key).append('=').append(val).append(' ');
         }
-        out.write("I2CP options: <input type=\"text\" name=\"i2cpOpts\" size=\"80\" value=\""
+        out.write("I2CP opts: <input type=\"text\" name=\"i2cpOpts\" size=\"40\" value=\""
                   + opts.toString() + "\" /><br />\n");
         out.write("<input type=\"submit\" value=\"Save configuration\" name=\"action\" />\n");
-        out.write("</form>\n</span>\n");
+        out.write("</span>\n");
+        out.write("</form>\n");
     }
     
     private String formatSize(long bytes) {
@@ -588,9 +589,12 @@ public class I2PSnarkServlet extends HttpServlet {
                                          "	font-size: 10pt;\n" +
                                          "}\n" +
                                          ".snarkConfigTitle {\n" +
-                                         "	font-size: 16pt;\n" +
+                                         "	font-size: 12pt;\n" +
                                          "                  font-weight: bold;\n" +
                                          "}\n" +
+                                         ".snarkConfig {\n" +
+                                         "                  font-size: 10pt;\n" +
+                                         "}\n" +
                                          "</style>\n" +
                                          "</head>\n" +
                                          "<body>\n";
diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
index f981214eaa..123812ebc7 100644
--- a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
+++ b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
@@ -190,6 +190,11 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
                        String offset, String requestTags, String filteredAuthor, boolean authorOnly) throws IOException {
         EntryContainer entry = archive.getEntry(post);
         if (entry == null) return;
+        ThreadNode node = index.getNode(post);
+        if (node == null) {
+            _log.error("Post is not in the index: " + post.toString());
+            return;
+        }
         _entry = entry;
    
         _baseURI = baseURI;
@@ -236,8 +241,6 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
         if ( (author == null) || (author.trim().length() <= 0) )
             author = post.getKeyHash().toBase64().substring(0,6);
         
-        ThreadNode node = index.getNode(post);
-        
         out.write(author);
         out.write("</a> @ ");
         out.write(getEntryDate(post.getEntryId()));
diff --git a/history.txt b/history.txt
index 18c268ba00..dc18446cd2 100644
--- a/history.txt
+++ b/history.txt
@@ -1,4 +1,15 @@
-$Id: history.txt,v 1.364 2005/12/19 08:34:56 jrandom Exp $
+$Id: history.txt,v 1.365 2005/12/19 21:01:37 jrandom Exp $
+
+2005-12-21  jrandom
+    * Adjusted I2PSnark's usage of the streaming lib (tweaking it for BT's
+      behavior)
+    * Fixed the I2PSnark bug that would lose track of live peers
+
+2005-12-20  jrandom
+    * Enabled the control in I2PSnark to toggle whether torrents should be
+      started automatically or not
+    * Hopefully finished the last hook to close down torrents completely when
+      they're stopped.
 
 2005-12-19  jrandom
     * Fix for old Syndie blog bookmarks (thanks Complication!)
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 15e0a044c4..52a044631e 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
  *
  */
 public class RouterVersion {
-    public final static String ID = "$Revision: 1.313 $ $Date: 2005/12/19 08:34:55 $";
+    public final static String ID = "$Revision: 1.314 $ $Date: 2005/12/19 21:01:37 $";
     public final static String VERSION = "0.6.1.7";
-    public final static long BUILD = 7;
+    public final static long BUILD = 8;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
         System.out.println("Router ID: " + RouterVersion.ID);
-- 
GitLab