summaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorPaul Saab <ps@FreeBSD.org>2005-04-14 20:09:52 +0000
committerPaul Saab <ps@FreeBSD.org>2005-04-14 20:09:52 +0000
commit25e6f9ed4bccbfcdf69aa811045c4f60b61d1aa7 (patch)
tree192aa6db528a920e2c180a45540eef55e2e4379f /sys/netinet/tcp_input.c
parenta87ba6e923f71f4bc9ecae348cbd3485fc178cca (diff)
Notes
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index d89bc2b2bd9a..93e45e189e9d 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1840,7 +1840,27 @@ trimthenstep6:
else if (++tp->t_dupacks > tcprexmtthresh ||
((tcp_do_newreno || tp->sack_enable) &&
IN_FASTRECOVERY(tp))) {
- tp->snd_cwnd += tp->t_maxseg;
+
+ if (tp->sack_enable && IN_FASTRECOVERY(tp)) {
+ int data_in_pipe;
+ int sacked, lost_not_rexmitted;
+
+ /*
+ * Compute the amount of data in flight first.
+ * We can inject new data into the pipe iff
+ * we have less than 1/2 the original window's
+ * worth of data in flight.
+ */
+ sacked = tcp_sacked_bytes(tp, &lost_not_rexmitted);
+ data_in_pipe = (tp->snd_nxt - tp->snd_una) -
+ (sacked + lost_not_rexmitted);
+ if (data_in_pipe < tp->snd_ssthresh) {
+ tp->snd_cwnd += tp->t_maxseg;
+ if (tp->snd_cwnd > tp->snd_ssthresh)
+ tp->snd_cwnd = tp->snd_ssthresh;
+ }
+ } else
+ tp->snd_cwnd += tp->t_maxseg;
(void) tcp_output(tp);
goto drop;
} else if (tp->t_dupacks == tcprexmtthresh) {