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);