From 55682810b1973c5772848d15fceff768edb5bdcd Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:35:15 +0000 Subject: [PATCH 01/17] doc updates --- INSTALL.txt | 10 +++++++--- README.txt | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/INSTALL.txt b/INSTALL.txt index 15a962df2..adbbc5ad5 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,10 +1,17 @@ I2P source installation instructions +Prerequisites to build from source: + Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended) + Apache Ant 1.7.0 or higher + Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed + from the GNU gettext package http://www.gnu.org/software/gettext/ + To build and install I2P from source, you must first build and package up the appropriate installer by running: ant pkg + This will produce a few key files: * install.jar: the GUI and console installer * i2pinstall.exe: the GUI and console installer wrapped for cross-platform execution @@ -18,9 +25,6 @@ Or run the GUI installer: Or move the update file into an existing installation directory and restart. -You will need to have ant installed from http://ant.apache.org/ -(1.7.0 or newer) - Supported JVMs: Windows: Latest available from http://java.sun.com/ (1.5+ supported) Linux: Latest available from http://java.sun.com/ (1.5+ supported) diff --git a/README.txt b/README.txt index 3aa2141bb..c5ddc12bd 100644 --- a/README.txt +++ b/README.txt @@ -1,11 +1,13 @@ Prerequisites to build from source: Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended) Apache Ant 1.7.0 or higher + Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed + from the GNU gettext package http://www.gnu.org/software/gettext/ To build: ant pkg Run 'ant' with no arguments to see other build options. - See http://www.i2p2.de/download.html for installation instructions. + See INSTALL.txt or http://www.i2p2.de/download.html for installation instructions. Documentation: http://www.i2p2.de/ From 08e54c515eb05fad293ea10df34f04ea5346e9d2 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:37:44 +0000 Subject: [PATCH 02/17] add isRouterContext() method --- .../java/src/net/i2p/router/web/NewsFetcher.java | 4 ++-- core/java/src/net/i2p/I2PAppContext.java | 7 +++++++ router/java/src/net/i2p/router/RouterContext.java | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java b/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java index 973357baa..8140282d1 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java @@ -179,7 +179,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener { if (get.fetch()) { String lastmod = get.getLastModified(); if (lastmod != null) { - if (!(_context instanceof RouterContext)) return; + if (!(_context.isRouterContext())) return; long modtime = parse822Date(lastmod); if (modtime <= 0) return; String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME); @@ -310,7 +310,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener { if (_log.shouldLog(Log.DEBUG)) _log.debug("Policy requests update, so we update"); UpdateHandler handler = null; - if (_context instanceof RouterContext) { + if (_context.isRouterContext()) { handler = new UpdateHandler((RouterContext)_context); } else { List contexts = RouterContext.listContexts(); diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index 1cdb6b297..974b69b84 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -722,4 +722,11 @@ public class I2PAppContext { return new HashSet(_shutdownTasks); } + /** + * Use this instead of context instanceof RouterContext + * @since 0.7.9 + */ + public boolean isRouterContext() { + return false; + } } diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index 2a3410348..8f1c240c3 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -379,4 +379,12 @@ public class RouterContext extends I2PAppContext { } } + /** + * Use this instead of context instanceof RouterContext + * @return true + * @since 0.7.9 + */ + public boolean isRouterContext() { + return true; + } } From 513b93f789637b86d468570b3a83ccecff007eef Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:39:06 +0000 Subject: [PATCH 03/17] no room for cows --- core/java/src/net/i2p/stat/RateStat.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/java/src/net/i2p/stat/RateStat.java b/core/java/src/net/i2p/stat/RateStat.java index b021d59f4..79ddec519 100644 --- a/core/java/src/net/i2p/stat/RateStat.java +++ b/core/java/src/net/i2p/stat/RateStat.java @@ -170,6 +170,7 @@ public class RateStat { } } +/********* public static void main(String args[]) { RateStat rs = new RateStat("moo", "moo moo moo", "cow trueisms", new long[] { 60 * 1000, 60 * 60 * 1000, 24 * 60 * 60 * 1000}); @@ -206,4 +207,5 @@ public class RateStat { } catch (InterruptedException ie) { // nop } } +*********/ } From 33407fd5be681e351c79e269b12366eacf979bd8 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:39:50 +0000 Subject: [PATCH 04/17] reduce delays (cuts 10s from router startup --- core/java/src/net/i2p/time/Timestamper.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/java/src/net/i2p/time/Timestamper.java b/core/java/src/net/i2p/time/Timestamper.java index e47ecd259..b1d763a3a 100644 --- a/core/java/src/net/i2p/time/Timestamper.java +++ b/core/java/src/net/i2p/time/Timestamper.java @@ -189,7 +189,10 @@ public class Timestamper implements Runnable { long expectedDelta = 0; _wellSynced = false; for (int i = 0; i < _concurringServers; i++) { - try { Thread.sleep(10*1000); } catch (InterruptedException ie) {} + if (i > 0) { + // this delays startup when net is disconnected or the timeserver list is bad, don't make it too long + try { Thread.sleep(2*1000); } catch (InterruptedException ie) {} + } now = NtpClient.currentTime(serverList); long delta = now - _context.clock().now(); found[i] = delta; From aaa7302e80f49850a7f477d43e45cdee6a4f719e Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:40:57 +0000 Subject: [PATCH 05/17] clarify table headings --- .../java/src/net/i2p/router/web/TunnelRenderer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java index 71aca046c..523b4d385 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java @@ -233,7 +233,7 @@ public class TunnelRenderer { Collections.sort(peerList, new CountryComparator(this._context.commSystem())); out.write("

" + _("Tunnel Counts By Peer") + "

\n"); - out.write("\n"); + out.write("
" + _("Peer") + "" + _("Expl. + Client") + "" + _("% of total") + "" + _("Part. from + to") + "" + _("% of total") + "
\n"); for (Hash h : peerList) { out.write("
" + _("Peer") + "" + _("Our Tunnels") + "" + _("% of total") + "" + _("Participating Tunnels") + "" + _("% of total") + "
"); out.write(netDbLink(h)); @@ -251,7 +251,7 @@ public class TunnelRenderer { out.write('0'); out.write('\n'); } - out.write("
" + _("Tunnels") + " " + tunnelCount); + out.write("
" + _("Totals") + " " + tunnelCount); out.write("   " + partCount); out.write("  
\n"); } From 8e656427d8de41be361407a919ecd429d3ad36c6 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:47:18 +0000 Subject: [PATCH 06/17] * Console: - Fix status to show a disconnected network error rather than clock skew or UDP error when disconnected - Use peer clock skew rather than clock offset for determining whether to display clock skew error, i.e. display what matters * Transport: Rework peer clock skew method to always return a value by falling back to router clock offset; Fix possible AIOOBE and divide by zero; remove logging; reduce min number of peers --- .../src/net/i2p/router/web/SummaryHelper.java | 19 +++++++++++--- .../transport/CommSystemFacadeImpl.java | 26 +++++++------------ 2 files changed, 24 insertions(+), 21 deletions(-) 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 1fc6c31b7..516855e2d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -62,6 +62,9 @@ public class SummaryHelper extends HelperBase { return DataHelper.formatDuration(router.getUptime()); } +/** + this displayed offset, not skew - now handled in reachability() + private String timeSkew() { if (_context == null) return ""; //if (!_context.clock().getUpdatedSuccessfully()) @@ -72,6 +75,7 @@ public class SummaryHelper extends HelperBase { return ""; return " (" + DataHelper.formatDuration(diff) + " " + _("skew") + ")"; } +**/ public boolean allowReseed() { return _context.netDb().isInitialized() && @@ -83,15 +87,20 @@ public class SummaryHelper extends HelperBase { public int getAllPeers() { return Math.max(_context.netDb().getKnownRouters() - 1, 0); } public String getReachability() { - return reachability() + timeSkew(); + return reachability(); // + timeSkew(); } private String reachability() { if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) && !_context.clientManager().isAlive()) return _("ERR-Client Manager I2CP Error - check logs"); // not a router problem but the user should know - if (!_context.clock().getUpdatedSuccessfully()) - return _("ERR-ClockSkew"); + // Warn based on actual skew from peers, not update status, so if we successfully offset + // the clock, we don't complain. + //if (!_context.clock().getUpdatedSuccessfully()) + Long skew = _context.commSystem().getFramedAveragePeerClockSkew(33); + // Display the actual skew, not the offset + if (skew != null && Math.abs(skew.longValue()) > 45) + return _("ERR-Clock Skew of {0}", DataHelper.formatDuration(Math.abs(skew.longValue()) * 1000)); if (_context.router().isHidden()) return _("Hidden"); @@ -118,7 +127,9 @@ public class SummaryHelper extends HelperBase { default: ra = _context.router().getRouterInfo().getTargetAddress("SSU"); if (ra == null && _context.router().getUptime() > 5*60*1000) { - if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null || + if (getActivePeers() <= 0) + return _("ERR-No Active Peers, Check Network Connection and Firewall"); + else if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null || _context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_PORT) == null) return _("ERR-UDP Disabled and Inbound TCP host/port not set"); else diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 6a7eaca84..f1460b9f7 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -77,31 +77,26 @@ public class CommSystemFacadeImpl extends CommSystemFacade { public boolean haveHighOutboundCapacity() { return (_manager == null ? false : _manager.haveHighOutboundCapacity()); } /** - * Framed average clock skew of connected peers in seconds, or null if we cannot answer. + * Framed average clock skew of connected peers in seconds, or the clock offset if we cannot answer. * Average is calculated over the middle "percentToInclude" peers. */ @Override public Long getFramedAveragePeerClockSkew(int percentToInclude) { if (_manager == null) { - if (_log.shouldLog(Log.INFO)) - _log.info("Returning null for framed averege peer clock skew (no transport manager)!"); - return null; + // round toward zero + return Long.valueOf(_context.clock().getOffset() / 1000); } Vector skews = _manager.getClockSkews(); if (skews == null) { - if (_log.shouldLog(Log.ERROR)) - _log.error("Returning null for framed average peer clock skew (no data)!"); - return null; + return Long.valueOf(_context.clock().getOffset() / 1000); } - if (skews.size() < 20) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Returning null for framed average peer clock skew (only " + skews.size() + " peers)!"); - return null; + if (skews.size() < 5) { + return Long.valueOf(_context.clock().getOffset() / 1000); } // Going to calculate, sort them Collections.sort(skews); // Calculate frame size - int frameSize = (skews.size() * percentToInclude / 100); + int frameSize = Math.min((skews.size() * percentToInclude / 100), 2); int first = (skews.size() / 2) - (frameSize / 2); int last = (skews.size() / 2) + (frameSize / 2); // Sum skew values @@ -112,11 +107,8 @@ public class CommSystemFacadeImpl extends CommSystemFacade { _log.debug("Adding clock skew " + i + " valued " + value + " s."); sum = sum + value; } - // Calculate average - Long framedAverageClockSkew = new Long(sum / frameSize); - if (_log.shouldLog(Log.INFO)) - _log.info("Our framed average peer clock skew is " + framedAverageClockSkew + " s."); - return framedAverageClockSkew; + // Calculate average (round toward zero) + return Long.valueOf(sum / frameSize); } public List getBids(OutNetMessage msg) { From 4baff9fbab70965e7cdb397e1d09cb0fcafed2d4 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:49:55 +0000 Subject: [PATCH 07/17] * Router: Move some more threads to I2PAppThread so an OOM won't crash the router --- router/java/src/net/i2p/router/Router.java | 13 ++++++------- .../net/i2p/router/networkdb/reseed/Reseeder.java | 6 ++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 7e231097b..4ed70a772 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -41,6 +41,7 @@ import net.i2p.stat.Rate; import net.i2p.stat.RateStat; import net.i2p.stat.StatManager; import net.i2p.util.FileUtil; +import net.i2p.util.I2PAppThread; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; @@ -201,6 +202,8 @@ public class Router { installUpdates(); // Apps may use this as an easy way to determine if they are in the router JVM + // But context.isRouterContext() is even easier... + // Both of these as of 0.7.9 System.setProperty("router.version", RouterVersion.VERSION); // NOW we start all the activity @@ -228,14 +231,10 @@ public class Router { } }; _shutdownHook = new ShutdownHook(_context); - _gracefulShutdownDetector = new I2PThread(new GracefulShutdown()); - _gracefulShutdownDetector.setDaemon(true); - _gracefulShutdownDetector.setName("Graceful shutdown hook"); + _gracefulShutdownDetector = new I2PAppThread(new GracefulShutdown(), "Graceful shutdown hook", true); _gracefulShutdownDetector.start(); - I2PThread watchdog = new I2PThread(new RouterWatchdog(_context)); - watchdog.setName("RouterWatchdog"); - watchdog.setDaemon(true); + Thread watchdog = new I2PAppThread(new RouterWatchdog(_context), "RouterWatchdog", true); watchdog.start(); } @@ -339,7 +338,7 @@ public class Router { long waited = System.currentTimeMillis() - before; if (_log.shouldLog(Log.INFO)) _log.info("Waited " + waited + "ms to initialize"); - + _context.jobQueue().addJob(new StartupJob(_context)); } diff --git a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java index f37f01aa2..2e93cb3e0 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -15,7 +15,7 @@ import java.util.StringTokenizer; import net.i2p.I2PAppContext; import net.i2p.router.RouterContext; import net.i2p.util.EepGet; -import net.i2p.util.I2PThread; +import net.i2p.util.I2PAppThread; import net.i2p.util.Log; /** @@ -52,13 +52,15 @@ public class Reseeder { return; } else { System.setProperty(PROP_INPROGRESS, "true"); - I2PThread reseed = new I2PThread(_reseedRunner, "Reseed"); + // set to daemon so it doesn't hang a shutdown + Thread reseed = new I2PAppThread(_reseedRunner, "Reseed", true); reseed.start(); } } } + /** Todo: translate the messages sent via PROP_STATUS */ public class ReseedRunner implements Runnable, EepGet.StatusListener { private boolean _isRunning; From f0d444b32eea1ef45ce9d0dab4791834091281fa Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:52:18 +0000 Subject: [PATCH 08/17] add to javadoc and adjust logging --- .../i2p/router/tunnel/FragmentHandler.java | 73 +++++++++++++++++-- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java index 43e1d1314..57e44203e 100644 --- a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java +++ b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java @@ -21,6 +21,65 @@ import net.i2p.util.SimpleTimer; * Handle fragments at the endpoint of a tunnel, peeling off fully completed * I2NPMessages when they arrive, and dropping fragments if they take too long * to arrive. + * + * From tunnel-alt.html: + +

When the gateway wants to deliver data through the tunnel, it first +gathers zero or more I2NP messages, selects how much padding will be used, +fragments it across the necessary number of 1KB tunnel messages, and decides how +each I2NP message should be handled by the tunnel endpoint, encoding that +data into the raw tunnel payload:

+
    +
  • the first 4 bytes of the SHA256 of the remaining preprocessed data concatenated + with the IV, using the IV as will be seen on the tunnel endpoint (for + outbound tunnels) or the IV as was seen on the tunnel gateway (for inbound + tunnels) (see below for IV processing).
  • +
  • 0 or more bytes containing random nonzero integers
  • +
  • 1 byte containing 0x00
  • +
  • a series of zero or more { instructions, message } pairs
  • +
+ +

The instructions are encoded with a single control byte, followed by any +necessary additional information. The first bit in that control byte determines +how the remainder of the header is interpreted - if it is not set, the message +is either not fragmented or this is the first fragment in the message. If it is +set, this is a follow on fragment.

+ +

With the first bit being 0, the instructions are:

+
    +
  • 1 byte control byte:
    +      bit 0: is follow on fragment?  (1 = true, 0 = false, must be 0)
    +   bits 1-2: delivery type
    +             (0x0 = LOCAL, 0x01 = TUNNEL, 0x02 = ROUTER)
    +      bit 3: delay included?  (1 = true, 0 = false)
    +      bit 4: fragmented?  (1 = true, 0 = false)
    +      bit 5: extended options?  (1 = true, 0 = false)
    +   bits 6-7: reserved
  • +
  • if the delivery type was TUNNEL, a 4 byte tunnel ID
  • +
  • if the delivery type was TUNNEL or ROUTER, a 32 byte router hash
  • +
  • if the delay included flag is true, a 1 byte value:
    +      bit 0: type (0 = strict, 1 = randomized)
    +   bits 1-7: delay exponent (2^value minutes)
  • +
  • if the fragmented flag is true, a 4 byte message ID
  • +
  • if the extended options flag is true:
    +   = a 1 byte option size (in bytes)
    +   = that many bytes
  • +
  • 2 byte size of the I2NP message or this fragment
  • +
+ +

If the first bit being 1, the instructions are:

+
    +
  • 1 byte control byte:
    +      bit 0: is follow on fragment?  (1 = true, 0 = false, must be 1)
    +   bits 1-6: fragment number
    +      bit 7: is last? (1 = true, 0 = false)
  • +
  • 4 byte message ID (same one defined in the first fragment)
  • +
  • 2 byte size of this fragment
  • +
+ +

The I2NP message is encoded in its standard form, and the +preprocessed payload must be padded to a multiple of 16 bytes.

+ * */ public class FragmentHandler { @@ -165,21 +224,19 @@ public class FragmentHandler { _log.debug("endpoint IV: " + Base64.encode(preV, validLength - HopProcessor.IV_LENGTH, HopProcessor.IV_LENGTH)); Hash v = _context.sha().calculateHash(preV, 0, validLength); + _validateCache.release(ba); - //Hash v = _context.sha().calculateHash(preV, 0, validLength); boolean eq = DataHelper.eq(v.getData(), 0, preprocessed, offset + HopProcessor.IV_LENGTH, 4); if (!eq) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Corrupt tunnel message - verification fails: \n" + Base64.encode(preprocessed, offset+HopProcessor.IV_LENGTH, 4) - + "\n" + Base64.encode(v.getData(), 0, 4)); - if (_log.shouldLog(Log.WARN)) - _log.warn("nomatching endpoint: # pad bytes: " + (paddingEnd-(HopProcessor.IV_LENGTH+4)-1) + "\n" + if (_log.shouldLog(Log.WARN)) { + _log.warn("Corrupt tunnel message - verification fails: " + Base64.encode(preprocessed, offset+HopProcessor.IV_LENGTH, 4) + + " != " + Base64.encode(v.getData(), 0, 4)); + _log.warn("No matching endpoint: # pad bytes: " + (paddingEnd-(HopProcessor.IV_LENGTH+4)-1) + " offset=" + offset + " length=" + length + " paddingEnd=" + paddingEnd + Base64.encode(preprocessed, offset, length)); + } } - _validateCache.release(ba); - if (eq) { int excessPadding = paddingEnd - (HopProcessor.IV_LENGTH + 4 + 1); if (excessPadding > 0) // suboptimal fragmentation From 2cd5c209f5f5c190ddce31d71c2278b6deab7553 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:52:49 +0000 Subject: [PATCH 09/17] unused cleanup --- router/java/src/net/i2p/router/tunnel/TunnelParticipant.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java index a73208e3b..6263f8ec7 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java @@ -101,8 +101,11 @@ public class TunnelParticipant { } } +/**** private int _periodMessagesTransferred; private long _lastCoallesced = System.currentTimeMillis(); +****/ + /** * take note that the peers specified were able to push us data. hmm, is this safe? * this could be easily gamed to get us to rank some peer of their choosing as quite From f226392c9d74b0e3cc7089e2a7944a73a2bdbffe Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:53:49 +0000 Subject: [PATCH 10/17] static access fix --- router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 e1cec3607..5e4456490 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -54,9 +54,7 @@ class BuildExecutor implements Runnable { // Get stat manager, get recognized bandwidth tiers StatManager statMgr = _context.statManager(); - @SuppressWarnings("static-access") - /* FIXME Accessing static field "BW_CAPABILITY_CHARS" FIXME */ - String bwTiers = _context.router().getRouterInfo().BW_CAPABILITY_CHARS; + String bwTiers = RouterInfo.BW_CAPABILITY_CHARS; // For each bandwidth tier, create tunnel build agree/reject/expire stats for (int i = 0; i < bwTiers.length(); i++) { String bwTier = String.valueOf(bwTiers.charAt(i)); From 72eafe0920d5b0a48663a4dffbf27701428fa9f6 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:54:59 +0000 Subject: [PATCH 11/17] * Tunnels: Reduce the drop probability for TunnelBuildMessages at the OBEP --- .../src/net/i2p/router/tunnel/TunnelDispatcher.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index 681dadec1..6b5457719 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -605,12 +605,17 @@ public class TunnelDispatcher implements Service { if (pctDrop <= 0) return false; // increase the drop probability for OBEP, + // (except lower it for tunnel build messages (type 21)), // and lower it for IBGW, for network efficiency double len = length; - if (type.startsWith("OBEP")) - len *= 1.5; - else if (type.startsWith("IBGW")) + if (type.startsWith("OBEP")) { + if (type.equals("OBEP 21")) + len /= 1.5; + else + len *= 1.5; + } else if (type.startsWith("IBGW")) { len /= 1.5; + } // drop in proportion to size w.r.t. a standard 1024-byte message // this is a little expensive but we want to adjust the curve between 0 and 1 // Most messages are 1024, only at the OBEP do we see other sizes From 579b450029cba2068154e724ac383c2a35360867 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:56:38 +0000 Subject: [PATCH 12/17] clean up context usage --- .../router/tunnel/InboundEndpointProcessor.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java b/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java index 6c572cb42..7376a5046 100644 --- a/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java +++ b/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java @@ -1,6 +1,5 @@ package net.i2p.router.tunnel; -import net.i2p.I2PAppContext; import net.i2p.data.ByteArray; import net.i2p.data.Hash; import net.i2p.router.RouterContext; @@ -16,7 +15,7 @@ import net.i2p.util.Log; * */ public class InboundEndpointProcessor { - private I2PAppContext _context; + private RouterContext _context; private Log _log; private TunnelCreatorConfig _config; private IVValidator _validator; @@ -24,10 +23,10 @@ public class InboundEndpointProcessor { static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION; private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH); - public InboundEndpointProcessor(I2PAppContext ctx, TunnelCreatorConfig cfg) { + public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg) { this(ctx, cfg, DummyValidator.getInstance()); } - public InboundEndpointProcessor(I2PAppContext ctx, TunnelCreatorConfig cfg, IVValidator validator) { + public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg, IVValidator validator) { _context = ctx; _log = ctx.logManager().getLog(InboundEndpointProcessor.class); _config = cfg; @@ -73,23 +72,19 @@ public class InboundEndpointProcessor { _cache.release(ba); - // now for a little bookkeeping - RouterContext ctx = null; - if (_context instanceof RouterContext) - ctx = (RouterContext)_context; - if ( (ctx != null) && (_config.getLength() > 0) ) { + if (_config.getLength() > 0) { int rtt = 0; // dunno... may not be related to an rtt if (_log.shouldLog(Log.DEBUG)) _log.debug("Received a " + length + "byte message through tunnel " + _config); for (int i = 0; i < _config.getLength(); i++) - ctx.profileManager().tunnelDataPushed(_config.getPeer(i), rtt, length); + _context.profileManager().tunnelDataPushed(_config.getPeer(i), rtt, length); _config.incrementVerifiedBytesTransferred(length); } return true; } - private void decrypt(I2PAppContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) { + private void decrypt(RouterContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) { Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class); ByteArray ba = _cache.acquire(); byte cur[] = ba.getData(); // new byte[HopProcessor.IV_LENGTH]; // so we dont malloc From 2a1d358141e7341c8c88e97a7d42f5e32469ce0c Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 17:10:39 +0000 Subject: [PATCH 13/17] * Profile, DBHistory: - Tweak the rate periods - Add a global fail rate stat - Increase the HashMap sizes --- router/java/src/net/i2p/router/peermanager/DBHistory.java | 8 ++++++-- .../src/net/i2p/router/peermanager/ProfileOrganizer.java | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/router/java/src/net/i2p/router/peermanager/DBHistory.java b/router/java/src/net/i2p/router/peermanager/DBHistory.java index a8e084e49..36b9bc9a3 100644 --- a/router/java/src/net/i2p/router/peermanager/DBHistory.java +++ b/router/java/src/net/i2p/router/peermanager/DBHistory.java @@ -105,6 +105,7 @@ public class DBHistory { */ public RateStat getFailedLookupRate() { return _failedLookupRate; } + /** not sure how much this is used, to be investigated */ public RateStat getInvalidReplyRate() { return _invalidReplyRate; } /** @@ -115,6 +116,7 @@ public class DBHistory { public void lookupSuccessful() { _successfulLookups++; _failedLookupRate.addData(0, 0); + _context.statManager().addRateData("peer.failedLookupRate", 0, 0); _lastLookupSuccessful = _context.clock().now(); } @@ -124,6 +126,7 @@ public class DBHistory { public void lookupFailed() { _failedLookups++; _failedLookupRate.addData(1, 0); + _context.statManager().addRateData("peer.failedLookupRate", 1, 0); _lastLookupFailed = _context.clock().now(); } @@ -136,6 +139,7 @@ public class DBHistory { // Fixme, redefined this to include both lookup and store fails, // need to fix the javadocs _failedLookupRate.addData(0, 0); + _context.statManager().addRateData("peer.failedLookupRate", 0, 0); _lastStoreSuccessful = _context.clock().now(); } @@ -275,9 +279,9 @@ public class DBHistory { private void createRates(String statGroup) { if (_failedLookupRate == null) - _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", statGroup, new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); + _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", statGroup, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); if (_invalidReplyRate == null) - _invalidReplyRate = new RateStat("dbHistory.invalidReplyRate", "How often does this peer give us a bad (nonexistant, forged, etc) peer?", statGroup, new long[] { 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _invalidReplyRate = new RateStat("dbHistory.invalidReplyRate", "How often does this peer give us a bad (nonexistant, forged, etc) peer?", statGroup, new long[] { 30*60*1000l }); _failedLookupRate.setStatLog(_context.statManager().getStatLog()); _invalidReplyRate.setStatLog(_context.statManager().getStatLog()); } diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 20f0fba3d..d249dc968 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -97,10 +97,10 @@ public class ProfileOrganizer { _log = context.logManager().getLog(ProfileOrganizer.class); _comp = new InverseCapacityComparator(); _fastPeers = new HashMap(16); - _highCapacityPeers = new HashMap(16); + _highCapacityPeers = new HashMap(32); _wellIntegratedPeers = new HashMap(16); - _notFailingPeers = new HashMap(64); - _notFailingPeersList = new ArrayList(64); + _notFailingPeers = new HashMap(256); + _notFailingPeersList = new ArrayList(256); _failingPeers = new HashMap(16); _strictCapacityOrder = new TreeSet(_comp); _thresholdSpeedValue = 0.0d; @@ -113,6 +113,8 @@ public class ProfileOrganizer { _context.statManager().createRateStat("peer.profileThresholdTime", "How long the reorg takes determining the tier thresholds", "Peers", new long[] { 10*60*1000 }); _context.statManager().createRateStat("peer.profilePlaceTime", "How long the reorg takes placing peers in the tiers", "Peers", new long[] { 10*60*1000 }); _context.statManager().createRateStat("peer.profileReorgTime", "How long the reorg takes overall", "Peers", new long[] { 10*60*1000 }); + // used in DBHistory + _context.statManager().createRateStat("peer.failedLookupRate", "DB Lookup fail rate", "Peers", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); } private void getReadLock() { From 9bf22fb0d336b47dd66d40545eeb0a2356f8a33e Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 17:41:47 +0000 Subject: [PATCH 14/17] stats.jsp tagging --- .../net/i2p/router/web/StatsGenerator.java | 29 +++++++++++-------- apps/routerconsole/java/strings/Strings.java | 19 ++++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java b/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java index 9ac1ae542..4ddc6e6f4 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java @@ -40,7 +40,7 @@ public class StatsGenerator { String group = (String)entry.getKey(); Set stats = (Set)entry.getValue(); buf.append("\n"); + buf.append(_(group)).append("\n"); for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) { String stat = (String)statIter.next(); buf.append("