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
This commit is contained in:
parent
743d528198
commit
8db239dc6b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336934
@ -2407,6 +2407,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
||||
* 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, struct socket *so,
|
||||
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
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user