diff --git a/net/tcp/tcp_close.c b/net/tcp/tcp_close.c index b3a81a80ce9de..4dca880ae8f07 100644 --- a/net/tcp/tcp_close.c +++ b/net/tcp/tcp_close.c @@ -294,6 +294,10 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) } #endif + /* Discard our reference to the connection */ + + conn->crefs = 0; + /* TCP_ESTABLISHED * We need to initiate an active close and wait for its completion. * @@ -327,6 +331,8 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) tcp_free(conn); } + psock->s_conn = NULL; + net_unlock(); return ret; } @@ -356,7 +362,6 @@ int tcp_close(FAR struct socket *psock) /* Perform the disconnection now */ tcp_unlisten(conn); /* No longer accepting connections */ - conn->crefs = 0; /* Discard our reference to the connection */ /* Break any current connections and close the socket */ diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index aad46069a52d3..018622e6fe096 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -652,15 +652,13 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain) /* Is this connection in a state we can sacrifice. */ - /* REVISIT: maybe we could check for SO_LINGER but it's buried - * in the socket layer. - */ - - if (tmp->tcpstateflags == TCP_CLOSING || + if ((tmp->crefs == 0) && + (tmp->tcpstateflags == TCP_CLOSED || + tmp->tcpstateflags == TCP_CLOSING || tmp->tcpstateflags == TCP_FIN_WAIT_1 || tmp->tcpstateflags == TCP_FIN_WAIT_2 || tmp->tcpstateflags == TCP_TIME_WAIT || - tmp->tcpstateflags == TCP_LAST_ACK) + tmp->tcpstateflags == TCP_LAST_ACK)) { /* Yes.. Is it the oldest one we have seen so far? */ @@ -767,9 +765,10 @@ void tcp_free(FAR struct tcp_conn_s *conn) * operation. */ - DEBUGASSERT(conn->crefs == 0); net_lock(); + DEBUGASSERT(conn->crefs == 0); + tcp_stop_timer(conn); /* Free remaining callbacks, actually there should be only the send