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:
jrandom
2006-04-19 17:46:51 +00:00
committed by zzz
parent 40d5ed31ac
commit 8cba2f4236
17 changed files with 212 additions and 72 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

@ -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

@ -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

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,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 {

View File

@ -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);

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

@ -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

@ -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,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(); }
}

View File

@ -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()) ) {