diff options
author | pkelsey <pkelsey@FreeBSD.org> | 2015-12-28 02:43:12 +0000 |
---|---|---|
committer | pkelsey <pkelsey@FreeBSD.org> | 2015-12-28 02:43:12 +0000 |
commit | ca800abb78cb6010f8fa04bd0ba6cb26e7722d92 (patch) | |
tree | d59fdf105fd7c8c6f25f22dda7cc1ca51c702fe8 /sys/netinet/tcp_usrreq.c | |
parent | a2034803c3289c1600ea2ec5fa2e9dbed47bdc62 (diff) | |
download | FreeBSD-src-ca800abb78cb6010f8fa04bd0ba6cb26e7722d92.zip FreeBSD-src-ca800abb78cb6010f8fa04bd0ba6cb26e7722d92.tar.gz |
MFC r292706:
Implementation of server-side TCP Fast Open (TFO) [RFC7413].
TFO is disabled by default in the kernel build. See the top comment
in sys/netinet/tcp_fastopen.c for implementation particulars.
Differential Revision: https://reviews.freebsd.org/D4350
Sponsored by: Verisign, Inc.
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index c848306..1ccbf9a 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -79,6 +79,9 @@ __FBSDID("$FreeBSD$"); #include <netinet6/ip6_var.h> #include <netinet6/scope6_var.h> #endif +#ifdef TCP_RFC7413 +#include <netinet/tcp_fastopen.h> +#endif #include <netinet/tcp_fsm.h> #include <netinet/tcp_seq.h> #include <netinet/tcp_timer.h> @@ -391,6 +394,10 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td) } SOCK_UNLOCK(so); +#ifdef TCP_RFC7413 + if (tp->t_flags & TF_FASTOPEN) + tp->t_tfo_pending = tcp_fastopen_alloc_counter(); +#endif out: TCPDEBUG2(PRU_LISTEN); INP_WUNLOCK(inp); @@ -436,6 +443,10 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td) } SOCK_UNLOCK(so); +#ifdef TCP_RFC7413 + if (tp->t_flags & TF_FASTOPEN) + tp->t_tfo_pending = tcp_fastopen_alloc_counter(); +#endif out: TCPDEBUG2(PRU_LISTEN); INP_WUNLOCK(inp); @@ -791,6 +802,18 @@ tcp_usr_rcvd(struct socket *so, int flags) } tp = intotcpcb(inp); TCPDEBUG1(); +#ifdef TCP_RFC7413 + /* + * For passively-created TFO connections, don't attempt a window + * update while still in SYN_RECEIVED as this may trigger an early + * SYN|ACK. It is preferable to have the SYN|ACK be sent along with + * application response data, or failing that, when the DELACK timer + * expires. + */ + if ((tp->t_flags & TF_FASTOPEN) && + (tp->t_state == TCPS_SYN_RECEIVED)) + goto out; +#endif #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) tcp_offload_rcvd(tp); @@ -1558,6 +1581,29 @@ unlock_and_done: TP_MAXIDLE(tp)); goto unlock_and_done; +#ifdef TCP_RFC7413 + case TCP_FASTOPEN: + INP_WUNLOCK(inp); + if (!V_tcp_fastopen_enabled) + return (EPERM); + + error = sooptcopyin(sopt, &optval, sizeof optval, + sizeof optval); + if (error) + return (error); + + INP_WLOCK_RECHECK(inp); + if (optval) { + tp->t_flags |= TF_FASTOPEN; + if ((tp->t_state == TCPS_LISTEN) && + (tp->t_tfo_pending == NULL)) + tp->t_tfo_pending = + tcp_fastopen_alloc_counter(); + } else + tp->t_flags &= ~TF_FASTOPEN; + goto unlock_and_done; +#endif + default: INP_WUNLOCK(inp); error = ENOPROTOOPT; @@ -1628,6 +1674,13 @@ unlock_and_done: INP_WUNLOCK(inp); error = sooptcopyout(sopt, &ui, sizeof(ui)); break; +#ifdef TCP_RFC7413 + case TCP_FASTOPEN: + optval = tp->t_flags & TF_FASTOPEN; + INP_WUNLOCK(inp); + error = sooptcopyout(sopt, &optval, sizeof optval); + break; +#endif default: INP_WUNLOCK(inp); error = ENOPROTOOPT; @@ -1951,6 +2004,10 @@ db_print_tflags(u_int t_flags) db_printf("%sTF_ECN_PERMIT", comma ? ", " : ""); comma = 1; } + if (t_flags & TF_FASTOPEN) { + db_printf("%sTF_FASTOPEN", comma ? ", " : ""); + comma = 1; + } } static void |