@@ -116,6 +116,7 @@ static enum test_case_no {
116116 TEST_CLIENT_FIN_ACK_WITH_DATA = 18 ,
117117 TEST_CLIENT_SEQ_VALIDATION = 19 ,
118118 TEST_SERVER_ACK_VALIDATION = 20 ,
119+ TEST_SERVER_FIN_ACK_AFTER_DATA = 21 ,
119120} test_case_no ;
120121
121122static enum test_state t_state ;
@@ -142,6 +143,7 @@ static void handle_syn_invalid_ack(sa_family_t af, struct tcphdr *th);
142143static void handle_client_fin_ack_with_data_test (sa_family_t af , struct tcphdr * th );
143144static void handle_client_seq_validation_test (sa_family_t af , struct tcphdr * th );
144145static void handle_server_ack_validation_test (struct net_pkt * pkt );
146+ static void handle_server_fin_ack_after_data_test (sa_family_t af , struct tcphdr * th );
145147
146148static void verify_flags (struct tcphdr * th , uint8_t flags ,
147149 const char * fun , int line )
@@ -494,6 +496,9 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt)
494496 case TEST_SERVER_ACK_VALIDATION :
495497 handle_server_ack_validation_test (pkt );
496498 break ;
499+ case TEST_SERVER_FIN_ACK_AFTER_DATA :
500+ handle_server_fin_ack_after_data_test (net_pkt_family (pkt ), & th );
501+ break ;
497502 default :
498503 zassert_true (false, "Undefined test case" );
499504 }
@@ -3002,4 +3007,204 @@ ZTEST(net_tcp, test_server_ack_validation)
30023007 net_context_put (accepted_ctx );
30033008}
30043009
3010+ #define TEST_FIN_ACK_AFTER_DATA_REQ "request"
3011+ #define TEST_FIN_ACK_AFTER_DATA_RSP "test data response"
3012+
3013+ /* In this test we check that FIN,ACK packet acknowledging latest data is
3014+ * handled correctly by the TCP stack.
3015+ */
3016+ static void handle_server_fin_ack_after_data_test (sa_family_t af , struct tcphdr * th )
3017+ {
3018+ struct net_pkt * reply = NULL ;
3019+
3020+ zassert_false (th == NULL && t_state != T_SYN ,
3021+ "NULL pkt only expected in T_SYN state" );
3022+
3023+ switch (t_state ) {
3024+ case T_SYN :
3025+ reply = prepare_syn_packet (af , htons (MY_PORT ), htons (PEER_PORT ));
3026+ seq ++ ;
3027+ t_state = T_SYN_ACK ;
3028+ break ;
3029+ case T_SYN_ACK :
3030+ test_verify_flags (th , SYN | ACK );
3031+ zassert_equal (ntohl (th -> th_ack ), seq ,
3032+ "Unexpected ACK in T_SYN_ACK, got %d, expected %d" ,
3033+ ntohl (th -> th_ack ), seq );
3034+ device_initial_seq = ntohl (th -> th_seq );
3035+ ack = ntohl (th -> th_seq ) + 1U ;
3036+ t_state = T_DATA_ACK ;
3037+
3038+ /* Dummy "request" packet */
3039+ reply = prepare_data_packet (af , htons (MY_PORT ), htons (PEER_PORT ),
3040+ TEST_FIN_ACK_AFTER_DATA_REQ ,
3041+ sizeof (TEST_FIN_ACK_AFTER_DATA_REQ ) - 1 );
3042+ seq += sizeof (TEST_FIN_ACK_AFTER_DATA_REQ ) - 1 ;
3043+ break ;
3044+ case T_DATA_ACK :
3045+ test_verify_flags (th , ACK );
3046+ t_state = T_DATA ;
3047+ zassert_equal (ntohl (th -> th_seq ), ack ,
3048+ "Unexpected SEQ in T_DATA_ACK, got %d, expected %d" ,
3049+ get_rel_seq (th ), ack );
3050+ zassert_equal (ntohl (th -> th_ack ), seq ,
3051+ "Unexpected ACK in T_DATA_ACK, got %d, expected %d" ,
3052+ ntohl (th -> th_ack ), seq );
3053+ break ;
3054+ case T_DATA :
3055+ test_verify_flags (th , PSH | ACK );
3056+ zassert_equal (ntohl (th -> th_seq ), ack ,
3057+ "Unexpected SEQ in T_DATA, got %d, expected %d" ,
3058+ get_rel_seq (th ), ack );
3059+ zassert_equal (ntohl (th -> th_ack ), seq ,
3060+ "Unexpected ACK in T_DATA, got %d, expected %d" ,
3061+ ntohl (th -> th_ack ), seq );
3062+ ack += sizeof (TEST_FIN_ACK_AFTER_DATA_RSP ) - 1 ;
3063+ t_state = T_FIN_ACK ;
3064+
3065+ reply = prepare_fin_ack_packet (af , htons (MY_PORT ), htons (PEER_PORT ));
3066+ seq ++ ;
3067+ break ;
3068+ case T_FIN_ACK :
3069+ test_verify_flags (th , FIN | ACK );
3070+ zassert_equal (ntohl (th -> th_seq ), ack ,
3071+ "Unexpected SEQ in T_FIN_ACK, got %d, expected %d" ,
3072+ get_rel_seq (th ), ack );
3073+ zassert_equal (ntohl (th -> th_ack ), seq ,
3074+ "Unexpected ACK in T_FIN_ACK, got %d, expected %d" ,
3075+ ntohl (th -> th_ack ), seq );
3076+
3077+ ack ++ ;
3078+ t_state = T_CLOSING ;
3079+
3080+ reply = prepare_ack_packet (af , htons (MY_PORT ), htons (PEER_PORT ));
3081+ seq ++ ;
3082+ break ;
3083+ case T_CLOSING :
3084+ zassert_true (false, "Should not receive anything after final ACK" );
3085+ break ;
3086+ default :
3087+ zassert_true (false, "%s unexpected state" , __func__ );
3088+ return ;
3089+ }
3090+
3091+ if (reply != NULL ) {
3092+ zassert_ok (net_recv_data (net_iface , reply ), "%s failed" , __func__ );
3093+ }
3094+ }
3095+
3096+ /* Receive callback to be installed in the accept handler */
3097+ static void test_fin_ack_after_data_recv_cb (struct net_context * context ,
3098+ struct net_pkt * pkt ,
3099+ union net_ip_header * ip_hdr ,
3100+ union net_proto_header * proto_hdr ,
3101+ int status ,
3102+ void * user_data )
3103+ {
3104+ zassert_ok (status , "failed to recv the data" );
3105+
3106+ if (pkt != NULL ) {
3107+ uint8_t buf [sizeof (TEST_FIN_ACK_AFTER_DATA_REQ )] = { 0 };
3108+ int data_len = net_pkt_remaining_data (pkt );
3109+
3110+ zassert_equal (data_len , sizeof (TEST_FIN_ACK_AFTER_DATA_REQ ) - 1 ,
3111+ "Invalid packet length, %d" , data_len );
3112+ zassert_ok (net_pkt_read (pkt , buf , data_len ));
3113+ zassert_mem_equal (buf , TEST_FIN_ACK_AFTER_DATA_REQ , data_len );
3114+
3115+ net_pkt_unref (pkt );
3116+ }
3117+
3118+ test_sem_give ();
3119+ }
3120+
3121+ static void test_fin_ack_after_data_accept_cb (struct net_context * ctx ,
3122+ struct sockaddr * addr ,
3123+ socklen_t addrlen ,
3124+ int status ,
3125+ void * user_data )
3126+ {
3127+ int ret ;
3128+
3129+ zassert_ok (status , "failed to accept the conn" );
3130+
3131+ /* set callback on newly created context */
3132+ accepted_ctx = ctx ;
3133+ ret = net_context_recv (ctx , test_fin_ack_after_data_recv_cb ,
3134+ K_NO_WAIT , NULL );
3135+ zassert_ok (ret , "Failed to recv data from peer" );
3136+
3137+ /* Ref the context on the app behalf. */
3138+ net_context_ref (ctx );
3139+ }
3140+
3141+ /* Verify that the TCP stack replies with a valid FIN,ACK after the peer
3142+ * acknowledges the latest data in the FIN packet.
3143+ * Test case scenario IPv4
3144+ * send SYN,
3145+ * expect SYN ACK,
3146+ * send ACK with Data,
3147+ * expect ACK,
3148+ * expect Data,
3149+ * send FIN,ACK
3150+ * expect FIN,ACK
3151+ * send ACK
3152+ * any failures cause test case to fail.
3153+ */
3154+ ZTEST (net_tcp , test_server_fin_ack_after_data )
3155+ {
3156+ struct net_context * ctx ;
3157+ int ret ;
3158+
3159+ test_case_no = TEST_SERVER_FIN_ACK_AFTER_DATA ;
3160+
3161+ t_state = T_SYN ;
3162+ seq = ack = 0 ;
3163+
3164+ ret = net_context_get (AF_INET , SOCK_STREAM , IPPROTO_TCP , & ctx );
3165+ zassert_ok (ret , "Failed to get net_context" );
3166+
3167+ net_context_ref (ctx );
3168+
3169+ ret = net_context_bind (ctx , (struct sockaddr * )& my_addr_s ,
3170+ sizeof (struct sockaddr_in ));
3171+ zassert_ok (ret , "Failed to bind net_context" );
3172+
3173+ /* Put context into listening mode and install accept cb */
3174+ ret = net_context_listen (ctx , 1 );
3175+ zassert_ok (ret , "Failed to listen on net_context" );
3176+
3177+ ret = net_context_accept (ctx , test_fin_ack_after_data_accept_cb ,
3178+ K_NO_WAIT , NULL );
3179+ zassert_ok (ret , "Failed to set accept on net_context" );
3180+
3181+ /* Trigger the peer to send SYN */
3182+ handle_server_fin_ack_after_data_test (AF_INET , NULL );
3183+
3184+ /* test_fin_ack_after_data_recv_cb will release the semaphore after
3185+ * dummy request is read.
3186+ */
3187+ test_sem_take (K_MSEC (100 ), __LINE__ );
3188+
3189+ /* Send dummy "response" */
3190+ ret = net_context_send (accepted_ctx , TEST_FIN_ACK_AFTER_DATA_RSP ,
3191+ sizeof (TEST_FIN_ACK_AFTER_DATA_RSP ) - 1 , NULL ,
3192+ K_NO_WAIT , NULL );
3193+ zassert_equal (ret , sizeof (TEST_FIN_ACK_AFTER_DATA_RSP ) - 1 ,
3194+ "Failed to send data to peer %d" , ret );
3195+
3196+ /* test_fin_ack_after_data_recv_cb will release the semaphore after
3197+ * the connection is marked closed.
3198+ */
3199+ test_sem_take (K_MSEC (100 ), __LINE__ );
3200+
3201+ net_context_put (ctx );
3202+ net_context_put (accepted_ctx );
3203+
3204+ /* Connection is in TIME_WAIT state, context will be released
3205+ * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it.
3206+ */
3207+ k_sleep (K_MSEC (CONFIG_NET_TCP_TIME_WAIT_DELAY ));
3208+ }
3209+
30053210ZTEST_SUITE (net_tcp , NULL , presetup , NULL , NULL , NULL );
0 commit comments