summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 59e6627..9105e8d 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1762,19 +1762,37 @@ trimthenstep6:
tp->snd_nxt = th->th_ack;
tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
+ KASSERT(tp->snd_limited <= 2,
+ ("tp->snd_limited too big"));
tp->snd_cwnd = tp->snd_ssthresh +
- tp->t_maxseg * tp->t_dupacks;
+ tp->t_maxseg *
+ (tp->t_dupacks - tp->snd_limited);
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
goto drop;
} else if (tcp_do_rfc3042) {
u_long oldcwnd = tp->snd_cwnd;
+ tcp_seq oldsndmax = tp->snd_max;
+ u_int sent;
KASSERT(tp->t_dupacks == 1 ||
tp->t_dupacks == 2,
("dupacks not 1 or 2"));
- tp->snd_cwnd += tp->t_dupacks *
- tp->t_maxseg;
+ if (tp->t_dupacks == 1) {
+ tp->snd_limited = 0;
+ tp->snd_cwnd += tp->t_maxseg;
+ } else {
+ tp->snd_cwnd +=
+ tp->t_maxseg * 2;
+ }
(void) tcp_output(tp);
+ sent = tp->snd_max - oldsndmax;
+ if (sent > tp->t_maxseg) {
+ KASSERT(tp->snd_limited == 0 &&
+ tp->t_dupacks == 2,
+ ("sent too much"));
+ tp->snd_limited = 2;
+ } else if (sent > 0)
+ ++tp->snd_limited;
tp->snd_cwnd = oldcwnd;
goto drop;
}
OpenPOWER on IntegriCloud