@@ -1514,6 +1514,10 @@ void net_tcp_reply_rst(struct net_pkt *pkt)
15141514 } else {
15151515 uint32_t ack = ntohl (th_pkt -> th_seq ) + tcp_data_len (pkt );
15161516
1517+ if (th_flags (th_pkt ) & SYN ) {
1518+ ack ++ ;
1519+ }
1520+
15171521 UNALIGNED_PUT (RST | ACK , & th_rst -> th_flags );
15181522 UNALIGNED_PUT (htonl (ack ), & th_rst -> th_ack );
15191523 }
@@ -2846,7 +2850,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
28462850 NET_DBG ("%s" , tcp_conn_state (conn , pkt ));
28472851
28482852 if (th_off (th ) < 5 ) {
2849- tcp_out ( conn , RST );
2853+ net_tcp_reply_rst ( pkt );
28502854 do_close = true;
28512855 close_status = - ECONNRESET ;
28522856 goto out ;
@@ -2874,6 +2878,13 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
28742878 if (conn -> in_connect ) {
28752879 fl = th_flags (th );
28762880 if (FL (& fl , = = , RST | ACK )) {
2881+ if (th_ack (th ) != conn -> seq ) {
2882+ /* Invalid ACKnum - drop it */
2883+ net_stats_update_tcp_seg_rsterr (net_pkt_iface (pkt ));
2884+ k_mutex_unlock (& conn -> lock );
2885+ return NET_DROP ;
2886+ }
2887+
28772888 close_status = - ECONNREFUSED ;
28782889 }
28792890 }
@@ -2884,7 +2895,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
28842895 if (tcp_options_len && !tcp_options_check (& conn -> recv_options , pkt ,
28852896 tcp_options_len )) {
28862897 NET_DBG ("DROP: Invalid TCP option list" );
2887- tcp_out ( conn , RST );
2898+ net_tcp_reply_rst ( pkt );
28882899 do_close = true;
28892900 close_status = - ECONNRESET ;
28902901 goto out ;
@@ -2899,7 +2910,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
28992910 NET_DBG ("conn: %p, SYN received in %s state, dropping connection" ,
29002911 conn , tcp_state_to_str (conn -> state , false));
29012912 net_stats_update_tcp_seg_drop (conn -> iface );
2902- tcp_out ( conn , RST );
2913+ net_tcp_reply_rst ( pkt );
29032914 do_close = true;
29042915 close_status = - ECONNRESET ;
29052916 goto out ;
@@ -3173,7 +3184,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
31733184 "(total=%zu)" , conn , len_acked ,
31743185 conn -> send_data_total );
31753186 net_stats_update_tcp_seg_drop (conn -> iface );
3176- tcp_out ( conn , RST );
3187+ net_tcp_reply_rst ( pkt );
31773188 do_close = true;
31783189 close_status = - ECONNRESET ;
31793190 break ;
@@ -3236,7 +3247,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
32363247
32373248 ret = tcp_send_queued_data (conn );
32383249 if (ret < 0 && ret != - ENOBUFS ) {
3239- tcp_out ( conn , RST );
3250+ net_tcp_reply_rst ( pkt );
32403251 do_close = true;
32413252 close_status = ret ;
32423253 verdict = NET_OK ;
@@ -3334,7 +3345,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
33343345
33353346 next = tcp_enter_time_wait (conn );
33363347
3337- tcp_out ( conn , RST );
3348+ net_tcp_reply_rst ( pkt );
33383349 break ;
33393350 }
33403351 if (FL (& fl , & , ACK , th_ack (th ) == conn -> seq )) {
@@ -3414,7 +3425,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
34143425
34153426 next = tcp_enter_time_wait (conn );
34163427
3417- tcp_out ( conn , RST );
3428+ net_tcp_reply_rst ( pkt );
34183429 break ;
34193430 }
34203431 /*
@@ -3459,7 +3470,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
34593470
34603471 next = tcp_enter_time_wait (conn );
34613472
3462- tcp_out ( conn , RST );
3473+ net_tcp_reply_rst ( pkt );
34633474 break ;
34643475 }
34653476
@@ -3513,7 +3524,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
35133524 conn , new_len );
35143525 net_stats_update_tcp_seg_drop (conn -> iface );
35153526
3516- tcp_out ( conn , RST );
3527+ net_tcp_reply_rst ( pkt );
35173528 } else {
35183529 /* Acknowledge any FIN attempts, in case retransmission took
35193530 * place.
0 commit comments