@@ -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