@@ -3137,7 +3137,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
31373137 * the TCP context and put the connection into
31383138 * active close (TCP_FIN_WAIT_1).
31393139 */
3140- net_tcp_put (conn -> context );
3140+ net_tcp_put (conn -> context , false );
31413141 break ;
31423142 }
31433143
@@ -3690,7 +3690,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
36903690}
36913691
36923692/* Active connection close: send FIN and go to FIN_WAIT_1 state */
3693- int net_tcp_put (struct net_context * context )
3693+ int net_tcp_put (struct net_context * context , bool force_close )
36943694{
36953695 struct tcp * conn = context -> tcp ;
36963696
@@ -3713,26 +3713,43 @@ int net_tcp_put(struct net_context *context)
37133713 conn -> send_data_total );
37143714 conn -> in_close = true;
37153715
3716- /* How long to wait until all the data has been sent?
3717- */
3718- k_work_reschedule_for_queue (& tcp_work_q ,
3719- & conn -> send_data_timer ,
3720- K_MSEC (TCP_RTO_MS ));
3716+ if (force_close ) {
3717+ k_work_cancel_delayable (& conn -> send_data_timer );
3718+
3719+ keep_alive_timer_stop (conn );
3720+ tcp_conn_close (conn , - ENETRESET );
3721+ } else {
3722+ /* How long to wait until all the data has been sent?
3723+ */
3724+ k_work_reschedule_for_queue (& tcp_work_q ,
3725+ & conn -> send_data_timer ,
3726+ K_MSEC (TCP_RTO_MS ));
3727+ }
3728+
37213729 } else {
3722- NET_DBG ("[%p] TCP connection in %s close, "
3723- "not disposing yet (waiting %dms)" ,
3724- conn , "active" , tcp_max_timeout_ms );
3725- k_work_reschedule_for_queue (& tcp_work_q ,
3726- & conn -> fin_timer ,
3727- FIN_TIMEOUT );
3730+ if (force_close ) {
3731+ NET_DBG ("[%p] TCP connection in %s close, "
3732+ "disposing immediately" ,
3733+ conn , "forced" );
37283734
3729- tcp_out (conn , FIN | ACK );
3730- conn_seq (conn , + 1 );
3731- tcp_setup_retransmission (conn );
3735+ keep_alive_timer_stop (conn );
3736+ tcp_conn_close (conn , - ENETRESET );
3737+ } else {
3738+ NET_DBG ("[%p] TCP connection in %s close, "
3739+ "not disposing yet (waiting %dms)" ,
3740+ conn , "active" , tcp_max_timeout_ms );
3741+ k_work_reschedule_for_queue (& tcp_work_q ,
3742+ & conn -> fin_timer ,
3743+ FIN_TIMEOUT );
3744+
3745+ tcp_out (conn , FIN | ACK );
3746+ conn_seq (conn , + 1 );
3747+ tcp_setup_retransmission (conn );
37323748
3733- conn_state (conn , TCP_FIN_WAIT_1 );
3749+ conn_state (conn , TCP_FIN_WAIT_1 );
37343750
3735- keep_alive_timer_stop (conn );
3751+ keep_alive_timer_stop (conn );
3752+ }
37363753 }
37373754 } else if (conn -> in_connect ) {
37383755 conn -> in_connect = false;
@@ -4411,7 +4428,7 @@ enum net_verdict tp_input(struct net_conn *net_conn,
44114428 if (is ("CLOSE2" , tp -> op )) {
44124429 struct tcp * conn =
44134430 (void * )sys_slist_peek_head (& tcp_conns );
4414- net_tcp_put (conn -> context );
4431+ net_tcp_put (conn -> context , false );
44154432 }
44164433 if (is ("RECV" , tp -> op )) {
44174434#define HEXSTR_SIZE 64
0 commit comments