diff --git a/README.txt b/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..49a62ee5ba4a59e7697cd1d8f84c6ed06fa7e772 --- /dev/null +++ b/README.txt @@ -0,0 +1,31 @@ +Prerequisites to build from source: + Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended) + Apache Ant 1.7.0 or higher + +To build: + ant pkg + Run 'ant' with no arguments to see other build options. + See http://www.i2p2.de/download.html for installation instructions. + +Documentation: + http://www.i2p2.de/ + API: run 'ant javadoc' then start at build/javadoc/index.html + +Latest release: + http://www.i2p2.de/download.html + +To get development branch from source control: + http://www.i2p2.de/newdevelopers.html + +FAQ: + http://www.i2p2.de/faq.html + +Need help? + IRC irc.freenode.net #i2p + http://forum.i2p2.de/ + +Licenses: + http://www.i2p2.de/licenses.html + Also http://localhost:7657/help.jsp + Also see licenses for the individual bundled apps in apps/* + diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index f014580ec5f5e4728e6d933fdc3f65fef630357a..26ed5860f07c30dab1d811ea2970d8bb3b34621c 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -24,6 +24,7 @@ import net.i2p.data.Destination; import net.i2p.data.Hash; import net.i2p.util.EepGet; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -183,7 +184,7 @@ public class I2PSnarkUtil { synchronized (_shitlist) { _shitlist.add(dest); } - SimpleTimer.getInstance().addEvent(new Unshitlist(dest), 10*60*1000); + SimpleScheduler.getInstance().addEvent(new Unshitlist(dest), 10*60*1000); throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage()); } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java index 8fed9577ae0d82d0e78177f5362a9c4104866627..1a53c342f5d1c48493d440793ac796a955335b3b 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java @@ -28,6 +28,7 @@ import java.util.List; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; class PeerConnectionOut implements Runnable @@ -215,7 +216,7 @@ class PeerConnectionOut implements Runnable private void addMessage(Message m) { if (m.type == Message.PIECE) - SimpleTimer.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT); synchronized(sendQueue) { sendQueue.add(m); diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java index 1b4feee75f5c8d6b1997d0984624c41b9a054505..054b58262b3ed013db52214738a6f76766cad0e5 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java @@ -60,7 +60,7 @@ class PeerState // If we have te resend outstanding requests (true after we got choked). private boolean resend = false; - private final static int MAX_PIPELINE = 2; // this is for outbound requests + private final static int MAX_PIPELINE = 3; // this is for outbound requests private final static int MAX_PIPELINE_BYTES = 128*1024; // this is for inbound requests public final static int PARTSIZE = 32*1024; // Snark was 16K, i2p-bt uses 64KB private final static int MAX_PARTSIZE = 64*1024; // Don't let anybody request more than this diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 7e5cd962f013aa8c8415a83858e3b72fcd912ee9..7b62ace8435a92fa3930300ef709b3df5b199247 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -141,7 +141,7 @@ public class SnarkManager implements Snark.CompleteListener { if (!_config.containsKey(PROP_I2CP_PORT)) _config.setProperty(PROP_I2CP_PORT, "7654"); if (!_config.containsKey(PROP_I2CP_OPTS)) - _config.setProperty(PROP_I2CP_OPTS, "inbound.length=2 inbound.lengthVariance=0 outbound.length=2 outbound.lengthVariance=0"); + _config.setProperty(PROP_I2CP_OPTS, "inbound.length=2 inbound.lengthVariance=0 outbound.length=2 outbound.lengthVariance=0 inbound.quantity=3 outbound.quantity=3"); if (!_config.containsKey(PROP_EEP_HOST)) _config.setProperty(PROP_EEP_HOST, "localhost"); if (!_config.containsKey(PROP_EEP_PORT)) 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 c7ee93d7d35200e2ffb2b4afc4e321abab496a71..c791ad2fb1150eb872c8181e715d23cc028b72da 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -580,7 +580,7 @@ public class I2PSnarkServlet extends HttpServlet { else if ("AUZV".equals(ch) || "AkZV".equals(ch) || "A0ZV".equals(ch)) client = "Robert"; else - client = "Unknown"; + client = "Unknown (" + ch + ')'; out.write("<font size=-1>" + client + "</font> <tt>" + peer.toString().substring(5, 9) + "</tt>"); if (showDebug) out.write(" inactive " + (peer.getInactiveTime() / 1000) + "s"); diff --git a/apps/i2ptunnel/java/build.xml b/apps/i2ptunnel/java/build.xml index 635cad2e44e735eba9a77aaf970c089c91e09380..564f6fc4b85b3e75aad91dcf58ec90e882e88291 100644 --- a/apps/i2ptunnel/java/build.xml +++ b/apps/i2ptunnel/java/build.xml @@ -42,7 +42,7 @@ </target> <target name="war" depends="precompilejsp"> <war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml" - basedir="../jsp/" excludes="web.xml, *.java, *.jsp"> + basedir="../jsp/" excludes="web.xml, **/*.java, *.jsp"> </war> </target> <target name="precompilejsp" unless="precompilejsp.uptodate"> diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index d6e5bf9f93339c6f08bf4e1047d3b5643137ebeb..38311eaf1de2c7175a41530e9844b7c6462d74ed 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -27,6 +27,7 @@ import net.i2p.data.Destination; import net.i2p.util.EventDispatcher; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runnable { @@ -401,7 +402,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna } if (_maxWaitTime > 0) - SimpleTimer.getInstance().addEvent(new CloseEvent(s), _maxWaitTime); + SimpleScheduler.getInstance().addEvent(new CloseEvent(s), _maxWaitTime); synchronized (_waitingSockets) { _waitingSockets.add(s); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java index 252d4e1aa8e3b55ff6228e473829a9fdc15dfb7c..38c50f2661fdfa57ee0b3eb519c88a1a7abcb445 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java @@ -361,24 +361,24 @@ public class SOCKS5Server extends SOCKSServer { /* * Some namespaces to enclose SOCKS protocol codes */ - private class Method { + private static class Method { private static final int NO_AUTH_REQUIRED = 0x00; private static final int NO_ACCEPTABLE_METHODS = 0xff; } - private class AddressType { + private static class AddressType { private static final int IPV4 = 0x01; private static final int DOMAINNAME = 0x03; private static final int IPV6 = 0x04; } - private class Command { + private static class Command { private static final int CONNECT = 0x01; private static final int BIND = 0x02; private static final int UDP_ASSOCIATE = 0x03; } - private class Reply { + private static class Reply { private static final int SUCCEEDED = 0x00; private static final int GENERAL_SOCKS_SERVER_FAILURE = 0x01; private static final int CONNECTION_NOT_ALLOWED_BY_RULESET = 0x02; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHelper.java index c901948604b90739b5fd17da2a33d791f30c34d6..3ab6354a6362fba67c97d14e470e41dab077264f 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHelper.java @@ -6,22 +6,7 @@ import java.util.TreeSet; import net.i2p.router.RouterContext; -public class ConfigAdvancedHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigAdvancedHelper extends HelperBase { public ConfigAdvancedHelper() {} public String getSettings() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java index d6441736a7ded763d0d73ea96e5b9b59a2b67581..2bee435335d43ac409cc748ca73ec9cdd9c7389b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java @@ -9,22 +9,7 @@ import java.util.TreeSet; import net.i2p.router.RouterContext; import net.i2p.router.startup.ClientAppConfig; -public class ConfigClientsHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigClientsHelper extends HelperBase { public ConfigClientsHelper() {} public String getForm1() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigKeyringHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigKeyringHelper.java index 48bc15068e9767b0af4029d33d2a25d7b719bdec..85c8ee42314830c32a04582ccd8b7ba4ce20f42b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigKeyringHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigKeyringHelper.java @@ -6,22 +6,7 @@ import java.io.OutputStreamWriter; import net.i2p.router.RouterContext; -public class ConfigKeyringHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigKeyringHelper extends HelperBase { public ConfigKeyringHelper() {} public String getSummary() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java index 07acb0849ed0f9d52cadde105398218a21103658..635d2e5445d3385f02dd6cc50f27f5bf027d0a47 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java @@ -6,22 +6,7 @@ import java.util.TreeSet; import net.i2p.router.RouterContext; -public class ConfigLoggingHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigLoggingHelper extends HelperBase { public ConfigLoggingHelper() {} public String getLogFilePattern() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java index d355e9d61c2026d1454e2180e66a771fa6382590..9beeb33cf500b7183f0a9fd8237e74b3e0c5b5e8 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java @@ -10,22 +10,7 @@ import net.i2p.router.transport.udp.UDPAddress; import net.i2p.router.transport.udp.UDPTransport; import net.i2p.time.Timestamper; -public class ConfigNetHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigNetHelper extends HelperBase { public ConfigNetHelper() {} /** copied from various private components */ diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigPeerHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigPeerHelper.java index 63fc1f5e512e22528e47db7f15fe6a34ab6c1e40..662a078b8140fb066c63658e29357a779ee1e194 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigPeerHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigPeerHelper.java @@ -4,25 +4,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; -public class ConfigPeerHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigPeerHelper extends HelperBase { public ConfigPeerHelper() {} public String getBlocklistSummary() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHelper.java index 925fce79acadf7054b828cd960f84051c3ec7c0a..3af4ffafb5f9c0e519c3f99c01371b3b8672d801 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHelper.java @@ -15,8 +15,7 @@ import net.i2p.stat.RateStat; import net.i2p.stat.StatManager; import net.i2p.util.Log; -public class ConfigStatsHelper { - private RouterContext _context; +public class ConfigStatsHelper extends HelperBase { private Log _log; private String _filter; private Set _filters; 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 98141771b71a18987eeecee4bf56c4181760925d..e21f9d9ce77305168ae8690bae51cfc370dc1cd4 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHelper.java @@ -8,22 +8,7 @@ import net.i2p.data.Destination; import net.i2p.router.RouterContext; import net.i2p.router.TunnelPoolSettings; -public class ConfigTunnelsHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigTunnelsHelper extends HelperBase { public ConfigTunnelsHelper() {} diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java index 68e2ec5b9d377c68e8edc8720917578f813e0ea6..818b748a7b534323f3f88418971257a4dee91648 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java @@ -51,7 +51,7 @@ public class ConfigUpdateHandler extends FormHandler { if ( (_updatePolicy == null) || (!_updatePolicy.equals("notify")) ) addFormNotice("Update available, attempting to download now"); else - addFormNotice("Update available, click link on left to download"); + addFormNotice("Update available, click button on left to download"); } else addFormNotice("No update available"); } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java index 0ecaca4f01a9fd8c152f10053f87647e4558975b..d0d2437994d567cafbf58106fa0f6f795888ce14 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java @@ -4,22 +4,7 @@ import net.i2p.crypto.TrustedUpdate; import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; -public class ConfigUpdateHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ConfigUpdateHelper extends HelperBase { public ConfigUpdateHelper() {} public boolean updateAvailable() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java index edacfaa41793da3f00b0fce3373758b7d05fefc0..ce29250b9fbdad83dca8d8c825fe88baa3435cf8 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java @@ -6,25 +6,11 @@ import java.util.Locale; import net.i2p.router.RouterContext; import net.i2p.util.FileUtil; -public class ContentHelper { +public class ContentHelper extends HelperBase { private String _page; private int _maxLines; private boolean _startAtBeginning; private String _lang; - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } public ContentHelper() {} diff --git a/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java index 658caa1a309d8ee27841bb9c91b16e3b4f6a2903..16ce7337d29b4a64f6c9baa0d1cb731864945596 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java @@ -11,27 +11,12 @@ import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; import net.i2p.stat.Rate; -public class GraphHelper { - private RouterContext _context; - private Writer _out; +public class GraphHelper extends HelperBase { private int _periodCount; private boolean _showEvents; private int _width; private int _height; private int _refreshDelaySeconds; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } public GraphHelper() { _periodCount = 60; // SummaryListener.PERIODS; @@ -41,7 +26,6 @@ public class GraphHelper { _refreshDelaySeconds = 60; } - public void setOut(Writer out) { _out = out; } public void setPeriodCount(String str) { try { _periodCount = Integer.parseInt(str); } catch (NumberFormatException nfe) {} } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/HelperBase.java b/apps/routerconsole/java/src/net/i2p/router/web/HelperBase.java new file mode 100644 index 0000000000000000000000000000000000000000..db5aa9ba249f9f7f35a3ac62ae53c214f0797732 --- /dev/null +++ b/apps/routerconsole/java/src/net/i2p/router/web/HelperBase.java @@ -0,0 +1,29 @@ +package net.i2p.router.web; + +import java.io.Writer; + +import net.i2p.router.RouterContext; + +/** + * Base helper + */ +public abstract class HelperBase { + protected RouterContext _context; + protected Writer _out; + + /** + * Configure this bean to query a particular router context + * + * @param contextId begging few characters of the routerHash, or null to pick + * the first one we come across. + */ + public void setContextId(String contextId) { + try { + _context = ContextHelper.getContext(contextId); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public void setWriter(Writer out) { _out = out; } +} diff --git a/apps/routerconsole/java/src/net/i2p/router/web/JobQueueHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/JobQueueHelper.java index a56cce19afd03d31813b815168b5552cab0441cc..cf8ed23520e12ce2d4c85209533e543e96263260 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/JobQueueHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/JobQueueHelper.java @@ -7,27 +7,9 @@ import java.io.Writer; import net.i2p.router.RouterContext; -public class JobQueueHelper { - private RouterContext _context; - private Writer _out; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class JobQueueHelper extends HelperBase { public JobQueueHelper() {} - public void setWriter(Writer writer) { _out = writer; } - public String getJobQueueSummary() { try { if (_out != null) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java index 67d2fc38c6a3a59edce8f75cdcb589f1354efecc..e1fce8f3ecc2ecc763823fd922ea4e2aca8a982a 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java @@ -5,22 +5,7 @@ import java.util.List; import net.i2p.router.RouterContext; import net.i2p.util.FileUtil; -public class LogsHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class LogsHelper extends HelperBase { public LogsHelper() {} public String getLogs() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java index a4b2125e3a8266c5183823be7d398194069610d3..2d50379f3402dac022d290471573521a11d2e79a 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java @@ -6,22 +6,8 @@ import java.util.Map; import net.i2p.router.RouterContext; -public class NavHelper { +public class NavHelper extends HelperBase { private static Map _apps = new HashMap(); - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } public NavHelper() {} diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java index 114579a27c854690343ae8ba66bdb42e0552bc81..a3280ac446c4af4ad3f29c1633103762e1f73a6e 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java @@ -7,29 +7,12 @@ import java.io.Writer; import net.i2p.router.RouterContext; -public class NetDbHelper { - private RouterContext _context; - private Writer _out; +public class NetDbHelper extends HelperBase { private String _routerPrefix; private boolean _full = false; - - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } public NetDbHelper() {} - public void setWriter(Writer writer) { _out = writer; } public void setRouter(String r) { _routerPrefix = r; } public void setFull(String f) { _full = "1".equals(f); }; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NoticeHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NoticeHelper.java index cd656e9e941a9b14625f5358c62428c47b666856..d5ce2b0d96ebe6de763ced489480a36428397eb8 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NoticeHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NoticeHelper.java @@ -7,22 +7,7 @@ import net.i2p.router.RouterContext; * Simple helper to query the appropriate router for data necessary to render * any emergency notices */ -public class NoticeHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class NoticeHelper extends HelperBase { public String getSystemNotice() { if (true) return ""; // moved to the left hand nav if (_context.router().gracefulShutdownInProgress()) { @@ -35,4 +20,4 @@ public class NoticeHelper { return ""; } } -} \ No newline at end of file +} diff --git a/apps/routerconsole/java/src/net/i2p/router/web/OldConsoleHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/OldConsoleHelper.java index 556367e27bcc16a58dd8a37672b65fd1d98477e7..6237183abf5fb9f035c7887be5711825babf6653 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/OldConsoleHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/OldConsoleHelper.java @@ -8,29 +8,9 @@ import java.io.Writer; import net.i2p.router.RouterContext; import net.i2p.router.admin.StatsGenerator; -public class OldConsoleHelper { - private RouterContext _context; - private Writer _out; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class OldConsoleHelper extends HelperBase { public OldConsoleHelper() {} - public void setWriter(Writer writer) { - _out = writer; - } - public String getConsole() { try { if (_out != null) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PeerHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/PeerHelper.java index e5561fe1fe61166bf45fcb4fe7a325ca8fd672c5..2504067ac3a484ccf35aa28c853810acc97f5139 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/PeerHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/PeerHelper.java @@ -5,28 +5,12 @@ import java.io.Writer; import net.i2p.router.RouterContext; -public class PeerHelper { - private RouterContext _context; - private Writer _out; +public class PeerHelper extends HelperBase { private int _sortFlags; private String _urlBase; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } public PeerHelper() {} - public void setOut(Writer out) { _out = out; } public void setSort(String flags) { if (flags != null) { try { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java index 4db1010a570d160d296da60c1cf02d907d10a195..702a63e50013d14fefd1f1a468f2253eaf9c965d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java @@ -6,22 +6,7 @@ import java.io.OutputStreamWriter; import net.i2p.router.RouterContext; -public class ProfilesHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class ProfilesHelper extends HelperBase { public ProfilesHelper() {} public String getProfileSummary() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java index 8b67d2622e2cea63ec565cf81a8c9b9ee36f99bb..ce6fefd5d677ab2ea860aa4d783f437d6092e5b2 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java @@ -11,12 +11,10 @@ import net.i2p.router.RouterContext; * uuuugly. dump the peer profile data if given a peer. * */ -public class StatHelper { +public class StatHelper extends HelperBase { private String _peer; - private Writer _writer; public void setPeer(String peer) { _peer = peer; } - public void setWriter(Writer writer) { _writer = writer; } public String getProfile() { RouterContext ctx = (RouterContext)net.i2p.router.RouterContext.listContexts().get(0); @@ -25,10 +23,10 @@ public class StatHelper { Hash peer = (Hash)iter.next(); if (peer.toBase64().startsWith(_peer)) { try { - WriterOutputStream wos = new WriterOutputStream(_writer); + WriterOutputStream wos = new WriterOutputStream(_out); ctx.profileOrganizer().exportProfile(peer, wos); wos.flush(); - _writer.flush(); + _out.flush(); return ""; } catch (Exception e) { e.printStackTrace(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index ad8e7135d5496dcd93fa768ea6457cae71f96baa..2e56e858bcbbc928f6324df3085b2274cf63c924 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -25,22 +25,7 @@ import net.i2p.stat.RateStat; * Simple helper to query the appropriate router for data necessary to render * the summary sections on the router console. */ -public class SummaryHelper { - private RouterContext _context; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class SummaryHelper extends HelperBase { /** * Retrieve the shortened 4 character ident for the router located within * the current JVM at the given context. diff --git a/apps/routerconsole/java/src/net/i2p/router/web/TunnelHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/TunnelHelper.java index 4d4eba76b79ef5d466c1da2d569426c03868bd32..3cd8a96e3d03d99694679394274195758a3bed12 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/TunnelHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/TunnelHelper.java @@ -7,27 +7,9 @@ import java.io.Writer; import net.i2p.router.RouterContext; -public class TunnelHelper { - private RouterContext _context; - private Writer _out; - /** - * Configure this bean to query a particular router context - * - * @param contextId begging few characters of the routerHash, or null to pick - * the first one we come across. - */ - public void setContextId(String contextId) { - try { - _context = ContextHelper.getContext(contextId); - } catch (Throwable t) { - t.printStackTrace(); - } - } - +public class TunnelHelper extends HelperBase { public TunnelHelper() {} - public void setWriter(Writer writer) { _out = writer; } - public String getTunnelSummary() { try { if (_out != null) { diff --git a/apps/routerconsole/jsp/graphs.jsp b/apps/routerconsole/jsp/graphs.jsp index 422bf19d67e0212ba3d4112fca7b9cb308c2d745..06807f397f3e8a6e0917b6987cf7153e18243d59 100644 --- a/apps/routerconsole/jsp/graphs.jsp +++ b/apps/routerconsole/jsp/graphs.jsp @@ -14,7 +14,7 @@ <jsp:useBean class="net.i2p.router.web.GraphHelper" id="graphHelper" scope="request" /> <jsp:setProperty name="graphHelper" property="*" /> <jsp:setProperty name="graphHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" /> - <jsp:setProperty name="graphHelper" property="out" value="<%=out%>" /> + <jsp:setProperty name="graphHelper" property="writer" value="<%=out%>" /> <jsp:getProperty name="graphHelper" property="images" /> <jsp:getProperty name="graphHelper" property="form" /> </div> diff --git a/apps/routerconsole/jsp/peers.jsp b/apps/routerconsole/jsp/peers.jsp index a537af634ad40e5520569ce781e8e3ce157a17c4..d3b941a34b408fb718cb3344c8944e9400e2b5d8 100644 --- a/apps/routerconsole/jsp/peers.jsp +++ b/apps/routerconsole/jsp/peers.jsp @@ -13,7 +13,7 @@ <div class="main" id="main"> <jsp:useBean class="net.i2p.router.web.PeerHelper" id="peerHelper" scope="request" /> <jsp:setProperty name="peerHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" /> - <jsp:setProperty name="peerHelper" property="out" value="<%=out%>" /> + <jsp:setProperty name="peerHelper" property="writer" value="<%=out%>" /> <jsp:setProperty name="peerHelper" property="urlBase" value="peers.jsp" /> <jsp:setProperty name="peerHelper" property="sort" value="<%=request.getParameter("sort") != null ? request.getParameter("sort") : ""%>" /> <jsp:getProperty name="peerHelper" property="peerSummary" /> diff --git a/apps/routerconsole/jsp/summary.jsp b/apps/routerconsole/jsp/summary.jsp index 687ccf15ad9682d28f3400cb13099cad9dc4bd11..48f3b4fefd9e2c9dcd153cdb2d7f555105da2b46 100644 --- a/apps/routerconsole/jsp/summary.jsp +++ b/apps/routerconsole/jsp/summary.jsp @@ -63,11 +63,9 @@ if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev); System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+""); String uri = request.getRequestURI(); - if (uri.indexOf('?') > 0) - uri = uri + "&reseedNonce=" + nonce; - else - uri = uri + "?reseedNonce=" + nonce; - out.print(" <a href=\"" + uri + "\">reseed</a><br />"); + out.print("<p><form action=\"" + uri + "\" method=\"GET\">\n"); + out.print("<input type=\"hidden\" name=\"reseedNonce\" value=\"" + nonce + "\" >\n"); + out.print("<button type=\"submit\" >Reseed</button></form></p>\n"); } } // If a new reseed ain't running, and the last reseed had errors, show error message 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 431540d46c51086a2f988152dcc6aa871fd7bea6..e493124d05c19fb4a223e34cae8a44325016dee3 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java @@ -12,6 +12,7 @@ import net.i2p.client.I2PSession; import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -247,7 +248,7 @@ public class Connection { void sendReset() { if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } long now = _context.clock().now(); if (_resetSentOn + 10*1000 > now) return; // don't send resets too fast @@ -461,7 +462,7 @@ public class Connection { void resetReceived() { if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } _resetReceived = true; MessageOutputStream mos = _outputStream; @@ -509,7 +510,7 @@ public class Connection { if (removeFromConMgr) { if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } } _connected = false; @@ -708,7 +709,7 @@ public class Connection { _closeSentOn = when; if (_disconnectScheduledOn < 0) { _disconnectScheduledOn = _context.clock().now(); - SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); } } public long getCloseReceivedOn() { return _closeReceivedOn; } 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 7d1d4827f84adcd47228da17ed492e88569ed980..a123708e4a515efd022d81ee12546620e62cd952 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java @@ -5,6 +5,7 @@ import java.util.List; import net.i2p.I2PAppContext; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -54,7 +55,7 @@ class ConnectionHandler { } if (_log.shouldLog(Log.DEBUG)) _log.debug("Receive new SYN: " + packet + ": timeout in " + _acceptTimeout); - RetransmissionTimer.getInstance().addEvent(new TimeoutSyn(packet), _acceptTimeout); + SimpleScheduler.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 7c445f0380140cb12199061d579da758cf260aa3..f7b245cb83fb0748f3d37e805ed1c2bd345b70b9 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java @@ -7,6 +7,7 @@ import net.i2p.I2PException; import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -168,7 +169,7 @@ public class ConnectionPacketHandler { // take note of congestion if (_log.shouldLog(Log.WARN)) _log.warn("congestion.. dup " + packet); - RetransmissionTimer.getInstance().addEvent(new AckDup(con), con.getOptions().getSendAckDelay()); + SimpleScheduler.getInstance().addEvent(new AckDup(con), con.getOptions().getSendAckDelay()); //con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay()); //fastAck = true; } else { diff --git a/apps/susidns/src/build.xml b/apps/susidns/src/build.xml index f31340954374ca54773b7196f1a3908ae6d9d28d..d3f5f1662c72284c6677379b447a60970f436753 100644 --- a/apps/susidns/src/build.xml +++ b/apps/susidns/src/build.xml @@ -63,12 +63,10 @@ <fileset dir="."> <include name="WEB-INF/**/*.class"/> <include name="WEB-INF/lib/*.jar"/> - <include name="${src}/**/*.java"/> <include name="jsp/*.jsp"/> <include name="images/*.png"/> <include name="css.css"/> <include name="index.html"/> - <include name="build.xml"/> <include name="WEB-INF/web-template.xml"/> <include name="WEB-INF/web-out.xml"/> <include name="WEB-INF/classes/${project}.properties"/> diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml index 2bdc4f164ed51c51cec87717b6c93d69d2576024..abf2a88cf71c2829a9ca9beeada5ad658f02e7f7 100644 --- a/apps/susimail/build.xml +++ b/apps/susimail/build.xml @@ -19,7 +19,7 @@ <target name="jar" depends="compile, war" /> <target name="war" depends="compile"> <war destfile="susimail.war" webxml="src/WEB-INF/web.xml" - basedir="src/" excludes="WEB-INF/web.xml"> + basedir="src/" excludes="WEB-INF/web.xml LICENSE src/**/*"> </war> </target> <target name="javadoc"> diff --git a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java index 380c5b172091bdf92187d7e2d04ad203284f200d..4a635fd08092d23ba9ac385a4e9cc338982fbc4f 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java +++ b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java @@ -11,6 +11,7 @@ package net.i2p.apps.systray; import java.awt.Frame; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; import snoozesoft.systray4j.SysTrayMenu; import snoozesoft.systray4j.SysTrayMenuEvent; @@ -60,14 +61,13 @@ public class SysTray implements SysTrayMenuListener { private SysTray() { _sysTrayMenuIcon.addSysTrayMenuListener(this); createSysTrayMenu(); - SimpleTimer.getInstance().addEvent(new RefreshDisplayEvent(), REFRESH_DISPLAY_FREQUENCY); + SimpleScheduler.getInstance().addPeriodicEvent(new RefreshDisplayEvent(), REFRESH_DISPLAY_FREQUENCY); } private static final long REFRESH_DISPLAY_FREQUENCY = 30*1000; private class RefreshDisplayEvent implements SimpleTimer.TimedEvent { public void timeReached() { refreshDisplay(); - SimpleTimer.getInstance().addEvent(RefreshDisplayEvent.this, REFRESH_DISPLAY_FREQUENCY); } } diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index a57957107a8d29380cee2ce7be4c7428ab331dd0..d4ff7360a73e48ac8b91607f0c790dd115ac18b9 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -40,6 +40,7 @@ import net.i2p.data.i2cp.MessagePayloadMessage; import net.i2p.data.i2cp.SessionId; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -369,7 +370,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Notified availability for session " + _sessionId + ", message " + id); } - SimpleTimer.getInstance().addEvent(new VerifyUsage(mid), 30*1000); + SimpleScheduler.getInstance().addEvent(new VerifyUsage(mid), 30*1000); } private class VerifyUsage implements SimpleTimer.TimedEvent { private Long _msgId; diff --git a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java index 1b160f8dd7cf4042bf29a21f81b6a8277290a4e9..0d71677a970a2f199a9a262dfe915528914ad9c4 100644 --- a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java @@ -24,6 +24,7 @@ import net.i2p.data.PublicKey; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -70,7 +71,7 @@ class TransientSessionKeyManager extends SessionKeyManager { _inboundTagSets = new HashMap(1024); context.statManager().createRateStat("crypto.sessionTagsExpired", "How many tags/sessions are expired?", "Encryption", new long[] { 10*60*1000, 60*60*1000, 3*60*60*1000 }); context.statManager().createRateStat("crypto.sessionTagsRemaining", "How many tags/sessions are remaining after a cleanup?", "Encryption", new long[] { 10*60*1000, 60*60*1000, 3*60*60*1000 }); - SimpleTimer.getInstance().addEvent(new CleanupEvent(), 60*1000); + SimpleScheduler.getInstance().addPeriodicEvent(new CleanupEvent(), 60*1000); } private TransientSessionKeyManager() { this(null); } @@ -80,7 +81,6 @@ class TransientSessionKeyManager extends SessionKeyManager { int expired = aggressiveExpire(); long expireTime = _context.clock().now() - beforeExpire; _context.statManager().addRateData("crypto.sessionTagsExpired", expired, expireTime); - SimpleTimer.getInstance().addEvent(CleanupEvent.this, 60*1000); } } diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 4a074f17cf9bdaefe2b59a8b90f16a48651a20a5..53e32a347e85d42c584e7bd822e87524fd17e64f 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -344,8 +344,9 @@ public class DataHelper { long rv = 0; for (int i = 0; i < numBytes; i++) { - long cur = rawStream.read() & 0xFF; + long cur = rawStream.read(); if (cur == -1) throw new DataFormatException("Not enough bytes for the field"); + cur &= 0xFF; // we loop until we find a nonzero byte (or we reach the end) if (cur != 0) { // ok, data found, now iterate through it to fill the rv @@ -355,9 +356,10 @@ public class DataHelper { cur = cur << shiftAmount; rv += cur; if (j + 1 < remaining) { - cur = rawStream.read() & 0xFF; + cur = rawStream.read(); if (cur == -1) throw new DataFormatException("Not enough bytes for the field"); + cur &= 0xFF; } } break; diff --git a/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java b/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java index 2cd630db618c166c95afa4c2db5254953d7b765c..b5fca013d78cb4c8c22e31225666228843b8ad9c 100644 --- a/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java +++ b/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java @@ -156,7 +156,7 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl { return buf.toString(); } - private class TunnelEndpoint { + private static class TunnelEndpoint { private Hash _router; private TunnelId _tunnelId; @@ -186,4 +186,4 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl { _tunnelId = tunnelId; } } -} \ No newline at end of file +} diff --git a/core/java/src/net/i2p/util/ByteCache.java b/core/java/src/net/i2p/util/ByteCache.java index aadc721aa447143fa0d90c2d6c10f5def65e7703..4bd3da6eff517abfed251ba57deb9374d2d5126c 100644 --- a/core/java/src/net/i2p/util/ByteCache.java +++ b/core/java/src/net/i2p/util/ByteCache.java @@ -55,7 +55,7 @@ public final class ByteCache { _maxCached = maxCachedEntries; _entrySize = entrySize; _lastOverflow = -1; - SimpleTimer.getInstance().addEvent(new Cleanup(), CLEANUP_FREQUENCY); + SimpleScheduler.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY); _log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class); } @@ -120,7 +120,6 @@ public final class ByteCache { _log.debug("Removing " + toRemove + " cached entries of size " + _entrySize); } } - SimpleTimer.getInstance().addEvent(Cleanup.this, CLEANUP_FREQUENCY); } } } diff --git a/core/java/src/net/i2p/util/SimpleScheduler.java b/core/java/src/net/i2p/util/SimpleScheduler.java new file mode 100644 index 0000000000000000000000000000000000000000..91415102c473c56b5c4cce900a9d9b3d96c0ee52 --- /dev/null +++ b/core/java/src/net/i2p/util/SimpleScheduler.java @@ -0,0 +1,164 @@ +package net.i2p.util; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadFactory; + +import net.i2p.I2PAppContext; + +/** + * Simple event scheduler - toss an event on the queue and it gets fired at the + * appropriate time. The method that is fired however should NOT block (otherwise + * they b0rk the timer). + * + * This is like SimpleScheduler but addEvent() for an existing event adds a second + * job. Events cannot be cancelled or rescheduled. + * + * For events that cannot or will not be cancelled or rescheduled - + * for example, a call such as: + * SimpleTimer.getInstance().addEvent(new FooEvent(bar), timeoutMs); + * use SimpleScheduler instead to reduce lock contention in SimpleTimer... + * + * For periodic events, use addPeriodicEvent(). Unlike SimpleTimer, + * uncaught Exceptions will not prevent subsequent executions. + * + * @author zzz + */ +public class SimpleScheduler { + private static final SimpleScheduler _instance = new SimpleScheduler(); + public static SimpleScheduler getInstance() { return _instance; } + private static final int THREADS = 4; + private I2PAppContext _context; + private Log _log; + private ScheduledThreadPoolExecutor _executor; + private String _name; + private int _count; + + protected SimpleScheduler() { this("SimpleScheduler"); } + protected SimpleScheduler(String name) { + _context = I2PAppContext.getGlobalContext(); + _log = _context.logManager().getLog(SimpleScheduler.class); + _name = name; + _count = 0; + _executor = new ScheduledThreadPoolExecutor(THREADS, new CustomThreadFactory()); + } + + /** + * Removes the SimpleScheduler. + */ + public void stop() { + _executor.shutdownNow(); + } + + /** + * Queue up the given event to be fired no sooner than timeoutMs from now. + * + * @param event + * @param timeoutMs + */ + public void addEvent(SimpleTimer.TimedEvent event, long timeoutMs) { + if (event == null) + throw new IllegalArgumentException("addEvent null"); + RunnableEvent re = new RunnableEvent(event, timeoutMs); + re.schedule(); + } + + public void addPeriodicEvent(SimpleTimer.TimedEvent event, long timeoutMs) { + addPeriodicEvent(event, timeoutMs, timeoutMs); + } + + /** + * Queue up the given event to be fired after initialDelay and every + * timeoutMs thereafter. The TimedEvent must not do its own rescheduling. + * As all Exceptions are caught in run(), these will not prevent + * subsequent executions (unlike SimpleTimer, where the TimedEvent does + * its own rescheduling) + * + * @param event + * @param initialDelay (ms) + * @param timeoutMs + */ + public void addPeriodicEvent(SimpleTimer.TimedEvent event, long initialDelay, long timeoutMs) { + if (event == null) + throw new IllegalArgumentException("addEvent null"); + RunnableEvent re = new PeriodicRunnableEvent(event, initialDelay, timeoutMs); + re.schedule(); + } + + private class CustomThreadFactory implements ThreadFactory { + public Thread newThread(Runnable r) { + Thread rv = Executors.defaultThreadFactory().newThread(r); + rv.setName(_name + ' ' + (++_count) + '/' + THREADS); + rv.setDaemon(true); + return rv; + } + } + + /** + * Same as SimpleTimer.TimedEvent but use run() instead of timeReached(), and remembers the time + */ + private class RunnableEvent implements Runnable { + protected SimpleTimer.TimedEvent _timedEvent; + protected long _scheduled; + + public RunnableEvent(SimpleTimer.TimedEvent t, long timeoutMs) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Creating w/ delay " + timeoutMs + " : " + t); + _timedEvent = t; + _scheduled = timeoutMs + System.currentTimeMillis(); + } + public void schedule() { + _executor.schedule(this, _scheduled - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + public void run() { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Running: " + _timedEvent); + long before = System.currentTimeMillis(); + if (_log.shouldLog(Log.WARN) && before < _scheduled - 100) + _log.warn(_name + " wtf, early execution " + (_scheduled - before) + ": " + _timedEvent); + else if (_log.shouldLog(Log.WARN) && before > _scheduled + 1000) + _log.warn(" wtf, late execution " + (before - _scheduled) + ": " + _timedEvent + debug()); + try { + _timedEvent.timeReached(); + } catch (Throwable t) { + _log.log(Log.CRIT, _name + " wtf, event borked: " + _timedEvent, t); + } + long time = System.currentTimeMillis() - before; + if (time > 1000 && _log.shouldLog(Log.WARN)) + _log.warn(_name + " wtf, event execution took " + time + ": " + _timedEvent); + long completed = _executor.getCompletedTaskCount(); + if (_log.shouldLog(Log.INFO) && completed % 250 == 0) + _log.info(debug()); + } + } + + /** Run every timeoutMs. TimedEvent must not do its own reschedule via addEvent() */ + private class PeriodicRunnableEvent extends RunnableEvent { + private long _timeoutMs; + private long _initialDelay; + public PeriodicRunnableEvent(SimpleTimer.TimedEvent t, long initialDelay, long timeoutMs) { + super(t, timeoutMs); + _initialDelay = initialDelay; + _timeoutMs = timeoutMs; + _scheduled = initialDelay + System.currentTimeMillis(); + } + public void schedule() { + _executor.scheduleWithFixedDelay(this, _initialDelay, _timeoutMs, TimeUnit.MILLISECONDS); + } + public void run() { + super.run(); + _scheduled = _timeoutMs + System.currentTimeMillis(); + } + } + + private String debug() { + return + " Pool: " + _name + + " Active: " + _executor.getActiveCount() + '/' + _executor.getPoolSize() + + " Completed: " + _executor.getCompletedTaskCount() + + " Queued: " + _executor.getQueue().size(); + } +} + diff --git a/router/java/src/net/i2p/router/Blocklist.java b/router/java/src/net/i2p/router/Blocklist.java index 5f686c19230f5f0b82bc837e80761b6f723c77f8..1c50eaa65ff0245aeb1fa37cc0a7afde14646717 100644 --- a/router/java/src/net/i2p/router/Blocklist.java +++ b/router/java/src/net/i2p/router/Blocklist.java @@ -256,7 +256,7 @@ public class Blocklist { } } - private class Entry { + private static class Entry { String comment; byte ip1[]; byte ip2[]; diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index f7342413afdcb0413d1d13c5962ad9451e181a75..033678924c63475de3ae6ac0d3083fc6dbdffb71 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -43,6 +43,7 @@ import net.i2p.stat.StatManager; import net.i2p.util.FileUtil; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -257,7 +258,7 @@ public class Router { _context.inNetMessagePool().startup(); startupQueue(); //_context.jobQueue().addJob(new CoalesceStatsJob(_context)); - SimpleTimer.getInstance().addEvent(new CoalesceStatsEvent(_context), 0); + SimpleScheduler.getInstance().addPeriodicEvent(new CoalesceStatsEvent(_context), 20*1000); _context.jobQueue().addJob(new UpdateRoutingKeyModifierJob(_context)); warmupCrypto(); _sessionKeyPersistenceHelper.startup(); @@ -346,7 +347,7 @@ public class Router { if (blockingRebuild) r.timeReached(); else - SimpleTimer.getInstance().addEvent(r, 0); + SimpleScheduler.getInstance().addEvent(r, 0); } catch (DataFormatException dfe) { _log.log(Log.CRIT, "Internal error - unable to sign our own address?!", dfe); } @@ -1261,8 +1262,6 @@ class CoalesceStatsEvent implements SimpleTimer.TimedEvent { getContext().statManager().addRateData("bw.sendBps", (long)KBps, 60*1000); } } - - SimpleTimer.getInstance().addEvent(this, 20*1000); } } diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java index 7d86926cfabaaa4c741795c04ab07c323fc2a1bd..2005366c26356b2455a33f6ffd56ae35b77c7e7d 100644 --- a/router/java/src/net/i2p/router/Shitlist.java +++ b/router/java/src/net/i2p/router/Shitlist.java @@ -36,7 +36,7 @@ public class Shitlist { private RouterContext _context; private Map _entries; - private class Entry { + private static class Entry { /** when it should expire, per the i2p clock */ long expireOn; /** why they were shitlisted */ diff --git a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java index 133ad142c8b040c415676c5fe9caff8b0f3a1896..189568eadd166bedad2fd3d00d37f0209395aeaa 100644 --- a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java +++ b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java @@ -38,6 +38,7 @@ import net.i2p.router.RouterContext; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.RandomSource; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -419,7 +420,7 @@ public class ClientConnectionRunner { // theirs is newer } else { // ours is newer, so wait a few secs and retry - SimpleTimer.getInstance().addEvent(new Rerequest(set, expirationTime, onCreateJob, onFailedJob), 3*1000); + SimpleScheduler.getInstance().addEvent(new Rerequest(set, expirationTime, onCreateJob, onFailedJob), 3*1000); } // fire onCreated? return; // already requesting diff --git a/router/java/src/net/i2p/router/peermanager/PeerManager.java b/router/java/src/net/i2p/router/peermanager/PeerManager.java index b2b16a00df9dda6812696caa977cbdb9077ff0c0..1c265ee6768e49bb6f22fffb7f54000d26f144fc 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManager.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManager.java @@ -24,6 +24,7 @@ import net.i2p.router.PeerSelectionCriteria; import net.i2p.router.RouterContext; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -50,7 +51,7 @@ class PeerManager { _peersByCapability[i] = new ArrayList(64); loadProfiles(); ////_context.jobQueue().addJob(new EvaluateProfilesJob(_context)); - SimpleTimer.getInstance().addEvent(new Reorg(), 0); + SimpleScheduler.getInstance().addPeriodicEvent(new Reorg(), 0, 30*1000); //_context.jobQueue().addJob(new PersistProfilesJob(_context, this)); } @@ -60,8 +61,6 @@ class PeerManager { _organizer.reorganize(true); } catch (Throwable t) { _log.log(Log.CRIT, "Error evaluating profiles", t); - } finally { - SimpleTimer.getInstance().addEvent(Reorg.this, 30*1000); } } } diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java new file mode 100644 index 0000000000000000000000000000000000000000..8d19c62498fedae7de6426558925dacd3f6739ff --- /dev/null +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java @@ -0,0 +1,89 @@ +package net.i2p.router.transport.ntcp; + +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadFactory; + +import net.i2p.I2PAppContext; +import net.i2p.router.OutNetMessage; +import net.i2p.util.Log; + +/** + * Previously, NTCP was using SimpleTimer with a delay of 0, which + * was a real abuse. + * + * Here we use the non-scheduled, lockless ThreadPoolExecutor with + * a fixed pool size and an unbounded queue. + * + * The old implementation was having problems with lock contention; + * this should work a lot better - and not clog up the SimpleTimer queue. + * + * @author zzz + */ +public class NTCPSendFinisher { + private static final int THREADS = 4; + private I2PAppContext _context; + private NTCPTransport _transport; + private Log _log; + private int _count; + private ThreadPoolExecutor _executor; + + public NTCPSendFinisher(I2PAppContext context, NTCPTransport transport) { + _context = context; + _log = _context.logManager().getLog(NTCPSendFinisher.class); + _transport = transport; + } + + public void start() { + _count = 0; + _executor = new CustomThreadPoolExecutor(); + } + + public void stop() { + _executor.shutdownNow(); + } + + public void add(OutNetMessage msg) { + _executor.execute(new RunnableEvent(msg)); + } + + // not really needed for now but in case we want to add some hooks like afterExecute() + private class CustomThreadPoolExecutor extends ThreadPoolExecutor { + public CustomThreadPoolExecutor() { + // use unbounded queue, so maximumPoolSize and keepAliveTime have no effect + super(THREADS, THREADS, 1000, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(), new CustomThreadFactory()); + } + } + + private class CustomThreadFactory implements ThreadFactory { + public Thread newThread(Runnable r) { + Thread rv = Executors.defaultThreadFactory().newThread(r); + rv.setName("NTCPSendFinisher " + (++_count) + '/' + THREADS); + rv.setDaemon(true); + return rv; + } + } + + /** + * Call afterSend() for the message + */ + private class RunnableEvent implements Runnable { + private OutNetMessage _msg; + + public RunnableEvent(OutNetMessage msg) { + _msg = msg; + } + + public void run() { + try { + _transport.afterSend(_msg, true, false, _msg.getSendTime()); + } catch (Throwable t) { + _log.log(Log.CRIT, " wtf, afterSend borked", t); + } + } + } +} + diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 4b5573917eb7f0c6afba5d4ecf22f015216476cd..c23245bae41edab88fb81c2903697474fb314b41 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -27,7 +27,6 @@ import net.i2p.router.transport.Transport; import net.i2p.router.transport.TransportBid; import net.i2p.router.transport.TransportImpl; import net.i2p.util.Log; -import net.i2p.util.SimpleTimer; /** * @@ -50,7 +49,7 @@ public class NTCPTransport extends TransportImpl { private List _establishing; private List _sent; - private SendFinisher _finisher; + private NTCPSendFinisher _finisher; public NTCPTransport(RouterContext ctx) { super(ctx); @@ -124,7 +123,7 @@ public class NTCPTransport extends TransportImpl { _conByIdent = new HashMap(64); _sent = new ArrayList(4); - _finisher = new SendFinisher(); + _finisher = new NTCPSendFinisher(ctx, this); _pumper = new EventPumper(ctx, this); _reader = new Reader(ctx); @@ -310,27 +309,8 @@ public class NTCPTransport extends TransportImpl { return countActivePeers() < getMaxConnections() * 4 / 5; } + /** queue up afterSend call, which can take some time w/ jobs, etc */ void sendComplete(OutNetMessage msg) { _finisher.add(msg); } - /** async afterSend call, which can take some time w/ jobs, etc */ - private class SendFinisher implements SimpleTimer.TimedEvent { - public void add(OutNetMessage msg) { - synchronized (_sent) { _sent.add(msg); } - SimpleTimer.getInstance().addEvent(SendFinisher.this, 0); - } - public void timeReached() { - int pending = 0; - OutNetMessage msg = null; - synchronized (_sent) { - pending = _sent.size()-1; - if (pending >= 0) - msg = (OutNetMessage)_sent.remove(0); - } - if (msg != null) - afterSend(msg, true, false, msg.getSendTime()); - if (pending > 0) - SimpleTimer.getInstance().addEvent(SendFinisher.this, 0); - } - } private boolean isEstablished(RouterIdentity peer) { return isEstablished(peer.calculateHash()); @@ -412,6 +392,7 @@ public class NTCPTransport extends TransportImpl { public RouterAddress startListening() { if (_log.shouldLog(Log.DEBUG)) _log.debug("Starting ntcp transport listening"); + _finisher.start(); _pumper.startPumping(); _reader.startReading(NUM_CONCURRENT_READERS); @@ -423,6 +404,7 @@ public class NTCPTransport extends TransportImpl { public RouterAddress restartListening(RouterAddress addr) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Restarting ntcp transport listening"); + _finisher.start(); _pumper.startPumping(); _reader.startReading(NUM_CONCURRENT_READERS); @@ -551,6 +533,7 @@ public class NTCPTransport extends TransportImpl { _pumper.stopPumping(); _writer.stopWriting(); _reader.stopReading(); + _finisher.stop(); Map cons = null; synchronized (_conLock) { cons = new HashMap(_conByIdent); diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index 6ab159408cc876fe16d1f877bb508a3ad8c4c5bb..896fe1ce435d26f84ba2752db5d04adcf0743b0a 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -22,6 +22,7 @@ import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -184,7 +185,7 @@ public class EstablishmentManager { msg.getTarget().getIdentity(), new SessionKey(addr.getIntroKey()), addr); _outboundStates.put(to, state); - SimpleTimer.getInstance().addEvent(new Expire(to, state), 10*1000); + SimpleScheduler.getInstance().addEvent(new Expire(to, state), 10*1000); } } if (state != null) { @@ -394,7 +395,7 @@ public class EstablishmentManager { msg.getTarget().getIdentity(), new SessionKey(addr.getIntroKey()), addr); _outboundStates.put(to, qstate); - SimpleTimer.getInstance().addEvent(new Expire(to, qstate), 10*1000); + SimpleScheduler.getInstance().addEvent(new Expire(to, qstate), 10*1000); for (int i = 0; i < queued.size(); i++) { OutNetMessage m = (OutNetMessage)queued.get(i); @@ -477,7 +478,7 @@ public class EstablishmentManager { dsm.setMessageExpiration(_context.clock().now()+10*1000); dsm.setMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE)); _transport.send(dsm, peer); - SimpleTimer.getInstance().addEvent(new PublishToNewInbound(peer), 0); + SimpleScheduler.getInstance().addEvent(new PublishToNewInbound(peer), 0); } private class PublishToNewInbound implements SimpleTimer.TimedEvent { private PeerState _peer; @@ -629,7 +630,7 @@ public class EstablishmentManager { } } } - SimpleTimer.getInstance().addEvent(new FailIntroduction(state, nonce), INTRO_ATTEMPT_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new FailIntroduction(state, nonce), INTRO_ATTEMPT_TIMEOUT); state.setIntroNonce(nonce); _context.statManager().addRateData("udp.sendIntroRelayRequest", 1, 0); UDPPacket requests[] = _builder.buildRelayRequest(_transport, state, _transport.getIntroKey()); diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 7aa3c2fa164ae4afb773729ed6bd6d6f1115a28b..35c5511be4be4bc994ced8a0f24ba4408ad3b039 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -15,6 +15,7 @@ import net.i2p.data.SessionKey; import net.i2p.router.CommSystemFacade; import net.i2p.router.RouterContext; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -79,7 +80,7 @@ class PeerTestManager { sendTestToBob(); - SimpleTimer.getInstance().addEvent(new ContinueTest(), RESEND_TIMEOUT); + SimpleScheduler.getInstance().addEvent(new ContinueTest(), RESEND_TIMEOUT); } private class ContinueTest implements SimpleTimer.TimedEvent { @@ -103,7 +104,7 @@ class PeerTestManager { // second message from Charlie yet sendTestToCharlie(); } - SimpleTimer.getInstance().addEvent(ContinueTest.this, RESEND_TIMEOUT); + SimpleScheduler.getInstance().addEvent(ContinueTest.this, RESEND_TIMEOUT); } } } @@ -430,7 +431,7 @@ class PeerTestManager { synchronized (_activeTests) { _activeTests.put(new Long(nonce), state); } - SimpleTimer.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); + SimpleScheduler.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); } UDPPacket packet = _packetBuilder.buildPeerTestToBob(bobIP, from.getPort(), aliceIP, alicePort, aliceIntroKey, nonce, state.getBobCipherKey(), state.getBobMACKey()); @@ -511,7 +512,7 @@ class PeerTestManager { synchronized (_activeTests) { _activeTests.put(new Long(nonce), state); } - SimpleTimer.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); + SimpleScheduler.getInstance().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); } UDPPacket packet = _packetBuilder.buildPeerTestToCharlie(aliceIP, from.getPort(), aliceIntroKey, nonce, diff --git a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java index 10876a0e7df37873efa12100487a0f4bb66f799b..3535484c9f4d8df1f13b6e546d96b7f13e8443de 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java @@ -9,6 +9,7 @@ import net.i2p.router.RouterContext; import net.i2p.router.transport.FIFOBandwidthLimiter; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -115,7 +116,7 @@ public class UDPReceiver { long delay = ARTIFICIAL_DELAY_BASE + _context.random().nextInt(ARTIFICIAL_DELAY); if (_log.shouldLog(Log.INFO)) _log.info("Delay packet " + packet + " for " + delay); - SimpleTimer.getInstance().addEvent(new ArtificiallyDelayedReceive(packet), delay); + SimpleScheduler.getInstance().addEvent(new ArtificiallyDelayedReceive(packet), delay); return -1; } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index 03714d7ef2c53ba64d76badb57b8693c8040eee8..e5185defaf28f50b3975416dbf8d658a4ac981dc 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -33,6 +33,7 @@ import net.i2p.router.transport.Transport; import net.i2p.router.transport.TransportBid; import net.i2p.router.transport.TransportImpl; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; /** @@ -631,7 +632,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } if (added) { _context.statManager().addRateData("udp.dropPeerDroplist", droplistSize, 0); - SimpleTimer.getInstance().addEvent(new RemoveDropList(remote), DROPLIST_PERIOD); + SimpleScheduler.getInstance().addEvent(new RemoveDropList(remote), DROPLIST_PERIOD); } } markUnreachable(peerHash); diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java index 390fe888dcc2ca829b974db6543edb9d1db55bdc..3a84f48105159cd1905df7334d2492c64c89946a 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -46,6 +46,7 @@ class BuildExecutor implements Runnable { _context.statManager().createRateStat("tunnel.buildRequestTime", "How long it takes to build a tunnel request", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.buildRequestZeroHopTime", "How long it takes to build a zero hop tunnel", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.pendingRemaining", "How many inbound requests are pending after a pass (period is how long the pass takes)?", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + _context.statManager().createRateStat("tunnel.buildFailFirstHop", "How often we fail to build a OB tunnel because we can't contact the first hop", "Tunnels", new long[] { 60*1000, 10*60*1000 }); // Get stat manager, get recognized bandwidth tiers StatManager statMgr = _context.statManager(); diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index 3c2a9dd204af3018fedf8bb54df98434f393e2bf..f6b4d3478682a3c24bdc9cb2d50408eb4a772ae0 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -61,6 +61,7 @@ class BuildHandler { _context.statManager().createRateStat("tunnel.decryptRequestTime", "How long it takes to decrypt a new tunnel build request", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.rejectTimeout", "How often we reject a tunnel because we can't find the next hop", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + _context.statManager().createRateStat("tunnel.rejectTimeout2", "How often we fail a tunnel because we can't contact the next hop", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.rejectOverloaded", "How long we had to wait before processing the request (when it was rejected)", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.acceptLoad", "Delay before processing the accepted request", "Tunnels", new long[] { 60*1000, 10*60*1000 }); @@ -413,7 +414,7 @@ class BuildHandler { } } - private class TimeoutReq extends JobImpl { + private static class TimeoutReq extends JobImpl { private BuildMessageState _state; private BuildRequestRecord _req; private Hash _nextPeer; @@ -425,10 +426,12 @@ class BuildHandler { } public String getName() { return "Timeout looking for next peer for tunnel join"; } public void runJob() { - getContext().statManager().addRateData("tunnel.rejectTimeout", 1, 1); - if (_log.shouldLog(Log.WARN)) - _log.warn("Request " + _state.msg.getUniqueId() - + " could no be satisfied, as the next peer could not be found: " + _nextPeer.toBase64()); + getContext().statManager().addRateData("tunnel.rejectTimeout", 1, 0); + // logging commented out so class can be static + //if (_log.shouldLog(Log.WARN)) + // _log.warn("Request " + _state.msg.getUniqueId() + // + " could no be satisfied, as the next peer could not be found: " + _nextPeer.toBase64()); + // ??? should we blame the peer here? getContext().profileManager().tunnelTimedOut(_nextPeer); getContext().messageHistory().tunnelRejected(_state.fromHash, new TunnelId(_req.readReceiveTunnelId()), _nextPeer, "rejected because we couldn't find " + _nextPeer.toBase64() + ": " + @@ -516,8 +519,9 @@ class BuildHandler { + " from " + (state.fromHash != null ? state.fromHash.toBase64() : state.from != null ? state.from.calculateHash().toBase64() : "tunnel")); + HopConfig cfg = null; if (response == 0) { - HopConfig cfg = new HopConfig(); + cfg = new HopConfig(); cfg.setCreation(_context.clock().now()); cfg.setExpiration(_context.clock().now() + 10*60*1000); cfg.setIVKey(req.readIVKey()); @@ -593,6 +597,8 @@ class BuildHandler { msg.setExpiration(state.msg.getMessageExpiration()); msg.setPriority(300); msg.setTarget(nextPeerInfo); + if (response == 0) + msg.setOnFailedSendJob(new TunnelBuildNextHopFailJob(_context, cfg)); _context.outNetMessagePool().add(msg); } else { // send it to the reply tunnel on the reply peer within a new TunnelBuildReplyMessage @@ -619,6 +625,8 @@ class BuildHandler { outMsg.setMessage(m); outMsg.setPriority(300); outMsg.setTarget(nextPeerInfo); + if (response == 0) + outMsg.setOnFailedSendJob(new TunnelBuildNextHopFailJob(_context, cfg)); _context.outNetMessagePool().add(outMsg); } } @@ -762,7 +770,7 @@ class BuildHandler { } /** normal inbound requests from other people */ - private class BuildMessageState { + private static class BuildMessageState { TunnelBuildMessage msg; RouterIdentity from; Hash fromHash; @@ -775,7 +783,7 @@ class BuildHandler { } } /** replies for outbound tunnels that we have created */ - private class BuildReplyMessageState { + private static class BuildReplyMessageState { TunnelBuildReplyMessage msg; long recvTime; public BuildReplyMessageState(I2NPMessage m) { @@ -784,7 +792,7 @@ class BuildHandler { } } /** replies for inbound tunnels we have created */ - private class BuildEndMessageState { + private static class BuildEndMessageState { TunnelBuildMessage msg; PooledTunnelCreatorConfig cfg; long recvTime; @@ -796,15 +804,35 @@ class BuildHandler { } // noop - private class TunnelBuildMessageHandlerJob extends JobImpl { + private static class TunnelBuildMessageHandlerJob extends JobImpl { private TunnelBuildMessageHandlerJob(RouterContext ctx) { super(ctx); } public void runJob() {} public String getName() { return "Receive tunnel build message"; } } // noop - private class TunnelBuildReplyMessageHandlerJob extends JobImpl { + private static class TunnelBuildReplyMessageHandlerJob extends JobImpl { private TunnelBuildReplyMessageHandlerJob(RouterContext ctx) { super(ctx); } public void runJob() {} public String getName() { return "Receive tunnel build reply message"; } } + + /** + * Remove the participating tunnel if we can't contact the next hop + * Not strictly necessary, as the entry doesn't use that much space, + * but it affects capacity calculations + */ + private static class TunnelBuildNextHopFailJob extends JobImpl { + HopConfig _cfg; + private TunnelBuildNextHopFailJob(RouterContext ctx, HopConfig cfg) { + super(ctx); + _cfg = cfg; + } + public String getName() { return "Timeout contacting next peer for tunnel join"; } + public void runJob() { + getContext().tunnelDispatcher().remove(_cfg); + getContext().statManager().addRateData("tunnel.rejectTimeout2", 1, 0); + // static, no _log + //_log.error("Cant contact next hop for " + _cfg); + } + } } diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java index a4917772fa5adfeba5a055b6620036d52aad8fb3..21325be85189c68045f0405a60f127decb6db6ec 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java @@ -12,6 +12,7 @@ import net.i2p.data.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.TunnelBuildMessage; +import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import net.i2p.router.TunnelInfo; @@ -136,6 +137,7 @@ class BuildRequestor { return; } outMsg.setTarget(peer); + outMsg.setOnFailedSendJob(new TunnelBuildFirstHopFailJob(ctx, pool, cfg, exec)); ctx.outNetMessagePool().add(outMsg); } if (log.shouldLog(Log.DEBUG)) @@ -213,4 +215,33 @@ class BuildRequestor { ctx.jobQueue().addJob(expireJob); // can it get much easier? } + + /** + * Do two important things if we can't get the build msg to the + * first hop on an outbound tunnel - + * - Call buildComplete() so we can get started on the next build + * without waiting for the full expire time + * - Blame the first hop in the profile + * Most likely to happen on an exploratory tunnel, obviously. + * Can't do this for inbound tunnels since the msg goes out an expl. tunnel. + */ + private static class TunnelBuildFirstHopFailJob extends JobImpl { + TunnelPool _pool; + PooledTunnelCreatorConfig _cfg; + BuildExecutor _exec; + private TunnelBuildFirstHopFailJob(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, BuildExecutor exec) { + super(ctx); + _cfg = cfg; + _exec = exec; + _pool = pool; + } + public String getName() { return "Timeout contacting first peer for OB tunnel"; } + public void runJob() { + _exec.buildComplete(_cfg, _pool); + getContext().profileManager().tunnelTimedOut(_cfg.getPeer(1)); + getContext().statManager().addRateData("tunnel.buildFailFirstHop", 1, 0); + // static, no _log + //System.err.println("Cant contact first hop for " + _cfg); + } + } } diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java index 43120d0b08039616e0485c3a856e17c100ef166b..c6b1f5b9a9925e356e0ac713e6e3bea14780d7d5 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java @@ -376,7 +376,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { _context.jobQueue().addJob(new BootstrapPool(_context, _outboundExploratory)); } - private class BootstrapPool extends JobImpl { + private static class BootstrapPool extends JobImpl { private TunnelPool _pool; public BootstrapPool(RouterContext ctx, TunnelPool pool) { super(ctx);