summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-06-08 10:57:11 +0000
committerrrs <rrs@FreeBSD.org>2007-06-08 10:57:11 +0000
commit9708f201776b19df8dda84648daf1fa51f897810 (patch)
tree080c7b0a0e79e1c2b2a76fb02e5ac7e8b95c2b25
parent651b3690ab2575a29446b886c1db5ca7421d4f96 (diff)
downloadFreeBSD-src-9708f201776b19df8dda84648daf1fa51f897810.zip
FreeBSD-src-9708f201776b19df8dda84648daf1fa51f897810.tar.gz
- 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.
-rw-r--r--sys/netinet/sctp_asconf.c2
-rw-r--r--sys/netinet/sctp_input.c2
-rw-r--r--sys/netinet/sctp_pcb.c6
-rw-r--r--sys/netinet/sctp_timer.h3
-rw-r--r--sys/netinet/sctputil.c19
5 files changed, 23 insertions, 9 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 932ba5a..b2c932c 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 85cfeed..adc4ce9 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 50369c4..a803eca 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 15a7f08..e284084 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 ee39de5..2afafcc 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;
OpenPOWER on IntegriCloud