From 108df27c0bffca8c218246141129c5f1ce2b36b6 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Fri, 8 Jun 2007 10:57:11 +0000 Subject: [PATCH] - RTO was not being initialized to 0, thus the rtt calculation algoritm would not go through the proper initialization. - The initialization was incorrect as well, causing problems in sat networks with > 1sec RTT - Get rid of magic numbers in RTT calculations. --- sys/netinet/sctp_asconf.c | 2 +- sys/netinet/sctp_input.c | 2 +- sys/netinet/sctp_pcb.c | 6 +++++- sys/netinet/sctp_timer.h | 3 +++ sys/netinet/sctputil.c | 19 +++++++++++++------ 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 932ba5a84ece..b2c932c02693 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -1794,7 +1794,7 @@ sctp_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, * address? */ sctp_set_initial_cc_param(stcb, net); - net->RTO = stcb->asoc.initial_rto; + net->RTO = 0; } } diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 85cfeed5d7ae..adc4ce900fab 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -2319,7 +2319,7 @@ sctp_handle_ecn_echo(struct sctp_ecne_chunk *cp, if (net->ssthresh < net->mtu) { net->ssthresh = net->mtu; /* here back off the timer as well, to slow us down */ - net->RTO <<= 2; + net->RTO <<= 1; } net->cwnd = net->ssthresh; #ifdef SCTP_CWND_MONITOR diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 50369c45e201..a803eca1c38b 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -3064,7 +3064,11 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, net->dest_state = SCTP_ADDR_REACHABLE | SCTP_ADDR_UNCONFIRMED; } - net->RTO = stcb->asoc.initial_rto; + /* + * We set this to 0, the timer code knows that this means its an + * initial value + */ + net->RTO = 0; stcb->asoc.numnets++; *(&net->ref_count) = 1; net->tos_flowlabel = 0; diff --git a/sys/netinet/sctp_timer.h b/sys/netinet/sctp_timer.h index 15a7f08b2703..e28408453bc8 100644 --- a/sys/netinet/sctp_timer.h +++ b/sys/netinet/sctp_timer.h @@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$"); #if defined(_KERNEL) +#define SCTP_RTT_SHIFT 3 +#define SCTP_RTT_VAR_SHIFT 2 + void sctp_early_fr_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net); diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index ee39de53770f..2afafccaebae 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -2577,24 +2577,31 @@ sctp_calculate_rto(struct sctp_tcb *stcb, o_calctime = calc_time; /* this is Van Jacobson's integer version */ if (net->RTO) { - calc_time -= (net->lastsa >> 3); + calc_time -= (net->lastsa >> SCTP_RTT_SHIFT); /* take away 1/8th when + * shift=3 */ #ifdef SCTP_RTTVAR_LOGGING rto_logging(net, SCTP_LOG_RTTVAR); #endif net->prev_rtt = o_calctime; - net->lastsa += calc_time; + net->lastsa += calc_time; /* add 7/8th into sa when + * shift=3 */ if (calc_time < 0) { calc_time = -calc_time; } - calc_time -= (net->lastsv >> 2); + calc_time -= (net->lastsv >> SCTP_RTT_VAR_SHIFT); /* take away 1/4 when + * VAR shift=2 */ net->lastsv += calc_time; if (net->lastsv == 0) { net->lastsv = SCTP_CLOCK_GRANULARITY; } } else { /* First RTO measurment */ - net->lastsa = calc_time; - net->lastsv = calc_time >> 1; + net->lastsa = calc_time << SCTP_RTT_SHIFT; /* Multiply by 8 when + * shift=3 */ + net->lastsv = calc_time; + if (net->lastsv == 0) { + net->lastsv = SCTP_CLOCK_GRANULARITY; + } first_measure = 1; net->prev_rtt = o_calctime; #ifdef SCTP_RTTVAR_LOGGING @@ -2602,7 +2609,7 @@ sctp_calculate_rto(struct sctp_tcb *stcb, #endif } calc_rto: - new_rto = ((net->lastsa >> 2) + net->lastsv) >> 1; + new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv; if ((new_rto > SCTP_SAT_NETWORK_MIN) && (stcb->asoc.sat_network_lockout == 0)) { stcb->asoc.sat_network = 1;