tcp_close: disable send callback before sending FIN
This fixes connection closing issues with CONFIG_NET_TCP_WRITE_BUFFERS. Because TCP_CLOSE is used for both of input and output for tcp_callback, the close callback and the send callback confuses each other as the following. As it effectively disposes the connection immediately, we end up with responding to the consequent ACK and FIN/ACK from the peer with RSTs. tcp_timer -> tcp_close_eventhandler returns TCP_CLOSE (meaning an active close) -> psock_send_eventhandler called with TCP_CLOSE from tcp_close_eventhandler, misinterpet as a passive close. -> tcp_lost_connection -> tcp_shutdown_monitor -> tcp_callback -> tcp_close_eventhandler misinterpret TCP_CLOSE from itself as a passive close
This commit is contained in:
parent
326a8ef0a2
commit
08e9dff0e9
@ -139,6 +139,22 @@ static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
* is set in the response
|
* is set in the response
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
||||||
|
FAR struct socket *psock = pstate->cl_psock;
|
||||||
|
|
||||||
|
/* We don't need the send callback anymore. */
|
||||||
|
|
||||||
|
if (psock->s_sndcb != NULL)
|
||||||
|
{
|
||||||
|
psock->s_sndcb->flags = 0;
|
||||||
|
psock->s_sndcb->event = NULL;
|
||||||
|
|
||||||
|
/* The callback will be freed by tcp_free. */
|
||||||
|
|
||||||
|
psock->s_sndcb = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dev->d_len = 0;
|
dev->d_len = 0;
|
||||||
flags = (flags & ~TCP_NEWDATA) | TCP_CLOSE;
|
flags = (flags & ~TCP_NEWDATA) | TCP_CLOSE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user