Skip to content

Commit

Permalink
fix: bug in kcp that caused invalid smoothing of rtt values
Browse files Browse the repository at this point in the history
  • Loading branch information
paulpach committed Oct 14, 2020
1 parent e51ab3f commit eacfefe
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 26 deletions.
43 changes: 18 additions & 25 deletions Assets/Mirror/Runtime/Transport/Kcp/Kcp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ internal struct AckItem
uint snd_nxt;
uint rcv_nxt;
uint ssthresh = 2;
uint rx_rttval;
uint rx_SmoothedRoundTripTime; //Used by UpdateAck
uint rx_rto = 200; //Default RTO
uint rx_MinimumRto = 100; // normal min rto
int rx_rttval;
int rx_SmoothedRoundTripTime; //Used by UpdateAck
int rx_rto = 200; //Default RTO
int rx_MinimumRto = 100; // normal min rto
uint cwnd;
uint probe;
uint interval = 100;
Expand Down Expand Up @@ -225,28 +225,21 @@ void UpdateAck(int roundTripTime)
// https://tools.ietf.org/html/rfc6298
if (rx_SmoothedRoundTripTime == 0)
{
rx_SmoothedRoundTripTime = (uint)roundTripTime;
rx_rttval = (uint)roundTripTime >> 1;
rx_SmoothedRoundTripTime = roundTripTime;
rx_rttval = roundTripTime >> 1;
}
else
{
uint delta = (uint)Math.Abs(roundTripTime - rx_SmoothedRoundTripTime);
rx_SmoothedRoundTripTime += delta >> 3;
int delta = Math.Abs(roundTripTime - rx_SmoothedRoundTripTime);

if (roundTripTime < rx_SmoothedRoundTripTime - rx_rttval)
{
// if the new RTT sample is below the bottom of the range of
// what an RTT measurement is expected to be.
// give an 8x reduced weight versus its normal weighting
rx_rttval += (delta - rx_rttval) >> 5;
}
else
{
rx_rttval += (delta - rx_rttval) >> 2;
}
rx_rttval = (3 * rx_rttval + delta) >> 2;
rx_SmoothedRoundTripTime = (7 * rx_SmoothedRoundTripTime + roundTripTime) >> 3;

if (rx_SmoothedRoundTripTime < 1)
rx_SmoothedRoundTripTime = 1;
}

uint rto = rx_SmoothedRoundTripTime + Math.Max(interval, rx_rttval << 2);
int rto = rx_SmoothedRoundTripTime + Math.Max((int)interval, rx_rttval << 2);
rx_rto = Utils.Clamp(rto, rx_MinimumRto, RTO_MAX);
}

Expand Down Expand Up @@ -695,24 +688,24 @@ public uint Flush(bool ackOnly)
if (segment.xmit == 0) // initial transmit
{
needSend = true;
segment.rto = rx_rto;
segment.rto = (uint)rx_rto;
segment.resendts = current + segment.rto;
}
else if (segment.fastack >= resent || segment.fastack > 0 && newSegsCount == 0 ) // fast retransmit
{
needSend = true;
segment.fastack = 0;
segment.rto = rx_rto;
segment.rto = (uint)rx_rto;
segment.resendts = current + segment.rto;
change++;
}
else if (current >= segment.resendts) // RTO
{
needSend = true;
if (!noDelay)
segment.rto += rx_rto;
segment.rto += (uint)rx_rto;
else
segment.rto += rx_rto / 2;
segment.rto += (uint)rx_rto >> 1;
segment.fastack = 0;
segment.resendts = current + segment.rto;
lostSegs++;
Expand Down Expand Up @@ -896,7 +889,7 @@ public void SetNoDelay(bool nodelay = false, uint interval = 40, int resend = 0,
if (nodelay)
{
noDelay = nodelay;
rx_MinimumRto = minimumRto;
rx_MinimumRto = (int)minimumRto;
}

if (interval >= 0)
Expand Down
2 changes: 1 addition & 1 deletion Assets/Mirror/Runtime/Transport/Kcp/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static int Decode32U(byte[] p, int offset, ref uint c)
return 4;
}

public static uint Clamp(uint value, uint lower, uint upper)
public static int Clamp(int value, int lower, int upper)
{
return Math.Min(Math.Max(lower, value), upper);
}
Expand Down

0 comments on commit eacfefe

Please sign in to comment.