summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjayanth <jayanth@FreeBSD.org>2004-07-01 23:34:06 +0000
committerjayanth <jayanth@FreeBSD.org>2004-07-01 23:34:06 +0000
commit657c0f9155fc383a82ca73a70137a4f6ec201444 (patch)
tree8b7987e999d9e82d18517e3f3328293db657f082 /sys
parent266fbe3791e0a47aab522d6a202b1a304c78584e (diff)
downloadFreeBSD-src-657c0f9155fc383a82ca73a70137a4f6ec201444.zip
FreeBSD-src-657c0f9155fc383a82ca73a70137a4f6ec201444.tar.gz
On receiving 3 duplicate acknowledgements, SACK recovery was not being entered correctly.
Fix this problem by separating out the SACK and the newreno cases. Also, check if we are in FASTRECOVERY for the sack case and if so, turn off dupacks. Fix an issue where the congestion window was not being incremented by ssthresh. Thanks to Mohan Srinivasan for finding this problem.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_input.c27
-rw-r--r--sys/netinet/tcp_reass.c27
2 files changed, 40 insertions, 14 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index ee6d3ce..78b1fad 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1931,12 +1931,25 @@ trimthenstep6:
} else if (tp->t_dupacks == tcprexmtthresh) {
tcp_seq onxt = tp->snd_nxt;
u_int win;
- if ((tcp_do_newreno ||
- tp->sack_enable) &&
- SEQ_LEQ(th->th_ack,
- tp->snd_recover)) {
- tp->t_dupacks = 0;
- break;
+
+ /*
+ * If we're doing sack, check to
+ * see if we're already in sack
+ * recovery. If we're not doing sack,
+ * check to see if we're in newreno
+ * recovery.
+ */
+ if (tp->sack_enable) {
+ if (IN_FASTRECOVERY(tp)) {
+ tp->t_dupacks = 0;
+ break;
+ }
+ } else if (tcp_do_newreno) {
+ if (SEQ_LEQ(th->th_ack,
+ tp->snd_recover)) {
+ tp->t_dupacks = 0;
+ break;
+ }
}
win = min(tp->snd_wnd, tp->snd_cwnd) /
2 / tp->t_maxseg;
@@ -1953,7 +1966,7 @@ trimthenstep6:
tp->t_maxseg *
tp->t_dupacks;
(void) tcp_output(tp);
- tp->snd_cwnd =
+ tp->snd_cwnd +=
tp->snd_ssthresh;
goto drop;
}
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index ee6d3ce..78b1fad 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -1931,12 +1931,25 @@ trimthenstep6:
} else if (tp->t_dupacks == tcprexmtthresh) {
tcp_seq onxt = tp->snd_nxt;
u_int win;
- if ((tcp_do_newreno ||
- tp->sack_enable) &&
- SEQ_LEQ(th->th_ack,
- tp->snd_recover)) {
- tp->t_dupacks = 0;
- break;
+
+ /*
+ * If we're doing sack, check to
+ * see if we're already in sack
+ * recovery. If we're not doing sack,
+ * check to see if we're in newreno
+ * recovery.
+ */
+ if (tp->sack_enable) {
+ if (IN_FASTRECOVERY(tp)) {
+ tp->t_dupacks = 0;
+ break;
+ }
+ } else if (tcp_do_newreno) {
+ if (SEQ_LEQ(th->th_ack,
+ tp->snd_recover)) {
+ tp->t_dupacks = 0;
+ break;
+ }
}
win = min(tp->snd_wnd, tp->snd_cwnd) /
2 / tp->t_maxseg;
@@ -1953,7 +1966,7 @@ trimthenstep6:
tp->t_maxseg *
tp->t_dupacks;
(void) tcp_output(tp);
- tp->snd_cwnd =
+ tp->snd_cwnd +=
tp->snd_ssthresh;
goto drop;
}
OpenPOWER on IntegriCloud