aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2021-01-13 22:43:40 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2021-01-14 13:39:35 +0000
commitcc3c34859eab1b317d0f38731355b53f7d978c97 (patch)
tree4a451161db0b7d4b289b56c45f26b26ae2fdf80c
parent03cab14ea3a8e0444cec2ec3844e0648bd60bb58 (diff)
downloadsrc-cc3c34859eab1b317d0f38731355b53f7d978c97.tar.gz
src-cc3c34859eab1b317d0f38731355b53f7d978c97.zip
tcp: fix handling of TCP RST segments missing timestamps
A TCP RST segment should be processed even it is missing TCP timestamps. Reported by: dmgk@, kevans@ Reviewed by: rscheff@, dmgk@ Sponsored by: Netflix, Inc. MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D28143
-rw-r--r--sys/netinet/tcp_input.c21
-rw-r--r--sys/netinet/tcp_stacks/bbr.c5
-rw-r--r--sys/netinet/tcp_stacks/rack.c5
3 files changed, 21 insertions, 10 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 7746ccf24073..dda37d4795c9 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1692,16 +1692,25 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
/*
* If timestamps were negotiated during SYN/ACK and a
* segment without a timestamp is received, silently drop
- * the segment.
+ * the segment, unless it is a RST segment.
* See section 3.2 of RFC 7323.
*/
if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) {
- if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
- log(LOG_DEBUG, "%s; %s: Timestamp missing, "
- "segment silently dropped\n", s, __func__);
- free(s, M_TCPLOG);
+ if ((thflags & TH_RST) != 0) {
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Timestamp missing, "
+ "segment processed normally\n",
+ s, __func__);
+ free(s, M_TCPLOG);
+ }
+ } else {
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Timestamp missing, "
+ "segment silently dropped\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
+ goto drop;
}
- goto drop;
}
/*
* If timestamps were not negotiated during SYN/ACK and a
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index ccf138f70719..e59d9b9ff168 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -11463,10 +11463,11 @@ bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
/*
* If timestamps were negotiated during SYN/ACK and a
* segment without a timestamp is received, silently drop
- * the segment.
+ * the segment, unless it is a RST segment.
* See section 3.2 of RFC 7323.
*/
- if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) {
+ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) &&
+ ((thflags & TH_RST) == 0)) {
retval = 0;
goto done_with_input;
}
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index c225377807ba..7c81e8b3a2bc 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -10879,10 +10879,11 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
/*
* If timestamps were negotiated during SYN/ACK and a
* segment without a timestamp is received, silently drop
- * the segment.
+ * the segment, unless it is a RST segment.
* See section 3.2 of RFC 7323.
*/
- if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) {
+ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) &&
+ ((thflags & TH_RST) == 0)) {
way_out = 5;
retval = 0;
goto done_with_input;