diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 23bec6a6e5..d1addb0bbf 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -314,10 +314,44 @@ found: if ((tcp->flags & TCP_RST) != 0) { - conn->tcpstateflags = TCP_CLOSED; - nwarn("WARNING: RESET - TCP state: TCP_CLOSED\n"); + FAR struct tcp_conn_s *listener = NULL; + + /* An RST received during the 3-way connection handshake requires + * little more clean-up. + */ + + if ((conn->tcpstateflags & TCP_STATE_MASK) == TCP_SYN_RCVD) + { + conn->tcpstateflags = TCP_CLOSED; + nwarn("WARNING: RESET in TCP_SYN_RCVD\n"); + + /* Notify the listerner for connection of the reset event */ + + listener = tcp_findlistener(conn->lport); + + /* We must free this TCP connection structure, this connection + * will never be established. + */ + + tcp_free(conn); + } + else + { + conn->tcpstateflags = TCP_CLOSED; + nwarn("WARNING: RESET TCP state: TCP_CLOSED\n"); + + /* Notify this connection of the reset event */ + + listener = conn; + } + + /* Perform the TCP_ABORT callback and drop the packet */ + + if (listener != NULL) + { + (void)tcp_callback(dev, listener, TCP_ABORT); + } - (void)tcp_callback(dev, conn, TCP_ABORT); goto drop; } diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index a9047fc478..03935c964b 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -231,7 +231,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, FAR struct tcp_conn_s *listener; conn->tcpstateflags = TCP_CLOSED; - ninfo("TCP state: TCP_CLOSED\n"); + ninfo("TCP state: TCP_SYN_RCVD->TCP_CLOSED\n"); /* Find the listener for this connection. */