From 7bb792836df8d2db8c50488d55eb6f7094fecffd Mon Sep 17 00:00:00 2001 From: jrandom <jrandom> Date: Thu, 23 Feb 2006 01:48:47 +0000 Subject: [PATCH] 2006-02-22 jrandom * Fix to properly profile tunnel joins (thanks Ragnarok, frosk, et al!) * More aggressive poor-man's PMTU, allowing larger MTUs on less reliable links * Further class validator refactorings --- router/java/src/net/i2p/router/Router.java | 316 +++++++++--------- .../src/net/i2p/router/RouterVersion.java | 4 +- .../i2p/router/transport/udp/PeerState.java | 32 +- .../i2p/router/tunnel/pool/BuildHandler.java | 1 + 4 files changed, 184 insertions(+), 169 deletions(-) diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 8dd3253e2d..e827540699 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -153,7 +153,7 @@ public class Router { shutdown(EXIT_OOM); } }; - _shutdownHook = new ShutdownHook(); + _shutdownHook = new ShutdownHook(_context); _gracefulShutdownDetector = new I2PThread(new GracefulShutdown()); _gracefulShutdownDetector.setDaemon(true); _gracefulShutdownDetector.setName("Graceful shutdown hook"); @@ -210,7 +210,7 @@ public class Router { public void setRouterInfo(RouterInfo info) { _routerInfo = info; if (info != null) - _context.jobQueue().addJob(new PersistRouterInfoJob()); + _context.jobQueue().addJob(new PersistRouterInfoJob(_context)); } /** @@ -245,8 +245,8 @@ public class Router { _context.tunnelDispatcher().startup(); _context.inNetMessagePool().startup(); startupQueue(); - _context.jobQueue().addJob(new CoalesceStatsJob()); - _context.jobQueue().addJob(new UpdateRoutingKeyModifierJob()); + _context.jobQueue().addJob(new CoalesceStatsJob(_context)); + _context.jobQueue().addJob(new UpdateRoutingKeyModifierJob(_context)); warmupCrypto(); _sessionKeyPersistenceHelper.startup(); //_context.adminManager().startup(); @@ -449,89 +449,6 @@ public class Router { finalShutdown(EXIT_HARD_RESTART); } - /** - * coalesce the stats framework every minute - * - */ - private final class CoalesceStatsJob extends JobImpl { - public CoalesceStatsJob() { - super(Router.this._context); - Router.this._context.statManager().createRateStat("bw.receiveBps", "How fast we receive data", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 }); - Router.this._context.statManager().createRateStat("bw.sendBps", "How fast we send data", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 }); - Router.this._context.statManager().createRateStat("router.activePeers", "How many peers we are actively talking with", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); - Router.this._context.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); - Router.this._context.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); - } - public String getName() { return "Coalesce stats"; } - public void runJob() { - Router.this._context.statManager().coalesceStats(); - - RateStat receiveRate = _context.statManager().getRate("transport.receiveMessageSize"); - if (receiveRate != null) { - Rate rate = receiveRate.getRate(60*1000); - if (rate != null) { - double bytes = rate.getLastTotalValue(); - double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d); - Router.this._context.statManager().addRateData("bw.receiveBps", (long)bps, 60*1000); - } - } - - RateStat sendRate = _context.statManager().getRate("transport.sendMessageSize"); - if (sendRate != null) { - Rate rate = sendRate.getRate(60*1000); - if (rate != null) { - double bytes = rate.getLastTotalValue(); - double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d); - Router.this._context.statManager().addRateData("bw.sendBps", (long)bps, 60*1000); - } - } - - int active = Router.this._context.commSystem().countActivePeers(); - Router.this._context.statManager().addRateData("router.activePeers", active, 60*1000); - - int fast = Router.this._context.profileOrganizer().countFastPeers(); - Router.this._context.statManager().addRateData("router.fastPeers", fast, 60*1000); - - int highCap = Router.this._context.profileOrganizer().countHighCapacityPeers(); - Router.this._context.statManager().addRateData("router.highCapacityPeers", highCap, 60*1000); - - requeue(60*1000); - } - } - - /** - * Update the routing Key modifier every day at midnight (plus on startup). - * This is done here because we want to make sure the key is updated before anyone - * uses it. - */ - private final class UpdateRoutingKeyModifierJob extends JobImpl { - private Calendar _cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); - public UpdateRoutingKeyModifierJob() { super(Router.this._context); } - public String getName() { return "Update Routing Key Modifier"; } - public void runJob() { - Router.this._context.routingKeyGenerator().generateDateBasedModData(); - requeue(getTimeTillMidnight()); - } - private long getTimeTillMidnight() { - long now = Router.this._context.clock().now(); - _cal.setTime(new Date(now)); - _cal.set(Calendar.YEAR, _cal.get(Calendar.YEAR)); // gcj <= 4.0 workaround - _cal.set(Calendar.DAY_OF_YEAR, _cal.get(Calendar.DAY_OF_YEAR)); // gcj <= 4.0 workaround - _cal.add(Calendar.DATE, 1); - _cal.set(Calendar.HOUR_OF_DAY, 0); - _cal.set(Calendar.MINUTE, 0); - _cal.set(Calendar.SECOND, 0); - _cal.set(Calendar.MILLISECOND, 0); - long then = _cal.getTime().getTime(); - long howLong = then - now; - if (howLong < 0) // hi kaffe - howLong = 24*60*60*1000l + howLong; - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Time till midnight: " + howLong + "ms"); - return howLong; - } - } - private void warmupCrypto() { _context.random().nextBoolean(); new DHSessionKeyBuilder(); // load the class so it starts the precalc process @@ -1060,7 +977,7 @@ public class Router { return _context.getProperty("router.pingFile", "router.ping"); } - private static final long LIVELINESS_DELAY = 60*1000; + static final long LIVELINESS_DELAY = 60*1000; /** * Start a thread that will periodically update the file "router.ping", but if @@ -1082,84 +999,177 @@ public class Router { } } // not an I2PThread for context creation issues - Thread t = new Thread(new MarkLiveliness(f)); + Thread t = new Thread(new MarkLiveliness(_context, this, f)); t.setName("Mark router liveliness"); t.setDaemon(true); t.start(); return true; } - - private class MarkLiveliness implements Runnable { - private File _pingFile; - public MarkLiveliness(File f) { - _pingFile = f; - } - public void run() { - _pingFile.deleteOnExit(); - do { - ping(); - try { Thread.sleep(LIVELINESS_DELAY); } catch (InterruptedException ie) {} - } while (_isAlive); - _pingFile.delete(); +} + +/** + * coalesce the stats framework every minute + * + */ +class CoalesceStatsJob extends JobImpl { + public CoalesceStatsJob(RouterContext ctx) { + super(ctx); + ctx.statManager().createRateStat("bw.receiveBps", "How fast we receive data", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 }); + ctx.statManager().createRateStat("bw.sendBps", "How fast we send data", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 }); + ctx.statManager().createRateStat("router.activePeers", "How many peers we are actively talking with", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); + ctx.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); + ctx.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); + } + public String getName() { return "Coalesce stats"; } + public void runJob() { + getContext().statManager().coalesceStats(); + + RateStat receiveRate = getContext().statManager().getRate("transport.receiveMessageSize"); + if (receiveRate != null) { + Rate rate = receiveRate.getRate(60*1000); + if (rate != null) { + double bytes = rate.getLastTotalValue(); + double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d); + getContext().statManager().addRateData("bw.receiveBps", (long)bps, 60*1000); + } } - - private void ping() { - FileOutputStream fos = null; - try { - fos = new FileOutputStream(_pingFile); - fos.write(("" + System.currentTimeMillis()).getBytes()); - } catch (IOException ioe) { - if (_log != null) { - _log.log(Log.CRIT, "Error writing to ping file", ioe); - } else { - System.err.println("Error writing to ping file"); - ioe.printStackTrace(); - } - } finally { - if (fos != null) try { fos.close(); } catch (IOException ioe) {} + + RateStat sendRate = getContext().statManager().getRate("transport.sendMessageSize"); + if (sendRate != null) { + Rate rate = sendRate.getRate(60*1000); + if (rate != null) { + double bytes = rate.getLastTotalValue(); + double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d); + getContext().statManager().addRateData("bw.sendBps", (long)bps, 60*1000); } } + + int active = getContext().commSystem().countActivePeers(); + getContext().statManager().addRateData("router.activePeers", active, 60*1000); + + int fast = getContext().profileOrganizer().countFastPeers(); + getContext().statManager().addRateData("router.fastPeers", fast, 60*1000); + + int highCap = getContext().profileOrganizer().countHighCapacityPeers(); + getContext().statManager().addRateData("router.highCapacityPeers", highCap, 60*1000); + + requeue(60*1000); } - - - private static int __id = 0; - private class ShutdownHook extends Thread { - private int _id; - public ShutdownHook() { - _id = ++__id; - } - public void run() { - setName("Router " + _id + " shutdown"); - _log.log(Log.CRIT, "Shutting down the router..."); - shutdown(EXIT_HARD); +} + +/** + * Update the routing Key modifier every day at midnight (plus on startup). + * This is done here because we want to make sure the key is updated before anyone + * uses it. + */ +class UpdateRoutingKeyModifierJob extends JobImpl { + private Log _log; + private Calendar _cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); + public UpdateRoutingKeyModifierJob(RouterContext ctx) { + super(ctx); + } + public String getName() { return "Update Routing Key Modifier"; } + public void runJob() { + _log = getContext().logManager().getLog(getClass()); + getContext().routingKeyGenerator().generateDateBasedModData(); + requeue(getTimeTillMidnight()); + } + private long getTimeTillMidnight() { + long now = getContext().clock().now(); + _cal.setTime(new Date(now)); + _cal.set(Calendar.YEAR, _cal.get(Calendar.YEAR)); // gcj <= 4.0 workaround + _cal.set(Calendar.DAY_OF_YEAR, _cal.get(Calendar.DAY_OF_YEAR)); // gcj <= 4.0 workaround + _cal.add(Calendar.DATE, 1); + _cal.set(Calendar.HOUR_OF_DAY, 0); + _cal.set(Calendar.MINUTE, 0); + _cal.set(Calendar.SECOND, 0); + _cal.set(Calendar.MILLISECOND, 0); + long then = _cal.getTime().getTime(); + long howLong = then - now; + if (howLong < 0) // hi kaffe + howLong = 24*60*60*1000l + howLong; + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Time till midnight: " + howLong + "ms"); + return howLong; + } +} + +class MarkLiveliness implements Runnable { + private RouterContext _context; + private Router _router; + private File _pingFile; + public MarkLiveliness(RouterContext ctx, Router router, File pingFile) { + _context = ctx; + _router = router; + _pingFile = pingFile; + } + public void run() { + _pingFile.deleteOnExit(); + do { + ping(); + try { Thread.sleep(Router.LIVELINESS_DELAY); } catch (InterruptedException ie) {} + } while (_router.isAlive()); + _pingFile.delete(); + } + + private void ping() { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(_pingFile); + fos.write(("" + System.currentTimeMillis()).getBytes()); + } catch (IOException ioe) { + System.err.println("Error writing to ping file"); + ioe.printStackTrace(); + } finally { + if (fos != null) try { fos.close(); } catch (IOException ioe) {} } } - - /** update the router.info file whenever its, er, updated */ - private class PersistRouterInfoJob extends JobImpl { - public PersistRouterInfoJob() { super(Router.this._context); } - public String getName() { return "Persist Updated Router Information"; } - public void runJob() { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Persisting updated router info"); +} - String infoFilename = getConfigSetting(PROP_INFO_FILENAME); - if (infoFilename == null) - infoFilename = PROP_INFO_FILENAME_DEFAULT; +class ShutdownHook extends Thread { + private RouterContext _context; + private static int __id = 0; + private int _id; + public ShutdownHook(RouterContext ctx) { + _context = ctx; + _id = ++__id; + } + public void run() { + setName("Router " + _id + " shutdown"); + Log l = _context.logManager().getLog(Router.class); + l.log(Log.CRIT, "Shutting down the router..."); + _context.router().shutdown(Router.EXIT_HARD); + } +} - RouterInfo info = getRouterInfo(); +/** update the router.info file whenever its, er, updated */ +class PersistRouterInfoJob extends JobImpl { + private Log _log; + public PersistRouterInfoJob(RouterContext ctx) { + super(ctx); + } + public String getName() { return "Persist Updated Router Information"; } + public void runJob() { + _log = getContext().logManager().getLog(PersistRouterInfoJob.class); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Persisting updated router info"); - FileOutputStream fos = null; - try { - fos = new FileOutputStream(infoFilename); - info.writeBytes(fos); - } catch (DataFormatException dfe) { - _log.error("Error rebuilding the router information", dfe); - } catch (IOException ioe) { - _log.error("Error writing out the rebuilt router information", ioe); - } finally { - if (fos != null) try { fos.close(); } catch (IOException ioe) {} - } + String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME); + if (infoFilename == null) + infoFilename = Router.PROP_INFO_FILENAME_DEFAULT; + + RouterInfo info = getContext().router().getRouterInfo(); + + FileOutputStream fos = null; + try { + fos = new FileOutputStream(infoFilename); + info.writeBytes(fos); + } catch (DataFormatException dfe) { + _log.error("Error rebuilding the router information", dfe); + } catch (IOException ioe) { + _log.error("Error writing out the rebuilt router information", ioe); + } finally { + if (fos != null) try { fos.close(); } catch (IOException ioe) {} } } -} +} \ No newline at end of file diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 993ecc2789..233e3e7c74 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.356 $ $Date: 2006/02/21 10:20:20 $"; + public final static String ID = "$Revision: 1.357 $ $Date: 2006/02/22 09:54:23 $"; public final static String VERSION = "0.6.1.11"; - public final static long BUILD = 1; + public final static long BUILD = 2; 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/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java index fb621aa8b7..cea6f8097c 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java @@ -835,13 +835,7 @@ public class PeerState { _messagesSent++; if (numSends < 2) { recalculateTimeouts(lifetime); - if (_mtu <= MIN_MTU) { - if (_context.random().nextInt(50*(int)_mtuDecreases) <= 0) { - _context.statManager().addRateData("udp.mtuIncrease", _packetsRetransmitted, _packetsTransmitted); - _mtu = LARGE_MTU; - _mtuIncreases++; - } - } + adjustMTU(); } else if (_log.shouldLog(Log.WARN)) _log.warn("acked after numSends=" + numSends + " w/ lifetime=" + lifetime + " and size=" + bytesACKed); @@ -870,14 +864,24 @@ public class PeerState { _rto = MAX_RTO; } - private void reduceMTU() { - if (_mtu > MIN_MTU) { - double retransPct = (double)_packetsRetransmitted/(double)_packetsTransmitted; - if (retransPct >= 0.05) { // should we go for lower? - _context.statManager().addRateData("udp.mtuDecrease", _packetsRetransmitted, _packetsTransmitted); + private void adjustMTU() { + double retransPct = 0; + if (_packetsTransmitted > 0) { + retransPct = (double)_packetsRetransmitted/(double)_packetsTransmitted; + boolean wantLarge = retransPct < .25d; // heuristic to allow fairly lossy links to use large MTUs + if (wantLarge && _mtu != LARGE_MTU) { + if (_context.random().nextLong(_mtuDecreases) <= 0) { + _mtu = LARGE_MTU; + _mtuIncreases++; + _context.statManager().addRateData("udp.mtuIncrease", _mtuIncreases, _mtuDecreases); + } + } else if (!wantLarge && _mtu == LARGE_MTU) { _mtu = MIN_MTU; _mtuDecreases++; - } + _context.statManager().addRateData("udp.mtuDecrease", _mtuDecreases, _mtuIncreases); + } + } else { + _mtu = DEFAULT_MTU; } } @@ -895,7 +899,7 @@ public class PeerState { } congestionOccurred(); _context.statManager().addRateData("udp.congestedRTO", _rto, _rttDeviation); - reduceMTU(); + adjustMTU(); //_rto *= 2; } public void packetsTransmitted(int packets) { 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 282aa2285c..9e812296b3 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -188,6 +188,7 @@ class BuildHandler { if (howBad == 0) { // w3wt + _context.profileManager().tunnelJoined(peer, rtt); } else { allAgree = false; switch (howBad) { -- GitLab