diff options
Diffstat (limited to 'src/vnet/tcp/tcp_input.c')
-rw-r--r-- | src/vnet/tcp/tcp_input.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 519219e2c74..5fa7bf23c72 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -424,31 +424,26 @@ acceptable: /** * Compute smoothed RTT as per VJ's '88 SIGCOMM and RFC6298 * - * Note that although the original article, srtt and rttvar are scaled + * Note that although in the original article srtt and rttvar are scaled * to minimize round-off errors, here we don't. Instead, we rely on * better precision time measurements. + * + * A known limitation of the algorithm is that a drop in rtt results in a + * rttvar increase and bigger RTO. + * + * mrtt must be provided in @ref TCP_TICK multiples, i.e., in us. Note that + * timestamps are measured as ms ticks so they must be converted before + * calling this function. */ static void tcp_estimate_rtt (tcp_connection_t * tc, u32 mrtt) { int err, diff; - if (tc->srtt != 0) - { - err = mrtt - tc->srtt; - - /* XXX Drop in RTT results in RTTVAR increase and bigger RTO. - * The increase should be bound */ - tc->srtt = clib_max ((int) tc->srtt + (err >> 3), 1); - diff = (clib_abs (err) - (int) tc->rttvar) >> 2; - tc->rttvar = clib_max ((int) tc->rttvar + diff, 1); - } - else - { - /* First measurement. */ - tc->srtt = mrtt; - tc->rttvar = mrtt >> 1; - } + err = mrtt - tc->srtt; + tc->srtt = clib_max ((int) tc->srtt + (err >> 3), 1); + diff = (clib_abs (err) - (int) tc->rttvar) >> 2; + tc->rttvar = clib_max ((int) tc->rttvar + diff, 1); } static inline void @@ -506,8 +501,8 @@ tcp_update_rtt (tcp_connection_t * tc, tcp_rate_sample_t * rs, u32 ack) * seq_lt (tc->snd_una, ack). This is a condition for calling update_rtt */ else if (tcp_opts_tstamp (&tc->rcv_opts) && tc->rcv_opts.tsecr) { - u32 now = tcp_tstamp (tc); - mrtt = clib_max (now - tc->rcv_opts.tsecr, 1); + mrtt = clib_max (tcp_tstamp (tc) - tc->rcv_opts.tsecr, 1); + mrtt *= TCP_TSTP_TO_HZ; } estimate_rtt: @@ -543,8 +538,8 @@ tcp_estimate_initial_rtt (tcp_connection_t * tc) } else { - mrtt = tcp_time_now_w_thread (thread_index) - tc->rcv_opts.tsecr; - mrtt = clib_max (mrtt, 1); + mrtt = tcp_tstamp (tc) - tc->rcv_opts.tsecr; + mrtt = clib_max (mrtt, 1) * TCP_TSTP_TO_HZ; /* Due to retransmits we don't know the initial mrtt */ if (tc->rto_boff && mrtt > 1 * THZ) mrtt = 1 * THZ; @@ -552,7 +547,11 @@ tcp_estimate_initial_rtt (tcp_connection_t * tc) } if (mrtt > 0 && mrtt < TCP_RTT_MAX) - tcp_estimate_rtt (tc, mrtt); + { + /* First measurement as per RFC 6298 */ + tc->srtt = mrtt; + tc->rttvar = mrtt >> 1; + } tcp_update_rto (tc); } |