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
This commit is contained in:
@ -153,7 +153,7 @@ public class Router {
|
|||||||
shutdown(EXIT_OOM);
|
shutdown(EXIT_OOM);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_shutdownHook = new ShutdownHook();
|
_shutdownHook = new ShutdownHook(_context);
|
||||||
_gracefulShutdownDetector = new I2PThread(new GracefulShutdown());
|
_gracefulShutdownDetector = new I2PThread(new GracefulShutdown());
|
||||||
_gracefulShutdownDetector.setDaemon(true);
|
_gracefulShutdownDetector.setDaemon(true);
|
||||||
_gracefulShutdownDetector.setName("Graceful shutdown hook");
|
_gracefulShutdownDetector.setName("Graceful shutdown hook");
|
||||||
@ -210,7 +210,7 @@ public class Router {
|
|||||||
public void setRouterInfo(RouterInfo info) {
|
public void setRouterInfo(RouterInfo info) {
|
||||||
_routerInfo = info;
|
_routerInfo = info;
|
||||||
if (info != null)
|
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.tunnelDispatcher().startup();
|
||||||
_context.inNetMessagePool().startup();
|
_context.inNetMessagePool().startup();
|
||||||
startupQueue();
|
startupQueue();
|
||||||
_context.jobQueue().addJob(new CoalesceStatsJob());
|
_context.jobQueue().addJob(new CoalesceStatsJob(_context));
|
||||||
_context.jobQueue().addJob(new UpdateRoutingKeyModifierJob());
|
_context.jobQueue().addJob(new UpdateRoutingKeyModifierJob(_context));
|
||||||
warmupCrypto();
|
warmupCrypto();
|
||||||
_sessionKeyPersistenceHelper.startup();
|
_sessionKeyPersistenceHelper.startup();
|
||||||
//_context.adminManager().startup();
|
//_context.adminManager().startup();
|
||||||
@ -449,89 +449,6 @@ public class Router {
|
|||||||
finalShutdown(EXIT_HARD_RESTART);
|
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() {
|
private void warmupCrypto() {
|
||||||
_context.random().nextBoolean();
|
_context.random().nextBoolean();
|
||||||
new DHSessionKeyBuilder(); // load the class so it starts the precalc process
|
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");
|
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
|
* Start a thread that will periodically update the file "router.ping", but if
|
||||||
@ -1082,24 +999,116 @@ public class Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not an I2PThread for context creation issues
|
// 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.setName("Mark router liveliness");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.start();
|
t.start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class MarkLiveliness implements Runnable {
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
private File _pingFile;
|
||||||
public MarkLiveliness(File f) {
|
public MarkLiveliness(RouterContext ctx, Router router, File pingFile) {
|
||||||
_pingFile = f;
|
_context = ctx;
|
||||||
|
_router = router;
|
||||||
|
_pingFile = pingFile;
|
||||||
}
|
}
|
||||||
public void run() {
|
public void run() {
|
||||||
_pingFile.deleteOnExit();
|
_pingFile.deleteOnExit();
|
||||||
do {
|
do {
|
||||||
ping();
|
ping();
|
||||||
try { Thread.sleep(LIVELINESS_DELAY); } catch (InterruptedException ie) {}
|
try { Thread.sleep(Router.LIVELINESS_DELAY); } catch (InterruptedException ie) {}
|
||||||
} while (_isAlive);
|
} while (_router.isAlive());
|
||||||
_pingFile.delete();
|
_pingFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,45 +1118,47 @@ public class Router {
|
|||||||
fos = new FileOutputStream(_pingFile);
|
fos = new FileOutputStream(_pingFile);
|
||||||
fos.write(("" + System.currentTimeMillis()).getBytes());
|
fos.write(("" + System.currentTimeMillis()).getBytes());
|
||||||
} catch (IOException ioe) {
|
} 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");
|
System.err.println("Error writing to ping file");
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ShutdownHook extends Thread {
|
||||||
|
private RouterContext _context;
|
||||||
private static int __id = 0;
|
private static int __id = 0;
|
||||||
private class ShutdownHook extends Thread {
|
|
||||||
private int _id;
|
private int _id;
|
||||||
public ShutdownHook() {
|
public ShutdownHook(RouterContext ctx) {
|
||||||
|
_context = ctx;
|
||||||
_id = ++__id;
|
_id = ++__id;
|
||||||
}
|
}
|
||||||
public void run() {
|
public void run() {
|
||||||
setName("Router " + _id + " shutdown");
|
setName("Router " + _id + " shutdown");
|
||||||
_log.log(Log.CRIT, "Shutting down the router...");
|
Log l = _context.logManager().getLog(Router.class);
|
||||||
shutdown(EXIT_HARD);
|
l.log(Log.CRIT, "Shutting down the router...");
|
||||||
}
|
_context.router().shutdown(Router.EXIT_HARD);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** update the router.info file whenever its, er, updated */
|
/** update the router.info file whenever its, er, updated */
|
||||||
private class PersistRouterInfoJob extends JobImpl {
|
class PersistRouterInfoJob extends JobImpl {
|
||||||
public PersistRouterInfoJob() { super(Router.this._context); }
|
private Log _log;
|
||||||
|
public PersistRouterInfoJob(RouterContext ctx) {
|
||||||
|
super(ctx);
|
||||||
|
}
|
||||||
public String getName() { return "Persist Updated Router Information"; }
|
public String getName() { return "Persist Updated Router Information"; }
|
||||||
public void runJob() {
|
public void runJob() {
|
||||||
|
_log = getContext().logManager().getLog(PersistRouterInfoJob.class);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Persisting updated router info");
|
_log.debug("Persisting updated router info");
|
||||||
|
|
||||||
String infoFilename = getConfigSetting(PROP_INFO_FILENAME);
|
String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME);
|
||||||
if (infoFilename == null)
|
if (infoFilename == null)
|
||||||
infoFilename = PROP_INFO_FILENAME_DEFAULT;
|
infoFilename = Router.PROP_INFO_FILENAME_DEFAULT;
|
||||||
|
|
||||||
RouterInfo info = getRouterInfo();
|
RouterInfo info = getContext().router().getRouterInfo();
|
||||||
|
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
try {
|
try {
|
||||||
@ -1161,5 +1172,4 @@ public class Router {
|
|||||||
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
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 String VERSION = "0.6.1.11";
|
||||||
public final static long BUILD = 1;
|
public final static long BUILD = 2;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
@ -835,13 +835,7 @@ public class PeerState {
|
|||||||
_messagesSent++;
|
_messagesSent++;
|
||||||
if (numSends < 2) {
|
if (numSends < 2) {
|
||||||
recalculateTimeouts(lifetime);
|
recalculateTimeouts(lifetime);
|
||||||
if (_mtu <= MIN_MTU) {
|
adjustMTU();
|
||||||
if (_context.random().nextInt(50*(int)_mtuDecreases) <= 0) {
|
|
||||||
_context.statManager().addRateData("udp.mtuIncrease", _packetsRetransmitted, _packetsTransmitted);
|
|
||||||
_mtu = LARGE_MTU;
|
|
||||||
_mtuIncreases++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_log.shouldLog(Log.WARN))
|
else if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("acked after numSends=" + numSends + " w/ lifetime=" + lifetime + " and size=" + bytesACKed);
|
_log.warn("acked after numSends=" + numSends + " w/ lifetime=" + lifetime + " and size=" + bytesACKed);
|
||||||
@ -870,14 +864,24 @@ public class PeerState {
|
|||||||
_rto = MAX_RTO;
|
_rto = MAX_RTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reduceMTU() {
|
private void adjustMTU() {
|
||||||
if (_mtu > MIN_MTU) {
|
double retransPct = 0;
|
||||||
double retransPct = (double)_packetsRetransmitted/(double)_packetsTransmitted;
|
if (_packetsTransmitted > 0) {
|
||||||
if (retransPct >= 0.05) { // should we go for lower?
|
retransPct = (double)_packetsRetransmitted/(double)_packetsTransmitted;
|
||||||
_context.statManager().addRateData("udp.mtuDecrease", _packetsRetransmitted, _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;
|
_mtu = MIN_MTU;
|
||||||
_mtuDecreases++;
|
_mtuDecreases++;
|
||||||
|
_context.statManager().addRateData("udp.mtuDecrease", _mtuDecreases, _mtuIncreases);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_mtu = DEFAULT_MTU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,7 +899,7 @@ public class PeerState {
|
|||||||
}
|
}
|
||||||
congestionOccurred();
|
congestionOccurred();
|
||||||
_context.statManager().addRateData("udp.congestedRTO", _rto, _rttDeviation);
|
_context.statManager().addRateData("udp.congestedRTO", _rto, _rttDeviation);
|
||||||
reduceMTU();
|
adjustMTU();
|
||||||
//_rto *= 2;
|
//_rto *= 2;
|
||||||
}
|
}
|
||||||
public void packetsTransmitted(int packets) {
|
public void packetsTransmitted(int packets) {
|
||||||
|
@ -188,6 +188,7 @@ class BuildHandler {
|
|||||||
|
|
||||||
if (howBad == 0) {
|
if (howBad == 0) {
|
||||||
// w3wt
|
// w3wt
|
||||||
|
_context.profileManager().tunnelJoined(peer, rtt);
|
||||||
} else {
|
} else {
|
||||||
allAgree = false;
|
allAgree = false;
|
||||||
switch (howBad) {
|
switch (howBad) {
|
||||||
|
Reference in New Issue
Block a user