summaryrefslogtreecommitdiff
path: root/tests/t_socket.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-25 18:51:51 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-10-25 18:51:51 +0100
commit2c7659ec930277981b6333b5b3aff7840d11933c (patch)
tree1c363ce905ef1a62395f398335a94a47916af278 /tests/t_socket.c
parent632960a33eb8d23925b2bbef24d5065de7280aef (diff)
Decouple config parsing from binding and worker spawning
* Options are parsed now into a listener description list before binding them at once and starting the workers later * UDP workers can now be configured per connection * socket reuse is now done more sensibly, mcast sockets always reused * Hold-off logic after spawning udp workers removed
Diffstat (limited to 'tests/t_socket.c')
-rw-r--r--tests/t_socket.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/tests/t_socket.c b/tests/t_socket.c
index bbc9e5e..8eef7fd 100644
--- a/tests/t_socket.c
+++ b/tests/t_socket.c
@@ -91,14 +91,14 @@ static void case_socket_options(void) {
91 int udp, tcp; 91 int udp, tcp;
92 92
93 test_case("a bound udp socket is non blocking and serves both families"); 93 test_case("a bound udp socket is non blocking and serves both families");
94 udp = socket_udp_bind(ip_any, 0); 94 udp = socket_udp_bind(ip_any, 0, SOCKET_EXCLUSIVE);
95 CHECK(udp != -1); 95 CHECK(udp != -1);
96 CHECK_INT(is_nonblocking(udp), 1); 96 CHECK_INT(is_nonblocking(udp), 1);
97 CHECK_INT(sock_flag(udp, IPPROTO_IPV6, IPV6_V6ONLY), 0); 97 CHECK_INT(sock_flag(udp, IPPROTO_IPV6, IPV6_V6ONLY), 0);
98 close(udp); 98 close(udp);
99 99
100 test_case("a listening tcp socket is non blocking and serves both families"); 100 test_case("a listening tcp socket is non blocking and serves both families");
101 tcp = socket_tcp_listen(ip_any, 0); 101 tcp = socket_tcp_listen(ip_any, 0, SOCKET_EXCLUSIVE);
102 CHECK(tcp != -1); 102 CHECK(tcp != -1);
103 CHECK_INT(is_nonblocking(tcp), 1); 103 CHECK_INT(is_nonblocking(tcp), 1);
104 CHECK_INT(sock_flag(tcp, IPPROTO_IPV6, IPV6_V6ONLY), 0); 104 CHECK_INT(sock_flag(tcp, IPPROTO_IPV6, IPV6_V6ONLY), 0);
@@ -106,24 +106,20 @@ static void case_socket_options(void) {
106} 106}
107 107
108#ifdef SO_REUSEPORT 108#ifdef SO_REUSEPORT
109static void case_reuseport_is_opt_in(void) { 109static void case_sharing_is_opt_in(void) {
110 int s; 110 int s;
111 111
112 test_case("reuseport stays off unless the operator asks for it"); 112 test_case("an address is exclusive unless sharing is asked for");
113 g_socket_reuseport = 0; 113 s = socket_udp_bind(ip_loopback, 0, SOCKET_EXCLUSIVE);
114 s = socket_udp_bind(ip_loopback, 0);
115 CHECK(s != -1); 114 CHECK(s != -1);
116 CHECK_INT(sock_flag(s, SOL_SOCKET, SO_REUSEPORT), 0); 115 CHECK_INT(sock_flag(s, SOL_SOCKET, SO_REUSEPORT), 0);
117 close(s); 116 close(s);
118 117
119 test_case("reuseport reaches the socket when it is asked for"); 118 test_case("and shared when it is");
120 g_socket_reuseport = 1; 119 s = socket_udp_bind(ip_loopback, 0, SOCKET_SHARED);
121 s = socket_udp_bind(ip_loopback, 0);
122 CHECK(s != -1); 120 CHECK(s != -1);
123 CHECK_INT(sock_flag(s, SOL_SOCKET, SO_REUSEPORT), 1); 121 CHECK_INT(sock_flag(s, SOL_SOCKET, SO_REUSEPORT), 1);
124 close(s); 122 close(s);
125
126 g_socket_reuseport = 0;
127} 123}
128#endif 124#endif
129 125
@@ -135,7 +131,7 @@ static void case_udp_roundtrip(void) {
135 int s; 131 int s;
136 132
137 test_case("a datagram comes back with the sender's address and port"); 133 test_case("a datagram comes back with the sender's address and port");
138 s = socket_udp_bind(ip_loopback, 0); 134 s = socket_udp_bind(ip_loopback, 0, SOCKET_EXCLUSIVE);
139 CHECK(s != -1); 135 CHECK(s != -1);
140 bound_address(s, own_ip, &own_port); 136 bound_address(s, own_ip, &own_port);
141 CHECK(own_port != 0); 137 CHECK(own_port != 0);
@@ -158,9 +154,9 @@ static void case_udp_v4mapped(void) {
158 int receiver, sender; 154 int receiver, sender;
159 155
160 test_case("an IPv4 sender is reported in its v4 mapped form"); 156 test_case("an IPv4 sender is reported in its v4 mapped form");
161 receiver = socket_udp_bind(ip_v4_loopback, 0); 157 receiver = socket_udp_bind(ip_v4_loopback, 0, SOCKET_EXCLUSIVE);
162 CHECK(receiver != -1); 158 CHECK(receiver != -1);
163 sender = socket_udp_bind(ip_v4_loopback, 0); 159 sender = socket_udp_bind(ip_v4_loopback, 0, SOCKET_EXCLUSIVE);
164 CHECK(sender != -1); 160 CHECK(sender != -1);
165 bound_address(receiver, receiver_ip, &receiver_port); 161 bound_address(receiver, receiver_ip, &receiver_port);
166 bound_address(sender, sender_ip, &sender_port); 162 bound_address(sender, sender_ip, &sender_port);
@@ -184,7 +180,7 @@ static void case_tcp_roundtrip(void) {
184 int listener, client, accepted; 180 int listener, client, accepted;
185 181
186 test_case("a connection is accepted and carries the caller's address"); 182 test_case("a connection is accepted and carries the caller's address");
187 listener = socket_tcp_listen(ip_loopback, 0); 183 listener = socket_tcp_listen(ip_loopback, 0, SOCKET_EXCLUSIVE);
188 CHECK(listener != -1); 184 CHECK(listener != -1);
189 bound_address(listener, listener_ip, &listener_port); 185 bound_address(listener, listener_ip, &listener_port);
190 CHECK(listener_port != 0); 186 CHECK(listener_port != 0);
@@ -216,7 +212,7 @@ static void case_connect_refused(void) {
216 212
217 test_case("a refused connection is reported by socket_is_connected"); 213 test_case("a refused connection is reported by socket_is_connected");
218 /* Take a port, then drop it, so nothing is listening on it any more */ 214 /* Take a port, then drop it, so nothing is listening on it any more */
219 listener = socket_tcp_listen(ip_loopback, 0); 215 listener = socket_tcp_listen(ip_loopback, 0, SOCKET_EXCLUSIVE);
220 CHECK(listener != -1); 216 CHECK(listener != -1);
221 bound_address(listener, listener_ip, &port); 217 bound_address(listener, listener_ip, &port);
222 close(listener); 218 close(listener);
@@ -247,8 +243,8 @@ static void case_bind_failure(void) {
247 test_case("binding an address no interface carries fails"); 243 test_case("binding an address no interface carries fails");
248 before = next_descriptor(); 244 before = next_descriptor();
249 CHECK(before != -1); 245 CHECK(before != -1);
250 CHECK_INT(socket_tcp_listen(ip_unassigned, 0), -1); 246 CHECK_INT(socket_tcp_listen(ip_unassigned, 0, SOCKET_EXCLUSIVE), -1);
251 CHECK_INT(socket_udp_bind(ip_unassigned, 0), -1); 247 CHECK_INT(socket_udp_bind(ip_unassigned, 0, SOCKET_EXCLUSIVE), -1);
252 248
253 test_case("a failed bind leaves no socket behind"); 249 test_case("a failed bind leaves no socket behind");
254 CHECK_INT(next_descriptor(), before); 250 CHECK_INT(next_descriptor(), before);
@@ -294,7 +290,7 @@ static void case_mcast_sender(void) {
294void test_socket(void) { 290void test_socket(void) {
295 case_socket_options(); 291 case_socket_options();
296#ifdef SO_REUSEPORT 292#ifdef SO_REUSEPORT
297 case_reuseport_is_opt_in(); 293 case_sharing_is_opt_in();
298#endif 294#endif
299 case_udp_roundtrip(); 295 case_udp_roundtrip();
300 case_udp_v4mapped(); 296 case_udp_v4mapped();