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
This commit is contained in:
@ -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();
|
||||
|
@ -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() &&
|
||||
|
10
history.txt
10
history.txt
@ -1,4 +1,12 @@
|
||||
$Id: history.txt,v 1.459 2006/04/15 02:15:19 jrandom Exp $
|
||||
$Id: history.txt,v 1.460 2006/04/15 02:58:12 jrandom Exp $
|
||||
|
||||
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
|
||||
|
||||
|
@ -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,7 +32,6 @@ 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;
|
||||
@ -218,32 +217,6 @@ 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 = 60; // .1KBps
|
||||
private static final int MIN_AVAILABLE_BPS = 4*1024; // always leave at least 4KBps free when allowing
|
||||
|
||||
@ -256,10 +229,10 @@ class RouterThrottleImpl implements RouterThrottle {
|
||||
private boolean allowTunnel(double bytesAllocated, int numTunnels) {
|
||||
int maxKBps = Math.min(_context.bandwidthLimiter().getOutboundKBytesPerSecond(), _context.bandwidthLimiter().getInboundKBytesPerSecond());
|
||||
int used1s = 0; //get1sRate(_context); // dont throttle on the 1s rate, its too volatile
|
||||
int used1m = get1mRate(_context);
|
||||
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);
|
||||
double share = 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);
|
||||
@ -326,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,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.399 $ $Date: 2006/04/15 02:15:23 $";
|
||||
public final static String ID = "$Revision: 1.400 $ $Date: 2006/04/15 02:58:14 $";
|
||||
public final static String VERSION = "0.6.1.16";
|
||||
public final static long BUILD = 0;
|
||||
public final static long BUILD = 1;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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,12 +109,34 @@ 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;
|
||||
List wanted = new ArrayList(8);
|
||||
@ -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(); }
|
||||
}
|
||||
|
@ -213,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
|
||||
@ -415,7 +415,7 @@ class BuildHandler {
|
||||
int proactiveDrops = countProactiveDrops();
|
||||
long recvDelay = System.currentTimeMillis()-state.recvTime;
|
||||
if (response == 0) {
|
||||
float pDrop = recvDelay / (BuildRequestor.REQUEST_TIMEOUT/2);
|
||||
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);
|
||||
@ -547,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 {
|
||||
@ -586,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 {
|
||||
@ -608,7 +610,7 @@ 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);
|
||||
float pDrop = queueTime/((float)BuildRequestor.REQUEST_TIMEOUT);
|
||||
pDrop = (float)Math.pow(pDrop, 16); // steeeep
|
||||
float f = _context.random().nextFloat();
|
||||
if ( (pDrop > f) && (allowProactiveDrop()) ) {
|
||||
|
Reference in New Issue
Block a user