1 /*
2 * Copyright (c) 2019 Linaro Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
9
10 #include <stdio.h>
11 #include <stdbool.h>
12 #include <errno.h>
13 #include <zephyr/ztest_assert.h>
14
15 #include <zephyr/net/socket.h>
16 #include <zephyr/net/net_ip.h>
17 #include <zephyr/net/net_if.h>
18
19 #include "../../socket_helpers.h"
20
21 #define TEST_IPV4_ANY_ADDR "0.0.0.0"
22 #define TEST_MY_IPV4_ADDR "192.0.2.1"
23 #define TEST_MY_IPV4_ADDR2 "192.0.2.2"
24
25 #define TEST_IPV6_ANY_ADDR "::"
26 #define TEST_MY_IPV6_ADDR "2001:db8::1"
27 #define TEST_MY_IPV6_ADDR2 "2001:db8::2"
28
29 #define LOCAL_PORT 4242
30
31 #define TCP_TEARDOWN_TIMEOUT K_SECONDS(3)
32
33 #define SHOULD_SUCCEED true
34 #define SHOULD_FAIL false
35
test_add_local_ip_address(sa_family_t family,const char * ip)36 static void test_add_local_ip_address(sa_family_t family, const char *ip)
37 {
38 if (family == AF_INET) {
39 struct sockaddr_in addr;
40 struct net_if_addr *ifaddr;
41
42 zsock_inet_pton(AF_INET, ip, &addr.sin_addr);
43
44 ifaddr = net_if_ipv4_addr_add(net_if_get_default(),
45 &addr.sin_addr,
46 NET_ADDR_MANUAL,
47 0);
48 zassert_not_null(ifaddr,
49 "Cannot add IPv4 address %s", ip);
50 } else if (family == AF_INET6) {
51 struct sockaddr_in6 addr;
52
53 zsock_inet_pton(AF_INET6, ip, &addr.sin6_addr);
54
55 zassert_not_null(net_if_ipv6_addr_add(net_if_get_default(),
56 &addr.sin6_addr,
57 NET_ADDR_MANUAL,
58 0),
59 "Cannot add IPv6 address %s", ip);
60 }
61 }
62
setup(void)63 static void *setup(void)
64 {
65 /* Make sure that both the specified IPv4 and IPv6 addresses are
66 * added to the network interface.
67 */
68 test_add_local_ip_address(AF_INET, TEST_MY_IPV4_ADDR);
69 test_add_local_ip_address(AF_INET6, TEST_MY_IPV6_ADDR);
70
71 return NULL;
72 }
73
prepare_sock_tcp(sa_family_t family,const char * ip,uint16_t port,int * sock,struct sockaddr * addr)74 static inline void prepare_sock_tcp(sa_family_t family, const char *ip, uint16_t port,
75 int *sock, struct sockaddr *addr)
76 {
77 if (family == AF_INET) {
78 prepare_sock_tcp_v4(ip,
79 port,
80 sock,
81 (struct sockaddr_in *) addr);
82 } else if (family == AF_INET6) {
83 prepare_sock_tcp_v6(ip,
84 port,
85 sock,
86 (struct sockaddr_in6 *) addr);
87 }
88 }
89
prepare_sock_udp(sa_family_t family,const char * ip,uint16_t port,int * sock,struct sockaddr * addr)90 static inline void prepare_sock_udp(sa_family_t family, const char *ip, uint16_t port,
91 int *sock, struct sockaddr *addr)
92 {
93 if (family == AF_INET) {
94 prepare_sock_udp_v4(ip,
95 port,
96 sock,
97 (struct sockaddr_in *) addr);
98 } else if (family == AF_INET6) {
99 prepare_sock_udp_v6(ip,
100 port,
101 sock,
102 (struct sockaddr_in6 *) addr);
103 }
104 }
105
test_getsocketopt_reuseaddr(int sock,void * optval,socklen_t * optlen)106 static void test_getsocketopt_reuseaddr(int sock, void *optval, socklen_t *optlen)
107 {
108 int ret;
109
110 ret = zsock_getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen);
111 zassert_equal(ret, 0, "getsocketopt() failed with error %d", errno);
112 }
113
test_setsocketopt_reuseaddr(int sock,void * optval,socklen_t optlen)114 static void test_setsocketopt_reuseaddr(int sock, void *optval, socklen_t optlen)
115 {
116 int ret;
117
118 ret = zsock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, optval, optlen);
119 zassert_equal(ret, 0, "setsocketopt() failed with error %d", errno);
120 }
121
test_enable_reuseaddr(int sock)122 static void test_enable_reuseaddr(int sock)
123 {
124 int value = 1;
125
126 test_setsocketopt_reuseaddr(sock, &value, sizeof(value));
127 }
128
test_getsocketopt_reuseport(int sock,void * optval,socklen_t * optlen)129 static void test_getsocketopt_reuseport(int sock, void *optval, socklen_t *optlen)
130 {
131 int ret;
132
133 ret = zsock_getsockopt(sock, SOL_SOCKET, SO_REUSEPORT, optval, optlen);
134 zassert_equal(ret, 0, "getsocketopt() failed with error %d", errno);
135 }
136
test_setsocketopt_reuseport(int sock,void * optval,socklen_t optlen)137 static void test_setsocketopt_reuseport(int sock, void *optval, socklen_t optlen)
138 {
139 int ret;
140
141 ret = zsock_setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, optval, optlen);
142 zassert_equal(ret, 0, "setsocketopt() failed with error %d", errno);
143 }
144
test_enable_reuseport(int sock)145 static void test_enable_reuseport(int sock)
146 {
147 int value = 1;
148
149 test_setsocketopt_reuseport(sock, &value, sizeof(value));
150 }
151
test_bind_success(int sock,const struct sockaddr * addr,socklen_t addrlen)152 static void test_bind_success(int sock, const struct sockaddr *addr, socklen_t addrlen)
153 {
154 int ret;
155
156 ret = zsock_bind(sock, addr, addrlen);
157 zassert_equal(ret, 0, "bind() failed with error %d", errno);
158 }
159
test_bind_fail(int sock,const struct sockaddr * addr,socklen_t addrlen)160 static void test_bind_fail(int sock, const struct sockaddr *addr, socklen_t addrlen)
161 {
162 int ret;
163
164 ret = zsock_bind(sock, addr, addrlen);
165 zassert_equal(ret, -1, "bind() succeeded incorrectly");
166
167 zassert_equal(errno, EADDRINUSE, "bind() returned unexpected errno (%d)", errno);
168 }
169
test_listen(int sock)170 static void test_listen(int sock)
171 {
172 zassert_equal(zsock_listen(sock, 0),
173 0,
174 "listen() failed with error %d", errno);
175 }
176
test_connect_success(int sock,const struct sockaddr * addr,socklen_t addrlen)177 static void test_connect_success(int sock, const struct sockaddr *addr, socklen_t addrlen)
178 {
179 int ret;
180
181 ret = zsock_connect(sock, addr, addrlen);
182 zassert_equal(ret, 0, "connect() failed with error %d", errno);
183
184 if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) {
185 /* Let the connection proceed */
186 k_msleep(50);
187 }
188 }
189
test_connect_fail(int sock,const struct sockaddr * addr,socklen_t addrlen)190 static void test_connect_fail(int sock, const struct sockaddr *addr, socklen_t addrlen)
191 {
192 int ret;
193
194 ret = zsock_connect(sock, addr, addrlen);
195 zassert_equal(ret, -1, "connect() succeeded incorrectly");
196
197 zassert_equal(errno, EADDRINUSE, "connect() returned unexpected errno (%d)", errno);
198 }
199
test_accept(int sock,struct sockaddr * addr,socklen_t * addrlen)200 static int test_accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
201 {
202 int new_sock = zsock_accept(sock, addr, addrlen);
203
204 zassert_not_equal(new_sock, -1, "accept() failed with error %d", errno);
205
206 return new_sock;
207 }
208
test_sendto(int sock,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)209 static void test_sendto(int sock, const void *buf, size_t len, int flags,
210 const struct sockaddr *dest_addr, socklen_t addrlen)
211 {
212 int ret;
213
214 ret = zsock_sendto(sock, buf, len, flags, dest_addr, addrlen);
215 zassert_equal(ret, len, "sendto failed with error %d", errno);
216 }
217
test_recvfrom_success(int sock,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)218 static void test_recvfrom_success(int sock, void *buf, size_t max_len, int flags,
219 struct sockaddr *src_addr, socklen_t *addrlen)
220 {
221 int ret;
222
223 ret = zsock_recvfrom(sock, buf, max_len, flags, src_addr, addrlen);
224 zassert_equal(ret, max_len, "recvfrom failed with error %d", errno);
225 }
226
test_recvfrom_fail(int sock,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)227 static void test_recvfrom_fail(int sock, void *buf, size_t max_len, int flags,
228 struct sockaddr *src_addr, socklen_t *addrlen)
229 {
230 int ret;
231
232 ret = zsock_recvfrom(sock, buf, max_len, flags, src_addr, addrlen);
233 zassert_equal(ret, -1, "recvfrom succeeded incorrectly");
234
235 zassert_equal(errno, EAGAIN, "recvfrom() returned unexpected errno (%d)", errno);
236 }
237
test_recv_success(int sock,void * buf,size_t max_len,int flags)238 static void test_recv_success(int sock, void *buf, size_t max_len, int flags)
239 {
240 int ret;
241
242 ret = zsock_recv(sock, buf, max_len, flags);
243 zassert_equal(ret, max_len, "recv failed with error %d", errno);
244 }
245
test_recv_fail(int sock,void * buf,size_t max_len,int flags)246 static void test_recv_fail(int sock, void *buf, size_t max_len, int flags)
247 {
248 int ret;
249
250 ret = zsock_recv(sock, buf, max_len, flags);
251 zassert_equal(ret, -1, "recvfrom succeeded incorrectly");
252
253 zassert_equal(errno, EAGAIN, "recv() returned unexpected errno (%d)", errno);
254 }
255
ZTEST_USER(socket_reuseaddr_test_suite,test_enable_disable)256 ZTEST_USER(socket_reuseaddr_test_suite, test_enable_disable)
257 {
258 int server_sock = -1;
259 int value = -1;
260 socklen_t value_size = sizeof(int);
261
262 server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
263 zassert_true(server_sock >= 0, "socket open failed");
264
265 /* Read initial value */
266 test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
267 zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()");
268 zassert_equal(value, (int) false, "SO_REUSEADDR incorrectly set (expected false)");
269
270 /* Enable option */
271 value = 1;
272 test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
273 test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
274 zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);
275
276 /* Enable option (with other value as linux takes any int here) */
277 value = 2;
278 test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
279 test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
280 zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);
281
282 /* Enable option (with other value as linux takes any int here) */
283 value = 0x100;
284 test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
285 test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
286 zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);
287
288 /* Enable option (with other value as linux takes any int here) */
289 value = -1;
290 test_setsocketopt_reuseaddr(server_sock, (void *)&value, sizeof(value));
291 test_getsocketopt_reuseaddr(server_sock, (void *)&value, &value_size);
292 zassert_equal(value, (int) true, "SO_REUSEADDR not correctly set, returned %d", value);
293
294 zsock_close(server_sock);
295 }
296
297
test_reuseaddr_unspecified_specified_common(sa_family_t family,char const * first_ip,char const * second_ip,bool should_succeed)298 static void test_reuseaddr_unspecified_specified_common(sa_family_t family,
299 char const *first_ip,
300 char const *second_ip,
301 bool should_succeed)
302 {
303 int server_sock1 = -1;
304 int server_sock2 = -1;
305
306 struct sockaddr bind_addr1;
307 struct sockaddr bind_addr2;
308
309 /* Create the sockets */
310 prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1);
311 prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2);
312
313 /* Bind the first socket */
314 test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1));
315
316 /* Try to bind the second socket, should fail */
317 test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));
318
319 /* Enable SO_REUSEADDR option for the second socket */
320 test_enable_reuseaddr(server_sock2);
321
322 /* Try to bind the second socket again */
323 if (should_succeed) {
324 test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2));
325 } else {
326 test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));
327 }
328
329 zsock_close(server_sock1);
330 zsock_close(server_sock2);
331 }
332
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_first_unspecified)333 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_first_unspecified)
334 {
335 test_reuseaddr_unspecified_specified_common(AF_INET,
336 TEST_IPV4_ANY_ADDR,
337 TEST_MY_IPV4_ADDR,
338 SHOULD_SUCCEED);
339 }
340
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_first_unspecified)341 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_first_unspecified)
342 {
343 test_reuseaddr_unspecified_specified_common(AF_INET6,
344 TEST_IPV6_ANY_ADDR,
345 TEST_MY_IPV6_ADDR,
346 SHOULD_SUCCEED);
347 }
348
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_second_unspecified)349 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_second_unspecified)
350 {
351 test_reuseaddr_unspecified_specified_common(AF_INET,
352 TEST_MY_IPV4_ADDR,
353 TEST_IPV4_ANY_ADDR,
354 SHOULD_SUCCEED);
355 }
356
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_second_unspecified)357 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_second_unspecified)
358 {
359 test_reuseaddr_unspecified_specified_common(AF_INET6,
360 TEST_MY_IPV6_ADDR,
361 TEST_IPV6_ANY_ADDR,
362 SHOULD_SUCCEED);
363 }
364
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_both_unspecified)365 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_both_unspecified)
366 {
367 test_reuseaddr_unspecified_specified_common(AF_INET,
368 TEST_IPV4_ANY_ADDR,
369 TEST_IPV4_ANY_ADDR,
370 SHOULD_FAIL);
371 }
372
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_both_unspecified)373 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_both_unspecified)
374 {
375 test_reuseaddr_unspecified_specified_common(AF_INET6,
376 TEST_IPV6_ANY_ADDR,
377 TEST_IPV6_ANY_ADDR,
378 SHOULD_FAIL);
379 }
380
381
test_reuseaddr_tcp_listening_common(sa_family_t family,char const * first_ip,char const * second_ip)382 static void test_reuseaddr_tcp_listening_common(sa_family_t family,
383 char const *first_ip,
384 char const *second_ip)
385 {
386 int server_sock1 = -1;
387 int server_sock2 = -1;
388
389 struct sockaddr bind_addr1;
390 struct sockaddr bind_addr2;
391
392 /* Create the sockets */
393 prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1);
394 prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2);
395
396 /* Bind the first socket */
397 test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1));
398
399 /* Set the first socket to LISTEN state */
400 test_listen(server_sock1);
401
402 /* Enable SO_REUSEADDR option for the second socket */
403 test_enable_reuseaddr(server_sock2);
404
405 /* Try to bind the second socket, should fail */
406 test_bind_fail(server_sock2, (struct sockaddr *) &bind_addr2, sizeof(bind_addr2));
407
408 zsock_close(server_sock1);
409 zsock_close(server_sock2);
410 }
411
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_tcp_unspecified_listening)412 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_unspecified_listening)
413 {
414 test_reuseaddr_tcp_listening_common(AF_INET,
415 TEST_IPV4_ANY_ADDR,
416 TEST_MY_IPV4_ADDR);
417 }
418
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_tcp_unspecified_listening)419 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_unspecified_listening)
420 {
421 test_reuseaddr_tcp_listening_common(AF_INET6,
422 TEST_IPV6_ANY_ADDR,
423 TEST_MY_IPV6_ADDR);
424 }
425
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_tcp_specified_listening)426 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_specified_listening)
427 {
428 test_reuseaddr_tcp_listening_common(AF_INET,
429 TEST_MY_IPV4_ADDR,
430 TEST_IPV4_ANY_ADDR);
431 }
432
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_tcp_specified_listening)433 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_specified_listening)
434 {
435 test_reuseaddr_tcp_listening_common(AF_INET6,
436 TEST_MY_IPV6_ADDR,
437 TEST_IPV6_ANY_ADDR);
438 }
439
440
test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family,char const * first_ip,char const * second_ip)441 static void test_reuseaddr_tcp_tcp_time_wait_common(sa_family_t family,
442 char const *first_ip,
443 char const *second_ip)
444 {
445 int server_sock = -1;
446 int client_sock = -1;
447 int accept_sock = -1;
448
449 struct sockaddr bind_addr;
450 struct sockaddr conn_addr;
451
452 struct sockaddr accept_addr;
453 socklen_t accept_addrlen = sizeof(accept_addr);
454
455 prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr);
456 prepare_sock_tcp(family, second_ip, LOCAL_PORT, &client_sock, &conn_addr);
457
458 /* Bind the server socket */
459 test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
460
461 /* Start listening on the server socket */
462 test_listen(server_sock);
463
464 /* Connect the client */
465 test_connect_success(client_sock, &conn_addr, sizeof(conn_addr));
466
467 /* Accept the client */
468 accept_sock = test_accept(server_sock, &accept_addr, &accept_addrlen);
469
470 /* Close the server socket */
471 zsock_close(server_sock);
472
473 /* Close the accepted socket */
474 zsock_close(accept_sock);
475
476 /* Wait a short time for the accept socket to enter TIME_WAIT state*/
477 k_msleep(50);
478
479 /* Recreate the server socket */
480 prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock, &bind_addr);
481
482 /* Bind the server socket, should fail */
483 test_bind_fail(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
484
485 /* Enable SO_REUSEADDR option for the new server socket */
486 test_enable_reuseaddr(server_sock);
487
488 /* Try to bind the new server socket again, should work now */
489 test_bind_success(server_sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
490
491 zsock_close(client_sock);
492 zsock_close(server_sock);
493
494 /* Connection is in TIME_WAIT state, context will be released
495 * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it.
496 */
497 k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY));
498 }
499
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_tcp_time_wait_unspecified)500 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_unspecified)
501 {
502 test_reuseaddr_tcp_tcp_time_wait_common(AF_INET,
503 TEST_IPV4_ANY_ADDR,
504 TEST_MY_IPV4_ADDR);
505 }
506
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_tcp_time_wait_unspecified)507 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_time_wait_unspecified)
508 {
509 test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6,
510 TEST_IPV6_ANY_ADDR,
511 TEST_MY_IPV6_ADDR);
512 }
513
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv4_tcp_time_wait_specified)514 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv4_tcp_time_wait_specified)
515 {
516 test_reuseaddr_tcp_tcp_time_wait_common(AF_INET,
517 TEST_MY_IPV4_ADDR,
518 TEST_MY_IPV4_ADDR);
519 }
520
ZTEST_USER(socket_reuseaddr_test_suite,test_ipv6_tcp_time_wait_specified)521 ZTEST_USER(socket_reuseaddr_test_suite, test_ipv6_tcp_time_wait_specified)
522 {
523 test_reuseaddr_tcp_tcp_time_wait_common(AF_INET6,
524 TEST_MY_IPV6_ADDR,
525 TEST_MY_IPV6_ADDR);
526 }
527
528
529 ZTEST_SUITE(socket_reuseaddr_test_suite, NULL, setup, NULL, NULL, NULL);
530
531
ZTEST_USER(socket_reuseport_test_suite,test_enable_disable)532 ZTEST_USER(socket_reuseport_test_suite, test_enable_disable)
533 {
534 int server_sock = -1;
535
536 int value = -1;
537 socklen_t value_size = sizeof(int);
538
539 server_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
540 zassert_true(server_sock >= 0, "socket open failed");
541
542 /* Read initial value */
543 test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
544 zassert_equal(value_size, sizeof(int), "incorrect value size returned by getsocketopt()");
545 zassert_equal(value, (int) false, "SO_REUSEPORT incorrectly set (expected false)");
546
547 /* Enable option */
548 value = 1;
549 test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
550 test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
551 zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);
552
553 /* Enable option (with other value as linux takes any int here) */
554 value = 2;
555 test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
556 test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
557 zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);
558
559 /* Enable option (with other value as linux takes any int here) */
560 value = 0x100;
561 test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
562 test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
563 zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);
564
565 /* Enable option (with other value as linux takes any int here) */
566 value = -1;
567 test_setsocketopt_reuseport(server_sock, (void *)&value, sizeof(value));
568 test_getsocketopt_reuseport(server_sock, (void *)&value, &value_size);
569 zassert_equal(value, (int) true, "SO_REUSEPORT not correctly set, returned %d", value);
570
571 zsock_close(server_sock);
572 }
573
574
test_reuseport_unspecified_specified_common(sa_family_t family,char const * first_ip,char const * second_ip,bool should_succeed)575 static void test_reuseport_unspecified_specified_common(sa_family_t family,
576 char const *first_ip,
577 char const *second_ip,
578 bool should_succeed)
579 {
580 int server_sock1 = -1;
581 int server_sock2 = -1;
582
583 struct sockaddr bind_addr1;
584 struct sockaddr bind_addr2;
585
586 /* Create the sockets */
587 prepare_sock_tcp(family, first_ip, LOCAL_PORT, &server_sock1, &bind_addr1);
588 prepare_sock_tcp(family, second_ip, LOCAL_PORT, &server_sock2, &bind_addr2);
589
590 /* Depending on the expected result, we enable SO_REUSEPORT for the first socket */
591 if (should_succeed) {
592 test_enable_reuseport(server_sock1);
593 }
594
595 /* Bind the first socket */
596 test_bind_success(server_sock1, &bind_addr1, sizeof(bind_addr1));
597
598 /* Try to bind the second socket, should fail */
599 test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));
600
601 /* Enable SO_REUSEPORT option for the second socket */
602 test_enable_reuseport(server_sock2);
603
604 /* Try to bind the second socket again */
605 if (should_succeed) {
606 test_bind_success(server_sock2, &bind_addr2, sizeof(bind_addr2));
607 } else {
608 test_bind_fail(server_sock2, &bind_addr2, sizeof(bind_addr2));
609 }
610
611 zsock_close(server_sock1);
612 zsock_close(server_sock2);
613 }
614
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_both_unspecified_bad)615 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_bad)
616 {
617 test_reuseport_unspecified_specified_common(AF_INET,
618 TEST_IPV4_ANY_ADDR,
619 TEST_IPV4_ANY_ADDR,
620 SHOULD_FAIL);
621 }
622
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_both_unspecified_bad)623 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_unspecified_bad)
624 {
625 test_reuseport_unspecified_specified_common(AF_INET6,
626 TEST_IPV6_ANY_ADDR,
627 TEST_IPV6_ANY_ADDR,
628 SHOULD_FAIL);
629 }
630
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_both_unspecified_good)631 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_unspecified_good)
632 {
633 test_reuseport_unspecified_specified_common(AF_INET,
634 TEST_IPV4_ANY_ADDR,
635 TEST_IPV4_ANY_ADDR,
636 SHOULD_SUCCEED);
637 }
638
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_both_unspecified_good)639 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_unspecified_good)
640 {
641 test_reuseport_unspecified_specified_common(AF_INET6,
642 TEST_IPV6_ANY_ADDR,
643 TEST_IPV6_ANY_ADDR,
644 SHOULD_SUCCEED);
645 }
646
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_both_specified_bad)647 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_specified_bad)
648 {
649 test_reuseport_unspecified_specified_common(AF_INET,
650 TEST_MY_IPV4_ADDR,
651 TEST_MY_IPV4_ADDR,
652 SHOULD_FAIL);
653 }
654
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_both_specified_bad)655 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_specified_bad)
656 {
657 test_reuseport_unspecified_specified_common(AF_INET6,
658 TEST_MY_IPV6_ADDR,
659 TEST_MY_IPV6_ADDR,
660 SHOULD_FAIL);
661 }
662
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_both_specified_good)663 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_both_specified_good)
664 {
665 test_reuseport_unspecified_specified_common(AF_INET,
666 TEST_MY_IPV4_ADDR,
667 TEST_MY_IPV4_ADDR,
668 SHOULD_SUCCEED);
669 }
670
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_both_specified_good)671 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_both_specified_good)
672 {
673 test_reuseport_unspecified_specified_common(AF_INET6,
674 TEST_MY_IPV6_ADDR,
675 TEST_MY_IPV6_ADDR,
676 SHOULD_SUCCEED);
677 }
678
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_first_unspecified_bad)679 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_first_unspecified_bad)
680 {
681 test_reuseport_unspecified_specified_common(AF_INET,
682 TEST_IPV4_ANY_ADDR,
683 TEST_MY_IPV4_ADDR,
684 SHOULD_FAIL);
685 }
686
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_first_unspecified_bad)687 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_first_unspecified_bad)
688 {
689 test_reuseport_unspecified_specified_common(AF_INET6,
690 TEST_IPV6_ANY_ADDR,
691 TEST_MY_IPV6_ADDR,
692 SHOULD_FAIL);
693 }
694
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_first_unspecified_good)695 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_first_unspecified_good)
696 {
697 test_reuseport_unspecified_specified_common(AF_INET,
698 TEST_IPV4_ANY_ADDR,
699 TEST_MY_IPV4_ADDR,
700 SHOULD_SUCCEED);
701 }
702
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_first_unspecified_good)703 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_first_unspecified_good)
704 {
705 test_reuseport_unspecified_specified_common(AF_INET6,
706 TEST_IPV6_ANY_ADDR,
707 TEST_MY_IPV6_ADDR,
708 SHOULD_SUCCEED);
709 }
710
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_second_unspecified_bad)711 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_second_unspecified_bad)
712 {
713 test_reuseport_unspecified_specified_common(AF_INET,
714 TEST_MY_IPV4_ADDR,
715 TEST_IPV4_ANY_ADDR,
716 SHOULD_FAIL);
717 }
718
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_second_unspecified_bad)719 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_second_unspecified_bad)
720 {
721 test_reuseport_unspecified_specified_common(AF_INET6,
722 TEST_MY_IPV6_ADDR,
723 TEST_IPV6_ANY_ADDR,
724 SHOULD_FAIL);
725 }
726
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_second_unspecified_good)727 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_second_unspecified_good)
728 {
729 test_reuseport_unspecified_specified_common(AF_INET,
730 TEST_MY_IPV4_ADDR,
731 TEST_IPV4_ANY_ADDR,
732 SHOULD_SUCCEED);
733 }
734
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_second_unspecified_good)735 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_second_unspecified_good)
736 {
737 test_reuseport_unspecified_specified_common(AF_INET6,
738 TEST_MY_IPV6_ADDR,
739 TEST_IPV6_ANY_ADDR,
740 SHOULD_SUCCEED);
741 }
742
743
744 enum sockets_reuseport_enabled {
745 NONE_SET = 0,
746 FIRST_SET,
747 SECOND_SET,
748 BOTH_SET
749 };
750
test_reuseport_udp_server_client_common(sa_family_t family,char const * ip,enum sockets_reuseport_enabled setup)751 static void test_reuseport_udp_server_client_common(sa_family_t family,
752 char const *ip,
753 enum sockets_reuseport_enabled setup)
754 {
755 int server_sock = -1;
756 int client_sock = -1;
757 int accept_sock = 1;
758
759 struct sockaddr server_addr;
760 struct sockaddr client_addr;
761
762 struct sockaddr accept_addr;
763 socklen_t accept_addr_len = sizeof(accept_addr);
764
765 char tx_buf = 0x55;
766 char rx_buf;
767
768 /* Create sockets */
769 prepare_sock_udp(family, ip, LOCAL_PORT, &server_sock, &server_addr);
770 prepare_sock_udp(family, ip, 0, &client_sock, &client_addr);
771
772 /* Make sure we can bind to the address:port */
773 if (setup == FIRST_SET || setup == BOTH_SET) {
774 test_enable_reuseport(server_sock);
775 }
776
777 /* Bind server socket */
778 test_bind_success(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
779
780 /* Bind client socket (on a random port) */
781 test_bind_success(client_sock, (struct sockaddr *) &client_addr, sizeof(client_addr));
782
783 /* Send message from client to server */
784 test_sendto(client_sock, &tx_buf, sizeof(tx_buf), 0, &server_addr, sizeof(server_addr));
785
786 /* Give the packet a chance to go through the net stack */
787 k_msleep(50);
788
789 /* Receive data from the client */
790 rx_buf = 0;
791 test_recvfrom_success(server_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT,
792 &accept_addr, &accept_addr_len);
793 zassert_equal(rx_buf, tx_buf, "wrong data");
794
795 /* Create a more specific socket to have a direct connection to the new client */
796 accept_sock = zsock_socket(family, SOCK_DGRAM, IPPROTO_UDP);
797 zassert_true(accept_sock >= 0, "socket open failed");
798
799 /* Make sure we can bind to the address:port */
800 if (setup == SECOND_SET || setup == BOTH_SET) {
801 test_enable_reuseport(accept_sock);
802 }
803
804 /* Try to bind new client socket */
805 if (setup == BOTH_SET) {
806 /* Should succeed */
807 test_bind_success(accept_sock, (struct sockaddr *) &server_addr,
808 sizeof(server_addr));
809 } else {
810 /* Should fail */
811 test_bind_fail(accept_sock, (struct sockaddr *) &server_addr,
812 sizeof(server_addr));
813 }
814
815 /* Connect the client to set remote address and remote port */
816 test_connect_success(accept_sock, &accept_addr, sizeof(accept_addr));
817
818 /* Send another message from client to server */
819 test_sendto(client_sock, &tx_buf, sizeof(tx_buf), 0, &server_addr, sizeof(server_addr));
820
821 /* Give the packet a chance to go through the net stack */
822 k_msleep(50);
823
824 /* Receive the data */
825 if (setup == BOTH_SET) {
826 /* We should receive data on the new specific socket, not on the general one */
827 rx_buf = 0;
828 test_recvfrom_fail(server_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT,
829 &accept_addr, &accept_addr_len);
830
831 rx_buf = 0;
832 test_recv_success(accept_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT);
833 } else {
834 /* We should receive data on the general server socket */
835 rx_buf = 0;
836 test_recvfrom_success(server_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT,
837 &accept_addr, &accept_addr_len);
838
839 rx_buf = 0;
840 test_recv_fail(accept_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT);
841 }
842
843 zsock_close(accept_sock);
844 zsock_close(client_sock);
845 zsock_close(server_sock);
846 }
847
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_udp_bad_both_not_set)848 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_both_not_set)
849 {
850 test_reuseport_udp_server_client_common(AF_INET,
851 TEST_MY_IPV4_ADDR,
852 NONE_SET);
853 }
854
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_udp_bad_both_not_set)855 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_both_not_set)
856 {
857 test_reuseport_udp_server_client_common(AF_INET6,
858 TEST_MY_IPV6_ADDR,
859 NONE_SET);
860 }
861
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_udp_bad_first_not_set)862 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_first_not_set)
863 {
864 test_reuseport_udp_server_client_common(AF_INET,
865 TEST_MY_IPV4_ADDR,
866 SECOND_SET);
867 }
868
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_udp_bad_first_not_set)869 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_first_not_set)
870 {
871 test_reuseport_udp_server_client_common(AF_INET6,
872 TEST_MY_IPV6_ADDR,
873 SECOND_SET);
874 }
875
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_udp_bad_second_not_set)876 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_bad_second_not_set)
877 {
878 test_reuseport_udp_server_client_common(AF_INET,
879 TEST_MY_IPV4_ADDR,
880 FIRST_SET);
881 }
882
883
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_udp_bad_second_not_set)884 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_bad_second_not_set)
885 {
886 test_reuseport_udp_server_client_common(AF_INET6,
887 TEST_MY_IPV6_ADDR,
888 FIRST_SET);
889 }
890
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_udp_good)891 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_udp_good)
892 {
893 test_reuseport_udp_server_client_common(AF_INET,
894 TEST_MY_IPV4_ADDR,
895 BOTH_SET);
896 }
897
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_udp_good)898 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_udp_good)
899 {
900 test_reuseport_udp_server_client_common(AF_INET6,
901 TEST_MY_IPV6_ADDR,
902 BOTH_SET);
903 }
904
905
test_reuseport_tcp_identical_clients_common(sa_family_t family,char const * server_ip,char const * client_ip)906 static void test_reuseport_tcp_identical_clients_common(sa_family_t family,
907 char const *server_ip,
908 char const *client_ip)
909 {
910 int server_sock = -1;
911 int client_sock1 = -1;
912 int client_sock2 = -1;
913 int accept_sock = 1;
914
915 struct sockaddr server_addr;
916 struct sockaddr client_addr;
917 struct sockaddr connect_addr;
918
919 struct sockaddr accept_addr;
920 socklen_t accept_addr_len = sizeof(accept_addr);
921
922 /* Create sockets */
923 prepare_sock_tcp(family, server_ip, LOCAL_PORT, &server_sock, &server_addr);
924 prepare_sock_tcp(family, client_ip, LOCAL_PORT + 1, &client_sock1, &client_addr);
925 prepare_sock_tcp(family, client_ip, LOCAL_PORT, &client_sock2, &connect_addr);
926
927 /* Enable SO_REUSEPORT option for the two sockets */
928 test_enable_reuseport(client_sock1);
929 test_enable_reuseport(client_sock2);
930
931 /* Bind server socket */
932 test_bind_success(server_sock, &server_addr, sizeof(server_addr));
933
934 /* Start listening on the server socket */
935 test_listen(server_sock);
936
937 /* Bind the client sockets */
938 test_bind_success(client_sock1, &client_addr, sizeof(client_addr));
939 test_bind_success(client_sock2, &client_addr, sizeof(client_addr));
940
941 /* Connect the first client */
942 test_connect_success(client_sock1, &connect_addr, sizeof(connect_addr));
943
944 /* Accept the first client */
945 accept_sock = test_accept(server_sock, &accept_addr, &accept_addr_len);
946
947 /* Connect the second client, should fail */
948 test_connect_fail(client_sock2, (struct sockaddr *)&connect_addr, sizeof(connect_addr));
949
950 zsock_close(accept_sock);
951 zsock_close(client_sock1);
952 zsock_close(client_sock2);
953 zsock_close(server_sock);
954
955 /* Connection is in TIME_WAIT state, context will be released
956 * after K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY), so wait for it.
957 */
958 k_sleep(K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY));
959 }
960
ZTEST_USER(socket_reuseport_test_suite,test_ipv4_tcp_identical_clients)961 ZTEST_USER(socket_reuseport_test_suite, test_ipv4_tcp_identical_clients)
962 {
963 test_reuseport_tcp_identical_clients_common(AF_INET,
964 TEST_IPV4_ANY_ADDR,
965 TEST_MY_IPV4_ADDR);
966 }
967
968
ZTEST_USER(socket_reuseport_test_suite,test_ipv6_tcp_identical_clients)969 ZTEST_USER(socket_reuseport_test_suite, test_ipv6_tcp_identical_clients)
970 {
971 test_reuseport_tcp_identical_clients_common(AF_INET6,
972 TEST_IPV6_ANY_ADDR,
973 TEST_MY_IPV6_ADDR);
974 }
975
976 ZTEST_SUITE(socket_reuseport_test_suite, NULL, setup, NULL, NULL, NULL);
977