forked from I2P_Developers/i2p.i2p
SSU: Fix RTT/RTO calculations (ticket #2443)
This commit is contained in:
@ -62,7 +62,7 @@ class ACKSender implements Runnable {
|
||||
|
||||
public synchronized void shutdown() {
|
||||
_alive = false;
|
||||
PeerState poison = new PeerState(_context, _transport, new byte[4], 0, null, false);
|
||||
PeerState poison = new PeerState(_context, _transport, new byte[4], 0, null, false, 0);
|
||||
poison.setTheyRelayToUsAs(POISON_PS);
|
||||
_peersToACK.offer(poison);
|
||||
for (int i = 1; i <= 5 && !_peersToACK.isEmpty(); i++) {
|
||||
|
@ -694,7 +694,7 @@ class EstablishmentManager {
|
||||
|
||||
RouterIdentity remote = state.getConfirmedIdentity();
|
||||
PeerState peer = new PeerState(_context, _transport,
|
||||
state.getSentIP(), state.getSentPort(), remote.calculateHash(), true);
|
||||
state.getSentIP(), state.getSentPort(), remote.calculateHash(), true, state.getRTT());
|
||||
peer.setCurrentCipherKey(state.getCipherKey());
|
||||
peer.setCurrentMACKey(state.getMACKey());
|
||||
peer.setWeRelayToThemAs(state.getSentRelayTag());
|
||||
@ -813,7 +813,7 @@ class EstablishmentManager {
|
||||
_outboundByClaimedAddress.remove(claimed, state);
|
||||
_outboundByHash.remove(remote.calculateHash(), state);
|
||||
PeerState peer = new PeerState(_context, _transport,
|
||||
state.getSentIP(), state.getSentPort(), remote.calculateHash(), false);
|
||||
state.getSentIP(), state.getSentPort(), remote.calculateHash(), false, state.getRTT());
|
||||
peer.setCurrentCipherKey(state.getCipherKey());
|
||||
peer.setCurrentMACKey(state.getMACKey());
|
||||
peer.setTheyRelayToUsAs(state.getReceivedRelayTag());
|
||||
|
@ -64,6 +64,8 @@ class InboundEstablishState {
|
||||
private int _createdSentCount;
|
||||
// default true
|
||||
private boolean _introductionRequested = true;
|
||||
|
||||
private int _rtt;
|
||||
|
||||
public enum InboundState {
|
||||
/** nothin known yet */
|
||||
@ -296,6 +298,8 @@ class InboundEstablishState {
|
||||
*/
|
||||
public synchronized long getNextSendTime() { return _nextSend; }
|
||||
|
||||
synchronized int getRTT() { return _rtt; }
|
||||
|
||||
/** RemoteHostId, uniquely identifies an attempt */
|
||||
RemoteHostId getRemoteHostId() { return _remoteHostId; }
|
||||
|
||||
@ -356,6 +360,10 @@ class InboundEstablishState {
|
||||
_currentState = InboundState.IB_STATE_CONFIRMED_PARTIALLY;
|
||||
}
|
||||
|
||||
if (_createdSentCount == 1) {
|
||||
_rtt = (int) ( _context.clock().now() - _lastSend );
|
||||
}
|
||||
|
||||
packetReceived();
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ class OutboundEstablishState {
|
||||
private long _confirmedSentTime;
|
||||
private long _requestSentTime;
|
||||
private long _introSentTime;
|
||||
private int _rtt;
|
||||
|
||||
public enum OutboundState {
|
||||
/** nothin sent yet */
|
||||
@ -179,6 +180,8 @@ class OutboundEstablishState {
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public boolean needIntroduction() { return _needIntroduction; }
|
||||
|
||||
synchronized int getRTT() { return _rtt; }
|
||||
|
||||
/**
|
||||
* Queue a message to be sent after the session is established.
|
||||
@ -304,6 +307,10 @@ class OutboundEstablishState {
|
||||
_currentState == OutboundState.OB_STATE_INTRODUCED ||
|
||||
_currentState == OutboundState.OB_STATE_PENDING_INTRO)
|
||||
_currentState = OutboundState.OB_STATE_CREATED_RECEIVED;
|
||||
|
||||
if (_requestSentCount == 1) {
|
||||
_rtt = (int) (_context.clock().now() - _requestSentTime);
|
||||
}
|
||||
packetReceived();
|
||||
}
|
||||
|
||||
|
@ -314,10 +314,10 @@ public class PeerState {
|
||||
*/
|
||||
public static final int MAX_MTU = Math.max(LARGE_MTU, MAX_IPV6_MTU);
|
||||
|
||||
private static final int MIN_RTO = 100 + ACKSender.ACK_FREQUENCY;
|
||||
private static final int INIT_RTO = 3*1000;
|
||||
public static final int INIT_RTT = INIT_RTO / 2;
|
||||
private static final int MAX_RTO = 15*1000;
|
||||
private static final int MIN_RTO = 1000;
|
||||
private static final int INIT_RTO = 1000;
|
||||
private static final int INIT_RTT = 0;
|
||||
private static final int MAX_RTO = 60*1000;
|
||||
private static final int CLOCK_SKEW_FUDGE = (ACKSender.ACK_FREQUENCY * 2) / 3;
|
||||
|
||||
/**
|
||||
@ -336,8 +336,11 @@ public class PeerState {
|
||||
private static final long RESEND_ACK_TIMEOUT = 5*60*1000;
|
||||
|
||||
|
||||
/**
|
||||
* @param rtt from the EstablishState, or 0 if not available
|
||||
*/
|
||||
public PeerState(RouterContext ctx, UDPTransport transport,
|
||||
byte[] remoteIP, int remotePort, Hash remotePeer, boolean isInbound) {
|
||||
byte[] remoteIP, int remotePort, Hash remotePeer, boolean isInbound, int rtt) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(PeerState.class);
|
||||
_transport = transport;
|
||||
@ -366,9 +369,14 @@ public class PeerState {
|
||||
}
|
||||
//_mtuLastChecked = -1;
|
||||
_lastACKSend = -1;
|
||||
|
||||
_rto = INIT_RTO;
|
||||
_rtt = INIT_RTT;
|
||||
_rttDeviation = _rtt;
|
||||
if (rtt > 0)
|
||||
recalculateTimeouts(rtt);
|
||||
else
|
||||
_rttDeviation = _rtt;
|
||||
|
||||
_inboundMessages = new HashMap<Long, InboundMessageState>(8);
|
||||
_outboundMessages = new CachedIteratorCollection<OutboundMessageState>();
|
||||
//_outboundQueue = new CoDelPriorityBlockingQueue(ctx, "UDP-PeerState", 32);
|
||||
@ -1226,16 +1234,18 @@ public class PeerState {
|
||||
* Caller should synch on this
|
||||
*/
|
||||
private void recalculateTimeouts(long lifetime) {
|
||||
// the rttDev calculation matches that recommended in RFC 2988 (beta = 1/4)
|
||||
_rttDeviation = _rttDeviation + (int)(0.25d*(Math.abs(lifetime-_rtt)-_rttDeviation));
|
||||
if (_rtt <= 0) {
|
||||
// first measurement
|
||||
_rtt = (int) lifetime;
|
||||
_rttDeviation = (int)(lifetime / 2);
|
||||
} else {
|
||||
// the rttDev calculation matches that recommended in RFC 2988 (beta = 1/4)
|
||||
_rttDeviation = (int)( 0.75*_rttDeviation + 0.25*Math.abs(lifetime-_rtt) );
|
||||
|
||||
float scale = RTT_DAMPENING;
|
||||
// the faster we are going, the slower we want to reduce the rtt
|
||||
//if (_sendBps > 0)
|
||||
// scale = lifetime / ((float)lifetime + (float)_sendBps);
|
||||
//if (scale < 0.001f) scale = 0.001f;
|
||||
float scale = RTT_DAMPENING;
|
||||
|
||||
_rtt = (int)(_rtt*(1.0f-scale) + (scale)*lifetime);
|
||||
_rtt = (int)(_rtt*(1.0f-scale) + (scale)*lifetime);
|
||||
}
|
||||
// K = 4
|
||||
_rto = Math.min(MAX_RTO, Math.max(minRTO(), _rtt + (_rttDeviation<<2)));
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
@ -1821,13 +1831,15 @@ public class PeerState {
|
||||
+ " remaining"
|
||||
+ " for message " + state.getMessageId() + ": " + state);
|
||||
|
||||
if (state.getPushCount() > 0)
|
||||
int rto = getRTO();
|
||||
if (state.getPushCount() > 0) {
|
||||
_retransmitter = state;
|
||||
rto = Math.min(MAX_RTO, rto << state.getPushCount()); // Section 5.5 RFC 6298
|
||||
}
|
||||
|
||||
if (state.push())
|
||||
_messagesSent++;
|
||||
|
||||
int rto = getRTO();
|
||||
state.setNextSendTime(now + rto);
|
||||
|
||||
//if (peer.getSendWindowBytesRemaining() > 0)
|
||||
|
@ -2723,7 +2723,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
for (PeerState peer : _peersByIdent.values()) {
|
||||
if ((!includeEverybody) && now - peer.getLastReceiveTime() > 5*60*1000)
|
||||
continue; // skip old peers
|
||||
if (peer.getRTT() > PeerState.INIT_RTT - 250)
|
||||
if (peer.getRTT() > 1250)
|
||||
continue; // Big RTT makes for a poor calculation
|
||||
skews.addElement(Long.valueOf(peer.getClockSkew() / 1000));
|
||||
}
|
||||
|
Reference in New Issue
Block a user