From 65138357d3cb87d25d03ca8535fd1a9cf78ecafb Mon Sep 17 00:00:00 2001 From: complication Date: Sun, 16 Jul 2006 17:20:46 +0000 Subject: [PATCH] 2006-07-16 Complication * Collect tunnel build agree/reject/expire statistics for each bandwidth tier of peers (and peers of unknown tiers, even if those shouldn't exist) --- core/java/src/net/i2p/data/RouterInfo.java | 21 ++++++++++ history.txt | 7 +++- .../src/net/i2p/router/RouterVersion.java | 4 +- .../i2p/router/tunnel/pool/BuildExecutor.java | 39 +++++++++++++++++++ .../i2p/router/tunnel/pool/BuildHandler.java | 17 ++++++++ 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/core/java/src/net/i2p/data/RouterInfo.java b/core/java/src/net/i2p/data/RouterInfo.java index a875759c3..2851f733a 100644 --- a/core/java/src/net/i2p/data/RouterInfo.java +++ b/core/java/src/net/i2p/data/RouterInfo.java @@ -53,6 +53,9 @@ public class RouterInfo extends DataStructureImpl { public static final String PROP_CAPABILITIES = "caps"; public static final char CAPABILITY_HIDDEN = 'H'; + // Public string of chars which serve as bandwidth capacity markers + // NOTE: individual chars defined in Router.java + public static final String BW_CAPABILITY_CHARS = "KLMNO"; public RouterInfo() { setIdentity(null); @@ -334,6 +337,24 @@ public class RouterInfo extends DataStructureImpl { return (getCapabilities().indexOf(CAPABILITY_HIDDEN) != -1); } + /** + * Return a string representation of this node's bandwidth tier, + * or "Unknown" + */ + public String getBandwidthTier() { + String bwTiers = BW_CAPABILITY_CHARS; + String bwTier = "Unknown"; + String capabilities = getCapabilities(); + // Iterate through capabilities, searching for known bandwidth tier + for (int i = 0; i < capabilities.length(); i++) { + if (bwTiers.contains(String.valueOf(capabilities.charAt(i)))) { + bwTier = String.valueOf(capabilities.charAt(i)); + break; + } + } + return (bwTier); + } + public void addCapability(char cap) { if (_options == null) _options = new OrderedProperties(); synchronized (_options) { diff --git a/history.txt b/history.txt index 966363caa..f14734108 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,9 @@ -$Id: history.txt,v 1.492 2006-07-04 16:17:44 jrandom Exp $ +$Id: history.txt,v 1.493 2006-07-14 13:08:44 jrandom Exp $ + +2006-07-16 Complication + * Collect tunnel build agree/reject/expire statistics + for each bandwidth tier of peers (and peers of unknown tiers, + even if those shouldn't exist) 2006-07-14 jrandom * Improve the multitransport shitlisting (thanks Complication!) diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index d601e83b5..1d60bd9f6 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.431 $ $Date: 2006-07-04 16:18:17 $"; + public final static String ID = "$Revision: 1.432 $ $Date: 2006-07-14 13:08:51 $"; public final static String VERSION = "0.6.1.21"; - public final static long BUILD = 3; + public final static long BUILD = 4; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); 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 7a6898e88..ba64c0284 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -7,6 +7,7 @@ import net.i2p.router.*; import net.i2p.router.tunnel.*; import net.i2p.router.peermanager.TunnelHistory; import net.i2p.util.Log; +import net.i2p.stat.StatManager; /** * Single threaded controller of the tunnel creation process, spanning all tunnel pools. @@ -42,6 +43,22 @@ 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 }); + + // Get stat manager, get recognized bandwidth tiers + StatManager statMgr = _context.statManager(); + String bwTiers = _context.router().getRouterInfo().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)); + statMgr.createRateStat("tunnel.tierAgree" + bwTier, "Agreed joins from " + bwTier, "Tunnels", new long[] { 60*1000, 10*60*1000 }); + statMgr.createRateStat("tunnel.tierReject" + bwTier, "Rejected joins from "+ bwTier, "Tunnels", new long[] { 60*1000, 10*60*1000 }); + statMgr.createRateStat("tunnel.tierExpire" + bwTier, "Expired joins from "+ bwTier, "Tunnels", new long[] { 60*1000, 10*60*1000 }); + } + // For caution, also create stats for unknown + statMgr.createRateStat("tunnel.tierAgreeUnknown", "Agreed joins from unknown", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + statMgr.createRateStat("tunnel.tierRejectUnknown", "Rejected joins from unknown", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + statMgr.createRateStat("tunnel.tierExpireUnknown", "Expired joins from unknown", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + _repoll = false; _handler = new BuildHandler(ctx, this); } @@ -90,6 +107,28 @@ class BuildExecutor implements Runnable { // or... not. if (_log.shouldLog(Log.INFO)) _log.info("Timed out waiting for reply asking for " + cfg); + + // Iterate through peers in the tunnel, get their bandwidth tiers, + // record for each that a peer of the given tier expired + for (int iPeer = 0; iPeer < cfg.getLength(); iPeer++) { + // Look up peer + Hash peer = cfg.getPeer(iPeer); + // Avoid recording ourselves + if (peer.toBase64().equals(_context.routerHash().toBase64())) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Not recording our own expiry in stats."); + continue; + } + // Look up routerInfo + RouterInfo ri = _context.netDb().lookupRouterInfoLocally(peer); + // Default and detect bandwidth tier + String bwTier = "Unknown"; + if (ri != null) bwTier = ri.getBandwidthTier(); // Returns "Unknown" if none recognized + else if (_log.shouldLog(Log.WARN)) _log.warn("Failed detecting bwTier, null routerInfo for: " + peer); + // Record that a peer of the given tier expired + _context.statManager().addRateData("tunnel.tierExpire" + bwTier, 1, 0); + } + + TunnelPool pool = cfg.getTunnelPool(); if (pool != null) pool.buildComplete(cfg); 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 fb45c642a..c87ca492f 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -220,6 +220,7 @@ class BuildHandler { int statuses[] = handler.decrypt(_context, msg, cfg, order); if (statuses != null) { boolean allAgree = true; + // For each peer in the tunnel for (int i = 0; i < cfg.getLength(); i++) { Hash peer = cfg.getPeer(i); int record = order.indexOf(new Integer(i)); @@ -227,6 +228,22 @@ class BuildHandler { if (_log.shouldLog(Log.INFO)) _log.info(msg.getUniqueId() + ": Peer " + peer.toBase64() + " replied with status " + howBad); + // If this tunnel member isn't ourselves + if (!peer.toBase64().equals(_context.routerHash().toBase64())) { + // Look up routerInfo + RouterInfo ri = _context.netDb().lookupRouterInfoLocally(peer); + // Default and detect bandwidth tier + String bwTier = "Unknown"; + if (ri != null) bwTier = ri.getBandwidthTier(); // Returns "Unknown" if none recognized + else if (_log.shouldLog(Log.WARN)) _log.warn("Failed detecting bwTier, null routerInfo for: " + peer); + // Record that a peer of the given tier agreed or rejected + if (howBad == 0) { + _context.statManager().addRateData("tunnel.tierAgree" + bwTier, 1, 0); + } else { + _context.statManager().addRateData("tunnel.tierReject" + bwTier, 1, 0); + } + } + if (howBad == 0) { // w3wt _context.profileManager().tunnelJoined(peer, rtt);