svn commit: r336934 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Mon Jul 30 20:35:52 UTC 2018
Author: tuexen
Date: Mon Jul 30 20:35:50 2018
New Revision: 336934
URL: https://svnweb.freebsd.org/changeset/base/336934
Log:
Fix some TCP fast open issues.
The following issues are fixed:
* Whenever a TCP server with TCP fast open enabled, calls accept(),
recv(), send(), and close() before the TCP-ACK segment has been received,
the TCP connection is just dropped and the reception of the TCP-ACK
segment triggers the sending of a TCP-RST segment.
* Whenever a TCP server with TCP fast open enabled, calls accept(), recv(),
send(), send(), and close() before the TCP-ACK segment has been received,
the first byte provided in the second send call is not transferred.
* Whenever a TCP client with TCP fast open enabled calls sendto() followed
by close() the TCP connection is just dropped.
Reviewed by: jtl@, kbowling@, rrs@
Sponsored by: Netflix, Inc.
Differential Revision: https://reviews.freebsd.org/D16485
Modified:
head/sys/netinet/tcp_input.c
head/sys/netinet/tcp_output.c
head/sys/netinet/tcp_usrreq.c
Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c Mon Jul 30 20:25:32 2018 (r336933)
+++ head/sys/netinet/tcp_input.c Mon Jul 30 20:35:50 2018 (r336934)
@@ -2407,6 +2407,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
* SYN-RECEIVED* -> FIN-WAIT-1
*/
tp->t_starttime = ticks;
+ if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) {
+ tcp_fastopen_decrement_counter(tp->t_tfo_pending);
+ tp->t_tfo_pending = NULL;
+
+ /*
+ * Account for the ACK of our SYN prior to
+ * regular ACK processing below.
+ */
+ tp->snd_una++;
+ }
if (tp->t_flags & TF_NEEDFIN) {
tcp_state_change(tp, TCPS_FIN_WAIT_1);
tp->t_flags &= ~TF_NEEDFIN;
@@ -2414,16 +2424,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
tcp_state_change(tp, TCPS_ESTABLISHED);
TCP_PROBE5(accept__established, NULL, tp,
m, tp, th);
- if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) {
- tcp_fastopen_decrement_counter(tp->t_tfo_pending);
- tp->t_tfo_pending = NULL;
-
- /*
- * Account for the ACK of our SYN prior to
- * regular ACK processing below.
- */
- tp->snd_una++;
- }
/*
* TFO connections call cc_conn_init() during SYN
* processing. Calling it again here for such
Modified: head/sys/netinet/tcp_output.c
==============================================================================
--- head/sys/netinet/tcp_output.c Mon Jul 30 20:25:32 2018 (r336933)
+++ head/sys/netinet/tcp_output.c Mon Jul 30 20:35:50 2018 (r336934)
@@ -228,13 +228,15 @@ tcp_output(struct tcpcb *tp)
#endif
/*
- * For TFO connections in SYN_RECEIVED, only allow the initial
- * SYN|ACK and those sent by the retransmit timer.
+ * For TFO connections in SYN_SENT or SYN_RECEIVED,
+ * only allow the initial SYN or SYN|ACK and those sent
+ * by the retransmit timer.
*/
if (IS_FASTOPEN(tp->t_flags) &&
- (tp->t_state == TCPS_SYN_RECEIVED) &&
- SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN|ACK sent */
- (tp->snd_nxt != tp->snd_una)) /* not a retransmit */
+ ((tp->t_state == TCPS_SYN_SENT) ||
+ (tp->t_state == TCPS_SYN_RECEIVED)) &&
+ SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN or SYN|ACK sent */
+ (tp->snd_nxt != tp->snd_una)) /* not a retransmit */
return (0);
/*
Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c Mon Jul 30 20:25:32 2018 (r336933)
+++ head/sys/netinet/tcp_usrreq.c Mon Jul 30 20:35:50 2018 (r336934)
@@ -2113,7 +2113,8 @@ tcp_disconnect(struct tcpcb *tp)
* Neither tcp_close() nor tcp_drop() should return NULL, as the
* socket is still open.
*/
- if (tp->t_state < TCPS_ESTABLISHED) {
+ if (tp->t_state < TCPS_ESTABLISHED &&
+ !(tp->t_state > TCPS_LISTEN && IS_FASTOPEN(tp->t_flags))) {
tp = tcp_close(tp);
KASSERT(tp != NULL,
("tcp_disconnect: tcp_close() returned NULL"));
More information about the svn-src-head
mailing list