diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHelper.java index 6e9c4691b..fe17164d3 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHelper.java @@ -90,14 +90,14 @@ public class ConfigTunnelsHelper { renderOptions(buf, 0, MAX_LENGTH, now, "", "hop"); if (now > MAX_LENGTH) renderOptions(buf, now, now, now, "", "hop"); - buf.append("\n"); + buf.append("\n"); buf.append("\n"); buf.append("\n"); // tunnel depth variance @@ -111,7 +111,7 @@ public class ConfigTunnelsHelper { renderOptions(buf, now, now, now, "+ 0-", "hop"); else if (now < MIN_NEG_VARIANCE) renderOptions(buf, now, now, now, "+/- 0", "hop"); - buf.append("\n"); + buf.append("\n"); buf.append("\n"); // tunnel quantity buf.append("Quantity\n"); @@ -131,14 +131,14 @@ public class ConfigTunnelsHelper { renderOptions(buf, 1, MAX_QUANTITY, now, "", "tunnel"); if (now > MAX_QUANTITY) renderOptions(buf, now, now, now, "", "tunnel"); - buf.append("\n"); + buf.append("\n"); buf.append("\n"); buf.append("\n"); // tunnel backup quantity @@ -148,14 +148,14 @@ public class ConfigTunnelsHelper { renderOptions(buf, 0, MAX_QUANTITY, now, "", "tunnel"); if (now > MAX_QUANTITY) renderOptions(buf, now, now, now, "", "tunnel"); - buf.append("\n"); + buf.append("\n"); buf.append("\n"); buf.append("\n"); // custom options diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java index 8ca0e982c..281203d91 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java @@ -28,11 +28,16 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver { /** * This tells the flusher in MessageOutputStream whether to flush. * It won't flush if this returns true. - * It was: return con.getUnackedPacketsSent() > 0; + * + * It was: return con.getUnackedPacketsSent() > 0 (i.e. Nagle) * But then, for data that fills more than one packet, the last part of * the data isn't sent until all the previous packets are acked. Which is very slow. + * The poor interaction of Nagle and Delayed Acknowledgements is well-documented. * * So let's send data along unless the outbound window is full. + * (i.e. no-Nagle or TCP_NODELAY) + * + * Probably should have a configuration option for this. * * @return !flush */ 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 07915a51e..3cc159f98 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java @@ -56,7 +56,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { private static final int TREND_COUNT = 3; static final int INITIAL_WINDOW_SIZE = 12; static final int DEFAULT_MAX_SENDS = 8; - + public static final int DEFAULT_INITIAL_RTT = 10*1000; static final int MIN_WINDOW_SIZE = 1; /** @@ -208,7 +208,7 @@ public 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, 10*1000)); + 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, 2000)); @@ -237,7 +237,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { 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, 10*1000)); + 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)) @@ -306,6 +306,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { } /** after how many consecutive messages should we ack? + * This doesn't appear to be used. * @return receive window size. */ public int getReceiveWindow() { return _receiveWindow; } @@ -420,7 +421,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { * @return Maximum retrys before failing a sent message. */ public int getMaxResends() { return _maxResends; } - public void setMaxResends(int numSends) { _maxResends = numSends; } + public void setMaxResends(int numSends) { _maxResends = Math.max(numSends, 0); } /** * What period of inactivity qualifies as "too long"? diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Packet.java b/apps/streaming/java/src/net/i2p/client/streaming/Packet.java index 32c33fdb0..61a7de96d 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/Packet.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/Packet.java @@ -38,7 +38,7 @@ import net.i2p.util.Log; *
  • {@link #FLAG_SIGNATURE_INCLUDED}: {@link net.i2p.data.Signature}
  • *
  • {@link #FLAG_SIGNATURE_REQUESTED}: no option data
  • *
  • {@link #FLAG_FROM_INCLUDED}: {@link net.i2p.data.Destination}
  • - *
  • {@link #FLAG_DELAY_REQUESTED}: 1 byte integer
  • + *
  • {@link #FLAG_DELAY_REQUESTED}: 2 byte integer
  • *
  • {@link #FLAG_MAX_PACKET_SIZE_INCLUDED}: 2 byte integer
  • *
  • {@link #FLAG_PROFILE_INTERACTIVE}: no option data
  • * diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index 69f6c99cc..6b62513c5 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -171,18 +171,14 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa for (Iterator iter = options.keySet().iterator(); iter.hasNext();) { String key = (String) iter.next(); String val = options.getProperty(key); - if (key.startsWith("java")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping java.* property: " + key); - } else if (key.startsWith("user")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping user.* property: " + key); - } else if (key.startsWith("os")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping os.* property: " + key); - } else if (key.startsWith("sun")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping sun.* property: " + key); - } else if (key.startsWith("file")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping file.* property: " + key); - } else if (key.startsWith("line")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping line.* property: " + key); + if (key.startsWith("java") || + key.startsWith("user") || + key.startsWith("os") || + key.startsWith("sun") || + key.startsWith("file") || + key.startsWith("line") || + key.startsWith("wrapper")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping property: " + key); } else if ((key.length() > 255) || (val.length() > 255)) { if (_log.shouldLog(Log.WARN)) _log.warn(getPrefix() + "Not passing on property [" diff --git a/core/java/src/net/i2p/data/Certificate.java b/core/java/src/net/i2p/data/Certificate.java index 40a239053..0d89fcdd8 100644 --- a/core/java/src/net/i2p/data/Certificate.java +++ b/core/java/src/net/i2p/data/Certificate.java @@ -39,6 +39,8 @@ public class Certificate extends DataStructureImpl { /** Signed with 40-byte Signature and (optional) 32-byte hash */ public final static int CERTIFICATE_TYPE_SIGNED = 3; public final static int CERTIFICATE_LENGTH_SIGNED_WITH_HASH = Signature.SIGNATURE_BYTES + Hash.HASH_LENGTH; + /** Contains multiple certs */ + public final static int CERTIFICATE_TYPE_MULTIPLE = 4; public Certificate() { _type = 0; diff --git a/history.txt b/history.txt index a14eea390..7caf84a83 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,12 @@ +2008-11-21 zzz + * Cache DNS and negative DNS for 5m (was 1m and forever) + * Delay shitlist cleaner at startup + * Strip wrapper properties from client config + * Define multiple cert type + * Prohibit negative maxSends in streaming + * HTML fixup on configtunnels.jsp + * Increase wrapper exit timeout from default 15s to 30s + 2008-11-20 zzz * I2PTunnel: Handle missing fields in edit pages better * Move DummyNetworkDatabaseFacade to his own file diff --git a/installer/resources/wrapper.config b/installer/resources/wrapper.config index 86fdce2eb..d546dbeff 100644 --- a/installer/resources/wrapper.config +++ b/installer/resources/wrapper.config @@ -60,6 +60,11 @@ wrapper.java.additional.1=-DloggerFilenameOverride=logs/log-router-@.txt wrapper.java.additional.2=-Dorg.mortbay.http.Version.paranoid=true wrapper.java.additional.3=-Dorg.mortbay.util.FileResource.checkAliases=false wrapper.java.additional.4=-Dorg.mortbay.xml.XmlParser.NotValidating=true +# Uncomment this for better performance. +# If it doesn't work, server mode is not available in your JVM. +# This may not be required if your machine is already "server-class". +# See http://java.sun.com/j2se/1.5.0/docs/guide/vm/server-class.html +#wrapper.java.additional.5=-server # Initial Java Heap Size (in MB) #wrapper.java.initmemory=4 @@ -134,6 +139,7 @@ wrapper.restart.delay=60 wrapper.ping.interval=600 wrapper.ping.timeout=605 +wrapper.jvm_exit.timeout=30 # use the wrapper's internal timer thread. otherwise this would # force a restart of the router during daylight savings time as well diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index c7c61245e..98fb1fccd 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -81,12 +81,15 @@ public class Router { public final static String PROP_KEYS_FILENAME = "router.keys.location"; public final static String PROP_KEYS_FILENAME_DEFAULT = "router.keys"; public final static String PROP_SHUTDOWN_IN_PROGRESS = "__shutdownInProgress"; + public final static String DNS_CACHE_TIME = "" + (5*60); static { // grumble about sun's java caching DNS entries *forever* by default - // so lets just keep 'em for a minute - System.setProperty("sun.net.inetaddr.ttl", "60"); - System.setProperty("networkaddress.cache.ttl", "60"); + // so lets just keep 'em for a short time + System.setProperty("sun.net.inetaddr.ttl", DNS_CACHE_TIME); + System.setProperty("sun.net.inetaddr.negative.ttl", DNS_CACHE_TIME); + System.setProperty("networkaddress.cache.ttl", DNS_CACHE_TIME); + System.setProperty("networkaddress.cache.negative.ttl", DNS_CACHE_TIME); // until we handle restricted routes and/or all peers support v6, try v4 first System.setProperty("java.net.preferIPv4Stack", "true"); System.setProperty("http.agent", "I2P"); diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java index b1d3629e7..5868a15b4 100644 --- a/router/java/src/net/i2p/router/Shitlist.java +++ b/router/java/src/net/i2p/router/Shitlist.java @@ -49,6 +49,7 @@ public class Shitlist { public final static long SHITLIST_DURATION_MAX = 60*60*1000; public final static long SHITLIST_DURATION_PARTIAL = 20*60*1000; public final static long SHITLIST_DURATION_FOREVER = 181l*24*60*60*1000; // will get rounded down to 180d on console + public final static long SHITLIST_CLEANER_START_DELAY = SHITLIST_DURATION_PARTIAL; public Shitlist(RouterContext context) { _context = context; @@ -62,6 +63,7 @@ public class Shitlist { public Cleanup(RouterContext ctx) { super(ctx); _toUnshitlist = new ArrayList(4); + getTiming().setStartAfter(_context.clock().now() + SHITLIST_CLEANER_START_DELAY); } public String getName() { return "Cleanup shitlist"; } public void runJob() {