diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1872,9 +1872,11 @@ * is new data available to be sent * or we need to send an ACK. */ - if (SEQ_GT(tp->snd_una + sbavail(&so->so_snd), - tp->snd_max) || tp->t_flags & TF_ACKNOW) + if ((tp->t_flags & TF_ACKNOW) || + SEQ_GEQ(sbavail(&so->so_snd), + SEQ_SUB(tp->snd_max, tp->snd_una))) { (void) tcp_output(tp); + } goto check_delack; } } else if (th->th_ack == tp->snd_una && @@ -2585,11 +2587,13 @@ */ if (th->th_ack != tp->snd_una || (tcp_is_sack_recovery(tp, &to) && - (sack_changed == SACK_NOCHANGE))) + (sack_changed == SACK_NOCHANGE))) { break; - else if (!tcp_timer_active(tp, TT_REXMT)) + } else + if (!tcp_timer_active(tp, TT_REXMT)) { tp->t_dupacks = 0; - else if (++tp->t_dupacks > tcprexmtthresh || + } else + if (++tp->t_dupacks > tcprexmtthresh || IN_FASTRECOVERY(tp->t_flags)) { cc_ack_received(tp, th, nsegs, CC_DUPACK); @@ -2597,7 +2601,8 @@ IN_FASTRECOVERY(tp->t_flags) && (tp->t_flags & TF_SACK_PERMIT)) { tcp_do_prr_ack(tp, th, &to, sack_changed); - } else if (tcp_is_sack_recovery(tp, &to) && + } else + if (tcp_is_sack_recovery(tp, &to) && IN_FASTRECOVERY(tp->t_flags)) { int awnd; @@ -2607,26 +2612,28 @@ * we have less than 1/2 the original window's * worth of data in flight. */ - if (V_tcp_do_newsack) + if (V_tcp_do_newsack) { awnd = tcp_compute_pipe(tp); - else + } else { awnd = (tp->snd_nxt - tp->snd_fack) + tp->sackhint.sack_bytes_rexmit; - + } if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += maxseg; if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; } - } else + } else { tp->snd_cwnd += maxseg; + } (void) tcp_output(tp); goto drop; - } else if (tp->t_dupacks == tcprexmtthresh || - (tp->t_flags & TF_SACK_PERMIT && - V_tcp_do_newsack && - tp->sackhint.sacked_bytes > - (tcprexmtthresh - 1) * maxseg)) { + } else + if (tp->t_dupacks == tcprexmtthresh || + (tp->t_flags & TF_SACK_PERMIT && + V_tcp_do_newsack && + tp->sackhint.sacked_bytes > + (tcprexmtthresh - 1) * maxseg)) { enter_recovery: /* * Above is the RFC6675 trigger condition of @@ -2687,13 +2694,13 @@ tp->snd_nxt - tp->snd_una); } if (tcp_is_sack_recovery(tp, &to)) { - TCPSTAT_INC( - tcps_sack_recovery_episode); + TCPSTAT_INC(tcps_sack_recovery_episode); tp->snd_recover = tp->snd_nxt; tp->snd_cwnd = maxseg; (void) tcp_output(tp); - if (SEQ_GT(th->th_ack, tp->snd_una)) + if (SEQ_GT(th->th_ack, tp->snd_una)) { goto resume_partialack; + } goto drop; } tp->snd_nxt = th->th_ack; @@ -2708,7 +2715,8 @@ if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; - } else if (V_tcp_do_rfc3042) { + } else + if (V_tcp_do_rfc3042) { /* * Process first and second duplicate * ACKs. Each indicates a segment @@ -2719,8 +2727,7 @@ * segment. Restore the original * snd_cwnd after packet transmission. */ - cc_ack_received(tp, th, nsegs, - CC_DUPACK); + cc_ack_received(tp, th, nsegs, CC_DUPACK); uint32_t oldcwnd = tp->snd_cwnd; tcp_seq oldsndmax = tp->snd_max; u_int sent; @@ -2743,11 +2750,12 @@ */ SOCKBUF_LOCK(&so->so_snd); avail = sbavail(&so->so_snd) - - (tp->snd_nxt - tp->snd_una); + SEQ_SUB(tp->snd_nxt, tp->snd_una); SOCKBUF_UNLOCK(&so->so_snd); - if (avail > 0 || tp->t_flags & TF_ACKNOW) + if (avail > 0 || tp->t_flags & TF_ACKNOW) { (void) tcp_output(tp); - sent = tp->snd_max - oldsndmax; + } + sent = SEQ_SUB(tp->snd_max, oldsndmax); if (sent > maxseg) { KASSERT((tp->t_dupacks == 2 && tp->snd_limited == 0) || @@ -2756,8 +2764,10 @@ ("%s: sent too much", __func__)); tp->snd_limited = 2; - } else if (sent > 0) + } else + if (sent > 0) { ++tp->snd_limited; + } tp->snd_cwnd = oldcwnd; goto drop; } @@ -3308,9 +3318,9 @@ /* * Return any desired output. */ - if (needoutput || (tp->t_flags & TF_ACKNOW)) + if (needoutput || (tp->t_flags & TF_ACKNOW)) { (void) tcp_output(tp); - + } check_delack: INP_WLOCK_ASSERT(inp); @@ -4020,8 +4030,10 @@ tp->snd_cwnd = (tp->snd_max - tp->snd_una) + (snd_cnt * maxseg); } - } else if (IN_CONGRECOVERY(tp->t_flags)) + } else + if (IN_CONGRECOVERY(tp->t_flags)) { tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); + } tp->snd_cwnd = imax(maxseg, tp->snd_cwnd); } diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -395,10 +395,10 @@ * in which case len is already set. */ if (sack_rxmit == 0) { - if (sack_bytes_rxmt == 0) + if (sack_bytes_rxmt == 0) { len = ((int32_t)min(sbavail(&so->so_snd), sendwin) - off); - else { + } else { int32_t cwin; /* @@ -561,12 +561,8 @@ ipoptlen == 0 && !(flags & TH_SYN)) tso = 1; - if (sack_rxmit) { - if (SEQ_LT(p->rxmit + len, tp->snd_una + sbused(&so->so_snd))) - flags &= ~TH_FIN; - } else { - if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + - sbused(&so->so_snd))) + if (SEQ_LT((sack_rxmit ? p->rxmit : tp->snd_nxt) + len, + tp->snd_una + sbused(&so->so_snd))) { flags &= ~TH_FIN; } @@ -612,9 +608,8 @@ if (!(tp->t_flags & TF_MORETOCOME) && /* normal case */ (idle || (tp->t_flags & TF_NODELAY)) && (uint32_t)len + (uint32_t)off >= sbavail(&so->so_snd) && - (tp->t_flags & TF_NOPUSH) == 0) { + (tp->t_flags & TF_NOPUSH) == 0) goto send; - } if (tp->t_flags & TF_FORCEDATA) /* typ. timeout case */ goto send; if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -983,12 +983,13 @@ if (tp->t_flags & TF_SENTFIN) highdata--; highdata = SEQ_MIN(highdata, tp->snd_recover); - if (th->th_ack != highdata) { + if (SEQ_LT(th->th_ack, highdata)) { tp->snd_fack = th->th_ack; if ((temp = tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack, - highdata - maxseg), highdata, NULL)) != NULL) - tp->sackhint.hole_bytes += temp->end - - temp->start; + highdata - maxseg), highdata, NULL)) != NULL) { + tp->sackhint.hole_bytes += + temp->end - temp->start; + } } } (void) tcp_output(tp); @@ -1060,27 +1061,33 @@ struct sackhole *p, *cur = TAILQ_FIRST(&tp->snd_holes); INP_WLOCK_ASSERT(tptoinpcb(tp)); - if (cur == NULL) - return; /* No holes */ - if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack)) - return; /* We're already beyond any SACKed blocks */ + if (cur == NULL) { + /* No holes */ + return; + } + if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack)) { + /* We're already beyond any SACKed blocks */ + return; + } /*- * Two cases for which we want to advance snd_nxt: * i) snd_nxt lies between end of one hole and beginning of another * ii) snd_nxt lies between end of last hole and snd_fack */ while ((p = TAILQ_NEXT(cur, scblink)) != NULL) { - if (SEQ_LT(tp->snd_nxt, cur->end)) + if (SEQ_LT(tp->snd_nxt, cur->end)) { return; - if (SEQ_GEQ(tp->snd_nxt, p->start)) + } + if (SEQ_GEQ(tp->snd_nxt, p->start)) { cur = p; - else { + } else { tp->snd_nxt = p->start; return; } } - if (SEQ_LT(tp->snd_nxt, cur->end)) + if (SEQ_LT(tp->snd_nxt, cur->end)) { return; + } tp->snd_nxt = tp->snd_fack; }