@@ -129,6 +129,7 @@ static void handle_client_closing_test(sa_family_t af, struct tcphdr *th);
129
129
static void handle_data_fin1_test (sa_family_t af , struct tcphdr * th );
130
130
static void handle_data_during_fin1_test (sa_family_t af , struct tcphdr * th );
131
131
static void handle_server_recv_out_of_order (struct net_pkt * pkt );
132
+ static void handle_client_fin_ack_with_data_test (sa_family_t af , struct tcphdr * th );
132
133
133
134
static void verify_flags (struct tcphdr * th , uint8_t flags ,
134
135
const char * fun , int line )
@@ -430,6 +431,11 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt)
430
431
case 11 :
431
432
handle_data_during_fin1_test (net_pkt_family (pkt ), & th );
432
433
break ;
434
+
435
+ case 18 :
436
+ handle_client_fin_ack_with_data_test (net_pkt_family (pkt ), & th );
437
+ break ;
438
+
433
439
default :
434
440
zassert_true (false, "Undefined test case" );
435
441
}
@@ -1811,4 +1817,191 @@ ZTEST(net_tcp, test_server_out_of_order_data)
1811
1817
test_server_timeout_out_of_order_data ();
1812
1818
}
1813
1819
1820
+ #define TEST_FIN_DATA "test_data"
1821
+
1822
+ static enum fin_data_variant {
1823
+ FIN_DATA_FIN ,
1824
+ FIN_DATA_FIN_ACK ,
1825
+ FIN_DATA_FIN_ACK_PSH ,
1826
+ } test_fin_data_variant ;
1827
+
1828
+ static struct k_work_delayable test_fin_data_work ;
1829
+
1830
+ /* In this test we check that FIN packet containing data is handled correctly
1831
+ * by the TCP stack.
1832
+ */
1833
+ static void handle_client_fin_ack_with_data_test (sa_family_t af , struct tcphdr * th )
1834
+ {
1835
+ static uint16_t peer_port ;
1836
+ struct net_pkt * reply ;
1837
+ uint8_t flags = 0 ;
1838
+
1839
+ switch (t_state ) {
1840
+ case T_SYN :
1841
+ test_verify_flags (th , SYN );
1842
+ device_initial_seq = ntohl (th -> th_seq );
1843
+ seq = 0U ;
1844
+ ack = ntohl (th -> th_seq ) + 1U ;
1845
+ peer_port = th -> th_sport ;
1846
+ reply = prepare_syn_ack_packet (af , htons (MY_PORT ), peer_port );
1847
+ seq ++ ;
1848
+ t_state = T_SYN_ACK ;
1849
+ break ;
1850
+ case T_SYN_ACK :
1851
+ test_verify_flags (th , ACK );
1852
+ t_state = T_DATA ;
1853
+
1854
+ /* FIN packet with DATA needs to be rescheduled for later - if
1855
+ * we send it here, the net_context_recv() won't have a chance
1856
+ * to execute, hence no callback will be registered and data
1857
+ * will be dropped.
1858
+ */
1859
+ k_work_reschedule (& test_fin_data_work , K_MSEC (1 ));
1860
+ return ;
1861
+ case T_DATA :
1862
+ switch (test_fin_data_variant ) {
1863
+ case FIN_DATA_FIN :
1864
+ flags = FIN ;
1865
+ t_state = T_FIN ;
1866
+ break ;
1867
+ case FIN_DATA_FIN_ACK :
1868
+ flags = FIN | ACK ;
1869
+ t_state = T_FIN_ACK ;
1870
+ break ;
1871
+ case FIN_DATA_FIN_ACK_PSH :
1872
+ flags = FIN | ACK | PSH ;
1873
+ t_state = T_FIN_ACK ;
1874
+ break ;
1875
+ }
1876
+
1877
+ reply = tester_prepare_tcp_pkt (af , htons (MY_PORT ), peer_port ,
1878
+ flags , TEST_FIN_DATA ,
1879
+ strlen (TEST_FIN_DATA ));
1880
+ seq += strlen (TEST_FIN_DATA ) + 1 ;
1881
+
1882
+ break ;
1883
+ case T_FIN :
1884
+ test_verify_flags (th , ACK );
1885
+ zassert_equal (get_rel_seq (th ), 1 , "Unexpected SEQ number in T_FIN, got %d" ,
1886
+ get_rel_seq (th ));
1887
+ zassert_equal (ntohl (th -> th_ack ), seq , "Unexpected ACK in T_FIN, got %d" ,
1888
+ ntohl (th -> th_ack ));
1889
+
1890
+ t_state = T_CLOSING ;
1891
+ return ;
1892
+ case T_FIN_ACK :
1893
+ test_verify_flags (th , FIN | ACK );
1894
+ zassert_equal (get_rel_seq (th ), 1 , "Unexpected SEQ number in T_FIN_ACK, got %d" ,
1895
+ get_rel_seq (th ));
1896
+ zassert_equal (ntohl (th -> th_ack ), seq , "Unexpected ACK in T_FIN_ACK, got %d" ,
1897
+ ntohl (th -> th_ack ));
1898
+
1899
+ ack ++ ;
1900
+ reply = prepare_ack_packet (af , htons (MY_PORT ), peer_port );
1901
+ t_state = T_SYN ;
1902
+ break ;
1903
+
1904
+ case T_CLOSING :
1905
+ test_verify_flags (th , FIN );
1906
+ zassert_equal (get_rel_seq (th ), 1 , "Unexpected SEQ number in T_CLOSING, got %d" ,
1907
+ get_rel_seq (th ));
1908
+
1909
+ ack ++ ;
1910
+ reply = prepare_ack_packet (af , htons (MY_PORT ), peer_port );
1911
+ t_state = T_SYN ;
1912
+ break ;
1913
+
1914
+ default :
1915
+ zassert_true (false, "%s unexpected state" , __func__ );
1916
+ return ;
1917
+ }
1918
+
1919
+ zassert_ok (net_recv_data (net_iface , reply ), "%s failed" , __func__ );
1920
+ }
1921
+
1922
+
1923
+ static void test_fin_data_handler (struct k_work * work )
1924
+ {
1925
+ ARG_UNUSED (work );
1926
+
1927
+ handle_client_fin_ack_with_data_test (AF_INET , NULL );
1928
+ }
1929
+
1930
+ static void test_fin_ack_data_recv_cb (struct net_context * context ,
1931
+ struct net_pkt * pkt ,
1932
+ union net_ip_header * ip_hdr ,
1933
+ union net_proto_header * proto_hdr ,
1934
+ int status ,
1935
+ void * user_data )
1936
+ {
1937
+ if (status ) {
1938
+ zassert_true (false, "failed to recv the data" );
1939
+ }
1940
+
1941
+ if (pkt ) {
1942
+ uint8_t buf [sizeof (TEST_FIN_DATA )] = { 0 };
1943
+ int data_len = net_pkt_remaining_data (pkt );
1944
+
1945
+ zassert_equal (data_len , strlen (TEST_FIN_DATA ),
1946
+ "Invalid packet length, %d" , data_len );
1947
+ zassert_ok (net_pkt_read (pkt , buf , data_len ));
1948
+ zassert_mem_equal (buf , TEST_FIN_DATA , data_len );
1949
+
1950
+ net_pkt_unref (pkt );
1951
+ }
1952
+
1953
+ test_sem_give ();
1954
+ }
1955
+
1956
+ /* Test case scenario IPv4
1957
+ * expect SYN,
1958
+ * send SYN ACK,
1959
+ * expect ACK,
1960
+ * send FIN/FIN,ACK/FIN,ACK,PSH with Data,
1961
+ * expect FIN/FIN,ACK/ACK,
1962
+ * send ACK
1963
+ * any failures cause test case to fail.
1964
+ */
1965
+ ZTEST (net_tcp , test_client_fin_ack_with_data )
1966
+ {
1967
+ struct net_context * ctx ;
1968
+
1969
+ test_case_no = 18 ;
1970
+
1971
+ k_work_init_delayable (& test_fin_data_work , test_fin_data_handler );
1972
+
1973
+ for (enum fin_data_variant variant = FIN_DATA_FIN ;
1974
+ variant <= FIN_DATA_FIN_ACK_PSH ; variant ++ ) {
1975
+ test_fin_data_variant = variant ;
1976
+ t_state = T_SYN ;
1977
+ seq = ack = 0 ;
1978
+
1979
+ zassert_ok (net_context_get (AF_INET , SOCK_STREAM , IPPROTO_TCP , & ctx ),
1980
+ "Failed to get net_context" );
1981
+
1982
+ net_context_ref (ctx );
1983
+
1984
+ zassert_ok (net_context_connect (ctx , (struct sockaddr * )& peer_addr_s ,
1985
+ sizeof (struct sockaddr_in ), NULL ,
1986
+ K_MSEC (1000 ), NULL ),
1987
+ "Failed to connect to peer" );
1988
+ zassert_ok (net_context_recv (ctx , test_fin_ack_data_recv_cb ,
1989
+ K_NO_WAIT , NULL ),
1990
+ "Failed to recv data from peer" );
1991
+
1992
+ /* Take sem twice, one for data packet, second for conn close
1993
+ * (NULL net_pkt).
1994
+ */
1995
+ test_sem_take (K_MSEC (100 ), __LINE__ );
1996
+ test_sem_take (K_MSEC (100 ), __LINE__ );
1997
+
1998
+ net_context_put (ctx );
1999
+
2000
+ /* Connection is in TIME_WAIT state, context will be released
2001
+ * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it.
2002
+ */
2003
+ k_sleep (K_MSEC (CONFIG_NET_TCP_TIME_WAIT_DELAY ));
2004
+ }
2005
+ }
2006
+
1814
2007
ZTEST_SUITE (net_tcp , NULL , presetup , NULL , NULL , NULL );
0 commit comments