forked from I2P_Developers/i2p.i2p
2005-02-26 jrandom
* Further streaming lib caching improvements * Reduce the minimum RTT (used to calculate retry timeouts), but also increase the RTT on resends. * Lower the default message size to 4KB from 16KB to further reduce the chance of failed fragmentation. * Extend tunnel rebuild throttling to include fallback rebuilds * If there are less than 20 routers known, don't drop the last 20 (to help avoid dropping all peers under catastrophic failures) * New stats for end to end messages - "client.leaseSetFoundLocally", "client.leaseSetFoundRemoteTime", and "client.leaseSetFailedRemoteTime"
This commit is contained in:
@ -76,7 +76,7 @@ public class Connection {
|
||||
private long _lifetimeDupMessageReceived;
|
||||
|
||||
public static final long MAX_RESEND_DELAY = 60*1000;
|
||||
public static final long MIN_RESEND_DELAY = 20*1000;
|
||||
public static final long MIN_RESEND_DELAY = 10*1000;
|
||||
|
||||
/** wait up to 5 minutes after disconnection so we can ack/close packets */
|
||||
public static int DISCONNECT_TIMEOUT = 5*60*1000;
|
||||
@ -870,6 +870,8 @@ public class Connection {
|
||||
_log.warn("Congestion resending packet " + _packet.getSequenceNum() + ": new windowSize " + newWindowSize
|
||||
+ ") for " + Connection.this.toString());
|
||||
|
||||
// setRTT has its own ceiling
|
||||
getOptions().setRTT(getOptions().getRTT() + 30*1000);
|
||||
getOptions().setWindowSize(newWindowSize);
|
||||
windowAdjusted();
|
||||
}
|
||||
|
@ -328,6 +328,7 @@ public class ConnectionManager {
|
||||
}
|
||||
|
||||
_outboundQueue.enqueue(packet);
|
||||
packet.releasePayload();
|
||||
|
||||
if (blocking) {
|
||||
synchronized (req) {
|
||||
|
@ -81,7 +81,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
super.init(opts);
|
||||
setConnectDelay(getInt(opts, PROP_CONNECT_DELAY, -1));
|
||||
setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK));
|
||||
setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, 16*1024));
|
||||
setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, 4*1024));
|
||||
setRTT(getInt(opts, PROP_INITIAL_RTT, 30*1000));
|
||||
setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
|
||||
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
|
||||
|
@ -77,7 +77,7 @@ public class ConnectionPacketHandler {
|
||||
+ ": dropping " + packet);
|
||||
ack(con, packet.getAckThrough(), packet.getNacks(), null, false);
|
||||
con.getOptions().setChoke(5*1000);
|
||||
_cache.release(packet.getPayload());
|
||||
packet.releasePayload();
|
||||
return;
|
||||
}
|
||||
con.getOptions().setChoke(0);
|
||||
@ -219,6 +219,8 @@ public class ConnectionPacketHandler {
|
||||
+ con.getLastCongestionSeenAt() + " (#resends: " + numResends
|
||||
+ ") for " + con);
|
||||
|
||||
// setRTT has its own ceiling
|
||||
con.getOptions().setRTT(con.getOptions().getRTT() + 30*1000);
|
||||
con.getOptions().setWindowSize(oldSize);
|
||||
|
||||
congested = true;
|
||||
|
@ -209,6 +209,8 @@ public class Packet {
|
||||
/** get the actual payload of the message. may be null */
|
||||
public ByteArray getPayload() { return _payload; }
|
||||
public void setPayload(ByteArray payload) {
|
||||
if ( (_payload != null) && (_payload != payload) )
|
||||
_cache.release(_payload);
|
||||
_payload = payload;
|
||||
if ( (payload != null) && (payload.getValid() > MAX_PAYLOAD_SIZE) )
|
||||
throw new IllegalArgumentException("Too large payload: " + payload.getValid());
|
||||
@ -216,6 +218,11 @@ public class Packet {
|
||||
public int getPayloadSize() {
|
||||
return (_payload == null ? 0 : _payload.getValid());
|
||||
}
|
||||
public void releasePayload() {
|
||||
if (_payload != null)
|
||||
_cache.release(_payload);
|
||||
_payload = null;
|
||||
}
|
||||
|
||||
/** is a particular flag set on this packet? */
|
||||
public boolean isFlagSet(int flag) { return 0 != (_flags & flag); }
|
||||
|
@ -155,12 +155,14 @@ public class PacketHandler {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Receive a syn packet with the wrong IDs, sending reset: " + packet);
|
||||
sendReset(packet);
|
||||
packet.releasePayload();
|
||||
} else {
|
||||
if (!con.getResetSent()) {
|
||||
// someone is sending us a packet on the wrong stream
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Received a packet on the wrong stream: " + packet + " connection: " + con);
|
||||
}
|
||||
packet.releasePayload();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,6 +189,7 @@ public class PacketHandler {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Echo packet received with no stream IDs: " + packet);
|
||||
}
|
||||
packet.releasePayload();
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Packet received on an unknown stream (and not an ECHO): " + packet);
|
||||
@ -221,6 +224,7 @@ public class PacketHandler {
|
||||
+ buf.toString() + " sendId: "
|
||||
+ (sendId != null ? Base64.encode(sendId) : " unknown"));
|
||||
}
|
||||
packet.releasePayload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,32 +82,24 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat
|
||||
_numSends++;
|
||||
_lastSend = _context.clock().now();
|
||||
}
|
||||
public void ackReceived() {
|
||||
ByteArray ba = null;
|
||||
public void ackReceived() {
|
||||
synchronized (this) {
|
||||
if (_ackOn <= 0)
|
||||
_ackOn = _context.clock().now();
|
||||
ba = getPayload();
|
||||
setPayload(null);
|
||||
_ackOn = _context.clock().now();
|
||||
releasePayload();
|
||||
notifyAll();
|
||||
}
|
||||
SimpleTimer.getInstance().removeEvent(_resendEvent);
|
||||
if (ba != null)
|
||||
_cache.release(ba);
|
||||
}
|
||||
public void cancelled() {
|
||||
ByteArray ba = null;
|
||||
synchronized (this) {
|
||||
_cancelledOn = _context.clock().now();
|
||||
ba = getPayload();
|
||||
setPayload(null);
|
||||
releasePayload();
|
||||
notifyAll();
|
||||
}
|
||||
SimpleTimer.getInstance().removeEvent(_resendEvent);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Cancelled! " + toString(), new Exception("cancelled"));
|
||||
if (ba != null)
|
||||
_cache.release(ba);
|
||||
}
|
||||
|
||||
/** how long after packet creation was it acked? */
|
||||
@ -144,10 +136,12 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat
|
||||
int window = _connection.getOptions().getWindowSize();
|
||||
boolean accepted = _connection.packetSendChoke(maxWaitMs);
|
||||
long after = _context.clock().now();
|
||||
if (accepted)
|
||||
if (accepted) {
|
||||
_acceptedOn = after;
|
||||
else
|
||||
} else {
|
||||
_acceptedOn = -1;
|
||||
releasePayload();
|
||||
}
|
||||
int afterQueued = _connection.getUnackedPacketsSent();
|
||||
if ( (after - before > 1000) && (_log.shouldLog(Log.DEBUG)) )
|
||||
_log.debug("Took " + (after-before) + "ms to get "
|
||||
@ -162,11 +156,11 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat
|
||||
long expiration = _context.clock().now()+maxWaitMs;
|
||||
while (true) {
|
||||
long timeRemaining = expiration - _context.clock().now();
|
||||
if ( (timeRemaining <= 0) && (maxWaitMs > 0) ) return;
|
||||
if ( (timeRemaining <= 0) && (maxWaitMs > 0) ) break;
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (_ackOn > 0) return;
|
||||
if (_cancelledOn > 0) return;
|
||||
if (_ackOn > 0) break;
|
||||
if (_cancelledOn > 0) break;
|
||||
if (timeRemaining > 60*1000)
|
||||
timeRemaining = 60*1000;
|
||||
else if (timeRemaining <= 0)
|
||||
@ -175,6 +169,8 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat
|
||||
}
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
if (!writeSuccessful())
|
||||
releasePayload();
|
||||
}
|
||||
|
||||
public boolean writeAccepted() { return _acceptedOn > 0 && _cancelledOn <= 0; }
|
||||
|
@ -25,7 +25,6 @@ class PacketQueue {
|
||||
private I2PSession _session;
|
||||
private ConnectionManager _connectionManager;
|
||||
private ByteCache _cache = ByteCache.getInstance(64, 36*1024);
|
||||
private ByteCache _packetCache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
|
||||
|
||||
public PacketQueue(I2PAppContext context, I2PSession session, ConnectionManager mgr) {
|
||||
_context = context;
|
||||
@ -129,7 +128,13 @@ class PacketQueue {
|
||||
|
||||
if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) {
|
||||
// ack only, so release it asap
|
||||
_packetCache.release(packet.getPayload());
|
||||
packet.releasePayload();
|
||||
} else if (packet.isFlagSet(Packet.FLAG_ECHO) && !packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED) ) {
|
||||
// pong
|
||||
packet.releasePayload();
|
||||
} else if (packet.isFlagSet(Packet.FLAG_RESET)) {
|
||||
// reset
|
||||
packet.releasePayload();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user