@@ -1514,6 +1514,10 @@ void net_tcp_reply_rst(struct net_pkt *pkt)
1514
1514
} else {
1515
1515
uint32_t ack = ntohl (th_pkt -> th_seq ) + tcp_data_len (pkt );
1516
1516
1517
+ if (th_flags (th_pkt ) & SYN ) {
1518
+ ack ++ ;
1519
+ }
1520
+
1517
1521
UNALIGNED_PUT (RST | ACK , & th_rst -> th_flags );
1518
1522
UNALIGNED_PUT (htonl (ack ), & th_rst -> th_ack );
1519
1523
}
@@ -2846,7 +2850,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
2846
2850
NET_DBG ("%s" , tcp_conn_state (conn , pkt ));
2847
2851
2848
2852
if (th_off (th ) < 5 ) {
2849
- tcp_out ( conn , RST );
2853
+ net_tcp_reply_rst ( pkt );
2850
2854
do_close = true;
2851
2855
close_status = - ECONNRESET ;
2852
2856
goto out ;
@@ -2874,6 +2878,13 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
2874
2878
if (conn -> in_connect ) {
2875
2879
fl = th_flags (th );
2876
2880
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
+
2877
2888
close_status = - ECONNREFUSED ;
2878
2889
}
2879
2890
}
@@ -2884,7 +2895,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
2884
2895
if (tcp_options_len && !tcp_options_check (& conn -> recv_options , pkt ,
2885
2896
tcp_options_len )) {
2886
2897
NET_DBG ("DROP: Invalid TCP option list" );
2887
- tcp_out ( conn , RST );
2898
+ net_tcp_reply_rst ( pkt );
2888
2899
do_close = true;
2889
2900
close_status = - ECONNRESET ;
2890
2901
goto out ;
@@ -2899,7 +2910,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
2899
2910
NET_DBG ("conn: %p, SYN received in %s state, dropping connection" ,
2900
2911
conn , tcp_state_to_str (conn -> state , false));
2901
2912
net_stats_update_tcp_seg_drop (conn -> iface );
2902
- tcp_out ( conn , RST );
2913
+ net_tcp_reply_rst ( pkt );
2903
2914
do_close = true;
2904
2915
close_status = - ECONNRESET ;
2905
2916
goto out ;
@@ -3173,7 +3184,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
3173
3184
"(total=%zu)" , conn , len_acked ,
3174
3185
conn -> send_data_total );
3175
3186
net_stats_update_tcp_seg_drop (conn -> iface );
3176
- tcp_out ( conn , RST );
3187
+ net_tcp_reply_rst ( pkt );
3177
3188
do_close = true;
3178
3189
close_status = - ECONNRESET ;
3179
3190
break ;
@@ -3236,7 +3247,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
3236
3247
3237
3248
ret = tcp_send_queued_data (conn );
3238
3249
if (ret < 0 && ret != - ENOBUFS ) {
3239
- tcp_out ( conn , RST );
3250
+ net_tcp_reply_rst ( pkt );
3240
3251
do_close = true;
3241
3252
close_status = ret ;
3242
3253
verdict = NET_OK ;
@@ -3334,7 +3345,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
3334
3345
3335
3346
next = tcp_enter_time_wait (conn );
3336
3347
3337
- tcp_out ( conn , RST );
3348
+ net_tcp_reply_rst ( pkt );
3338
3349
break ;
3339
3350
}
3340
3351
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)
3414
3425
3415
3426
next = tcp_enter_time_wait (conn );
3416
3427
3417
- tcp_out ( conn , RST );
3428
+ net_tcp_reply_rst ( pkt );
3418
3429
break ;
3419
3430
}
3420
3431
/*
@@ -3459,7 +3470,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
3459
3470
3460
3471
next = tcp_enter_time_wait (conn );
3461
3472
3462
- tcp_out ( conn , RST );
3473
+ net_tcp_reply_rst ( pkt );
3463
3474
break ;
3464
3475
}
3465
3476
@@ -3513,7 +3524,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
3513
3524
conn , new_len );
3514
3525
net_stats_update_tcp_seg_drop (conn -> iface );
3515
3526
3516
- tcp_out ( conn , RST );
3527
+ net_tcp_reply_rst ( pkt );
3517
3528
} else {
3518
3529
/* Acknowledge any FIN attempts, in case retransmission took
3519
3530
* place.
0 commit comments