summaryrefslogtreecommitdiff
path: root/tests/t_socket.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-28 23:31:07 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-10-28 23:31:07 +0100
commit772873104658182a5b76f5c0eed76047c62c6651 (patch)
tree431ba9c063fab10b4356cd8c7e63c9d2e957e2d9 /tests/t_socket.c
parentdd0ad26ea9824b75accced2b56328cbb222c4c6d (diff)
With more workers blockingly waiting on udp sockets, we need to keep track of all sockets to shut them down on exit
Diffstat (limited to 'tests/t_socket.c')
-rw-r--r--tests/t_socket.c40
1 files changed, 40 insertions, 0 deletions
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 @@
10#include <poll.h> 10#include <poll.h>
11#include <string.h> 11#include <string.h>
12#include <sys/socket.h> 12#include <sys/socket.h>
13#include <time.h>
13#include <unistd.h> 14#include <unistd.h>
14 15
15/* Opentracker */ 16/* Opentracker */
@@ -144,6 +145,44 @@ static void case_udp_roundtrip(void) {
144 close(s); 145 close(s);
145} 146}
146 147
148/* udp_workers_deinit relies on a worker parked in a read coming back. The
149 receive timeout is what guarantees that; shutting the socket down is what
150 makes it prompt where the platform allows it. Neither is uniform across the
151 systems opentracker runs on, so both are checked rather than assumed. */
152static void case_blocking_read_comes_back(void) {
153 char buf[32], ip[16], own_ip[16];
154 uint16_t port = 0, own_port = 0;
155 time_t started;
156 int s;
157
158 test_case("a receive timeout does not delay a datagram that is already there");
159 s = socket_udp_bind(ip_loopback, 0, SOCKET_EXCLUSIVE);
160 CHECK(s != -1);
161 CHECK_INT(socket_set_blocking(s, 1), 0);
162 CHECK_INT(socket_set_timeout(s, 1), 0);
163 bound_address(s, own_ip, &own_port);
164 CHECK_INT(socket_send(s, "opentracker", 11, own_ip, own_port), 11);
165 CHECK_INT(socket_recv(s, buf, sizeof(buf), ip, &port), 11);
166
167 test_case("and ends a read that would otherwise never return");
168 started = time(NULL);
169 CHECK_INT(socket_recv(s, buf, sizeof(buf), ip, &port), -1);
170 CHECK(errno == EAGAIN || errno == EWOULDBLOCK);
171 CHECK(time(NULL) - started <= 3);
172 close(s);
173
174 test_case("shutting the socket down ends one too");
175 s = socket_udp_bind(ip_loopback, 0, SOCKET_EXCLUSIVE);
176 CHECK(s != -1);
177 CHECK_INT(socket_set_blocking(s, 1), 0);
178 CHECK_INT(socket_set_timeout(s, 1), 0);
179 shutdown(s, SHUT_RD);
180 started = time(NULL);
181 CHECK(socket_recv(s, buf, sizeof(buf), ip, &port) <= 0);
182 CHECK(time(NULL) - started <= 3);
183 close(s);
184}
185
147/* An IPv4 peer must arrive in the v4 mapped form opentracker stores, however 186/* An IPv4 peer must arrive in the v4 mapped form opentracker stores, however
148 the kernel chose to report it. Linux fills a v4 mapped sockaddr_in6 here 187 the kernel chose to report it. Linux fills a v4 mapped sockaddr_in6 here
149 and the BSDs fill a plain sockaddr_in, so this is the case that tells the 188 and the BSDs fill a plain sockaddr_in, so this is the case that tells the
@@ -293,6 +332,7 @@ void test_socket(void) {
293 case_sharing_is_opt_in(); 332 case_sharing_is_opt_in();
294#endif 333#endif
295 case_udp_roundtrip(); 334 case_udp_roundtrip();
335 case_blocking_read_comes_back();
296 case_udp_v4mapped(); 336 case_udp_v4mapped();
297 case_tcp_roundtrip(); 337 case_tcp_roundtrip();
298 case_connect_refused(); 338 case_connect_refused();