diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 62dfa05e9f7..188e46c2b82 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -449,6 +449,16 @@ void tcp_initialize(void); FAR struct tcp_conn_s *tcp_alloc(uint8_t domain); +/**************************************************************************** + * Name: tcp_free_rx_buffers + * + * Description: + * Free rx buffer of a connection + * + ****************************************************************************/ + +void tcp_free_rx_buffers(FAR struct tcp_conn_s *conn); + /**************************************************************************** * Name: tcp_free * diff --git a/net/tcp/tcp_close.c b/net/tcp/tcp_close.c index 63afbe767e9..3f1eb46ae2b 100644 --- a/net/tcp/tcp_close.c +++ b/net/tcp/tcp_close.c @@ -236,6 +236,10 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) conn->tcpstateflags == TCP_LAST_ACK) && (conn->clscb = tcp_callback_alloc(conn)) != NULL) { + /* Free rx buffers of the connection immediately */ + + tcp_free_rx_buffers(conn); + /* Set up to receive TCP data event callbacks */ conn->clscb->flags = TCP_NEWDATA | TCP_ACKDATA | diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 487ab0829b5..28b2d9c7493 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -746,6 +746,38 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain) return conn; } +/**************************************************************************** + * Name: tcp_free_rx_buffers + * + * Description: + * Free rx buffer of a connection + * + ****************************************************************************/ + +void tcp_free_rx_buffers(FAR struct tcp_conn_s *conn) +{ + /* Release any read-ahead buffers attached to the connection */ + + iob_free_chain(conn->readahead); + conn->readahead = NULL; + +#ifdef CONFIG_NET_TCP_OUT_OF_ORDER + /* Release any out-of-order buffers */ + + if (conn->nofosegs > 0) + { + int i; + + for (i = 0; i < conn->nofosegs; i++) + { + iob_free_chain(conn->ofosegs[i].data); + } + + conn->nofosegs = 0; + } +#endif /* CONFIG_NET_TCP_OUT_OF_ORDER */ +} + /**************************************************************************** * Name: tcp_free * @@ -801,26 +833,7 @@ void tcp_free(FAR struct tcp_conn_s *conn) dq_rem(&conn->sconn.node, &g_active_tcp_connections); } - /* Release any read-ahead buffers attached to the connection */ - - iob_free_chain(conn->readahead); - conn->readahead = NULL; - -#ifdef CONFIG_NET_TCP_OUT_OF_ORDER - /* Release any out-of-order buffers */ - - if (conn->nofosegs > 0) - { - int i; - - for (i = 0; i < conn->nofosegs; i++) - { - iob_free_chain(conn->ofosegs[i].data); - } - - conn->nofosegs = 0; - } -#endif /* CONFIG_NET_TCP_OUT_OF_ORDER */ + tcp_free_rx_buffers(conn); #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Release any write buffers attached to the connection */