summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2017-10-22 14:11:35 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2017-10-22 14:11:35 +0000
commit462cfae87d08f8a971ddc0da2fd9ac7e7387a66a (patch)
treee8253148d0fd6acdf1559daa55cad72eb90d0c34
parentb00a9568384c6eff1c091fe2f0e09b7f86371732 (diff)
Unconditionally enable TCP selective acknowledgements (SACK)
OK deraadt, mpi, visa, job
-rw-r--r--sys/conf/GENERIC3
-rw-r--r--sys/netinet/tcp_input.c97
-rw-r--r--sys/netinet/tcp_output.c69
-rw-r--r--sys/netinet/tcp_subr.c17
-rw-r--r--sys/netinet/tcp_timer.c12
-rw-r--r--sys/netinet/tcp_usrreq.c18
-rw-r--r--sys/netinet/tcp_var.h16
7 files changed, 54 insertions, 178 deletions
diff --git a/sys/conf/GENERIC b/sys/conf/GENERIC
index 87dd069f514..6df800175ed 100644
--- a/sys/conf/GENERIC
+++ b/sys/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.248 2017/10/04 19:28:56 naddy Exp $
+# $OpenBSD: GENERIC,v 1.249 2017/10/22 14:11:34 mikeb Exp $
#
# Machine-independent option; used by all architectures for their
# GENERIC kernel
@@ -45,7 +45,6 @@ option FIFO # FIFOs; RECOMMENDED
option FUSE # FUSE
option SOCKET_SPLICE # Socket Splicing for TCP and UDP
-option TCP_SACK # Selective Acknowledgements for TCP
option TCP_ECN # Explicit Congestion Notification for TCP
option TCP_SIGNATURE # TCP MD5 Signatures, for BGP routing sessions
#option TCP_FACK # Forward Acknowledgements for TCP
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 52c206f0bf5..790e163975e 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.347 2017/08/11 21:24:20 mpi Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.348 2017/10/22 14:11:34 mikeb Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -854,10 +854,8 @@ findpcb:
if (TCPS_HAVEESTABLISHED(tp->t_state))
TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle);
-#ifdef TCP_SACK
if (tp->sack_enable)
tcp_del_sackholes(tp, th); /* Delete stale SACK holes */
-#endif /* TCP_SACK */
/*
* Process options.
@@ -964,7 +962,6 @@ findpcb:
tp->t_pmtud_mss_acked = acked;
tp->snd_una = th->th_ack;
-#if defined(TCP_SACK) || defined(TCP_ECN)
/*
* We want snd_last to track snd_una so
* as to avoid sequence wraparound problems
@@ -974,11 +971,10 @@ findpcb:
if (SEQ_GT(tp->snd_una, tp->snd_last))
#endif
tp->snd_last = tp->snd_una;
-#endif /* TCP_SACK */
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
tp->snd_fack = tp->snd_una;
tp->retran_data = 0;
-#endif /* TCP_FACK */
+#endif
m_freem(m);
/*
@@ -1014,11 +1010,9 @@ findpcb:
* with nothing on the reassembly queue and
* we have enough buffer space to take it.
*/
-#ifdef TCP_SACK
/* Clean receiver SACK report if present */
if (tp->sack_enable && tp->rcv_numsacks)
tcp_clean_sackreport(tp);
-#endif /* TCP_SACK */
tcpstat_inc(tcps_preddat);
tp->rcv_nxt += tlen;
tcpstat_pkt(tcps_rcvpack, tcps_rcvbyte, tlen);
@@ -1139,7 +1133,6 @@ findpcb:
tp->snd_cwnd = tp->t_maxseg;
tcp_rcvseqinit(tp);
tp->t_flags |= TF_ACKNOW;
-#ifdef TCP_SACK
/*
* If we've sent a SACK_PERMITTED option, and the peer
* also replied with one, then TF_SACK_PERMIT should have
@@ -1147,7 +1140,6 @@ findpcb:
*/
if (tp->sack_enable)
tp->sack_enable = tp->t_flags & TF_SACK_PERMIT;
-#endif
#ifdef TCP_ECN
/*
* if ECE is set but CWR is not set for SYN-ACK, or
@@ -1571,7 +1563,7 @@ trimthenstep6:
*/
if (TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0)
tp->t_dupacks = 0;
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/*
* In FACK, can enter fast rec. if the receiver
* reports a reass. queue longer than 3 segs.
@@ -1588,7 +1580,6 @@ trimthenstep6:
ulmin(tp->snd_wnd, tp->snd_cwnd) /
2 / tp->t_maxseg;
-#if defined(TCP_SACK) || defined(TCP_ECN)
if (SEQ_LT(th->th_ack, tp->snd_last)){
/*
* False fast retx after
@@ -1597,11 +1588,9 @@ trimthenstep6:
tp->t_dupacks = 0;
goto drop;
}
-#endif
if (win < 2)
win = 2;
tp->snd_ssthresh = win * tp->t_maxseg;
-#ifdef TCP_SACK
tp->snd_last = tp->snd_max;
if (tp->sack_enable) {
TCP_TIMER_DISARM(tp, TCPT_REXMT);
@@ -1611,7 +1600,7 @@ trimthenstep6:
#endif
tcpstat_inc(tcps_cwr_frecovery);
tcpstat_inc(tcps_sack_recovery_episode);
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
tp->t_dupacks = tcprexmtthresh;
(void) tcp_output(tp);
/*
@@ -1630,7 +1619,6 @@ trimthenstep6:
#endif /* TCP_FACK */
goto drop;
}
-#endif /* TCP_SACK */
TCP_TIMER_DISARM(tp, TCPT_REXMT);
tp->t_rtttime = 0;
tp->snd_nxt = th->th_ack;
@@ -1648,7 +1636,7 @@ trimthenstep6:
tp->snd_nxt = onxt;
goto drop;
} else if (tp->t_dupacks > tcprexmtthresh) {
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/*
* while (awnd < cwnd)
* sendsomething();
@@ -1678,12 +1666,11 @@ trimthenstep6:
* If the congestion window was inflated to account
* for the other side's cached packets, retract it.
*/
-#if defined(TCP_SACK)
if (tp->sack_enable) {
if (tp->t_dupacks >= tcprexmtthresh) {
/* Check for a partial ACK */
if (tcp_sack_partialack(tp, th)) {
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/* Force call to tcp_output */
if (tp->snd_awnd < tp->snd_cwnd)
tp->t_flags |= TF_NEEDOUTPUT;
@@ -1700,10 +1687,10 @@ trimthenstep6:
tcp_seq_subtract(tp->snd_max,
th->th_ack);
tp->t_dupacks = 0;
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
if (SEQ_GT(th->th_ack, tp->snd_fack))
tp->snd_fack = th->th_ack;
-#endif /* TCP_FACK */
+#endif
}
}
} else {
@@ -1721,12 +1708,6 @@ trimthenstep6:
}
if (tp->t_dupacks < tcprexmtthresh)
tp->t_dupacks = 0;
-#else /* else no TCP_SACK */
- if (tp->t_dupacks >= tcprexmtthresh &&
- tp->snd_cwnd > tp->snd_ssthresh)
- tp->snd_cwnd = tp->snd_ssthresh;
- tp->t_dupacks = 0;
-#endif
if (SEQ_GT(th->th_ack, tp->snd_max)) {
tcpstat_inc(tcps_rcvacktoomuch);
goto dropafterack_ratelim;
@@ -1772,10 +1753,9 @@ trimthenstep6:
if (cw > tp->snd_ssthresh)
incr = incr * incr / cw;
-#if defined (TCP_SACK)
if (tp->t_dupacks < tcprexmtthresh)
-#endif
- tp->snd_cwnd = ulmin(cw + incr, TCP_MAXWIN<<tp->snd_scale);
+ tp->snd_cwnd = ulmin(cw + incr,
+ TCP_MAXWIN << tp->snd_scale);
}
ND6_HINT(tp);
if (acked > so->so_snd.sb_cc) {
@@ -1819,7 +1799,7 @@ trimthenstep6:
#endif
if (SEQ_LT(tp->snd_nxt, tp->snd_una))
tp->snd_nxt = tp->snd_una;
-#if defined (TCP_SACK) && defined (TCP_FACK)
+#ifdef TCP_FACK
if (SEQ_GT(tp->snd_una, tp->snd_fack)) {
tp->snd_fack = tp->snd_una;
/* Update snd_awnd for partial ACK
@@ -1982,10 +1962,9 @@ dodata: /* XXX */
*/
if ((tlen || (tiflags & TH_FIN)) &&
TCPS_HAVERCVDFIN(tp->t_state) == 0) {
-#ifdef TCP_SACK
tcp_seq laststart = th->th_seq;
tcp_seq lastend = th->th_seq + tlen;
-#endif
+
if (th->th_seq == tp->rcv_nxt && TAILQ_EMPTY(&tp->t_segq) &&
tp->t_state == TCPS_ESTABLISHED) {
TCP_SETUP_ACK(tp, tiflags, m);
@@ -2007,10 +1986,8 @@ dodata: /* XXX */
tiflags = tcp_reass(tp, th, m, &tlen);
tp->t_flags |= TF_ACKNOW;
}
-#ifdef TCP_SACK
if (tp->sack_enable)
tcp_update_sack_list(tp, laststart, lastend);
-#endif
/*
* variable len never referenced again in modern BSD,
@@ -2259,7 +2236,6 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcphdr *th,
tp->ts_recent_age = tcp_now;
break;
-#ifdef TCP_SACK
case TCPOPT_SACK_PERMITTED:
if (!tp->sack_enable || optlen!=TCPOLEN_SACK_PERMITTED)
continue;
@@ -2273,7 +2249,6 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcphdr *th,
case TCPOPT_SACK:
tcp_sack_option(tp, th, cp, optlen);
break;
-#endif
#ifdef TCP_SIGNATURE
case TCPOPT_SIGNATURE:
if (optlen != TCPOLEN_SIGNATURE)
@@ -2357,16 +2332,12 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcphdr *th,
return (0);
}
-#if defined(TCP_SACK)
u_long
tcp_seq_subtract(u_long a, u_long b)
{
return ((long)(a - b));
}
-#endif
-
-#ifdef TCP_SACK
/*
* This function is called upon receipt of new valid data (while not in header
* prediction mode), and it updates the ordered list of sacks.
@@ -2506,11 +2477,11 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
continue; /* bad SACK fields */
if (SEQ_LEQ(sack.end, tp->snd_una))
continue; /* old block */
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/* Updates snd_fack. */
if (SEQ_GT(sack.end, tp->snd_fack))
tp->snd_fack = sack.end;
-#endif /* TCP_FACK */
+#endif
if (SEQ_GT(th->th_ack, tp->snd_una)) {
if (SEQ_LT(sack.start, th->th_ack))
continue;
@@ -2559,7 +2530,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
}
if (SEQ_LEQ(sack.start, cur->start)) {
/* Data acks at least the beginning of hole */
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
if (SEQ_GT(sack.end, cur->rxmit))
tp->retran_data -=
tcp_seq_subtract(cur->rxmit,
@@ -2568,7 +2539,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
tp->retran_data -=
tcp_seq_subtract(sack.end,
cur->start);
-#endif /* TCP_FACK */
+#endif
if (SEQ_GEQ(sack.end, cur->end)) {
/* Acks entire hole, so delete hole */
if (p != cur) {
@@ -2593,12 +2564,12 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
}
/* move end of hole backward */
if (SEQ_GEQ(sack.end, cur->end)) {
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
if (SEQ_GT(cur->rxmit, sack.start))
tp->retran_data -=
tcp_seq_subtract(cur->rxmit,
sack.start);
-#endif /* TCP_FACK */
+#endif
cur->end = sack.start;
cur->rxmit = SEQ_MIN(cur->rxmit, cur->end);
cur->dups++;
@@ -2619,7 +2590,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
pool_get(&sackhl_pool, PR_NOWAIT);
if (temp == NULL)
goto done; /* ENOBUFS */
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
if (SEQ_GT(cur->rxmit, sack.end))
tp->retran_data -=
tcp_seq_subtract(sack.end,
@@ -2628,7 +2599,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
tp->retran_data -=
tcp_seq_subtract(cur->rxmit,
sack.start);
-#endif /* TCP_FACK */
+#endif
temp->next = cur->next;
temp->start = sack.end;
temp->end = cur->end;
@@ -2670,7 +2641,7 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen)
}
}
done:
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/*
* Update retran_data and snd_awnd. Go through the list of
* holes. Increment retran_data by (hole->rxmit - hole->start).
@@ -2683,7 +2654,7 @@ done:
}
tp->snd_awnd = tcp_seq_subtract(tp->snd_nxt, tp->snd_fack) +
tp->retran_data;
-#endif /* TCP_FACK */
+#endif
return;
}
@@ -2761,7 +2732,6 @@ tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th)
}
return (0);
}
-#endif /* TCP_SACK */
/*
* Pull out of band byte out of a segment so
@@ -3120,7 +3090,6 @@ tcp_mss_update(struct tcpcb *tp)
}
-#if defined (TCP_SACK)
/*
* Checks for partial ack. If partial ack arrives, force the retransmission
* of the next unacknowledged segment, do not clear tp->t_dupacks, and return
@@ -3165,7 +3134,6 @@ tcp_newreno(struct tcpcb *tp, struct tcphdr *th)
}
return 0;
}
-#endif /* TCP_SACK */
int
tcp_mss_adv(struct mbuf *m, int af)
@@ -3740,33 +3708,26 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
m_freem(m);
goto abort;
}
-#ifdef TCP_SACK
tp->sack_enable = sc->sc_flags & SCF_SACK_PERMIT;
-#endif
-
tp->ts_modulate = sc->sc_modulate;
tp->ts_recent = sc->sc_timestamp;
tp->iss = sc->sc_iss;
tp->irs = sc->sc_irs;
tcp_sendseqinit(tp);
-#if defined (TCP_SACK) || defined(TCP_ECN)
tp->snd_last = tp->snd_una;
-#endif /* TCP_SACK */
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
tp->snd_fack = tp->snd_una;
tp->retran_data = 0;
tp->snd_awnd = 0;
-#endif /* TCP_FACK */
+#endif
#ifdef TCP_ECN
if (sc->sc_flags & SCF_ECN_PERMIT) {
tp->t_flags |= TF_ECN_PERMIT;
tcpstat_inc(tcps_ecn_accepts);
}
#endif
-#ifdef TCP_SACK
if (sc->sc_flags & SCF_SACK_PERMIT)
tp->t_flags |= TF_SACK_PERMIT;
-#endif
#ifdef TCP_SIGNATURE
if (sc->sc_flags & SCF_SIGNATURE)
tp->t_flags |= TF_SIGNATURE;
@@ -3919,9 +3880,7 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
if (optp) {
#endif
tb.pf = tp->pf;
-#ifdef TCP_SACK
tb.sack_enable = tp->sack_enable;
-#endif
tb.t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
#ifdef TCP_SIGNATURE
if (tp->t_flags & TF_SIGNATURE)
@@ -4034,14 +3993,12 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
(th->th_flags & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR))
sc->sc_flags |= SCF_ECN_PERMIT;
#endif
-#ifdef TCP_SACK
/*
* Set SCF_SACK_PERMIT if peer did send a SACK_PERMITTED option
* (i.e., if tcp_dooptions() did set TF_SACK_PERMIT).
*/
if (tb.sack_enable && (tb.t_flags & TF_SACK_PERMIT))
sc->sc_flags |= SCF_SACK_PERMIT;
-#endif
#ifdef TCP_SIGNATURE
if (tb.t_flags & TF_SIGNATURE)
sc->sc_flags |= SCF_SIGNATURE;
@@ -4089,9 +4046,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m)
/* Compute the size of the TCP options. */
optlen = 4 + (sc->sc_request_r_scale != 15 ? 4 : 0) +
-#ifdef TCP_SACK
((sc->sc_flags & SCF_SACK_PERMIT) ? 4 : 0) +
-#endif
#ifdef TCP_SIGNATURE
((sc->sc_flags & SCF_SIGNATURE) ? TCPOLEN_SIGLEN : 0) +
#endif
@@ -4171,13 +4126,11 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m)
*optp++ = (sc->sc_ourmaxseg >> 8) & 0xff;
*optp++ = sc->sc_ourmaxseg & 0xff;
-#ifdef TCP_SACK
/* Include SACK_PERMIT_HDR option if peer has already done so. */
if (sc->sc_flags & SCF_SACK_PERMIT) {
*((u_int32_t *)optp) = htonl(TCPOPT_SACK_PERMIT_HDR);
optp += 4;
}
-#endif
if (sc->sc_request_r_scale != 15) {
*((u_int32_t *)optp) = htonl(TCPOPT_NOP << 24 |
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index d2510bf83e1..a0a88b5ec3d 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_output.c,v 1.121 2017/06/26 09:32:32 mpi Exp $ */
+/* $OpenBSD: tcp_output.c,v 1.122 2017/10/22 14:11:34 mikeb Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@@ -96,11 +96,8 @@
extern struct mbuf *m_copypack();
#endif
-#ifdef TCP_SACK
extern int tcprexmtthresh;
-#endif
-#ifdef TCP_SACK
#ifdef TCP_SACK_DEBUG
void tcp_print_holes(struct tcpcb *tp);
@@ -193,7 +190,6 @@ tcp_sack_adjust(struct tcpcb *tp)
tp->snd_nxt = tp->rcv_lastsack;
return;
}
-#endif /* TCP_SACK */
/*
* Tcp output routine: figure out what should be sent and send it.
@@ -210,11 +206,9 @@ tcp_output(struct tcpcb *tp)
u_char *opt = (u_char *)optbuf;
unsigned int optlen, hdrlen, packetlen;
int idle, sendalot = 0;
-#ifdef TCP_SACK
int i, sack_rxmit = 0;
struct sackhole *p;
int maxburst = TCP_MAXBURST;
-#endif
#ifdef TCP_SIGNATURE
unsigned int sigoff;
#endif /* TCP_SIGNATURE */
@@ -228,10 +222,10 @@ tcp_output(struct tcpcb *tp)
} else
tp->t_flags &= ~TF_NEEDOUTPUT;
-#if defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC)
+#if defined(TCP_SIGNATURE) && defined(DIAGNOSTIC)
if (tp->sack_enable && (tp->t_flags & TF_SIGNATURE))
return (EINVAL);
-#endif /* defined(TCP_SACK) && defined(TCP_SIGNATURE) && defined(DIAGNOSTIC) */
+#endif /* defined(TCP_SIGNATURE) && defined(DIAGNOSTIC) */
/*
* Determine length of data that should be transmitted,
@@ -256,7 +250,6 @@ tcp_output(struct tcpcb *tp)
tp->t_flags &= ~TF_LASTIDLE;
again:
-#ifdef TCP_SACK
/*
* If we've recently taken a timeout, snd_max will be greater than
* snd_nxt. There may be SACK information that allows us to avoid
@@ -264,9 +257,8 @@ again:
*/
if (tp->sack_enable && SEQ_LT(tp->snd_nxt, tp->snd_max))
tcp_sack_adjust(tp);
-#endif
off = tp->snd_nxt - tp->snd_una;
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/* Normally, sendable data is limited by off < tp->snd_cwnd.
* But in FACK, sendable data is limited by snd_awnd < snd_cwnd,
* regardless of offset.
@@ -279,7 +271,6 @@ again:
flags = tcp_outflags[tp->t_state];
-#ifdef TCP_SACK
/*
* Send any SACK-generated retransmissions. If we're explicitly trying
* to send out new data (when sendalot is 1), bypass this function.
@@ -301,7 +292,6 @@ again:
#endif
}
}
-#endif /* TCP_SACK */
sendalot = 0;
/*
@@ -337,24 +327,20 @@ again:
}
}
-#ifdef TCP_SACK
if (!sack_rxmit) {
-#endif
- len = ulmin(so->so_snd.sb_cc, win) - off;
+ len = ulmin(so->so_snd.sb_cc, win) - off;
-#if defined(TCP_SACK) && defined(TCP_FACK)
- /*
- * If we're in fast recovery (SEQ_GT(tp->snd_last, tp->snd_una)), and
- * amount of outstanding data (snd_awnd) is >= snd_cwnd, then
- * do not send data (like zero window conditions)
- */
- if (tp->sack_enable && len && SEQ_GT(tp->snd_last, tp->snd_una) &&
- (tp->snd_awnd >= tp->snd_cwnd))
- len = 0;
+#ifdef TCP_FACK
+ /*
+ * If we're in fast recovery (SEQ_GT(tp->snd_last, tp->snd_una)),
+ * and amount of outstanding data (snd_awnd) is >= snd_cwnd, then
+ * do not send data (like zero window conditions)
+ */
+ if (tp->sack_enable && SEQ_GT(tp->snd_last, tp->snd_una) &&
+ len && (tp->snd_awnd >= tp->snd_cwnd))
+ len = 0;
#endif /* TCP_FACK */
-#ifdef TCP_SACK
}
-#endif
if (len < 0) {
/*
@@ -417,10 +403,8 @@ again:
goto send;
if (SEQ_LT(tp->snd_nxt, tp->snd_max))
goto send;
-#ifdef TCP_SACK
if (sack_rxmit)
goto send;
-#endif
}
/*
@@ -462,7 +446,6 @@ again:
if (flags & TH_FIN &&
((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
goto send;
-#ifdef TCP_SACK
/*
* In SACK, it is possible for tcp_output to fail to send a segment
* after the retransmission timer has been turned off. Make sure
@@ -474,7 +457,6 @@ again:
TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur);
return (0);
}
-#endif /* TCP_SACK */
/*
* TCP window updates are not reliable, rather a polling protocol
@@ -548,7 +530,6 @@ send:
if (flags & TH_ACK)
tcp_mss_update(tp);
-#ifdef TCP_SACK
/*
* If this is the first SYN of connection (not a SYN
* ACK), include SACK_PERMIT_HDR option. If this is a
@@ -561,8 +542,6 @@ send:
htonl(TCPOPT_SACK_PERMIT_HDR);
optlen += 4;
}
-#endif
-
if ((tp->t_flags & TF_REQ_SCALE) &&
((flags & TH_ACK) == 0 ||
(tp->t_flags & TF_RCVD_SCALE))) {
@@ -626,7 +605,6 @@ send:
}
#endif /* TCP_SIGNATURE */
-#ifdef TCP_SACK
/*
* Send SACKs if necessary. This should be the last option processed.
* Only as many SACKs are sent as are permitted by the maximum options
@@ -653,7 +631,6 @@ send:
*olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2));
optlen += TCPOLEN_SACK*count + 4; /* including leading NOPs */
}
-#endif /* TCP_SACK */
#ifdef DIAGNOSTIC
if (optlen > MAX_TCPOPTLEN)
@@ -807,7 +784,6 @@ send:
else
th->th_seq = htonl(tp->snd_max);
-#ifdef TCP_SACK
if (sack_rxmit) {
/*
* If sendalot was turned on (due to option stuffing), turn it
@@ -818,12 +794,11 @@ send:
sendalot = 0;
th->th_seq = htonl(p->rxmit);
p->rxmit += len;
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
tp->retran_data += len;
-#endif /* TCP_FACK */
+#endif
tcpstat_pkt(tcps_sack_rexmits, tcps_sack_rexmit_bytes, len);
}
-#endif /* TCP_SACK */
th->th_ack = htonl(tp->rcv_nxt);
if (optlen) {
@@ -962,13 +937,11 @@ send:
tp->t_flags |= TF_SENTFIN;
}
}
-#ifdef TCP_SACK
if (tp->sack_enable) {
if (sack_rxmit && (p->rxmit != tp->snd_nxt)) {
goto timer;
}
}
-#endif
tp->snd_nxt += len;
if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
tp->snd_max = tp->snd_nxt;
@@ -991,7 +964,6 @@ send:
* Initialize shift counter which is used for backoff
* of retransmit time.
*/
-#ifdef TCP_SACK
timer:
if (tp->sack_enable && sack_rxmit &&
TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0 &&
@@ -1002,7 +974,6 @@ send:
tp->t_rxtshift = 0;
}
}
-#endif
if (TCP_TIMER_ISARMED(tp, TCPT_REXMT) == 0 &&
tp->snd_nxt != tp->snd_una) {
@@ -1125,11 +1096,11 @@ send:
#endif /* INET6 */
}
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
/* Update snd_awnd to reflect the new data that was sent. */
tp->snd_awnd = tcp_seq_subtract(tp->snd_max, tp->snd_fack) +
tp->retran_data;
-#endif /* defined(TCP_SACK) && defined(TCP_FACK) */
+#endif
if (error) {
out:
@@ -1184,11 +1155,7 @@ out:
tp->last_ack_sent = tp->rcv_nxt;
tp->t_flags &= ~TF_ACKNOW;
TCP_CLEAR_DELACK(tp);
-#if defined(TCP_SACK)
if (sendalot && --maxburst)
-#else
- if (sendalot)
-#endif
goto again;
return (0);
}
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 27cab0e05bb..50f9b7872f0 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_subr.c,v 1.165 2017/06/26 09:32:32 mpi Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.166 2017/10/22 14:11:34 mikeb Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@@ -104,9 +104,7 @@ int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
/* values controllable via sysctl */
int tcp_do_rfc1323 = 1;
-#ifdef TCP_SACK
int tcp_do_sack = 1; /* RFC 2018 selective ACKs */
-#endif
int tcp_ack_on_push = 0; /* set to enable immediate ACK-on-PUSH */
#ifdef TCP_ECN
int tcp_do_ecn = 0; /* RFC3168 ECN enabled/disabled? */
@@ -120,15 +118,11 @@ u_int32_t tcp_now = 1;
#endif
int tcp_reass_limit = NMBCLUSTERS / 8; /* hardlimit for tcpqe_pool */
-#ifdef TCP_SACK
int tcp_sackhole_limit = 32*1024; /* hardlimit for sackhl_pool */
-#endif
struct pool tcpcb_pool;
struct pool tcpqe_pool;
-#ifdef TCP_SACK
struct pool sackhl_pool;
-#endif
struct cpumem *tcpcounters; /* tcp statistics */
tcp_seq tcp_iss;
@@ -145,11 +139,9 @@ tcp_init(void)
pool_init(&tcpqe_pool, sizeof(struct tcpqent), 0, IPL_SOFTNET, 0,
"tcpqe", NULL);
pool_sethardlimit(&tcpqe_pool, tcp_reass_limit, NULL, 0);
-#ifdef TCP_SACK
pool_init(&sackhl_pool, sizeof(struct sackhole), 0, IPL_SOFTNET, 0,
"sackhl", NULL);
pool_sethardlimit(&sackhl_pool, tcp_sackhole_limit, NULL, 0);
-#endif /* TCP_SACK */
in_pcbinit(&tcbtable, TCB_INITIAL_HASH_SIZE);
tcpcounters = counters_alloc(tcps_ncounters);
@@ -439,9 +431,7 @@ tcp_newtcpcb(struct inpcb *inp)
TCP_TIMER_INIT(tp, i);
timeout_set(&tp->t_reap_to, tcp_reaper, tp);
-#ifdef TCP_SACK
tp->sack_enable = tcp_do_sack;
-#endif
tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
tp->t_inpcb = inp;
/*
@@ -515,9 +505,7 @@ tcp_close(struct tcpcb *tp)
{
struct inpcb *inp = tp->t_inpcb;
struct socket *so = inp->inp_socket;
-#ifdef TCP_SACK
struct sackhole *p, *q;
-#endif
/* free the reassembly queue, if any */
tcp_freeq(tp);
@@ -526,7 +514,6 @@ tcp_close(struct tcpcb *tp)
TCP_CLEAR_DELACK(tp);
syn_cache_cleanup(tp);
-#ifdef TCP_SACK
/* Free SACK holes. */
q = p = tp->snd_holes;
while (p != 0) {
@@ -534,7 +521,7 @@ tcp_close(struct tcpcb *tp)
pool_put(&sackhl_pool, p);
p = q;
}
-#endif
+
m_free(tp->t_template);
tp->t_flags |= TF_DEAD;
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 3f063ed9936..9d2e75942cd 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_timer.c,v 1.57 2017/08/11 21:24:20 mpi Exp $ */
+/* $OpenBSD: tcp_timer.c,v 1.58 2017/10/22 14:11:34 mikeb Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
@@ -156,7 +156,6 @@ int tcp_totbackoff = 511; /* sum of tcp_backoff[] */
* TCP timer processing.
*/
-#ifdef TCP_SACK
void tcp_timer_freesack(struct tcpcb *);
void
@@ -177,9 +176,8 @@ tcp_timer_freesack(struct tcpcb *tp)
tp->snd_fack = tp->snd_una;
tp->retran_data = 0;
tp->snd_awnd = 0;
-#endif /* TCP_FACK */
+#endif
}
-#endif /* TCP_SACK */
void
tcp_timer_rexmt(void *arg)
@@ -219,9 +217,7 @@ tcp_timer_rexmt(void *arg)
goto out;
}
-#ifdef TCP_SACK
tcp_timer_freesack(tp);
-#endif
if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
tp->t_rxtshift = TCP_MAXRXTSHIFT;
tcpstat_inc(tcps_timeoutdrop);
@@ -305,13 +301,11 @@ tcp_timer_rexmt(void *arg)
tp->t_srtt = 0;
}
tp->snd_nxt = tp->snd_una;
-#if defined(TCP_SACK)
/*
* Note: We overload snd_last to function also as the
* snd_last variable described in RFC 2582
*/
tp->snd_last = tp->snd_max;
-#endif /* TCP_SACK */
/*
* If timing a segment in this window, stop the timer.
*/
@@ -462,9 +456,7 @@ tcp_timer_2msl(void *arg)
if (tp->t_flags & TF_DEAD)
goto out;
-#ifdef TCP_SACK
tcp_timer_freesack(tp);
-#endif
if (tp->t_state != TCPS_TIME_WAIT &&
((tcp_maxidle == 0) || ((tcp_now - tp->t_rcvtime) <= tcp_maxidle)))
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 1e70b9e07c9..d7ee1ecc517 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.156 2017/10/09 08:35:38 mpi Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.157 2017/10/22 14:11:34 mikeb Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -268,10 +268,8 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
TCP_TIMER_ARM(tp, TCPT_KEEP, tcptv_keep_init);
tcp_set_iss_tsm(tp);
tcp_sendseqinit(tp);
-#if defined(TCP_SACK)
tp->snd_last = tp->snd_una;
-#endif
-#if defined(TCP_SACK) && defined(TCP_FACK)
+#ifdef TCP_FACK
tp->snd_fack = tp->snd_una;
tp->retran_data = 0;
tp->snd_awnd = 0;
@@ -496,7 +494,6 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
error = EINVAL;
break;
-#ifdef TCP_SACK
case TCP_SACK_ENABLE:
if (m == NULL || m->m_len < sizeof (int)) {
error = EINVAL;
@@ -518,7 +515,6 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
else
tp->sack_enable = 0;
break;
-#endif
#ifdef TCP_SIGNATURE
case TCP_MD5SIG:
if (m == NULL || m->m_len < sizeof (int)) {
@@ -533,9 +529,7 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
if (*mtod(m, int *)) {
tp->t_flags |= TF_SIGNATURE;
-#ifdef TCP_SACK
tp->sack_enable = 0;
-#endif /* TCP_SACK */
} else
tp->t_flags &= ~TF_SIGNATURE;
break;
@@ -559,11 +553,9 @@ tcp_ctloutput(int op, struct socket *so, int level, int optname,
case TCP_MAXSEG:
*mtod(m, int *) = tp->t_maxseg;
break;
-#ifdef TCP_SACK
case TCP_SACK_ENABLE:
*mtod(m, int *) = tp->sack_enable;
break;
-#endif
#ifdef TCP_SIGNATURE
case TCP_MD5SIG:
*mtod(m, int *) = tp->t_flags & TF_SIGNATURE;
@@ -960,14 +952,13 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
return (ENOTDIR);
switch (name[0]) {
-#ifdef TCP_SACK
case TCPCTL_SACK:
NET_LOCK();
error = sysctl_int(oldp, oldlenp, newp, newlen,
&tcp_do_sack);
NET_UNLOCK();
return (error);
-#endif
+
case TCPCTL_SLOWHZ:
return (sysctl_rdint(oldp, oldlenp, newp, PR_SLOWHZ));
@@ -1025,7 +1016,7 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
}
NET_UNLOCK();
return (error);
-#ifdef TCP_SACK
+
case TCPCTL_SACKHOLE_LIMIT:
NET_LOCK();
nval = tcp_sackhole_limit;
@@ -1037,7 +1028,6 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
}
NET_UNLOCK();
return (error);
-#endif
case TCPCTL_STATS:
return (tcp_sysctl_tcpstat(oldp, oldlenp, newp));
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index de3390b61f1..6b797fd48e7 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.124 2017/04/14 20:46:31 bluhm Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.125 2017/10/22 14:11:34 mikeb Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -116,30 +116,24 @@ struct tcpcb {
tcp_seq snd_wl2; /* window update seg ack number */
tcp_seq iss; /* initial send sequence number */
u_long snd_wnd; /* send window */
-#if 1 /*def TCP_SACK*/
int sack_enable; /* enable SACK for this connection */
int snd_numholes; /* number of holes seen by sender */
struct sackhole *snd_holes; /* linked list of holes (sorted) */
-#if 1 /*defined(TCP_SACK) && defined(TCP_FACK)*/
+#if 1 /*defined(TCP_FACK)*/
tcp_seq snd_fack; /* for FACK congestion control */
u_long snd_awnd; /* snd_nxt - snd_fack + */
/* retransmitted data */
int retran_data; /* amount of outstanding retx. data */
#endif /* TCP_FACK */
-#endif /* TCP_SACK */
-#if 1 /*defined(TCP_SACK) || defined(TCP_ECN)*/
tcp_seq snd_last; /* for use in fast recovery */
-#endif
/* receive sequence variables */
u_long rcv_wnd; /* receive window */
tcp_seq rcv_nxt; /* receive next */
tcp_seq rcv_up; /* receive urgent pointer */
tcp_seq irs; /* initial receive sequence number */
-#if 1 /*def TCP_SACK*/
tcp_seq rcv_lastsack; /* last seq number(+1) sack'd by rcv'r*/
int rcv_numsacks; /* # distinct sack blks present */
struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */
-#endif
/*
* Additional variables for this implementation.
@@ -698,11 +692,9 @@ extern int tcptv_keep_init; /* time to keep alive the initial SYN packet */
extern int tcp_mssdflt; /* default maximum segment size */
extern int tcp_rst_ppslim; /* maximum outgoing RST packet per second */
extern int tcp_ack_on_push; /* ACK immediately on PUSH */
-#ifdef TCP_SACK
extern int tcp_do_sack; /* SACK enabled/disabled */
extern struct pool sackhl_pool;
extern int tcp_sackhole_limit; /* max entries for tcp sack queues */
-#endif
extern int tcp_do_ecn; /* RFC3168 ECN enabled/disabled? */
extern int tcp_do_rfc3390; /* RFC3390 Increasing TCP's Initial Window */
@@ -767,7 +759,6 @@ int tcp_usrreq(struct socket *,
int tcp_attach(struct socket *, int);
void tcp_xmit_timer(struct tcpcb *, int);
void tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
-#ifdef TCP_SACK
void tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
void tcp_update_sack_list(struct tcpcb *tp, tcp_seq, tcp_seq);
void tcp_del_sackholes(struct tcpcb *, struct tcphdr *);
@@ -779,11 +770,8 @@ int tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
#ifdef DEBUG
void tcp_print_holes(struct tcpcb *tp);
#endif
-#endif /* TCP_SACK */
-#if defined(TCP_SACK)
int tcp_newreno(struct tcpcb *, struct tcphdr *);
u_long tcp_seq_subtract(u_long, u_long );
-#endif /* TCP_SACK */
#ifdef TCP_SIGNATURE
int tcp_signature_apply(caddr_t, caddr_t, unsigned int);
int tcp_signature(struct tdb *, int, struct mbuf *, struct tcphdr *,