From ac075505667e036658069ff756ff7d8bf78f647f Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Thu, 22 Jun 2017 11:07:09 +0300 Subject: [PATCH] net: context: Go back to LISTEN state when receiving RST In LISTEN state ignore a TCP RST. In SYN RCVD state, reset TCP connection state to LISTEN when a valid RST segment is received. In all other states close the connection - except that these other states will not be handled in tcp_syn_rcvd() function. Jira: ZEP-2279 Signed-off-by: Patrik Flykt --- subsys/net/ip/net_context.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 3d5de171924..dcc2cfba140 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1378,14 +1378,17 @@ NET_CONN_CB(tcp_syn_rcvd) } /* - * If we receive RST, we go back to LISTEN state if the previous state - * was LISTEN, otherwise we go to CLOSED state. - * See RFC 793 chapter 3.4 "Reset Processing" for more details. + * See RFC 793 chapter 3.4 "Reset Processing" and RFC 793, page 65 + * for more details. If RST is received in SYN_RCVD state, go back + * to LISTEN state. No other states are valid for this function. */ if (NET_TCP_FLAGS(pkt) == NET_TCP_RST) { - /* We only accept RST packet that has valid seq field. */ - if (!net_tcp_validate_seq(tcp, pkt)) { + /* We only accept an RST packet that has valid seq field + * and ignore RST received in LISTEN state. + */ + if (!net_tcp_validate_seq(tcp, pkt) || + net_tcp_get_state(tcp) == NET_TCP_LISTEN) { net_stats_update_tcp_seg_rsterr(); return NET_DROP; } @@ -1396,7 +1399,10 @@ NET_CONN_CB(tcp_syn_rcvd) net_tcp_print_recv_info("RST", pkt, NET_TCP_HDR(pkt)->src_port); - if (net_tcp_get_state(tcp) != NET_TCP_LISTEN) { + if (net_tcp_get_state(tcp) == NET_TCP_SYN_RCVD) { + net_tcp_change_state(tcp, NET_TCP_LISTEN); + } else { + NET_DBG("TCP socket not in SYN RCVD state, closing"); net_tcp_change_state(tcp, NET_TCP_CLOSED); }