From 772873104658182a5b76f5c0eed76047c62c6651 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Wed, 28 Oct 2026 23:31:07 +0100 Subject: With more workers blockingly waiting on udp sockets, we need to keep track of all sockets to shut them down on exit --- tests/t_socket.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'tests/t_socket.c') diff --git a/tests/t_socket.c b/tests/t_socket.c index 8eef7fd..ede8ae0 100644 --- a/tests/t_socket.c +++ b/tests/t_socket.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* Opentracker */ @@ -144,6 +145,44 @@ static void case_udp_roundtrip(void) { close(s); } +/* udp_workers_deinit relies on a worker parked in a read coming back. The + receive timeout is what guarantees that; shutting the socket down is what + makes it prompt where the platform allows it. Neither is uniform across the + systems opentracker runs on, so both are checked rather than assumed. */ +static void case_blocking_read_comes_back(void) { + char buf[32], ip[16], own_ip[16]; + uint16_t port = 0, own_port = 0; + time_t started; + int s; + + test_case("a receive timeout does not delay a datagram that is already there"); + s = socket_udp_bind(ip_loopback, 0, SOCKET_EXCLUSIVE); + CHECK(s != -1); + CHECK_INT(socket_set_blocking(s, 1), 0); + CHECK_INT(socket_set_timeout(s, 1), 0); + bound_address(s, own_ip, &own_port); + CHECK_INT(socket_send(s, "opentracker", 11, own_ip, own_port), 11); + CHECK_INT(socket_recv(s, buf, sizeof(buf), ip, &port), 11); + + test_case("and ends a read that would otherwise never return"); + started = time(NULL); + CHECK_INT(socket_recv(s, buf, sizeof(buf), ip, &port), -1); + CHECK(errno == EAGAIN || errno == EWOULDBLOCK); + CHECK(time(NULL) - started <= 3); + close(s); + + test_case("shutting the socket down ends one too"); + s = socket_udp_bind(ip_loopback, 0, SOCKET_EXCLUSIVE); + CHECK(s != -1); + CHECK_INT(socket_set_blocking(s, 1), 0); + CHECK_INT(socket_set_timeout(s, 1), 0); + shutdown(s, SHUT_RD); + started = time(NULL); + CHECK(socket_recv(s, buf, sizeof(buf), ip, &port) <= 0); + CHECK(time(NULL) - started <= 3); + close(s); +} + /* An IPv4 peer must arrive in the v4 mapped form opentracker stores, however the kernel chose to report it. Linux fills a v4 mapped sockaddr_in6 here and the BSDs fill a plain sockaddr_in, so this is the case that tells the @@ -293,6 +332,7 @@ void test_socket(void) { case_sharing_is_opt_in(); #endif case_udp_roundtrip(); + case_blocking_read_comes_back(); case_udp_v4mapped(); case_tcp_roundtrip(); case_connect_refused(); -- cgit v1.3