forked from I2P_Developers/i2p.i2p
Compare commits
9 Commits
i2p_0_6_1_
...
i2p_0_6_1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb36e993c1 | ||
|
|
e5eca5fa45 | ||
|
|
8cba2f4236 | ||
|
|
40d5ed31ac | ||
|
|
181275fe35 | ||
|
|
23d8c01ce7 | ||
|
|
de83944486 | ||
|
|
90cd7ff23a | ||
|
|
8d0a9b4ccd |
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() &&
|
||||
|
||||
@@ -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; }
|
||||
|
||||
31
history.txt
31
history.txt
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
13
news.xml
13
news.xml
@@ -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" />
|
||||
•
|
||||
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>
|
||||
•
|
||||
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>
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user