Compare commits

...

9 Commits

Author SHA1 Message Date
jrandom
eb36e993c1 * 2006-04-23 0.6.1.17 released 2006-04-23 21:06:12 +00:00
zzz
e5eca5fa45 zzz update 2006-04-22 20:37:21 +00:00
jrandom
8cba2f4236 2006-04-19 jrandom
* Adjust how we pick high capacity peers to allow the inclusion of fast
      peers (the previous filter assumed an old usage pattern)
    * New set of stats to help track per-packet-type bandwidth usage better
    * Cut out the proactive tail drop from the SSU transport, for now
    * Reduce the frequency of tunnel build attempts while we're saturated
    * Don't drop tunnel requests as easily - prefer to explicitly reject them
2006-04-19 17:46:51 +00:00
complication
40d5ed31ac 2006-04-15 Complication
* Update news.xml to reflect 0.6.1.16
2006-04-15 17:25:50 +00:00
jrandom
181275fe35 * 2006-04-15 0.6.1.16 released 2006-04-15 07:58:12 +00:00
jrandom
23d8c01ce7 2006-04-15 jrandom
* Adjust the proactive tunnel request dropping so we will reject what we
      can instead of dropping so much (but still dropping if we get too far
      overloaded)
2006-04-15 07:15:19 +00:00
jrandom
de83944486 2006-04-14 jrandom
* 0 isn't very random
    * Adjust the tunnel drop to be more reasonable
2006-04-14 20:24:07 +00:00
jrandom
90cd7ff23a 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 18:04:11 +00:00
jrandom
8d0a9b4ccd 2006-04-14 jrandom
* Make some more stats graphable, and allow some internal tweaking on the
      tunnel pairing for creation and testing.
2006-04-14 11:40:35 +00:00
24 changed files with 329 additions and 111 deletions

View File

@@ -62,8 +62,10 @@ public class GraphHelper {
+ "\" title=\"Combined bandwidth graph\" />\n");
List listeners = StatSummarizer.instance().getListeners();
for (int i = 0; i < listeners.size(); i++) {
SummaryListener lsnr = (SummaryListener)listeners.get(i);
TreeSet ordered = new TreeSet(new AlphaComparator());
ordered.addAll(listeners);
for (Iterator iter = ordered.iterator(); iter.hasNext(); ) {
SummaryListener lsnr = (SummaryListener)iter.next();
Rate r = lsnr.getRate();
String title = r.getRateStat().getName() + " for " + DataHelper.formatDuration(_periodCount * r.getPeriod());
_out.write("<img src=\"viewstat.jsp?stat=" + r.getRateStat().getName()
@@ -108,3 +110,13 @@ public class GraphHelper {
return "";
}
}
class AlphaComparator implements Comparator {
public int compare(Object lhs, Object rhs) {
SummaryListener l = (SummaryListener)lhs;
SummaryListener r = (SummaryListener)rhs;
String lName = l.getRate().getRateStat().getName() + "." + l.getRate().getPeriod();
String rName = r.getRate().getRateStat().getName() + "." + r.getRate().getPeriod();
return lName.compareTo(rName);
}
}

View File

@@ -153,7 +153,7 @@ class SummaryRenderer {
* specify who can get it from where, etc.
*
*/
public static void render(I2PAppContext ctx, OutputStream out, String filename) throws IOException {
public static synchronized void render(I2PAppContext ctx, OutputStream out, String filename) throws IOException {
long end = ctx.clock().now();
long start = end - 60*1000*SummaryListener.PERIODS;
long begin = System.currentTimeMillis();

View File

@@ -14,8 +14,8 @@ package net.i2p;
*
*/
public class CoreVersion {
public final static String ID = "$Revision: 1.57 $ $Date: 2006/04/05 12:08:07 $";
public final static String VERSION = "0.6.1.15";
public final static String ID = "$Revision: 1.59 $ $Date: 2006/04/15 02:58:13 $";
public final static String VERSION = "0.6.1.17";
public static void main(String args[]) {
System.out.println("I2P Core version: " + VERSION);

View File

@@ -433,6 +433,7 @@ public class Rate {
public boolean equals(Object obj) {
if ((obj == null) || (obj.getClass() != Rate.class)) return false;
if (obj == this) return true;
Rate r = (Rate) obj;
return _period == r.getPeriod() && _creationDate == r.getCreationDate() &&
//_lastCoalesceDate == r.getLastCoalesceDate() &&

View File

@@ -157,11 +157,16 @@ public class FortunaRandomSource extends RandomSource implements EntropyHarveste
* through 2^numBits-1
*/
protected synchronized int nextBits(int numBits) {
int rv = 0;
long rv = 0;
int bytes = (numBits + 7) / 8;
for (int i = 0; i < bytes; i++)
rv += ((_fortuna.nextByte() & 0xFF) << i*8);
return rv;
//rv >>>= (64-numBits);
if (rv < 0)
rv = 0 - rv;
int off = 8*bytes - numBits;
rv >>>= off;
return (int)rv;
}
public EntropyHarvester harvester() { return this; }

View File

@@ -1,4 +1,33 @@
$Id: history.txt,v 1.454 2006/04/12 23:22:07 jrandom Exp $
$Id: history.txt,v 1.461 2006/04/19 12:47:02 jrandom Exp $
* 2006-04-23 0.6.1.17 released
2006-04-19 jrandom
* Adjust how we pick high capacity peers to allow the inclusion of fast
peers (the previous filter assumed an old usage pattern)
* New set of stats to help track per-packet-type bandwidth usage better
* Cut out the proactive tail drop from the SSU transport, for now
* Reduce the frequency of tunnel build attempts while we're saturated
* Don't drop tunnel requests as easily - prefer to explicitly reject them
* 2006-04-15 0.6.1.16 released
2006-04-15 jrandom
* Adjust the proactive tunnel request dropping so we will reject what we
can instead of dropping so much (but still dropping if we get too far
overloaded)
2006-04-14 jrandom
* 0 isn't very random
* Adjust the tunnel drop to be more reasonable
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
* Make some more stats graphable, and allow some internal tweaking on the
tunnel pairing for creation and testing.
* 2006-04-13 0.6.1.15 released

View File

@@ -1,5 +1,5 @@
<i2p.news date="$Date: 2006/04/05 12:08:05 $">
<i2p.release version="0.6.1.15" date="2006/04/13" minVersion="0.6"
<i2p.news date="$Date: 2006/04/13 07:40:21 $">
<i2p.release version="0.6.1.16" date="2006/04/15" minVersion="0.6"
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
publicurl="http://dev.i2p.net/i2p/i2pupdate.sud"
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-September/000878.html"

View File

@@ -4,7 +4,7 @@
<info>
<appname>i2p</appname>
<appversion>0.6.1.15</appversion>
<appversion>0.6.1.17</appversion>
<authors>
<author name="I2P" email="support@i2p.net"/>
</authors>

View File

@@ -1,5 +1,5 @@
<i2p.news date="$Date: 2006/04/05 12:08:04 $">
<i2p.release version="0.6.1.15" date="2006/04/13" minVersion="0.6"
<i2p.news date="$Date: 2006/04/15 12:25:50 $">
<i2p.release version="0.6.1.17" date="2006/04/23" minVersion="0.6"
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
publicurl="http://dev.i2p.net/i2p/i2pupdate.sud"
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-September/000878.html"
@@ -10,12 +10,13 @@
anonlogs="http://i2p/Nf3ab-ZFkmI-LyMt7GjgT-jfvZ3zKDl0L96pmGQXF1B82W2Bfjf0n7~288vafocjFLnQnVcmZd~-p0-Oolfo9aW2Rm-AhyqxnxyLlPBqGxsJBXjPhm1JBT4Ia8FB-VXt0BuY0fMKdAfWwN61-tj4zIcQWRxv3DFquwEf035K~Ra4SWOqiuJgTRJu7~o~DzHVljVgWIzwf8Z84cz0X33pv-mdG~~y0Bsc2qJVnYwjjR178YMcRSmNE0FVMcs6f17c6zqhMw-11qjKpY~EJfHYCx4lBWF37CD0obbWqTNUIbL~78vxqZRT3dgAgnLixog9nqTO-0Rh~NpVUZnoUi7fNR~awW5U3Cf7rU7nNEKKobLue78hjvRcWn7upHUF45QqTDuaM3yZa7OsjbcH-I909DOub2Q0Dno6vIwuA7yrysccN1sbnkwZbKlf4T6~iDdhaSLJd97QCyPOlbyUfYy9QLNExlRqKgNVJcMJRrIual~Lb1CLbnzt0uvobM57UpqSAAAA/meeting141"
publiclogs="http://www.i2p.net/meeting141" />
&#149;
2006-04-13: 0.6.1.15 released with helpful tunnel building and ssu improvements.
2006-04-15: 0.6.1.16 <a href="http://dev.i2p/pipermail/i2p/2006-April/001280.html">released</a>
with a significant PRNG bugfix and other improvements.
<br>
&#149;
2006-04-04:
<a href="http://dev.i2p/pipermail/i2p/2006-April/001275.html">status notes</a>
2006-04-18:
<a href="http://dev.i2p/pipermail/i2p/2006-April/001281.html">status notes</a>
and
<a href="http://www.i2p/meeting175">meeting log</a>
<a href="http://www.i2p/meeting176">meeting log</a>
<br>
</i2p.news>

View File

@@ -333,7 +333,7 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
}
protected void verifyUnwritten() {
if (_written) throw new RuntimeException("Already written");
if (_written) throw new IllegalStateException("Already written");
}
protected void written() { _written = true; }
protected void read() { _read = true; }

View File

@@ -506,9 +506,9 @@ public class LoadTestManager {
}
private int getBps() {
int used1s = RouterThrottleImpl.get1sRate(_context);
int used1m = RouterThrottleImpl.get1mRate(_context);
int used5m = RouterThrottleImpl.get5mRate(_context);
int used1s = _context.router().get1sRate();
int used1m = _context.router().get1mRate();
int used5m = _context.router().get5mRate();
return Math.max(used1s, Math.max(used1m, used5m));
}

View File

@@ -35,8 +35,10 @@ import net.i2p.router.message.GarlicMessageHandler;
//import net.i2p.router.message.TunnelMessageHandler;
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
import net.i2p.router.startup.StartupJob;
import net.i2p.router.transport.FIFOBandwidthLimiter;
import net.i2p.stat.Rate;
import net.i2p.stat.RateStat;
import net.i2p.stat.StatManager;
import net.i2p.util.FileUtil;
import net.i2p.util.I2PThread;
import net.i2p.util.SimpleTimer;
@@ -1029,6 +1031,82 @@ public class Router {
t.start();
return true;
}
private static final String PROP_BANDWIDTH_SHARE_PERCENTAGE = "router.sharePercentage";
/**
* What fraction of the bandwidth specified in our bandwidth limits should
* we allow to be consumed by participating tunnels?
*
*/
public double getSharePercentage() {
RouterContext ctx = _context;
if (ctx == null) return 0;
String pct = ctx.getProperty(PROP_BANDWIDTH_SHARE_PERCENTAGE);
if (pct != null) {
try {
double d = Double.parseDouble(pct);
if (d > 1)
return d/100d; // *cough* sometimes its 80 instead of .8 (!stab jrandom)
else
return d;
} catch (NumberFormatException nfe) {
if (_log.shouldLog(Log.INFO))
_log.info("Unable to get the share percentage");
}
}
return 0.8;
}
public int get1sRate() { return get1sRate(false); }
public int get1sRate(boolean outboundOnly) {
RouterContext ctx = _context;
if (ctx != null) {
FIFOBandwidthLimiter bw = ctx.bandwidthLimiter();
if (bw != null) {
int out = (int)bw.getSendBps();
if (outboundOnly)
return out;
return (int)Math.max(out, bw.getReceiveBps());
}
}
return 0;
}
public int get1mRate() { return get1mRate(false); }
public int get1mRate(boolean outboundOnly) {
int send = 0;
RouterContext ctx = _context;
if (ctx == null)
return 0;
StatManager mgr = ctx.statManager();
if (mgr == null)
return 0;
RateStat rs = mgr.getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(1*60*1000).getAverageValue();
if (outboundOnly)
return send;
int recv = 0;
rs = mgr.getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(1*60*1000).getAverageValue();
return Math.max(send, recv);
}
public int get5mRate() { return get5mRate(false); }
public int get5mRate(boolean outboundOnly) {
int send = 0;
RateStat rs = _context.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(5*60*1000).getAverageValue();
if (outboundOnly)
return send;
int recv = 0;
rs = _context.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(5*60*1000).getAverageValue();
return Math.max(send, recv);
}
}
/**

View File

@@ -32,8 +32,7 @@ class RouterThrottleImpl implements RouterThrottle {
private static final String PROP_MAX_TUNNELS = "router.maxParticipatingTunnels";
private static final String PROP_DEFAULT_KBPS_THROTTLE = "router.defaultKBpsThrottle";
private static final String PROP_BANDWIDTH_SHARE_PERCENTAGE = "router.sharePercentage";
/** tunnel acceptance */
public static final int TUNNEL_ACCEPT = 0;
@@ -190,9 +189,16 @@ class RouterThrottleImpl implements RouterThrottle {
// of another tunnel?
rs = _context.statManager().getRate("tunnel.participatingMessageCount");
r = null;
if (rs != null)
double messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
if (rs != null) {
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)
messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
int participatingTunnels = _context.tunnelManager().getParticipatingCount();
@@ -211,33 +217,7 @@ class RouterThrottleImpl implements RouterThrottle {
return TUNNEL_ACCEPT;
}
static int get1sRate(RouterContext ctx) {
return (int)Math.max(ctx.bandwidthLimiter().getSendBps(), ctx.bandwidthLimiter().getReceiveBps());
}
static int get1mRate(RouterContext ctx) {
int send = 0;
RateStat rs = ctx.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(1*60*1000).getAverageValue();
int recv = 0;
rs = ctx.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(1*60*1000).getAverageValue();
return Math.max(send, recv);
}
static int get5mRate(RouterContext ctx) {
int send = 0;
RateStat rs = ctx.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(5*60*1000).getAverageValue();
int recv = 0;
rs = ctx.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(5*60*1000).getAverageValue();
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
/**
@@ -248,15 +228,37 @@ class RouterThrottleImpl implements RouterThrottle {
*/
private boolean allowTunnel(double bytesAllocated, int numTunnels) {
int maxKBps = Math.min(_context.bandwidthLimiter().getOutboundKBytesPerSecond(), _context.bandwidthLimiter().getInboundKBytesPerSecond());
int used1s = get1sRate(_context); // dont throttle on the 1s rate, its too volatile
int used1m = get1mRate(_context);
int used1s = 0; //get1sRate(_context); // dont throttle on the 1s rate, its too volatile
int used1m = _context.router().get1mRate();
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 availBps = (int)(((maxKBps*1024) - used) * getSharePercentage());
double share = _context.router().getSharePercentage();
int availBps = (int)(((maxKBps*1024)*share) - used); //(int)(((maxKBps*1024) - used) * getSharePercentage());
_context.statManager().addRateData("router.throttleTunnelBytesUsed", used, maxKBps);
_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) {
// lets be more conservative for people near their limit and assume 1KBps per tunnel
@@ -280,7 +282,7 @@ class RouterThrottleImpl implements RouterThrottle {
return true;
} else {
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 (_log.shouldLog(Log.INFO))
_log.info("Probabalistically allowing the tunnel w/ " + (pctFull*100d) + "% of our " + availBps
@@ -297,28 +299,6 @@ class RouterThrottleImpl implements RouterThrottle {
}
}
/**
* What fraction of the bandwidth specified in our bandwidth limits should
* we allow to be consumed by participating tunnels?
*
*/
private double getSharePercentage() {
String pct = _context.getProperty(PROP_BANDWIDTH_SHARE_PERCENTAGE);
if (pct != null) {
try {
double d = Double.parseDouble(pct);
if (d > 1)
return d/100d; // *cough* sometimes its 80 instead of .8 (!stab jrandom)
else
return d;
} catch (NumberFormatException nfe) {
if (_log.shouldLog(Log.INFO))
_log.info("Unable to get the share percentage");
}
}
return 0.8;
}
/** dont ever probabalistically throttle tunnels if we have less than this many */
private int getMinThrottleTunnels() {
try {

View File

@@ -15,8 +15,8 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.394 $ $Date: 2006/04/12 23:22:33 $";
public final static String VERSION = "0.6.1.15";
public final static String ID = "$Revision: 1.401 $ $Date: 2006/04/19 12:46:53 $";
public final static String VERSION = "0.6.1.17";
public final static long BUILD = 0;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);

View File

@@ -251,10 +251,12 @@ public class ProfileOrganizer {
// we only use selectHighCapacityPeers when we are selecting for PURPOSE_TEST
// or we are falling back due to _fastPeers being too small, so we can always
// exclude the fast peers
/*
if (exclude == null)
exclude = new HashSet(_fastPeers.keySet());
else
exclude.addAll(_fastPeers.keySet());
*/
locked_selectPeers(_highCapacityPeers, howMany, exclude, matches);
}
if (matches.size() < howMany) {
@@ -809,6 +811,8 @@ public class ProfileOrganizer {
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Peer " + peer.toBase64() + " is locally known, allowing its use");
// perhaps check to see if they are active?
return true;
}
} else {

View File

@@ -62,10 +62,10 @@ public class EstablishmentManager {
_queuedOutbound = new HashMap(32);
_liveIntroductions = new HashMap(32);
_activityLock = new Object();
_context.statManager().createRateStat("udp.inboundEstablishTime", "How long it takes for a new inbound session to be established", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.outboundEstablishTime", "How long it takes for a new outbound session to be established", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.inboundEstablishFailedState", "What state a failed inbound establishment request fails in", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.outboundEstablishFailedState", "What state a failed outbound establishment request fails in", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.inboundEstablishTime", "How long it takes for a new inbound session to be established", "udp", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.outboundEstablishTime", "How long it takes for a new outbound session to be established", "udp", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.inboundEstablishFailedState", "What state a failed inbound establishment request fails in", "udp", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.outboundEstablishFailedState", "What state a failed outbound establishment request fails in", "udp", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendIntroRelayRequest", "How often we send a relay request to reach a peer", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendIntroRelayTimeout", "How often a relay request times out before getting a response (due to the target or intro peer being offline)", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.receiveIntroRelayResponse", "How long it took to receive a relay response", "udp", new long[] { 60*60*1000, 24*60*60*1000 });

View File

@@ -402,6 +402,7 @@ public class PacketBuilder {
authenticate(packet, ourIntroKey, ourIntroKey, iv);
setTo(packet, to, state.getSentPort());
_ivCache.release(iv);
packet.setMessageType(53);
return packet;
}
@@ -465,6 +466,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, state.getIntroKey(), state.getIntroKey());
setTo(packet, to, state.getSentPort());
packet.setMessageType(52);
return packet;
}
@@ -571,6 +573,7 @@ public class PacketBuilder {
}
setTo(packet, to, state.getSentPort());
packet.setMessageType(51);
return packet;
}
@@ -623,6 +626,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, toCipherKey, toMACKey);
setTo(packet, toIP, toPort);
packet.setMessageType(50);
return packet;
}
@@ -667,6 +671,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, aliceIntroKey, aliceIntroKey);
setTo(packet, aliceIP, alicePort);
packet.setMessageType(49);
return packet;
}
@@ -713,6 +718,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, charlieCipherKey, charlieMACKey);
setTo(packet, charlieIP, charliePort);
packet.setMessageType(48);
return packet;
}
@@ -757,6 +763,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, bobCipherKey, bobMACKey);
setTo(packet, bobIP, bobPort);
packet.setMessageType(47);
return packet;
}
@@ -854,6 +861,7 @@ public class PacketBuilder {
if (encrypt)
authenticate(packet, new SessionKey(introKey), new SessionKey(introKey));
setTo(packet, introHost, introPort);
packet.setMessageType(46);
return packet;
}
@@ -903,6 +911,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, charlie.getCurrentCipherKey(), charlie.getCurrentMACKey());
setTo(packet, charlie.getRemoteIPAddress(), charlie.getRemotePort());
packet.setMessageType(45);
return packet;
}
@@ -963,6 +972,7 @@ public class PacketBuilder {
packet.getPacket().setLength(off);
authenticate(packet, aliceIntroKey, aliceIntroKey);
setTo(packet, aliceAddr, alice.getPort());
packet.setMessageType(44);
return packet;
}
@@ -994,6 +1004,8 @@ public class PacketBuilder {
// its just for hole punching
packet.getPacket().setLength(0);
setTo(packet, to, port);
packet.setMessageType(43);
return packet;
}

View File

@@ -68,6 +68,17 @@ public class PacketHandler {
_context.statManager().createRateStat("udp.packetVerifyTimeSlow", "How long it takes the PacketHandler to verify a data packet after dequeueing when its slow (period is dequeue time)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
_context.statManager().createRateStat("udp.packetValidateMultipleCount", "How many times we validate a packet, if done more than once (period = afterValidate-enqueue)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
_context.statManager().createRateStat("udp.packetNoValidationLifetime", "How long packets that are never validated are around for", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.sessionRequest", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.sessionConfirmed", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.sessionCreated", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.dataKnown", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.dataKnownAck", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.dataUnknown", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.dataUnknownAck", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.test", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.relayRequest", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.relayIntro", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
_context.statManager().createRateStat("udp.receivePacketSize.relayResponse", "Packet size of the given inbound packet type (period is the packet's lifetime)", "udp", new long[] { 60*1000, 10*60*1000 });
}
public void startup() {
@@ -440,14 +451,17 @@ public class PacketHandler {
case UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST:
_state = 47;
_establisher.receiveSessionRequest(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.sessionRequest", packet.getPacket().getLength(), packet.getLifetime());
break;
case UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED:
_state = 48;
_establisher.receiveSessionConfirmed(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.sessionConfirmed", packet.getPacket().getLength(), packet.getLifetime());
break;
case UDPPacket.PAYLOAD_TYPE_SESSION_CREATED:
_state = 49;
_establisher.receiveSessionCreated(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.sessionCreated", packet.getPacket().getLength(), packet.getLifetime());
break;
case UDPPacket.PAYLOAD_TYPE_DATA:
_state = 50;
@@ -472,6 +486,14 @@ public class PacketHandler {
}
packet.beforeReceiveFragments();
_inbound.receiveData(state, dr);
_context.statManager().addRateData("udp.receivePacketSize.dataKnown", packet.getPacket().getLength(), packet.getLifetime());
if (dr.readFragmentCount() <= 0)
_context.statManager().addRateData("udp.receivePacketSize.dataKnownAck", packet.getPacket().getLength(), packet.getLifetime());
} else {
_context.statManager().addRateData("udp.receivePacketSize.dataUnknown", packet.getPacket().getLength(), packet.getLifetime());
UDPPacketReader.DataReader dr = reader.getDataReader();
if (dr.readFragmentCount() <= 0)
_context.statManager().addRateData("udp.receivePacketSize.dataUnknownAck", packet.getPacket().getLength(), packet.getLifetime());
}
break;
case UDPPacket.PAYLOAD_TYPE_TEST:
@@ -479,21 +501,25 @@ public class PacketHandler {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received test packet: " + reader + " from " + from);
_testManager.receiveTest(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.test", packet.getPacket().getLength(), packet.getLifetime());
break;
case UDPPacket.PAYLOAD_TYPE_RELAY_REQUEST:
if (_log.shouldLog(Log.INFO))
_log.info("Received relay request packet: " + reader + " from " + from);
_introManager.receiveRelayRequest(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.relayRequest", packet.getPacket().getLength(), packet.getLifetime());
break;
case UDPPacket.PAYLOAD_TYPE_RELAY_INTRO:
if (_log.shouldLog(Log.INFO))
_log.info("Received relay intro packet: " + reader + " from " + from);
_introManager.receiveRelayIntro(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.relayIntro", packet.getPacket().getLength(), packet.getLifetime());
break;
case UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE:
if (_log.shouldLog(Log.INFO))
_log.info("Received relay response packet: " + reader + " from " + from);
_establisher.receiveRelayResponse(from, reader);
_context.statManager().addRateData("udp.receivePacketSize.relayResponse", packet.getPacket().getLength(), packet.getLifetime());
break;
default:
_state = 52;

View File

@@ -1036,7 +1036,7 @@ public class PeerState {
remaining = 1; // total lifetime will exceed it anyway, guaranteeing failure
float pDrop = totalLifetime / (float)remaining;
pDrop = pDrop * pDrop * pDrop;
if (pDrop >= _context.random().nextFloat()) {
if (false && (pDrop >= _context.random().nextFloat())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Proactively tail dropping for " + _remotePeer.toBase64() + " (messages=" + msgs.size()
+ " headLifetime=" + lifetime + " totalLifetime=" + totalLifetime + " curLifetime=" + state.getLifetime()

View File

@@ -55,7 +55,21 @@ public class UDPSender {
_context.statManager().createRateStat("udp.sendPacketSize.18", "tunnel data message size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.19", "tunnel gateway message size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.20", "data message size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.21", "tunnel build", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.22", "tunnel build reply", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.20", "data message size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.42", "ack-only packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.43", "hole punch packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.44", "relay response packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.45", "relay intro packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.46", "relay request packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.47", "peer test charlie to bob packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.48", "peer test bob to charlie packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.49", "peer test to alice packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.50", "peer test from alice packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.51", "session confirmed packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.52", "session request packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
_context.statManager().createRateStat("udp.sendPacketSize.53", "session created packet size", "udp", new long[] { 60*1000, 5*60*1000, 30*60*1000 });
}
public void startup() {
@@ -211,7 +225,7 @@ public class UDPSender {
//_log.debug("Sending packet: (size="+size + "/"+size2 +")\nraw: " + Base64.encode(packet.getPacket().getData(), 0, size));
}
//_context.statManager().addRateData("udp.sendPacketSize." + packet.getMessageType(), size, packet.getFragmentCount());
_context.statManager().addRateData("udp.sendPacketSize." + packet.getMessageType(), size, packet.getFragmentCount());
//packet.getPacket().setLength(size);
try {

View File

@@ -154,7 +154,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_context.statManager().createRateStat("udp.alreadyConnected", "What is the lifetime of a reestablished session", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.droppedPeer", "How long ago did we receive from a dropped peer (duration == session lifetime", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.droppedPeerInactive", "How long ago did we receive from a dropped peer (duration == session lifetime)", "udp", new long[] { 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.droppedPeerInactive", "How long ago did we receive from a dropped peer (duration == session lifetime)", "udp", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.statusOK", "How many times the peer test returned OK", "udp", new long[] { 5*60*1000, 20*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.statusDifferent", "How many times the peer test returned different IP/ports", "udp", new long[] { 5*60*1000, 20*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.statusReject", "How many times the peer test returned reject unsolicited", "udp", new long[] { 5*60*1000, 20*60*1000, 60*60*1000, 24*60*60*1000 });
@@ -1673,6 +1673,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
if (_alive) {
long delay = _context.random().nextInt(2*TEST_FREQUENCY);
if (delay <= 0)
throw new RuntimeException("wtf, delay is " + delay);
SimpleTimer.getInstance().addEvent(PeerTestEvent.this, delay);
}
}

View File

@@ -52,7 +52,7 @@ class BuildExecutor implements Runnable {
buf = new StringBuffer(128);
buf.append("Allowed: ");
}
int allowed = 20;
int allowed = 5;
String prop = _context.getProperty("router.tunnelConcurrentBuilds");
if (prop != null)
try { allowed = Integer.valueOf(prop).intValue(); } catch (NumberFormatException nfe) {}
@@ -92,6 +92,8 @@ class BuildExecutor implements Runnable {
_context.statManager().addRateData("tunnel.buildExploratoryExpire", 1, 0);
else
_context.statManager().addRateData("tunnel.buildClientExpire", 1, 0);
for (int j = 0; j < cfg.getLength(); j++)
didNotReply(cfg.getReplyMessageId(), cfg.getPeer(j));
}
}
@@ -107,11 +109,33 @@ class BuildExecutor implements Runnable {
_context.statManager().addRateData("tunnel.concurrentBuildsLagged", concurrent, lag);
return 0; // if we have a job heavily blocking our jobqueue, ssllloowww dddooowwwnnn
}
//if (isOverloaded())
// return 0;
if (isOverloaded())
return 0;
return allowed;
}
/**
* Don't even try to build tunnels if we're saturated
*/
private boolean isOverloaded() {
//if (true) return false;
// dont include the inbound rates when throttling tunnel building, since
// that'd expose a pretty trivial attack.
int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
int used1s = _context.router().get1sRate(true); // dont throttle on the 1s rate, its too volatile
int used1m = _context.router().get1mRate(true);
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);
if ((maxKBps * 1024) - used <= 0) {
if (_log.shouldLog(Log.WARN))
_log.warn("Too overloaded to build our own tunnels (used=" + used + ", maxKBps=" + maxKBps + ", 1s=" + used1s + ", 1m=" + used1m + ")");
return true;
} else {
return false;
}
}
public void run() {
_isRunning = true;
@@ -306,6 +330,7 @@ class BuildExecutor implements Runnable {
_currentlyBuilding.remove(cfg);
_currentlyBuilding.notifyAll();
}
long expireBefore = _context.clock().now() + 10*60*1000 - BuildRequestor.REQUEST_TIMEOUT;
if (cfg.getExpiration() <= expireBefore) {
if (_log.shouldLog(Log.INFO))
@@ -331,6 +356,11 @@ class BuildExecutor implements Runnable {
}
}
private void didNotReply(long tunnel, Hash peer) {
if (_log.shouldLog(Log.INFO))
_log.info(tunnel + ": Peer " + peer.toBase64() + " did not reply to the tunnel join request");
}
List locked_getCurrentlyBuilding() { return _currentlyBuilding; }
public int getInboundBuildQueueSize() { return _handler.getInboundBuildQueueSize(); }
}

View File

@@ -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.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.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.receiveRejectionProbabalistic", "How often we are rejected probabalistically?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
@@ -212,8 +213,8 @@ class BuildHandler {
Hash peer = cfg.getPeer(i);
int record = order.indexOf(new Integer(i));
int howBad = statuses[record];
if (_log.shouldLog(Log.DEBUG))
_log.debug(msg.getUniqueId() + ": Peer " + peer.toBase64() + " replied with status " + howBad);
if (_log.shouldLog(Log.INFO))
_log.info(msg.getUniqueId() + ": Peer " + peer.toBase64() + " replied with status " + howBad);
if (howBad == 0) {
// w3wt
@@ -371,7 +372,7 @@ class BuildHandler {
* If we are dropping lots of requests before even trying to handle them,
* 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() {
int dropped = 0;
@@ -413,14 +414,18 @@ class BuildHandler {
int proactiveDrops = countProactiveDrops();
long recvDelay = System.currentTimeMillis()-state.recvTime;
if ( (response == 0) && ( (recvDelay > BuildRequestor.REQUEST_TIMEOUT/2) || (proactiveDrops > MAX_PROACTIVE_DROPS) ) ) {
_context.statManager().addRateData("tunnel.rejectOverloaded", recvDelay, proactiveDrops);
if (true || (proactiveDrops < MAX_PROACTIVE_DROPS*2))
response = TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
else
response = TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
} else if (response == 0) {
_context.statManager().addRateData("tunnel.acceptLoad", recvDelay, recvDelay);
if (response == 0) {
float pDrop = recvDelay / (BuildRequestor.REQUEST_TIMEOUT);
pDrop = (float)Math.pow(pDrop, 16);
if (_context.random().nextFloat() < pDrop) { // || (proactiveDrops > MAX_PROACTIVE_DROPS) ) ) {
_context.statManager().addRateData("tunnel.rejectOverloaded", recvDelay, proactiveDrops);
if (true || (proactiveDrops < MAX_PROACTIVE_DROPS*2))
response = TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
else
response = TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
} else {
_context.statManager().addRateData("tunnel.acceptLoad", recvDelay, recvDelay);
}
}
if (_log.shouldLog(Log.DEBUG))
@@ -542,6 +547,8 @@ class BuildHandler {
}
}
/** um, this is bad. don't set this. */
private static final boolean DROP_ALL_REQUESTS = false;
private static final boolean HANDLE_REPLIES_INLINE = true;
private class TunnelBuildMessageHandlerJobBuilder implements HandlerJobBuilder {
@@ -581,7 +588,7 @@ class BuildHandler {
_exec.repoll();
}
} else {
if (_exec.wasRecentlyBuilding(reqId)) {
if (DROP_ALL_REQUESTS || _exec.wasRecentlyBuilding(reqId)) {
if (_log.shouldLog(Log.WARN))
_log.warn("Dropping the reply " + reqId + ", as we used to be building that");
} else {
@@ -603,10 +610,10 @@ class BuildHandler {
_context.statManager().addRateData("tunnel.dropLoadBacklog", _inboundBuildMessages.size(), _inboundBuildMessages.size());
} else {
int queueTime = estimateQueueTime(_inboundBuildMessages.size());
float pDrop = queueTime/((float)BuildRequestor.REQUEST_TIMEOUT/2);
pDrop = pDrop * pDrop;
float pDrop = queueTime/((float)BuildRequestor.REQUEST_TIMEOUT);
pDrop = (float)Math.pow(pDrop, 16); // steeeep
float f = _context.random().nextFloat();
if (pDrop > f) {
if ( (pDrop > f) && (allowProactiveDrop()) ) {
_context.statManager().addRateData("tunnel.dropLoadProactive", queueTime, _inboundBuildMessages.size());
} else {
_inboundBuildMessages.add(new BuildMessageState(receivedMessage, from, fromHash));
@@ -620,6 +627,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) {
int decryptTime = 200;
RateStat rs = _context.statManager().getRate("crypto.elGamal.decrypt");
@@ -636,9 +653,9 @@ class BuildHandler {
decryptTime = (int)avg;
}
}
int estimatedQueueTime = numPendingMessages * decryptTime;
estimatedQueueTime *= 2; // lets leave some cpu to spare, 'eh?
return estimatedQueueTime;
float estimatedQueueTime = numPendingMessages * decryptTime;
estimatedQueueTime *= 1.2f; // lets leave some cpu to spare, 'eh?
return (int)estimatedQueueTime;
}

View File

@@ -21,10 +21,17 @@ class BuildRequestor {
for (int i = 0; i < BuildMessageGenerator.ORDER.length; i++)
ORDER.add(new Integer(i));
}
private static final boolean USE_PAIRED_CLIENT_TUNNELS = true;
private static final int PRIORITY = 500;
static final int REQUEST_TIMEOUT = 20*1000;
private static boolean usePairedTunnels(RouterContext ctx) {
String val = ctx.getProperty("router.usePairedTunnels");
if ( (val == null) || (Boolean.valueOf(val).booleanValue()) )
return true;
else
return false;
}
/** new style requests need to fill in the tunnel IDs before hand */
public static void prepare(RouterContext ctx, PooledTunnelCreatorConfig cfg) {
for (int i = 0; i < cfg.getLength(); i++) {
@@ -58,7 +65,7 @@ class BuildRequestor {
cfg.setTunnelPool(pool);
TunnelInfo pairedTunnel = null;
if (pool.getSettings().isExploratory() || !USE_PAIRED_CLIENT_TUNNELS) {
if (pool.getSettings().isExploratory() || !usePairedTunnels(ctx)) {
if (pool.getSettings().isInbound())
pairedTunnel = ctx.tunnelManager().selectOutboundTunnel();
else
@@ -72,7 +79,7 @@ class BuildRequestor {
if (pairedTunnel == null) {
if (log.shouldLog(Log.WARN))
log.warn("Couldn't find a paired tunnel for " + cfg + ", fall back on exploratory tunnels for pairing");
if (!pool.getSettings().isExploratory() && USE_PAIRED_CLIENT_TUNNELS)
if (!pool.getSettings().isExploratory() && usePairedTunnels(ctx))
if (pool.getSettings().isInbound())
pairedTunnel = ctx.tunnelManager().selectOutboundTunnel();
else