diff options
author | hsu <hsu@FreeBSD.org> | 2003-07-15 21:49:53 +0000 |
---|---|---|
committer | hsu <hsu@FreeBSD.org> | 2003-07-15 21:49:53 +0000 |
commit | 58acc5cc7759d48d4657b2cebf6cae1b298b4c73 (patch) | |
tree | 36d4a503a9c109905df229081f20d0f9c880956b /sys/netinet/tcp_input.c | |
parent | cb4467d0644178df3985f6ce76adaa8decbecd8a (diff) | |
download | FreeBSD-src-58acc5cc7759d48d4657b2cebf6cae1b298b4c73.zip FreeBSD-src-58acc5cc7759d48d4657b2cebf6cae1b298b4c73.tar.gz |
Unify the "send high" and "recover" variables as specified in the
lastest rev of the spec. Use an explicit flag for Fast Recovery. [1]
Fix bug with exiting Fast Recovery on a retransmit timeout
diagnosed by Lu Guohan. [2]
Reviewed by: Thomas Henderson <thomas.r.henderson@boeing.com>
Reported and tested by: Lu Guohan <lguohan00@mails.tsinghua.edu.cn> [2]
Approved by: Thomas Henderson <thomas.r.henderson@boeing.com>,
Sally Floyd <floyd@acm.org> [1]
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index f112022..a58e830 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -992,8 +992,7 @@ after_listen: tp->snd_cwnd >= tp->snd_wnd && ((!tcp_do_newreno && tp->t_dupacks < tcprexmtthresh) || - (tcp_do_newreno && - !SEQ_LT(tp->snd_una, tp->snd_recover)))) { + (tcp_do_newreno && !IN_FASTRECOVERY(tp)))) { KASSERT(headlocked, ("headlocked")); INP_INFO_WUNLOCK(&tcbinfo); /* @@ -1009,7 +1008,9 @@ after_listen: tp->snd_cwnd = tp->snd_cwnd_prev; tp->snd_ssthresh = tp->snd_ssthresh_prev; - tp->snd_high = tp->snd_high_prev; + tp->snd_recover = tp->snd_recover_prev; + if (tp->t_flags & TF_WASFRECOVERY) + ENTER_FASTRECOVERY(tp); tp->snd_nxt = tp->snd_max; tp->t_badrxtwin = 0; } @@ -1036,10 +1037,10 @@ after_listen: tcpstat.tcps_rcvackpack++; tcpstat.tcps_rcvackbyte += acked; sbdrop(&so->so_snd, acked); - if (SEQ_GT(tp->snd_una, tp->snd_high) && - SEQ_LEQ(th->th_ack, tp->snd_high)) - tp->snd_high = th->th_ack - 1; - tp->snd_una = tp->snd_recover = th->th_ack; + if (SEQ_GT(tp->snd_una, tp->snd_recover) && + SEQ_LEQ(th->th_ack, tp->snd_recover)) + tp->snd_recover = th->th_ack - 1; + tp->snd_una = th->th_ack; /* * pull snd_wl2 up to prevent seq wrap relative * to th_ack. @@ -1739,8 +1740,7 @@ trimthenstep6: tp->t_dupacks = 0; else if (++tp->t_dupacks > tcprexmtthresh || (tcp_do_newreno && - SEQ_LT(tp->snd_una, - tp->snd_recover))) { + IN_FASTRECOVERY(tp))) { tp->snd_cwnd += tp->t_maxseg; (void) tcp_output(tp); goto drop; @@ -1748,7 +1748,8 @@ trimthenstep6: tcp_seq onxt = tp->snd_nxt; u_int win; if (tcp_do_newreno && - SEQ_LEQ(th->th_ack, tp->snd_high)) { + SEQ_LEQ(th->th_ack, + tp->snd_recover)) { tp->t_dupacks = 0; break; } @@ -1757,6 +1758,7 @@ trimthenstep6: if (win < 2) win = 2; tp->snd_ssthresh = win * tp->t_maxseg; + ENTER_FASTRECOVERY(tp); tp->snd_recover = tp->snd_max; callout_stop(tp->tt_rexmt); tp->t_rtttime = 0; @@ -1809,7 +1811,7 @@ trimthenstep6: * for the other side's cached packets, retract it. */ if (tcp_do_newreno) { - if (SEQ_LT(tp->snd_una, tp->snd_recover)) { + if (IN_FASTRECOVERY(tp)) { if (SEQ_LT(th->th_ack, tp->snd_recover)) { tcp_newreno_partial_ack(tp, th); } else { @@ -1879,7 +1881,9 @@ process_ACK: ++tcpstat.tcps_sndrexmitbad; tp->snd_cwnd = tp->snd_cwnd_prev; tp->snd_ssthresh = tp->snd_ssthresh_prev; - tp->snd_high = tp->snd_high_prev; + tp->snd_recover = tp->snd_recover_prev; + if (tp->t_flags & TF_WASFRECOVERY) + ENTER_FASTRECOVERY(tp); tp->snd_nxt = tp->snd_max; tp->t_badrxtwin = 0; /* XXX probably not required */ } @@ -1933,7 +1937,7 @@ process_ACK: * Otherwise open linearly: maxseg per window * (maxseg^2 / cwnd per packet). */ - if (!tcp_do_newreno || SEQ_GEQ(tp->snd_una, tp->snd_recover)) { + if (!tcp_do_newreno || !IN_FASTRECOVERY(tp)) { register u_int cw = tp->snd_cwnd; register u_int incr = tp->t_maxseg; if (cw > tp->snd_ssthresh) @@ -1951,12 +1955,13 @@ process_ACK: } sowwakeup(so); /* detect una wraparound */ - if (SEQ_GEQ(tp->snd_una, tp->snd_recover) && - SEQ_LT(th->th_ack, tp->snd_recover)) - tp->snd_recover = th->th_ack; - if (SEQ_GT(tp->snd_una, tp->snd_high) && - SEQ_LEQ(th->th_ack, tp->snd_high)) - tp->snd_high = th->th_ack - 1; + if (tcp_do_newreno && !IN_FASTRECOVERY(tp) && + SEQ_GT(tp->snd_una, tp->snd_recover) && + SEQ_LEQ(th->th_ack, tp->snd_recover)) + tp->snd_recover = th->th_ack - 1; + if (tcp_do_newreno && IN_FASTRECOVERY(tp) && + SEQ_GEQ(th->th_ack, tp->snd_recover)) + EXIT_FASTRECOVERY(tp); tp->snd_una = th->th_ack; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; |