diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index 3d9dc20445813545d2d8042e2fcac44deab5585b..9a0a18a476754a4f658f81fe1ff5fb85ad9364b5 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -78,8 +78,8 @@ public class Storage
 
   /** The default piece size. */
   private static final int DEFAULT_PIECE_SIZE = 256*1024;
-  /** note that we start reducing max number of peer connections above 1MB */
-  public static final int MAX_PIECE_SIZE = 2*1024*1024;
+  /** bigger than this will be rejected */
+  public static final int MAX_PIECE_SIZE = 4*1024*1024;
   /** The maximum number of pieces in a torrent. */
   public static final int MAX_PIECES = 10*1024;
   public static final long MAX_TOTAL_SIZE = MAX_PIECE_SIZE * (long) MAX_PIECES;
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 20cb23a0a046e1a31e4f6a7698f6b14d9dddfdf7..1fb6d0064e93bec02ca84d1b1ef8f359ea213e9c 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -1542,7 +1542,7 @@ public class I2PSnarkServlet extends BasicServlet {
                 float pct;
                 if (isValid) {
                     pct = (float) (100.0 * peer.completed() / meta.getPieces());
-                    if (pct == 100.0)
+                    if (pct >= 100.0)
                         out.write(_("Seed"));
                     else {
                         String ps = String.valueOf(pct);
@@ -2644,7 +2644,8 @@ public class I2PSnarkServlet extends BasicServlet {
             icon = "html";
         else if (mime.equals("text/plain") ||
                  mime.equals("application/rtf") ||
-                 mime.equals("application/epub+zip"))
+                 mime.equals("application/epub+zip") ||
+                 mime.equals("application/x-mobipocket-ebook"))
             icon = "page";
         else if (mime.equals("application/java-archive") ||
                  plc.endsWith(".deb"))
diff --git a/apps/i2psnark/mime.properties b/apps/i2psnark/mime.properties
index 56c9d9aa958a474632fd82d522a774b93abeb970..8e64792524cc5fbe7e4a33189c87703e57016389 100644
--- a/apps/i2psnark/mime.properties
+++ b/apps/i2psnark/mime.properties
@@ -8,6 +8,7 @@ iso	= application/x-iso9660-image
 m4a	= audio/mp4a-latm
 m4v	= video/x-m4v
 mkv	= video/x-matroska
+mobi	= application/x-mobipocket-ebook
 mp4	= video/mp4
 mpc	= audio/x-musepack
 nfo	= text/plain
@@ -19,5 +20,6 @@ su2	= application/zip
 sud	= application/zip
 txt	= text/plain
 war	= application/java-archive
+webm	= video/webm
 wma	= audio/x-ms-wma
 wmv	= video/x-ms-wmv
diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketOptionsImpl.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketOptionsImpl.java
index 3a1722dfb31942c1ffa174b71be64894139d843c..02a4d9dd41284e4ada99ff066ac1fce27385c207 100644
--- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketOptionsImpl.java
+++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketOptionsImpl.java
@@ -93,6 +93,20 @@ class I2PSocketOptionsImpl implements I2PSocketOptions {
         }
     }
     
+    protected static double getDouble(Properties opts, String name, double defaultVal) {
+        if (opts == null) return defaultVal;
+        String val = opts.getProperty(name);
+        if (val == null) {
+            return defaultVal;
+        } else {
+            try {
+                return Double.parseDouble(val);
+            } catch (NumberFormatException nfe) {
+                return defaultVal;
+            }
+        }
+    }
+    
     /**
      * How long we will wait for the ACK from a SYN, in milliseconds.
      *
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
index 324c56d11ba930c04ebda0ba08935442f71d3883..5a41fb394c6b00ea1d76026e37c3531550687b81 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
@@ -27,7 +27,7 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
     private int _profile;
     private int _rtt;
     private int _rttDev;
-    private int _rto;
+    private int _rto = INITIAL_RTO;
     private int _resendDelay;
     private int _sendAckDelay;
     private int _maxMessageSize;
@@ -51,7 +51,17 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
     private int _maxTotalConnsPerDay;
     private int _maxConns;
     private boolean _disableRejectLog;
-
+    
+    /** state of a connection */
+    private enum AckInit {
+        INIT, // just created
+        FIRST, // first received ack
+        STEADY 
+    }
+    
+    /** LOCKING: this */
+    private AckInit _initState = AckInit.INIT;
+    
     // NOTE - almost all the options are below, but see
     // I2PSocketOptions in ministreaming for a few more
 
@@ -65,11 +75,21 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
     /** on inactivity timeout, send a payload message */
     public static final int INACTIVITY_ACTION_SEND = 2;
     
+    /* 
+     * These values are specified in RFC 6298
+     * Do not change unless you know what you're doing
+     */
+    private static final double TCP_ALPHA = 1.0/8;
+    private static final double TCP_BETA = 1.0/4; 
+    private static final double TCP_KAPPA = 4;
+    
+    private static final String PROP_INITIAL_RTO = "i2p.streaming.initialRTO";
+    private static final int INITIAL_RTO = 9000; 
+    
     public static final String PROP_CONNECT_DELAY = "i2p.streaming.connectDelay";
     public static final String PROP_PROFILE = "i2p.streaming.profile";
     public static final String PROP_MAX_MESSAGE_SIZE = "i2p.streaming.maxMessageSize";
     public static final String PROP_MAX_RESENDS = "i2p.streaming.maxResends";
-    public static final String PROP_INITIAL_RTT = "i2p.streaming.initialRTT";
     public static final String PROP_INITIAL_RESEND_DELAY = "i2p.streaming.initialResendDelay";
     public static final String PROP_INITIAL_ACK_DELAY = "i2p.streaming.initialAckDelay";
     public static final String PROP_INITIAL_WINDOW_SIZE = "i2p.streaming.initialWindowSize";
@@ -295,6 +315,7 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
             setMaxWindowSize(opts.getMaxWindowSize());
             setConnectDelay(opts.getConnectDelay());
             setProfile(opts.getProfile());
+            setRTTDev(opts.getRTTDev());
             setRTT(opts.getRTT());
             setRequireFullySigned(opts.getRequireFullySigned());
             setWindowSize(opts.getWindowSize());
@@ -332,7 +353,6 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
         setConnectDelay(getInt(opts, PROP_CONNECT_DELAY, -1));
         setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK));
         setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, DEFAULT_MAX_MESSAGE_SIZE));
-        setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT));
         setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
         setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
         setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY));
@@ -360,6 +380,8 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
         _maxTotalConnsPerHour = getInt(opts, PROP_MAX_TOTAL_CONNS_HOUR, 0);
         _maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0);
         _maxConns = getInt(opts, PROP_MAX_STREAMS, 0);
+        
+        _rto = getInt(opts, PROP_INITIAL_RTO, INITIAL_RTO);
     }
     
     /**
@@ -377,8 +399,6 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
             setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK));
         if (opts.containsKey(PROP_MAX_MESSAGE_SIZE))
             setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, Packet.MAX_PAYLOAD_SIZE));
-        if (opts.containsKey(PROP_INITIAL_RTT))
-            setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT));
         if (opts.containsKey(PROP_INITIAL_RECEIVE_WINDOW))
             setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
         if (opts.containsKey(PROP_INITIAL_RESEND_DELAY))
@@ -427,6 +447,8 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
             _maxTotalConnsPerDay = getInt(opts, PROP_MAX_TOTAL_CONNS_DAY, 0);
         if (opts.containsKey(PROP_MAX_STREAMS))
             _maxConns = getInt(opts, PROP_MAX_STREAMS, 0);
+        
+        _rto = getInt(opts, PROP_INITIAL_RTO, INITIAL_RTO);
     }
     
     /** 
@@ -515,12 +537,8 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
      * What to set the round trip time estimate to (in milliseconds)
      * @return round trip time estimate in ms
      */
-    public int getRTT() { return _rtt; }
+    public synchronized int getRTT() { return _rtt; }
     public void setRTT(int ms) { 
-        if (_rto == 0) {
-            _rttDev = ms / 2;
-            _rto = ms + ms / 2;
-        }
         synchronized (_trend) {
             _trend[0] = _trend[1];
             _trend[1] = _trend[2];
@@ -532,15 +550,50 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
                 _trend[2] = 0;
         }
         
-        _rtt = ms; 
-        if (_rtt > 60*1000)
-            _rtt = 60*1000;
+        synchronized(this) {
+            _rtt = ms; 
+            if (_rtt > 60*1000)
+                _rtt = 60*1000;
+        }
     }
 
-    public int getRTO() { return _rto; }
+    public synchronized int getRTO() { return _rto; }
 
-    /** for debugging @since 0.7.13 */
-    int getRTTDev() { return _rttDev; }
+    /** used in TCB @since 0.9.8 */
+    synchronized int getRTTDev() { return _rttDev; }
+    private synchronized void setRTTDev(int rttDev) { _rttDev = rttDev; }
+    
+    /** 
+     * Loads options from TCB cache.
+     */
+    synchronized void loadFromCache(int rtt, int rttDev, int wdw) {
+        _initState = AckInit.STEADY;
+        setRTT(rtt);
+        setRTTDev(rttDev);
+        setWindowSize(wdw);
+        computeRTO();
+    }
+    
+    /** 
+     * computes RTO based on formula in RFC
+     */
+    private synchronized void computeRTO() {
+        switch(_initState) {
+        case INIT :
+            throw new IllegalStateException();
+        case FIRST :
+            _rto = _rtt + _rtt / 2;
+            break;
+        case STEADY :
+            _rto = _rtt + (int) (_rttDev * TCP_KAPPA);
+            break;
+        }
+        
+        if (_rto < Connection.MIN_RESEND_DELAY) 
+            _rto = (int)Connection.MIN_RESEND_DELAY;
+        else if (_rto > Connection.MAX_RESEND_DELAY)
+            _rto = (int)Connection.MAX_RESEND_DELAY;
+    }
     
     /**
      * If we have 3 consecutive rtt increases, we are trending upwards (1), or if we have
@@ -558,22 +611,22 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
         }
     }
     
-    /** rtt = rtt*RTT_DAMPENING + (1-RTT_DAMPENING)*currentPacketRTT */
-    /** This is the value specified in RFC 2988, let's try it */
-    private static final double RTT_DAMPENING = 0.875;
-    
-    public void updateRTT(int measuredValue) {
-        // the rttDev calculation matches that recommended in RFC 2988 (beta = 1/4)
-        _rttDev = _rttDev + (int)(0.25d*(Math.abs(measuredValue-_rtt)-_rttDev));
-        int smoothed = (int)(RTT_DAMPENING*_rtt + (1-RTT_DAMPENING)*measuredValue);        
-        // K = 4
-        _rto = smoothed + (_rttDev<<2);
-        if (_rto < Connection.MIN_RESEND_DELAY) 
-            _rto = (int)Connection.MIN_RESEND_DELAY;
-        else if (_rto > Connection.MAX_RESEND_DELAY)
-            _rto = (int)Connection.MAX_RESEND_DELAY;
-
-        setRTT(smoothed);
+    public synchronized void updateRTT(int measuredValue) {
+        switch(_initState) {
+        case INIT:
+            _initState = AckInit.FIRST;
+            setRTT(measuredValue); // no smoothing first sample
+            _rttDev = _rtt / 2;
+            break;
+        case FIRST:
+            _initState = AckInit.STEADY; // fall through
+        case STEADY:
+            // calculation matches that recommended in RFC 6298
+            _rttDev = (int) ((1-TCP_BETA) *_rttDev  + TCP_BETA * Math.abs(measuredValue-_rtt));
+            int smoothed = (int)((1-TCP_ALPHA)*_rtt + TCP_ALPHA*measuredValue);        
+            setRTT(smoothed);
+        }
+        computeRTO();
     }
     
     /** How long after sending a packet will we wait before resending?
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java b/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java
index 7772330f4f9d5dc1a7b04de33ee65596bcd02db3..67d30f52db3b7ae18627c4ddb927f5f14c803b9e 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java
@@ -2,6 +2,7 @@ package net.i2p.client.streaming;
 
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 
 import net.i2p.I2PAppContext;
@@ -9,6 +10,8 @@ import net.i2p.data.Destination;
 import net.i2p.util.Log;
 import net.i2p.util.SimpleTimer2;
 
+import static net.i2p.client.streaming.I2PSocketOptionsImpl.getDouble;
+
 /**
  *  Share important TCP Control Block parameters across Connections
  *  to the same remote peer.
@@ -25,20 +28,43 @@ class TCBShare {
     private final Log _log;
     private final Map<Destination, Entry> _cache;
     private final CleanEvent _cleaner;
+    private final double _rttDampening, _wdwDampening, _rttDevDampening;
 
     private static final long EXPIRE_TIME = 30*60*1000;
     private static final long CLEAN_TIME = 10*60*1000;
+    ///// constants defined in rfc 2140
+    ///// do not change unless you know what you're doing
     private static final double RTT_DAMPENING = 0.75;
+    private static final double RTTDEV_DAMPENING = 0.75;
     private static final double WDW_DAMPENING = 0.75;
+    private static final String RTT_DAMP_PROP="i2p.streaming.tcbcache.rttDampening";
+    private static final String WDW_DAMP_PROP="i2p.streaming.tcbcache.wdwDampening";
+    private static final String RTTDEV_DAMP_PROP="i2p.streaming.tcbcache.rttdevDampening";
+    /////
     private static final int MAX_RTT = ((int) Connection.MAX_RESEND_DELAY) / 2;
+    private static final int MAX_RTT_DEV = (int) (MAX_RTT * 1.5);
     private static final int MAX_WINDOW_SIZE = ConnectionPacketHandler.MAX_SLOW_START_WINDOW;
     
     public TCBShare(I2PAppContext ctx, SimpleTimer2 timer) {
         _context = ctx;
         _log = ctx.logManager().getLog(TCBShare.class);
+        
+        final Properties props = ctx.getProperties();
+        _rttDampening = getDouble(props, RTT_DAMP_PROP, RTT_DAMPENING);
+        _wdwDampening = getDouble(props, WDW_DAMP_PROP, WDW_DAMPENING);
+        _rttDevDampening = getDouble(props, RTTDEV_DAMP_PROP, RTTDEV_DAMPENING);
+        
         _cache = new ConcurrentHashMap<Destination,Entry>(4);
         _cleaner = new CleanEvent(timer);
         _cleaner.schedule(CLEAN_TIME);
+        
+        if (_log.shouldLog(Log.DEBUG)) {
+            String log = "Creating TCBCache with rttDamp=%s, rttDevDamp=%s, wdwDamp=%s, "+
+                    "expire=%d, clean=%d";
+            log = String.format(log,_rttDampening,_rttDevDampening,_wdwDampening,
+                    EXPIRE_TIME,CLEAN_TIME);
+             _log.debug(log);
+        }
     }
 
     /**
@@ -60,14 +86,22 @@ class TCBShare {
         Entry e = _cache.get(dest);
         if (e == null || e.isExpired())
             return;
-        if (_log.shouldLog(Log.DEBUG))
+        final int rtt, rttDev, wdw;
+        synchronized(e) {
+            rtt = e.getRTT();
+            rttDev = e.getRTTDev();
+            wdw = e.getWindowSize();
+        }
+        if (_log.shouldLog(Log.DEBUG)) {
             _log.debug("From cache: " +
                        con.getSession().getMyDestination().calculateHash().toBase64().substring(0, 4) +
                        '-' +
                        dest.calculateHash().toBase64().substring(0, 4) +
-                       " RTT: " + e.getRTT() + " wdw: " + e.getWindowSize());
-        opts.setRTT(e.getRTT());
-        opts.setWindowSize(e.getWindowSize());
+                       " RTT: " + rtt + 
+                       " RTTDev: "+ rttDev +
+                       " wdw: " + wdw );
+        }
+        opts.loadFromCache(rtt,rttDev,wdw);
     }
 
     /** store to cache */
@@ -82,47 +116,61 @@ class TCBShare {
             return;
         int old = -1;
         int oldw = -1;
+        int oldDev = -1;
         Entry e = _cache.get(dest);
         if (e == null || e.isExpired()) {
-            e = new Entry(opts.getRTT(), opts.getWindowSize());
+            e = new Entry(opts.getRTT(), opts.getWindowSize(), opts.getRTTDev());
             _cache.put(dest, e);
         } else {
             synchronized(e) {
                 old = e.getRTT();
                 oldw = e.getWindowSize();
+                oldDev = e.getRTTDev();
                 e.setRTT(opts.getRTT());
                 e.setWindowSize(opts.getWindowSize());
+                e.setRTTDev(opts.getRTTDev());
             }
         }
-        if (_log.shouldLog(Log.DEBUG))
+        if (_log.shouldLog(Log.DEBUG)) {
             _log.debug("To cache: " +
                        con.getSession().getMyDestination().calculateHash().toBase64().substring(0, 4) +
                        '-' +
                        dest.calculateHash().toBase64().substring(0, 4) +
                        " old: " + old + " con: " + opts.getRTT() + " new: " + e.getRTT() +
+                       " oldDev: " + oldDev + " conDev: " + opts.getRTTDev() + " newDev: " + e.getRTTDev() +
                        " oldw: " + oldw + " conw: " + opts.getWindowSize() + " neww: " + e.getWindowSize());
+        }
     }
 
     private class Entry {
         int _rtt;
         int _wdw;
+        int _rttDev;
         long _updated;
 
-        public Entry(int ms, int wdw) {
+        public Entry(int ms, int wdw, int rttDev) {
             _rtt = ms;
             _wdw = wdw;
+            _rttDev = rttDev;
             _updated = _context.clock().now();
         }
         public synchronized int getRTT() { return _rtt; }
         public synchronized void setRTT(int ms) {
-            _rtt = (int)(RTT_DAMPENING*_rtt + (1-RTT_DAMPENING)*ms);        
+            _rtt = (int)(_rttDampening*_rtt + (1-_rttDampening)*ms);        
             if (_rtt > MAX_RTT)
                 _rtt = MAX_RTT;
             _updated = _context.clock().now();
         }
+        public synchronized int getRTTDev() { return _rttDev; }
+        public synchronized void setRTTDev(int count) {
+            _rttDev = (int)(_rttDevDampening*_rttDev + (1-_rttDevDampening)*count);        
+            if (_rttDev > MAX_RTT_DEV)
+                _rttDev = MAX_RTT_DEV;
+            _updated = _context.clock().now();
+        }
         public synchronized int getWindowSize() { return _wdw; }
         public synchronized void setWindowSize(int wdw) {
-            _wdw = (int)(0.5 + WDW_DAMPENING*_wdw + (1-WDW_DAMPENING)*wdw);       
+            _wdw = (int)(0.5 + _wdwDampening*_wdw + (1-_wdwDampening)*wdw);       
             if (_wdw > MAX_WINDOW_SIZE)
                 _wdw = MAX_WINDOW_SIZE;
             _updated = _context.clock().now();
diff --git a/debian/patches/0001-path-substitution.patch b/debian/patches/0001-path-substitution.patch
index b88aa1e448aa3786434239bac987b3cd691226ec..68d4be8cb71c2dc7ae1ab08e9f72e95d24577ea1 100644
--- a/debian/patches/0001-path-substitution.patch
+++ b/debian/patches/0001-path-substitution.patch
@@ -41,7 +41,7 @@ Debian wrapper.config to try to prevent confusion.
 -# should have been replaced by the izpack installer.
 -# If you did not run the installer, replace them with the appropriate paths.
 -I2P="%INSTALL_PATH"
--if [ "`uname -s`" == "Darwin" ]; then
+-if [ "`uname -s`" = "Darwin" ]; then
 -   if [ -d "%USER_HOME/Library/Application Support" ]; then
 -       I2P_CONFIG_DIR="%USER_HOME/Library/Application Support/i2p"
 -   else
diff --git a/installer/resources/certificates/reseed.pkol.de.crt b/installer/resources/certificates/reseed.pkol.de.crt
new file mode 100644
index 0000000000000000000000000000000000000000..c560b64f6aeec8c9f9ec28e8688f79de9d1fc888
--- /dev/null
+++ b/installer/resources/certificates/reseed.pkol.de.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/jCCAmegAwIBAgIJALLizEjOqx6kMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMTDnJlc2VlZC5wa29sLmRlMB4XDTEzMDcy
+MjE3MjAwN1oXDTI0MDcwNDE3MjAwN1owXjELMAkGA1UEBhMCQVUxEzARBgNVBAgT
+ClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEX
+MBUGA1UEAxMOcmVzZWVkLnBrb2wuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
+AoGBAKcGetxR5BVrCjUe/sCvMfGiMoyhATjPGVdN+j5qxFdSOhbsC6KAhqL5GNyu
+so8VKpHkIKaD5NeCAonUDLNXB+YOtR+YAHQRsKoR7ApQ5mwpNBsnbUthg1WK3Y/0
+DrYsN7q7rzhLZ1eKm9qy09Ym2c8GnMy/4WpJzwVMji86+p9rAgMBAAGjgcMwgcAw
+HQYDVR0OBBYEFIzPJdHcn4B0CbPOisqt/JLb+BQ/MIGQBgNVHSMEgYgwgYWAFIzP
+JdHcn4B0CbPOisqt/JLb+BQ/oWKkYDBeMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRcw
+FQYDVQQDEw5yZXNlZWQucGtvbC5kZYIJALLizEjOqx6kMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADgYEAMhy4JVAsTdmkcdxb3x1JNgD7ftWEPl5T2vKrRYCR
+LD24FgLLdTGoXEB/NeH8qD3i5xwqc8h9oAvsFx5lp8DhcsZ0YMIuqmRDwmxAVOJ7
+Ke3UR9Zu40ql7u8K4dXtjTyCi6J7twTY76JA/fAhTzgPJoGVBysVQCoW97ukY2jR
+PGk=
+-----END CERTIFICATE-----
diff --git a/installer/resources/i2prouter b/installer/resources/i2prouter
index 39bc19d0b496b3aa093d4dff91224e701124be56..59f8b5232de5e2734499341bf58dc59923d89857 100644
--- a/installer/resources/i2prouter
+++ b/installer/resources/i2prouter
@@ -29,7 +29,7 @@
 # should have been replaced by the izpack installer.
 # If you did not run the installer, replace them with the appropriate paths.
 I2P="%INSTALL_PATH"
-if [ "`uname -s`" == "Darwin" ]; then
+if [ "`uname -s`" = "Darwin" ]; then
    if [ -d "%USER_HOME/Library/Application Support" ]; then
        I2P_CONFIG_DIR="%USER_HOME/Library/Application Support/i2p"
    else
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index a411b009986dc5f1f6384384ad98aeea42885422..346f62411f548984dcfd553fffffbe92b1477cd0 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -21,7 +21,7 @@ public class RouterVersion {
     public final static long BUILD = 0;
 
     /** for example "-test" */
-    public final static String EXTRA = "";
+    public final static String EXTRA = "-rc0971";
     public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + FULL_VERSION);
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java
index 34987aa5ee660d9b999b2cececc7f9648cac3b81..363c748e89648941350f2ade23d6ee2753df8512 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java
@@ -24,6 +24,8 @@ import net.i2p.util.Log;
 class FloodfillStoreJob extends StoreJob {    
     private final FloodfillNetworkDatabaseFacade _facade;
 
+    private static final String PROP_RI_VERIFY = "router.verifyRouterInfoStore";
+
     /**
      * Send a data structure to the floodfills
      * 
@@ -64,6 +66,10 @@ class FloodfillStoreJob extends StoreJob {
             // it finds something stamped with that time or newer.
             DatabaseEntry data = _state.getData();
             boolean isRouterInfo = data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO;
+            // default false
+            if (isRouterInfo && !getContext().getBooleanProperty(PROP_RI_VERIFY))
+                return;
+
             long published = data.getDate();
 
             // we should always have exactly one successful entry
diff --git a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java
index aa82f82bbd3751ad50487e67488fde2d496d29b6..9c8bb8eeb897d871cc1777eca045738cd07092e7 100644
--- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java
+++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java
@@ -69,6 +69,7 @@ public class Reseeder {
               "http://193.150.121.66/netDb/" + "," +
               "http://netdb.i2p2.no/" + "," +
               "http://reseed.info/"  + "," +
+              "http://reseed.pkol.de/" + "," +
               "http://ieb9oopo.mooo.com";
               // Temp disabled since h2ik have been AWOL since 06-03-2013
               //"http://i2p.feared.eu/";
@@ -83,6 +84,7 @@ public class Reseeder {
               "https://193.150.121.66/netDb/" + "," +
               "https://netdb.i2p2.no/" + "," +
               "https://reseed.info/"  + "," +
+              "https://reseed.pkol.de/" + "," +
               "https://ieb9oopo.mooo.com";
               // Temp disabled since h2ik have been AWOL since 06-03-2013
               //"https://i2p.feared.eu/";
diff --git a/router/java/src/org/cybergarage/upnp/Device.java b/router/java/src/org/cybergarage/upnp/Device.java
index 7c492624c39524de4f39fe738462a746b60e707c..ba1f26eeeeb72eaa2b2273245f1ddc6df896b80f 100644
--- a/router/java/src/org/cybergarage/upnp/Device.java
+++ b/router/java/src/org/cybergarage/upnp/Device.java
@@ -283,6 +283,9 @@ public class Device implements org.cybergarage.http.HTTPRequestListener, SearchL
 		}
 
 		urlString = HTTP.toRelativeURL(urlString);
+		// I2P fix for devices that return a base URL with trailing /
+		if (urlBaseStr.endsWith("/") && urlString.startsWith("/"))
+			urlString = urlString.substring(1);
 		String absUrl = urlBaseStr + urlString;
 		try {
 			URL url = new URL(absUrl);