2006-04-14 jrandom
* -28.00230115311259 is not between 0 and 1 in any universe I know. * Made the bw-related tunnel join throttle much simpler
This commit is contained in:
@ -157,11 +157,12 @@ public class FortunaRandomSource extends RandomSource implements EntropyHarveste
|
|||||||
* through 2^numBits-1
|
* through 2^numBits-1
|
||||||
*/
|
*/
|
||||||
protected synchronized int nextBits(int numBits) {
|
protected synchronized int nextBits(int numBits) {
|
||||||
int rv = 0;
|
long rv = 0;
|
||||||
int bytes = (numBits + 7) / 8;
|
int bytes = (numBits + 7) / 8;
|
||||||
for (int i = 0; i < bytes; i++)
|
for (int i = 0; i < bytes; i++)
|
||||||
rv += ((_fortuna.nextByte() & 0xFF) << i*8);
|
rv += ((_fortuna.nextByte() & 0xFF) << i*8);
|
||||||
return rv;
|
rv >>>= (64-numBits);
|
||||||
|
return (int)rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntropyHarvester harvester() { return this; }
|
public EntropyHarvester harvester() { return this; }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
$Id: history.txt,v 1.455 2006/04/13 07:40:21 jrandom Exp $
|
$Id: history.txt,v 1.456 2006/04/14 06:42:44 jrandom Exp $
|
||||||
|
|
||||||
|
2006-04-14 jrandom
|
||||||
|
* -28.00230115311259 is not between 0 and 1 in any universe I know.
|
||||||
|
* Made the bw-related tunnel join throttle much simpler
|
||||||
|
|
||||||
2006-04-14 jrandom
|
2006-04-14 jrandom
|
||||||
* Make some more stats graphable, and allow some internal tweaking on the
|
* Make some more stats graphable, and allow some internal tweaking on the
|
||||||
|
@ -190,9 +190,16 @@ class RouterThrottleImpl implements RouterThrottle {
|
|||||||
// of another tunnel?
|
// of another tunnel?
|
||||||
rs = _context.statManager().getRate("tunnel.participatingMessageCount");
|
rs = _context.statManager().getRate("tunnel.participatingMessageCount");
|
||||||
r = null;
|
r = null;
|
||||||
if (rs != null)
|
double messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
|
||||||
|
if (rs != null) {
|
||||||
r = rs.getRate(10*60*1000);
|
r = rs.getRate(10*60*1000);
|
||||||
double messagesPerTunnel = (r != null ? r.getAverageValue() : 0d);
|
if (r != null) {
|
||||||
|
if (r.getLastEventCount() > 0)
|
||||||
|
messagesPerTunnel = r.getAverageValue();
|
||||||
|
else
|
||||||
|
messagesPerTunnel = r.getLifetimeAverageValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (messagesPerTunnel < DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE)
|
if (messagesPerTunnel < DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE)
|
||||||
messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
|
messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
|
||||||
int participatingTunnels = _context.tunnelManager().getParticipatingCount();
|
int participatingTunnels = _context.tunnelManager().getParticipatingCount();
|
||||||
@ -237,7 +244,7 @@ class RouterThrottleImpl implements RouterThrottle {
|
|||||||
return Math.max(send, recv);
|
return Math.max(send, recv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE = 600; // 1KBps
|
private static final int DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE = 60; // .1KBps
|
||||||
private static final int MIN_AVAILABLE_BPS = 4*1024; // always leave at least 4KBps free when allowing
|
private static final int MIN_AVAILABLE_BPS = 4*1024; // always leave at least 4KBps free when allowing
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,15 +255,37 @@ class RouterThrottleImpl implements RouterThrottle {
|
|||||||
*/
|
*/
|
||||||
private boolean allowTunnel(double bytesAllocated, int numTunnels) {
|
private boolean allowTunnel(double bytesAllocated, int numTunnels) {
|
||||||
int maxKBps = Math.min(_context.bandwidthLimiter().getOutboundKBytesPerSecond(), _context.bandwidthLimiter().getInboundKBytesPerSecond());
|
int maxKBps = Math.min(_context.bandwidthLimiter().getOutboundKBytesPerSecond(), _context.bandwidthLimiter().getInboundKBytesPerSecond());
|
||||||
int used1s = get1sRate(_context); // dont throttle on the 1s rate, its too volatile
|
int used1s = 0; //get1sRate(_context); // dont throttle on the 1s rate, its too volatile
|
||||||
int used1m = get1mRate(_context);
|
int used1m = get1mRate(_context);
|
||||||
int used5m = 0; //get5mRate(_context); // don't throttle on the 5m rate, as that'd hide available bandwidth
|
int used5m = 0; //get5mRate(_context); // don't throttle on the 5m rate, as that'd hide available bandwidth
|
||||||
int used = Math.max(Math.max(used1s, used1m), used5m);
|
int used = Math.max(Math.max(used1s, used1m), used5m);
|
||||||
int availBps = (int)(((maxKBps*1024) - used) * getSharePercentage());
|
double share = getSharePercentage();
|
||||||
|
int availBps = (int)(((maxKBps*1024)*share) - used); //(int)(((maxKBps*1024) - used) * getSharePercentage());
|
||||||
|
|
||||||
_context.statManager().addRateData("router.throttleTunnelBytesUsed", used, maxKBps);
|
_context.statManager().addRateData("router.throttleTunnelBytesUsed", used, maxKBps);
|
||||||
_context.statManager().addRateData("router.throttleTunnelBytesAllowed", availBps, (long)bytesAllocated);
|
_context.statManager().addRateData("router.throttleTunnelBytesAllowed", availBps, (long)bytesAllocated);
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
// ok, ignore any predictions of 'bytesAllocated', since that makes poorly
|
||||||
|
// grounded conclusions about future use (or even the bursty use). Instead,
|
||||||
|
// simply say "do we have the bw to handle a new request"?
|
||||||
|
float maxBps = maxKBps * 1024f;
|
||||||
|
float pctFull = (maxBps - availBps) / (maxBps);
|
||||||
|
double probReject = Math.pow(pctFull, 16); // steep curve
|
||||||
|
double rand = _context.random().nextFloat();
|
||||||
|
boolean reject = (availBps < MIN_AVAILABLE_BPS) || (rand <= probReject);
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("reject = " + reject + " avail/maxK/used " + availBps + "/" + maxKBps + "/"
|
||||||
|
+ used + " pReject = " + probReject + " pFull = " + pctFull + " numTunnels = " + numTunnels
|
||||||
|
+ "rand = " + rand + " est = " + bytesAllocated + " share = " + (float)share);
|
||||||
|
if (reject) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (availBps <= 8*1024) {
|
if (availBps <= 8*1024) {
|
||||||
// lets be more conservative for people near their limit and assume 1KBps per tunnel
|
// lets be more conservative for people near their limit and assume 1KBps per tunnel
|
||||||
@ -280,7 +309,7 @@ class RouterThrottleImpl implements RouterThrottle {
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
double probAllow = availBps / (allocatedBps + availBps);
|
double probAllow = availBps / (allocatedBps + availBps);
|
||||||
boolean allow = (availBps > MIN_AVAILABLE_BPS) && (_context.random().nextDouble() <= probAllow);
|
boolean allow = (availBps > MIN_AVAILABLE_BPS) && (_context.random().nextFloat() <= probAllow);
|
||||||
if (allow) {
|
if (allow) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Probabalistically allowing the tunnel w/ " + (pctFull*100d) + "% of our " + availBps
|
_log.info("Probabalistically allowing the tunnel w/ " + (pctFull*100d) + "% of our " + availBps
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.395 $ $Date: 2006/04/13 07:40:22 $";
|
public final static String ID = "$Revision: 1.396 $ $Date: 2006/04/14 06:42:02 $";
|
||||||
public final static String VERSION = "0.6.1.15";
|
public final static String VERSION = "0.6.1.15";
|
||||||
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);
|
||||||
|
@ -49,6 +49,7 @@ class BuildHandler {
|
|||||||
_context.statManager().createRateStat("tunnel.dropLoadDelay", "How long we had to wait before finally giving up on an inbound request?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.dropLoadDelay", "How long we had to wait before finally giving up on an inbound request?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.dropLoadBacklog", "How many requests were pending when they were so lagged that we had to drop a new inbound request??", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.dropLoadBacklog", "How many requests were pending when they were so lagged that we had to drop a new inbound request??", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.dropLoadProactive", "What the estimated queue time was when we dropped an inbound request (period is num pending)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.dropLoadProactive", "What the estimated queue time was when we dropped an inbound request (period is num pending)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
|
_context.statManager().createRateStat("tunnel.dropLoadProactiveAbort", "How often we would have proactively dropped a request, but allowed it through?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
_context.statManager().createRateStat("tunnel.handleRemaining", "How many pending inbound requests were left on the queue after one pass?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
_context.statManager().createRateStat("tunnel.handleRemaining", "How many pending inbound requests were left on the queue after one pass?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||||
|
|
||||||
_context.statManager().createRateStat("tunnel.receiveRejectionProbabalistic", "How often we are rejected probabalistically?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("tunnel.receiveRejectionProbabalistic", "How often we are rejected probabalistically?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
@ -371,7 +372,7 @@ class BuildHandler {
|
|||||||
* If we are dropping lots of requests before even trying to handle them,
|
* If we are dropping lots of requests before even trying to handle them,
|
||||||
* I suppose you could call us "overloaded"
|
* I suppose you could call us "overloaded"
|
||||||
*/
|
*/
|
||||||
private final static int MAX_PROACTIVE_DROPS = 120;
|
private final static int MAX_PROACTIVE_DROPS = 240;
|
||||||
|
|
||||||
private int countProactiveDrops() {
|
private int countProactiveDrops() {
|
||||||
int dropped = 0;
|
int dropped = 0;
|
||||||
@ -413,7 +414,7 @@ class BuildHandler {
|
|||||||
|
|
||||||
int proactiveDrops = countProactiveDrops();
|
int proactiveDrops = countProactiveDrops();
|
||||||
long recvDelay = System.currentTimeMillis()-state.recvTime;
|
long recvDelay = System.currentTimeMillis()-state.recvTime;
|
||||||
if ( (response == 0) && ( (recvDelay > BuildRequestor.REQUEST_TIMEOUT/2) || (proactiveDrops > MAX_PROACTIVE_DROPS) ) ) {
|
if ( (response == 0) && ( (recvDelay > BuildRequestor.REQUEST_TIMEOUT) || (proactiveDrops > MAX_PROACTIVE_DROPS) ) ) {
|
||||||
_context.statManager().addRateData("tunnel.rejectOverloaded", recvDelay, proactiveDrops);
|
_context.statManager().addRateData("tunnel.rejectOverloaded", recvDelay, proactiveDrops);
|
||||||
if (true || (proactiveDrops < MAX_PROACTIVE_DROPS*2))
|
if (true || (proactiveDrops < MAX_PROACTIVE_DROPS*2))
|
||||||
response = TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
|
response = TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
|
||||||
@ -603,10 +604,10 @@ class BuildHandler {
|
|||||||
_context.statManager().addRateData("tunnel.dropLoadBacklog", _inboundBuildMessages.size(), _inboundBuildMessages.size());
|
_context.statManager().addRateData("tunnel.dropLoadBacklog", _inboundBuildMessages.size(), _inboundBuildMessages.size());
|
||||||
} else {
|
} else {
|
||||||
int queueTime = estimateQueueTime(_inboundBuildMessages.size());
|
int queueTime = estimateQueueTime(_inboundBuildMessages.size());
|
||||||
float pDrop = queueTime/((float)BuildRequestor.REQUEST_TIMEOUT/2);
|
float pDrop = queueTime/((float)BuildRequestor.REQUEST_TIMEOUT);
|
||||||
pDrop = pDrop * pDrop;
|
pDrop = pDrop * pDrop * pDrop;
|
||||||
float f = _context.random().nextFloat();
|
float f = _context.random().nextFloat();
|
||||||
if (pDrop > f) {
|
if ( (pDrop > f) && (allowProactiveDrop()) ) {
|
||||||
_context.statManager().addRateData("tunnel.dropLoadProactive", queueTime, _inboundBuildMessages.size());
|
_context.statManager().addRateData("tunnel.dropLoadProactive", queueTime, _inboundBuildMessages.size());
|
||||||
} else {
|
} else {
|
||||||
_inboundBuildMessages.add(new BuildMessageState(receivedMessage, from, fromHash));
|
_inboundBuildMessages.add(new BuildMessageState(receivedMessage, from, fromHash));
|
||||||
@ -620,6 +621,16 @@ class BuildHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean allowProactiveDrop() {
|
||||||
|
String allow = _context.getProperty("router.allowProactiveDrop", "true");
|
||||||
|
boolean rv = false;
|
||||||
|
if ( (allow == null) || (Boolean.valueOf(allow).booleanValue()) )
|
||||||
|
rv = true;
|
||||||
|
if (!rv)
|
||||||
|
_context.statManager().addRateData("tunnel.dropLoadProactiveAbort", 1, 0);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
private int estimateQueueTime(int numPendingMessages) {
|
private int estimateQueueTime(int numPendingMessages) {
|
||||||
int decryptTime = 200;
|
int decryptTime = 200;
|
||||||
RateStat rs = _context.statManager().getRate("crypto.elGamal.decrypt");
|
RateStat rs = _context.statManager().getRate("crypto.elGamal.decrypt");
|
||||||
|
Reference in New Issue
Block a user