tests: net: socket: tcp: Add test to validate obstructed close
When there is no response from the server, a client side close is obstructed, it should terminate and clean the context. This tests breaks the connection after the accept and validates this behavior. Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
This commit is contained in:
parent
ae31773ddd
commit
c3158804d4
|
@ -771,6 +771,106 @@ void test_connect_timeout(void)
|
|||
"net_context still in use");
|
||||
}
|
||||
|
||||
#define TCP_CLOSE_FAILURE_TIMEOUT 60000
|
||||
|
||||
void test_close_obstructed(void)
|
||||
{
|
||||
/* Test if socket closing even when there is not communication
|
||||
* possible any more
|
||||
*/
|
||||
uint32_t start_time, time_diff;
|
||||
int count_before = 0, count_after = 0;
|
||||
struct sockaddr_in c_saddr;
|
||||
struct sockaddr_in s_saddr;
|
||||
struct sockaddr addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
int c_sock;
|
||||
int s_sock;
|
||||
int new_sock;
|
||||
int dropped_packets_before = 0;
|
||||
int dropped_packets_after = 0;
|
||||
|
||||
prepare_sock_tcp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, ANY_PORT,
|
||||
&c_sock, &c_saddr);
|
||||
prepare_sock_tcp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, SERVER_PORT,
|
||||
&s_sock, &s_saddr);
|
||||
|
||||
test_bind(s_sock, (struct sockaddr *)&s_saddr, sizeof(s_saddr));
|
||||
test_listen(s_sock);
|
||||
|
||||
zassert_equal(connect(c_sock, (struct sockaddr *)&s_saddr,
|
||||
sizeof(s_saddr)),
|
||||
0, "connect not succeed");
|
||||
test_accept(s_sock, &new_sock, &addr, &addrlen);
|
||||
|
||||
/* We should have two contexts open now */
|
||||
net_context_foreach(calc_net_context, &count_before);
|
||||
|
||||
/* Break the communication */
|
||||
loopback_set_packet_drop_ratio(1.0f);
|
||||
|
||||
dropped_packets_before = loopback_get_num_dropped_packets();
|
||||
|
||||
test_close(c_sock);
|
||||
|
||||
start_time = k_uptime_get_32();
|
||||
|
||||
/* After the client socket closing, the context count should be 1 less */
|
||||
net_context_foreach(calc_net_context, &count_after);
|
||||
|
||||
time_diff = k_uptime_get_32() - start_time;
|
||||
|
||||
/* Eventually the client socket should be cleaned up */
|
||||
while ((count_before == count_after) && (time_diff < TCP_CLOSE_FAILURE_TIMEOUT)) {
|
||||
count_after = 0;
|
||||
net_context_foreach(calc_net_context, &count_after);
|
||||
k_sleep(K_MSEC(50));
|
||||
time_diff = k_uptime_get_32() - start_time;
|
||||
}
|
||||
|
||||
zassert_equal(count_before - 1, count_after,
|
||||
"net_context still in use (before %d vs after %d)",
|
||||
count_before - 1, count_after);
|
||||
|
||||
dropped_packets_after = loopback_get_num_dropped_packets();
|
||||
int dropped_packets = dropped_packets_after - dropped_packets_before;
|
||||
|
||||
/* At least some packet should have been dropped */
|
||||
zassert_equal(dropped_packets,
|
||||
CONFIG_NET_TCP_RETRY_COUNT + 1,
|
||||
"Incorrect number of FIN retries, got %i, expected %i",
|
||||
dropped_packets, CONFIG_NET_TCP_RETRY_COUNT+1);
|
||||
|
||||
test_close(new_sock);
|
||||
test_close(s_sock);
|
||||
|
||||
start_time = k_uptime_get_32();
|
||||
|
||||
k_sleep(TCP_TEARDOWN_TIMEOUT);
|
||||
|
||||
/* After the client socket closing, the context count should be 0 */
|
||||
count_after = 0;
|
||||
net_context_foreach(calc_net_context, &count_after);
|
||||
|
||||
/* Eventually the client socket should be cleaned up */
|
||||
while ((count_after > 0) && (time_diff < TCP_CLOSE_FAILURE_TIMEOUT)) {
|
||||
count_after = 0;
|
||||
net_context_foreach(calc_net_context, &count_after);
|
||||
k_sleep(K_MSEC(50));
|
||||
time_diff = k_uptime_get_32() - start_time;
|
||||
}
|
||||
|
||||
zassert_equal(count_after, 0, "net_context still in use");
|
||||
|
||||
/* After everything is closed, we expect no more dropped packets */
|
||||
dropped_packets_before = loopback_get_num_dropped_packets();
|
||||
k_sleep(K_SECONDS(2));
|
||||
dropped_packets_after = loopback_get_num_dropped_packets();
|
||||
|
||||
zassert_equal(dropped_packets_before, dropped_packets_after,
|
||||
"packets after close");
|
||||
}
|
||||
|
||||
void test_v4_accept_timeout(void)
|
||||
{
|
||||
/* Test if accept() will timeout properly */
|
||||
|
@ -1336,6 +1436,8 @@ void test_main(void)
|
|||
ztest_unit_test(test_open_close_immediately),
|
||||
ztest_unit_test_setup_teardown(test_connect_timeout,
|
||||
restore_packet_loss_ratio, restore_packet_loss_ratio),
|
||||
ztest_unit_test_setup_teardown(test_close_obstructed,
|
||||
restore_packet_loss_ratio, restore_packet_loss_ratio),
|
||||
ztest_user_unit_test(test_v4_accept_timeout),
|
||||
ztest_unit_test(test_so_type),
|
||||
ztest_unit_test(test_so_protocol),
|
||||
|
|
Loading…
Reference in a new issue