From 33d57dd545b22914cf2886a2e4e6b2aa9f6541d7 Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Mon, 21 Nov 2005 14:37:06 +0000
Subject: [PATCH] 2005-11-21  jrandom     * IE doesn't strip SPAN from <button>
 form fields, so add in a workaround       within I2PTunnel.     * Increase
 the maximum SSU retransmission timeout to accomodate slower or       more
 congested links (though SSU's RTO calculation will usually use a       much
 lower timeout)     * Moved the streaming lib timed events off the main timer
 queues and onto       a streaming lib specific set of timer queues. 
 Streaming lib timed       events are more likely to have lock contention on
 the I2CP socket while       other timed events in the router are (largely)
 independent.     * Fixed a case sensitive lookup bug (thanks tino!)     *
 Syndie cleanup - new edit form on the preview page, and fixed some blog      
 links (thanks tino!)

---
 .../src/net/i2p/i2ptunnel/web/IndexBean.java  |   6 +-
 .../net/i2p/client/streaming/Connection.java  |  12 +-
 .../client/streaming/ConnectionHandler.java   |   2 +-
 .../streaming/ConnectionPacketHandler.java    |   2 +-
 .../client/streaming/MessageOutputStream.java |   2 +-
 .../client/streaming/RetransmissionTimer.java |  12 ++
 .../src/net/i2p/syndie/sml/HTMLRenderer.java  |   6 +-
 .../i2p/syndie/sml/ThreadedHTMLRenderer.java  |   2 +
 .../src/net/i2p/syndie/web/PostServlet.java   | 103 +++++++++++++++---
 .../client/naming/HostsTxtNamingService.java  |   4 +-
 core/java/src/net/i2p/data/DataHelper.java    |  13 ++-
 history.txt                                   |  16 ++-
 .../src/net/i2p/router/RouterVersion.java     |   4 +-
 .../i2p/router/transport/udp/PeerState.java   |   4 +-
 14 files changed, 149 insertions(+), 39 deletions(-)
 create mode 100644 apps/streaming/java/src/net/i2p/client/streaming/RetransmissionTimer.java

diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
index 43e85bf496..8b8d49b090 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
@@ -139,9 +139,11 @@ public class IndexBean {
             return stop();
         else if ("start".equals(_action))
             return start();
-        else if ("Save changes".equals(_action))
+        else if ("Save changes".equals(_action) || // IE workaround:
+                (_action.toLowerCase().indexOf("s</span>ave") >= 0))
             return saveChanges();
-        else if ("Delete this proxy".equals(_action))
+        else if ("Delete this proxy".equals(_action) || // IE workaround:
+                (_action.toLowerCase().indexOf("d</span>elete") >= 0))
             return deleteTunnel();
         else
             return "Action " + _action + " unknown";
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 a3329f3c6a..1e7fa629b8 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
@@ -298,7 +298,7 @@ public class Connection {
             if (_log.shouldLog(Log.DEBUG))
                 _log.debug("Resend in " + timeout + " for " + packet, new Exception("Sent by"));
 
-            SimpleTimer.getInstance().addEvent(new ResendPacketEvent(packet, timeout + _context.clock().now()), timeout);
+            RetransmissionTimer.getInstance().addEvent(new ResendPacketEvent(packet, timeout + _context.clock().now()), timeout);
         }
 
         _context.statManager().getStatLog().addData(Packet.toId(_sendStreamId), "stream.rtt", _options.getRTT(), _options.getWindowSize());
@@ -758,8 +758,8 @@ public class Connection {
         if (_log.shouldLog(Log.DEBUG))
             _log.debug("Resetting the inactivity timer to " + howLong, new Exception("Reset by"));
         // this will get rescheduled, and rescheduled, and rescheduled...
-        SimpleTimer.getInstance().removeEvent(_activityTimer);
-        SimpleTimer.getInstance().addEvent(_activityTimer, howLong);
+        RetransmissionTimer.getInstance().removeEvent(_activityTimer);
+        RetransmissionTimer.getInstance().addEvent(_activityTimer, howLong);
     }
     
     private class ActivityTimer implements SimpleTimer.TimedEvent {
@@ -773,7 +773,7 @@ public class Connection {
             long left = getTimeLeft();
             if (left > 0) {
                 if (_log.shouldLog(Log.DEBUG)) _log.debug("Inactivity timeout reached, but there is time left (" + left + ")");
-                SimpleTimer.getInstance().addEvent(ActivityTimer.this, left);
+                RetransmissionTimer.getInstance().addEvent(ActivityTimer.this, left);
                 return;
             }
             // these are either going to time out or cause further rescheduling
@@ -963,7 +963,7 @@ public class Connection {
                     if (_log.shouldLog(Log.WARN))
                         _log.warn("Delaying resend of " + _packet + " as there are " 
                                   + _activeResends + " active resends already in play");
-                    SimpleTimer.getInstance().addEvent(ResendPacketEvent.this, 1000);
+                    RetransmissionTimer.getInstance().addEvent(ResendPacketEvent.this, 1000);
                     _nextSendTime = 1000 + _context.clock().now();
                     return false;
                 }
@@ -1055,7 +1055,7 @@ public class Connection {
                         timeout = MAX_RESEND_DELAY;
                     if (_log.shouldLog(Log.DEBUG))
                         _log.debug("Scheduling resend in " + timeout + "ms for " + _packet);
-                    SimpleTimer.getInstance().addEvent(ResendPacketEvent.this, timeout);
+                    RetransmissionTimer.getInstance().addEvent(ResendPacketEvent.this, timeout);
                     _nextSendTime = timeout + _context.clock().now();
                 }
                 return true;
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 471cc97a87..4960f1a228 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
@@ -50,7 +50,7 @@ class ConnectionHandler {
         }
         if (_log.shouldLog(Log.DEBUG))
             _log.debug("Receive new SYN: " + packet + ": timeout in " + _acceptTimeout);
-        SimpleTimer.getInstance().addEvent(new TimeoutSyn(packet), _acceptTimeout);
+        RetransmissionTimer.getInstance().addEvent(new TimeoutSyn(packet), _acceptTimeout);
         synchronized (_synQueue) {
             _synQueue.add(packet);
             _synQueue.notifyAll();
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java
index 2c4a4f3cfa..be27fb71d6 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java
@@ -155,7 +155,7 @@ public class ConnectionPacketHandler {
                 // take note of congestion
                 if (_log.shouldLog(Log.WARN))
                     _log.warn("congestion.. dup " + packet);
-                SimpleTimer.getInstance().addEvent(new AckDup(con), con.getOptions().getSendAckDelay());
+                RetransmissionTimer.getInstance().addEvent(new AckDup(con), con.getOptions().getSendAckDelay());
                 //con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay());
                 //fastAck = true;
             } else {
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/MessageOutputStream.java b/apps/streaming/java/src/net/i2p/client/streaming/MessageOutputStream.java
index 64a7bb6cc2..89fd9d7a7a 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/MessageOutputStream.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/MessageOutputStream.java
@@ -194,7 +194,7 @@ public class MessageOutputStream extends OutputStream {
             // no need to be overly worried about duplicates - it would just 
             // push it further out
             if (!_enqueued) {
-                SimpleTimer.getInstance().addEvent(_flusher, _passiveFlushDelay);
+                RetransmissionTimer.getInstance().addEvent(_flusher, _passiveFlushDelay);
                 if (_log.shouldLog(Log.DEBUG))
                     _log.debug("Enqueueing the flusher for " + _passiveFlushDelay + "ms out");
             } else {
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/RetransmissionTimer.java b/apps/streaming/java/src/net/i2p/client/streaming/RetransmissionTimer.java
new file mode 100644
index 0000000000..0ea0c83d70
--- /dev/null
+++ b/apps/streaming/java/src/net/i2p/client/streaming/RetransmissionTimer.java
@@ -0,0 +1,12 @@
+package net.i2p.client.streaming;
+
+import net.i2p.util.SimpleTimer;
+
+/**
+ *
+ */
+class RetransmissionTimer extends SimpleTimer {
+    private static final RetransmissionTimer _instance = new RetransmissionTimer();
+    public static final SimpleTimer getInstance() { return _instance; }
+    protected RetransmissionTimer() { super("StreamingTimer"); }
+}
diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java
index a7f6cd1118..0dc0819946 100644
--- a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java
+++ b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java
@@ -341,14 +341,16 @@ public class HTMLRenderer extends EventReceiverImpl {
         }
         
         
-        String url = getPageURL(blog, null, -1, -1, -1, (_user != null ? _user.getShowExpanded() : false), (_user != null ? _user.getShowImages() : false));
+        //String url = getPageURL(blog, null, -1, -1, -1, (_user != null ? _user.getShowExpanded() : false), (_user != null ? _user.getShowImages() : false));
+        String url = getMetadataURL(blog);
         _bodyBuffer.append(getSpan("blogEntrySummary")).append(" [<a ").append(getClass("blogLink")).append(" href=\"").append(url);
         _bodyBuffer.append("\">");
         if ( (name != null) && (name.trim().length() > 0) )
             _bodyBuffer.append(sanitizeString(name));
         else
             _bodyBuffer.append("view");
-        _bodyBuffer.append("</a> (<a ").append(getClass("blogMeta")).append(" href=\"").append(getMetadataURL(blog)).append("\">meta</a>)");
+        _bodyBuffer.append("</a> ");
+        //_bodyBuffer.append("</a> (<a ").append(getClass("blogMeta")).append(" href=\"").append(getMetadataURL(blog)).append("\">meta</a>)");
         if ( (tag != null) && (tag.trim().length() > 0) ) {
             url = getPageURL(blog, tag, -1, -1, -1, false, false);
             _bodyBuffer.append(" <a ").append(getClass("blogTagLink")).append(" href=\"").append(url);
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 0a46adf329..c9995b9353 100644
--- a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
+++ b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
@@ -468,6 +468,8 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
         if ( (blog != null) && (entryId > 0) ) {
             buf.append(PARAM_VIEW_POST).append('=').append(Base64.encode(blog.getData())).append('/').append(entryId).append('&');
             buf.append(PARAM_VISIBLE).append('=').append(Base64.encode(blog.getData())).append('/').append(entryId).append('&');
+        } else if (blog != null) {
+            buf.append(PARAM_AUTHOR).append('=').append(blog.toBase64()).append('&');
         }
         if (tag != null)
             buf.append(PARAM_TAGS).append('=').append(sanitizeTagParam(tag)).append('&');
diff --git a/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java
index f3a3e90525..631bbfc68b 100644
--- a/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java
+++ b/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java
@@ -148,9 +148,7 @@ public class PostServlet extends BaseServlet {
         writeAuthActionFields(out);
         out.write("Please confirm that the above is ok");
         if (BlogManager.instance().authorizeRemote(user)) { 
-            out.write(", and select what additional archives you want the post transmitted to.  ");
-            out.write("To make changes, hit your browser's back arrow and try again.\n");
-            out.write("Remote archive to push this post to: ");
+            out.write(", and select what additional archive you want the post transmitted to: ");
             out.write("<select class=\"b_postConfirm\" name=\"" + PARAM_REMOTE_ARCHIVE + "\">\n");
             PetNameDB db = user.getPetNameDB();
             TreeSet names = new TreeSet();
@@ -174,6 +172,10 @@ public class PostServlet extends BaseServlet {
         out.write("</span><input class=\"b_postConfirm\" type=\"submit\" name=\"" + PARAM_ACTION 
                   + "\" value=\"" + ACTION_CONFIRM + "\" />\n");
         
+        out.write("</form>\n");
+        
+        displayEditForm(user, req, post, out);
+        
         out.write("</td></tr>\n");
     }
     
@@ -200,37 +202,37 @@ public class PostServlet extends BaseServlet {
         post.reinitialize();
         post.setUser(user);
         
+        String parentURI = req.getParameter(PARAM_PARENT);
+        
+        String subject = getParam(req, PARAM_SUBJECT);
+        
         out.write("<form action=\"" + getPostURI() + "\" method=\"POST\" enctype=\"multipart/form-data\">\n");
         writeAuthActionFields(out);
         out.write("<tr><td colspan=\"3\">\n");
         out.write("<span class=\"b_postField\">Post subject:</span> ");
         out.write("<input type=\"text\" class=\"b_postSubject\" size=\"80\" name=\"" + PARAM_SUBJECT 
-                  + "\" value=\"" + getParam(req,PARAM_SUBJECT) + "\" /><br />\n");
-        out.write("<span class=\"b_postField\">Post tags:</span> ");
-        out.write("<input type=\"text\" class=\"b_postTags\" size=\"20\" name=\"" + PARAM_TAGS 
-                  + "\" value=\"" + getParam(req, PARAM_TAGS) + "\" /><br />\n");
-        out.write("<span class=\"b_postField\">Include public names?</span> ");
-        out.write("<input class=\"b_postNames\" type=\"checkbox\" name=\"" + PARAM_INCLUDENAMES 
-                  + "\" value=\"true\" /><br />\n");
+                  + "\" value=\"" + HTMLRenderer.sanitizeTagParam(subject) + "\" /><br />\n");
         out.write("<span class=\"b_postField\">Post content (in raw <a href=\"smlref.jsp\" target=\"_blank\">SML</a>, no headers):</span><br />\n");
         out.write("<textarea class=\"b_postText\" rows=\"6\" cols=\"80\" name=\"" + PARAM_TEXT + "\">" + getParam(req, PARAM_TEXT) + "</textarea><br />\n");
         out.write("<span class=\"b_postField\">SML post headers:</span><br />\n");
         out.write("<textarea class=\"b_postHeaders\" rows=\"3\" cols=\"80\" name=\"" + PARAM_HEADERS + "\">" + getParam(req, PARAM_HEADERS) + "</textarea><br />\n");
         
-        
-        String parentURI = req.getParameter(PARAM_PARENT);
         if ( (parentURI != null) && (parentURI.trim().length() > 0) )
             out.write("<input type=\"hidden\" name=\"" + PARAM_PARENT + "\" value=\"" + parentURI + "\" />\n");
 
-        out.write(" Tags: <input type=\"text\" size=\"10\" name=\"" + PARAM_TAGS + "\" value=\"" + getParam(req, PARAM_TAGS) + "\" />\n");
+        out.write(" Tags: <input type=\"text\" size=\"10\" name=\"" + PARAM_TAGS + "\" value=\"" + getParam(req, PARAM_TAGS) + "\" /><br />\n");
         
         boolean inNewThread = getInNewThread(req);
         boolean refuseReplies = getRefuseReplies(req);
 
-        out.write(" in a new thread? <input type=\"checkbox\" value=\"true\" name=\"" + PARAM_IN_NEW_THREAD + 
-                  (inNewThread ? "\" checked=\"true\" " : "\" " ) + " />\n");
-        out.write(" refuse replies? <input type=\"checkbox\" value=\"true\" name=\"" + PARAM_REFUSE_REPLIES + 
-                  (refuseReplies ? "\" checked=\"true\" " : "\" " ) + " />\n");
+        out.write("In a new thread? <input type=\"checkbox\" value=\"true\" name=\"" + PARAM_IN_NEW_THREAD + 
+                  (inNewThread ? "\" checked=\"true\" " : "\" " ) + " /><br />\n");
+        out.write("Refuse replies? <input type=\"checkbox\" value=\"true\" name=\"" + PARAM_REFUSE_REPLIES + 
+                  (refuseReplies ? "\" checked=\"true\" " : "\" " ) + " /><br />\n");
+        
+        out.write("<span class=\"b_postField\">Include public names?</span> ");
+        out.write("<input class=\"b_postNames\" type=\"checkbox\" name=\"" + PARAM_INCLUDENAMES 
+                  + "\" value=\"true\" /><br />\n");
         
         out.write(ATTACHMENT_FIELDS);
 
@@ -249,9 +251,68 @@ public class PostServlet extends BaseServlet {
         out.write("</form>\n");
     }
     
+    private void displayEditForm(User user, MultiPartRequest req, PostBean post, PrintWriter out) throws IOException {
+        String parentURI = req.getString(PARAM_PARENT);
+        
+        String subject = getParam(req, PARAM_SUBJECT);
+        
+        out.write("<hr />\n");
+        out.write("<form action=\"" + getPostURI() + "\" method=\"POST\" enctype=\"multipart/form-data\">\n");
+        writeAuthActionFields(out);
+        out.write("<tr><td colspan=\"3\">\n");
+        out.write("<span class=\"b_postField\">Post subject:</span> ");
+        out.write("<input type=\"text\" class=\"b_postSubject\" size=\"80\" name=\"" + PARAM_SUBJECT 
+                  + "\" value=\"" + HTMLRenderer.sanitizeTagParam(subject) + "\" /><br />\n");
+        out.write("<span class=\"b_postField\">Post content (in raw <a href=\"smlref.jsp\" target=\"_blank\">SML</a>, no headers):</span><br />\n");
+        out.write("<textarea class=\"b_postText\" rows=\"6\" cols=\"80\" name=\"" + PARAM_TEXT + "\">" + getParam(req, PARAM_TEXT) + "</textarea><br />\n");
+        out.write("<span class=\"b_postField\">SML post headers:</span><br />\n");
+        out.write("<textarea class=\"b_postHeaders\" rows=\"3\" cols=\"80\" name=\"" + PARAM_HEADERS + "\">" + getParam(req, PARAM_HEADERS) + "</textarea><br />\n");
+        
+        if ( (parentURI != null) && (parentURI.trim().length() > 0) )
+            out.write("<input type=\"hidden\" name=\"" + PARAM_PARENT + "\" value=\"" + parentURI + "\" />\n");
+
+        out.write(" Tags: <input type=\"text\" size=\"10\" name=\"" + PARAM_TAGS + "\" value=\"" + getParam(req, PARAM_TAGS) + "\" /><br />\n");
+        
+        boolean inNewThread = getInNewThread(req);
+        boolean refuseReplies = getRefuseReplies(req);
+
+        out.write("In a new thread? <input type=\"checkbox\" value=\"true\" name=\"" + PARAM_IN_NEW_THREAD + 
+                  (inNewThread ? "\" checked=\"true\" " : "\" " ) + " /><br />\n");
+        out.write("Refuse replies? <input type=\"checkbox\" value=\"true\" name=\"" + PARAM_REFUSE_REPLIES + 
+                  (refuseReplies ? "\" checked=\"true\" " : "\" " ) + " /><br />\n");
+        
+        out.write("<span class=\"b_postField\">Include public names?</span> ");
+        out.write("<input class=\"b_postNames\" type=\"checkbox\" name=\"" + PARAM_INCLUDENAMES 
+                  + "\" value=\"true\" /><br />\n");
+        
+        int newCount = 0;
+        for (int i = 0; i < 32 && newCount < 3; i++) {
+          String filename = req.getFilename("entryfile" + i);
+          if ( (filename != null) && (filename.trim().length() > 0) ) {
+              out.write("<span class=\"b_postField\">Attachment " + i + ":</span> ");
+              out.write(HTMLRenderer.sanitizeString(filename));
+              out.write("<br />");
+          } else {
+              out.write("<span class=\"b_postField\">Attachment " + i + ":</span> ");
+              out.write("<input class=\"b_postField\" type=\"file\" name=\"entryfile" + i + "\" ");
+              out.write("/><br />");
+              newCount++;
+          }
+        }
+
+        out.write("<hr />\n");
+        out.write("<input class=\"b_postPreview\" type=\"submit\" name=\"Post\" value=\"Preview...\" /> ");
+        out.write("<input class=\"b_postReset\" type=\"reset\" value=\"Cancel\" />\n");
+        
+        out.write("</form>\n");
+    }
+    
     private boolean getInNewThread(HttpServletRequest req) {
         return getInNewThread(req.getParameter(PARAM_IN_NEW_THREAD));
     }
+    private boolean getInNewThread(MultiPartRequest req) {
+        return getInNewThread(getParam(req, PARAM_IN_NEW_THREAD));
+    }
     private boolean getInNewThread(String val) {
         boolean rv = false;
         String inNewThread = val;
@@ -262,6 +323,9 @@ public class PostServlet extends BaseServlet {
     private boolean getRefuseReplies(HttpServletRequest req) {
         return getRefuseReplies(req.getParameter(PARAM_REFUSE_REPLIES));
     }
+    private boolean getRefuseReplies(MultiPartRequest req) {
+        return getRefuseReplies(getParam(req, PARAM_REFUSE_REPLIES));
+    }
     private boolean getRefuseReplies(String val) {
         boolean rv = false;
         String refuseReplies = val;
@@ -284,6 +348,11 @@ public class PostServlet extends BaseServlet {
         if (val == null) val = "";
         return val;
     }
+    private String getParam(MultiPartRequest req, String param) {
+        String val = req.getString(param);
+        if (val == null) return "";
+        return val;
+    }
     
     private static final String ATTACHMENT_FIELDS = ""
         + "<span class=\"b_postField\">Attachment 0:</span> <input class=\"b_postField\" type=\"file\" name=\"entryfile0\" /><br />"
diff --git a/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java b/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java
index 841fb699aa..20a59121e1 100644
--- a/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java
+++ b/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java
@@ -64,9 +64,9 @@ public class HostsTxtNamingService extends NamingService {
             try {
                 File f = new File(hostsfile);
                 if ( (f.exists()) && (f.canRead()) ) {
-                    DataHelper.loadProps(hosts, f);
+                    DataHelper.loadProps(hosts, f, true);
                     
-                    String key = hosts.getProperty(hostname);
+                    String key = hosts.getProperty(hostname.toLowerCase());
                     if ( (key != null) && (key.trim().length() > 0) ) {
                         return lookupBase64(key);
                     }
diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java
index 61415a0b8b..ef5370150b 100644
--- a/core/java/src/net/i2p/data/DataHelper.java
+++ b/core/java/src/net/i2p/data/DataHelper.java
@@ -212,9 +212,15 @@ public class DataHelper {
      *
      */
     public static void loadProps(Properties props, File file) throws IOException {
-        loadProps(props, new FileInputStream(file));
+        loadProps(props, file, false);
+    }
+    public static void loadProps(Properties props, File file, boolean forceLowerCase) throws IOException {
+        loadProps(props, new FileInputStream(file), forceLowerCase);
     }
     public static void loadProps(Properties props, InputStream inStr) throws IOException {
+        loadProps(props, inStr, false);
+    }
+    public static void loadProps(Properties props, InputStream inStr, boolean forceLowerCase) throws IOException {
         BufferedReader in = null;
         try {
             in = new BufferedReader(new InputStreamReader(inStr, "UTF-8"), 16*1024);
@@ -230,7 +236,10 @@ public class DataHelper {
                 String key = line.substring(0, split);
                 String val = line.substring(split+1);
                 if ( (key.length() > 0) && (val.length() > 0) )
-                    props.setProperty(key, val);
+                    if (forceLowerCase)
+                        props.setProperty(key.toLowerCase(), val);
+                    else
+                        props.setProperty(key, val);
             }
         } finally {
             if (in != null) try { in.close(); } catch (IOException ioe) {}
diff --git a/history.txt b/history.txt
index 00829366ee..f7432da80f 100644
--- a/history.txt
+++ b/history.txt
@@ -1,4 +1,18 @@
-$Id: history.txt,v 1.324 2005/11/17 03:23:46 jrandom Exp $
+$Id: history.txt,v 1.325 2005/11/19 23:42:17 jrandom Exp $
+
+2005-11-21  jrandom
+    * IE doesn't strip SPAN from <button> form fields, so add in a workaround
+      within I2PTunnel.
+    * Increase the maximum SSU retransmission timeout to accomodate slower or
+      more congested links (though SSU's RTO calculation will usually use a
+      much lower timeout)
+    * Moved the streaming lib timed events off the main timer queues and onto
+      a streaming lib specific set of timer queues.  Streaming lib timed
+      events are more likely to have lock contention on the I2CP socket while
+      other timed events in the router are (largely) independent.
+    * Fixed a case sensitive lookup bug (thanks tino!)
+    * Syndie cleanup - new edit form on the preview page, and fixed some blog
+      links (thanks tino!)
 
 2005-11-19  jrandom
     * Implemented a trivial pure java PMTU backoff strategy, switching between
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index f48d59c2d7..f6206b3aa5 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.292 $ $Date: 2005/11/17 03:23:46 $";
+    public final static String ID = "$Revision: 1.293 $ $Date: 2005/11/19 23:42:17 $";
     public final static String VERSION = "0.6.1.5";
-    public final static long BUILD = 3;
+    public final static long BUILD = 4;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
         System.out.println("Router ID: " + RouterVersion.ID);
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java
index 007400b218..ec9841f4a7 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java
@@ -189,7 +189,7 @@ public class PeerState {
     private static final int LARGE_MTU = 1350;
     
     private static final int MIN_RTO = 500 + ACKSender.ACK_FREQUENCY;
-    private static final int MAX_RTO = 1200; // 5000;
+    private static final int MAX_RTO = 2500; // 5000;
     /** override the default MTU */
     private static final String PROP_DEFAULT_MTU = "i2np.udp.mtu";
     
@@ -733,7 +733,7 @@ public class PeerState {
         if (numSends < 2) {
             recalculateTimeouts(lifetime);
             if (_mtu <= MIN_MTU) {
-                if (_context.random().nextInt((int)_mtuDecreases) <= 0) {
+                if (_context.random().nextInt(50*(int)_mtuDecreases) <= 0) {
                     _context.statManager().addRateData("udp.mtuIncrease", _packetsRetransmitted, _packetsTransmitted);
                     _mtu = LARGE_MTU;
                     _mtuIncreases++;
-- 
GitLab