1 /*
2 * Copyright (c) 2023-2024 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <sys/fcntl.h>
30 #include <sys/socket.h>
31 #include <net/if.h>
32 #include <netinet/in.h>
33 #include <netinet/tcp.h>
34 #include <arpa/inet.h>
35
36 #include <darwintest.h>
37 #include <pthread.h>
38 #include <stdbool.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 /*
43 * The test is disabled on platforms that could be limited in term of CPU
44 * or memory because this stress test that cycles rapidly through a lot of socket
45 */
46 T_GLOBAL_META(
47 T_META_NAMESPACE("xnu.net"),
48 T_META_RADAR_COMPONENT_NAME("xnu"),
49 T_META_RADAR_COMPONENT_VERSION("networking"),
50 T_META_CHECK_LEAKS(false),
51 T_META_ENABLED(TARGET_OS_OSX || TARGET_OS_IPHONE));
52
53 #define SECONDS_TO_SLEEP 3
54
55 static int fd = -1;
56 static bool finished = false;
57 static bool is_tcp = false;
58
59 static void
init_sin6_address(struct sockaddr_in6 * sin6)60 init_sin6_address(struct sockaddr_in6 *sin6)
61 {
62 memset(sin6, 0, sizeof(struct sockaddr_in6));
63 sin6->sin6_len = sizeof(struct sockaddr_in6);
64 sin6->sin6_family = AF_INET6;
65 }
66
67 static void
setnonblocking(int s)68 setnonblocking(int s)
69 {
70 int flags;
71
72 T_QUIET; T_EXPECT_POSIX_SUCCESS(flags = fcntl(s, F_GETFL, 0), NULL);
73
74 flags |= O_NONBLOCK;
75
76 T_QUIET; T_EXPECT_POSIX_SUCCESS(flags = fcntl(s, F_SETFL, flags), NULL);
77 }
78
79 static void *
bind4_racer(void * arg)80 bind4_racer(void *arg)
81 {
82 #pragma unused(arg)
83 struct sockaddr_in6 sin6 = { 0 };
84
85 init_sin6_address(&sin6);
86 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6.sin6_addr), 1, NULL);
87 sin6.sin6_port = htons(1234);
88
89 while (finished == false) {
90 (void)bind(fd, (struct sockaddr*)&sin6, sin6.sin6_len);
91 }
92 return NULL;
93 }
94
95 static void *
bind6_racer(void * arg)96 bind6_racer(void *arg)
97 {
98 #pragma unused(arg)
99 struct sockaddr_in6 sin6 = { 0 };
100
101 init_sin6_address(&sin6);
102 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
103 sin6.sin6_port = htons(1234);
104
105 while (finished == false) {
106 (void)bind(fd, (struct sockaddr*)&sin6, sin6.sin6_len);
107 }
108 return NULL;
109 }
110
111 static void *
connect6_racer(void * arg)112 connect6_racer(void *arg)
113 {
114 #pragma unused(arg)
115 struct sockaddr_in6 sin6 = { 0 };
116
117 init_sin6_address(&sin6);
118 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
119 sin6.sin6_port = htons(3456);
120
121 while (finished == false) {
122 (void)connect(fd, (struct sockaddr*)&sin6, sin6.sin6_len);
123 }
124 return NULL;
125 }
126
127 static void *
connect4_racer(void * arg)128 connect4_racer(void *arg)
129 {
130 #pragma unused(arg)
131 struct sockaddr_in6 sin6 = { 0 };
132
133 init_sin6_address(&sin6);
134 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6.sin6_addr), 1, NULL);
135 sin6.sin6_port = htons(3456);
136
137 while (finished == false) {
138 (void)connect(fd, (struct sockaddr*)&sin6, sin6.sin6_len);
139 }
140 return NULL;
141 }
142
143 static void *
bind6_leader(void * arg)144 bind6_leader(void *arg)
145 {
146 #pragma unused(arg)
147 struct sockaddr_in6 sin6 = { 0 };
148
149 init_sin6_address(&sin6);
150 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
151
152 while (finished == false) {
153 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
154
155 setnonblocking(fd);
156
157 (void)bind(fd, (struct sockaddr*)&sin6, sin6.sin6_len);
158
159 close(fd);
160 }
161 return NULL;
162 }
163
164 static void *
bind4_leader(void * arg)165 bind4_leader(void *arg)
166 {
167 #pragma unused(arg)
168 struct sockaddr_in6 sin6 = { 0 };
169
170 init_sin6_address(&sin6);
171 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6.sin6_addr), 1, NULL);
172
173 while (finished == false) {
174 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
175
176 setnonblocking(fd);
177
178 (void)bind(fd, (struct sockaddr*)&sin6, sin6.sin6_len);
179
180 close(fd);
181 }
182 return NULL;
183 }
184
185 static void *
send6_racer(void * arg)186 send6_racer(void *arg)
187 {
188 #pragma unused(arg)
189 struct sockaddr_in6 sin6 = { 0 };
190
191 init_sin6_address(&sin6);
192 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
193 sin6.sin6_port = htons(3456);
194
195 while (finished == false) {
196 (void)sendto(fd, "", 1, 0, (struct sockaddr*)&sin6, sin6.sin6_len);
197 }
198 return NULL;
199 }
200
201 static void *
send4_racer(void * arg)202 send4_racer(void *arg)
203 {
204 #pragma unused(arg)
205 struct sockaddr_in6 sin6 = { 0 };
206
207 init_sin6_address(&sin6);
208 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6.sin6_addr), 1, NULL);
209 sin6.sin6_port = htons(3456);
210
211 while (finished == false) {
212 (void)sendto(fd, "", 1, 0, (struct sockaddr*)&sin6, sin6.sin6_len);
213 }
214 return NULL;
215 }
216
217 static void *
send6_leader(void * arg)218 send6_leader(void *arg)
219 {
220 #pragma unused(arg)
221 struct sockaddr_in6 sin6 = { 0 };
222
223 init_sin6_address(&sin6);
224 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6.sin6_addr), 1, NULL);
225 sin6.sin6_port = htons(3456);
226
227 while (finished == false) {
228 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
229
230 setnonblocking(fd);
231
232 (void)sendto(fd, "", 1, 0, (struct sockaddr*)&sin6, sin6.sin6_len);
233
234 close(fd);
235 }
236 return NULL;
237 }
238
239 static void *
connectx6_leader(void * arg)240 connectx6_leader(void *arg)
241 {
242 #pragma unused(arg)
243 struct sockaddr_in6 sin6_dst = { 0 };
244 sa_endpoints_t sae = { 0 };
245
246 init_sin6_address(&sin6_dst);
247 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6_dst.sin6_addr), 1, NULL);
248 sin6_dst.sin6_port = htons(3456);
249 sae.sae_dstaddr = (struct sockaddr *)&sin6_dst;
250 sae.sae_dstaddrlen = sin6_dst.sin6_len;
251
252 while (finished == false) {
253 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
254
255 setnonblocking(fd);
256
257 (void)connectx(fd, &sae, SAE_ASSOCID_ANY, 0, NULL, 0, 0, NULL);
258
259 close(fd);
260 }
261 return NULL;
262 }
263
264 static void *
connectx4_leader(void * arg)265 connectx4_leader(void *arg)
266 {
267 #pragma unused(arg)
268 struct sockaddr_in6 sin6_dst = { 0 };
269 sa_endpoints_t sae = { 0 };
270
271 init_sin6_address(&sin6_dst);
272 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_dst.sin6_addr), 1, NULL);
273 sin6_dst.sin6_port = htons(3456);
274 sae.sae_dstaddr = (struct sockaddr *)&sin6_dst;
275 sae.sae_dstaddrlen = sin6_dst.sin6_len;
276
277 while (finished == false) {
278 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
279
280 setnonblocking(fd);
281
282 (void)connectx(fd, &sae, SAE_ASSOCID_ANY, 0, NULL, 0, 0, NULL);
283
284 close(fd);
285 }
286 return NULL;
287 }
288
289 static void *
connectx6_binding_leader(void * arg)290 connectx6_binding_leader(void *arg)
291 {
292 #pragma unused(arg)
293 struct sockaddr_in6 sin6_src = { 0 };
294 struct sockaddr_in6 sin6_dst = { 0 };
295 sa_endpoints_t sae = { 0 };
296
297 init_sin6_address(&sin6_src);
298 sin6_src.sin6_port = htons(1234);
299 sae.sae_srcaddr = (struct sockaddr *)&sin6_src;
300 sae.sae_srcaddrlen = sin6_src.sin6_len;
301
302 init_sin6_address(&sin6_dst);
303 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6_dst.sin6_addr), 1, NULL);
304 sin6_dst.sin6_port = htons(3456);
305 sae.sae_dstaddr = (struct sockaddr *)&sin6_dst;
306 sae.sae_dstaddrlen = sin6_dst.sin6_len;
307
308 while (finished == false) {
309 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
310
311 setnonblocking(fd);
312
313 (void)connectx(fd, &sae, SAE_ASSOCID_ANY, 0, NULL, 0, 0, NULL);
314
315 close(fd);
316 }
317 return NULL;
318 }
319
320 static void *
connectx4_binding_leader(void * arg)321 connectx4_binding_leader(void *arg)
322 {
323 #pragma unused(arg)
324 struct sockaddr_in6 sin6_src = { 0 };
325 struct sockaddr_in6 sin6_dst = { 0 };
326 sa_endpoints_t sae = { 0 };
327
328 init_sin6_address(&sin6_src);
329 sin6_src.sin6_port = htons(1234);
330 sae.sae_srcaddr = (struct sockaddr *)&sin6_src;
331 sae.sae_srcaddrlen = sin6_src.sin6_len;
332
333 init_sin6_address(&sin6_dst);
334 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_dst.sin6_addr), 1, NULL);
335 sin6_dst.sin6_port = htons(3456);
336 sae.sae_dstaddr = (struct sockaddr *)&sin6_dst;
337 sae.sae_dstaddrlen = sin6_dst.sin6_len;
338
339 while (finished == false) {
340 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
341
342 setnonblocking(fd);
343
344 (void)connectx(fd, &sae, SAE_ASSOCID_ANY, 0, NULL, 0, 0, NULL);
345
346 close(fd);
347 }
348 return NULL;
349 }
350
351 static void *
connectx6_racer(void * arg)352 connectx6_racer(void *arg)
353 {
354 #pragma unused(arg)
355 struct sockaddr_in6 sin6_dst = { 0 };
356 sa_endpoints_t sae = { 0 };
357
358 init_sin6_address(&sin6_dst);
359 T_ASSERT_EQ(inet_pton(AF_INET6, "::1", &sin6_dst.sin6_addr), 1, NULL);
360 sin6_dst.sin6_port = htons(3456);
361 sae.sae_dstaddr = (struct sockaddr *)&sin6_dst;
362 sae.sae_dstaddrlen = sin6_dst.sin6_len;
363
364 while (finished == false) {
365 (void)connectx(fd, &sae, SAE_ASSOCID_ANY, 0, NULL, 0, 0, NULL);
366 }
367 return NULL;
368 }
369
370 static void *
connectx4_racer(void * arg)371 connectx4_racer(void *arg)
372 {
373 #pragma unused(arg)
374 struct sockaddr_in6 sin6_dst = { 0 };
375 sa_endpoints_t sae = { 0 };
376
377 init_sin6_address(&sin6_dst);
378 T_ASSERT_EQ(inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_dst.sin6_addr), 1, NULL);
379 sin6_dst.sin6_port = htons(3456);
380 sae.sae_dstaddr = (struct sockaddr *)&sin6_dst;
381 sae.sae_dstaddrlen = sin6_dst.sin6_len;
382
383 while (finished == false) {
384 (void)connectx(fd, &sae, SAE_ASSOCID_ANY, 0, NULL, 0, 0, NULL);
385 }
386 return NULL;
387 }
388
389 static void *
listen6_leader(void * arg)390 listen6_leader(void *arg)
391 {
392 #pragma unused(arg)
393
394 while (finished == false) {
395 int val = 1;
396
397 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
398
399 setnonblocking(fd);
400
401 /* Note: The following may fail of an IPv4 racer has won the bind race */
402 (void)setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
403
404 (void)listen(fd, 5);
405
406 close(fd);
407 }
408 return NULL;
409 }
410
411 static void *
listen4_leader(void * arg)412 listen4_leader(void *arg)
413 {
414 #pragma unused(arg)
415
416 while (finished == false) {
417 int val = 0;
418
419 T_QUIET; T_EXPECT_POSIX_SUCCESS(fd = socket(AF_INET6, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0), "socket");
420
421 setnonblocking(fd);
422
423 /* Note: The following may fail of an IPv4 racer has won the bind race */
424 (void)setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
425
426 (void)listen(fd, 5);
427
428 close(fd);
429 }
430 return NULL;
431 }
432
433 static void
do_bind_race(bool do_test_tcp,void * (* leader)(void *),void * (* racer)(void *))434 do_bind_race(bool do_test_tcp, void *(*leader)(void *), void *(*racer)(void *))
435 {
436 pthread_t runner1;
437 pthread_t runner2;
438
439 is_tcp = do_test_tcp;
440
441 if (pthread_create(&runner1, NULL, leader, NULL)) {
442 T_ASSERT_FAIL("pthread_create failed");
443 }
444
445 if (pthread_create(&runner2, NULL, racer, NULL)) {
446 T_ASSERT_FAIL("pthread_create failed");
447 }
448
449 sleep(SECONDS_TO_SLEEP);
450
451 finished = true;
452
453 pthread_join(runner1, 0);
454 pthread_join(runner2, 0);
455 }
456
457 T_DECL(ipv6_tcp_bind6_bind4_race, "race bind calls with TCP sockets")
458 {
459 do_bind_race(true, bind6_leader, bind4_racer);
460 }
461
462 T_DECL(ipv6_tcp_bind6_connect4_race, "race bind calls with TCP sockets")
463 {
464 do_bind_race(true, bind6_leader, connect4_racer);
465 }
466
467 T_DECL(ipv6_tcp_bind4_connect6_race, "race bind calls with TCP sockets")
468 {
469 do_bind_race(true, bind4_leader, connect6_racer);
470 }
471
472 T_DECL(ipv6_tcp_bind6_send4_race, "race bind calls with TCP sockets")
473 {
474 do_bind_race(true, bind6_leader, send4_racer);
475 }
476
477 T_DECL(ipv6_tcp_bind4_send6_race, "race bind calls with TCP sockets")
478 {
479 do_bind_race(true, bind4_leader, send6_racer);
480 }
481
482 T_DECL(ipv6_tcp_send6_send4_race, "race bind calls with TCP sockets")
483 {
484 do_bind_race(true, send6_leader, send4_racer);
485 }
486
487 T_DECL(ipv6_tcp_bind6_connectx4_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
488 {
489 do_bind_race(true, bind6_leader, connectx4_racer);
490 }
491
492 T_DECL(ipv6_tcp_bind4_connectx6_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
493 {
494 do_bind_race(true, bind4_leader, connectx6_racer);
495 }
496
497 T_DECL(ipv6_tcp_connectx4_bind6_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
498 {
499 do_bind_race(true, connectx4_leader, bind6_racer);
500 }
501
502 T_DECL(ipv6_tcp_connectx6_bind4_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
503 {
504 do_bind_race(true, connectx6_leader, bind4_racer);
505 }
506
507 T_DECL(ipv6_tcp_connectx4_connect6_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
508 {
509 do_bind_race(true, connectx4_leader, connect6_racer);
510 }
511
512 T_DECL(ipv6_tcp_connectx6_connect4_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
513 {
514 do_bind_race(true, connectx6_leader, connect4_racer);
515 }
516
517 T_DECL(ipv6_tcp_connectx4_binding_bind6_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
518 {
519 do_bind_race(true, connectx4_binding_leader, bind6_racer);
520 }
521
522 T_DECL(ipv6_tcp_connectx6_binding_bind4_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
523 {
524 do_bind_race(true, connectx6_binding_leader, bind4_racer);
525 }
526
527 T_DECL(ipv6_tcp_connectx4_binding_connect6_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
528 {
529 do_bind_race(true, connectx4_binding_leader, connect6_racer);
530 }
531
532 T_DECL(ipv6_tcp_connectx6_binding_connect4_race, "race bind calls with TCP sockets", T_META_ENABLED(false))
533 {
534 do_bind_race(true, connectx6_binding_leader, connect4_racer);
535 }
536
537 T_DECL(ipv6_tcp_listen6_bind4_race, "race bind calls with TCP sockets")
538 {
539 do_bind_race(true, listen6_leader, bind4_racer);
540 }
541
542 T_DECL(ipv6_tcp_listen4_bind6_race, "race bind calls with TCP sockets")
543 {
544 do_bind_race(true, listen4_leader, bind6_racer);
545 }
546
547
548 T_DECL(ipv6_udp_bind6_bind4_race, "race bind calls with UDP sockets")
549 {
550 do_bind_race(false, bind6_leader, bind4_racer);
551 }
552
553 T_DECL(ipv6_udp_bind6_connect4_race, "race bind calls with UDP sockets")
554 {
555 do_bind_race(false, bind6_leader, connect4_racer);
556 }
557
558 T_DECL(ipv6_udp_bind4_connect6_race, "race bind calls with UDP sockets")
559 {
560 do_bind_race(false, bind4_leader, connect6_racer);
561 }
562
563 T_DECL(ipv6_udp_bind6_send4_race, "race bind calls with UDP sockets")
564 {
565 do_bind_race(false, bind6_leader, send4_racer);
566 }
567
568 T_DECL(ipv6_udp_bind4_send6_race, "race bind calls with UDP sockets")
569 {
570 do_bind_race(false, bind4_leader, send6_racer);
571 }
572
573 T_DECL(ipv6_udp_send6_send4_race, "race bind calls with UDP sockets")
574 {
575 do_bind_race(false, send6_leader, send4_racer);
576 }
577
578 T_DECL(ipv6_udp_bind6_connectx4_race, "race bind calls with UDP sockets", T_META_ENABLED(false))
579 {
580 do_bind_race(false, bind6_leader, connectx4_racer);
581 }
582
583 T_DECL(ipv6_udp_bind4_connectx6_race, "race bind calls with UDP sockets", T_META_ENABLED(false))
584 {
585 do_bind_race(false, bind4_leader, connectx6_racer);
586 }
587
588 T_DECL(ipv6_udp_connectx4_bind6_race, "race bind calls with UDP sockets", T_META_ENABLED(false))
589 {
590 do_bind_race(false, connectx4_leader, bind6_racer);
591 }
592
593 T_DECL(ipv6_udp_connectx6_bind4_race, "race bind calls with UDP sockets", T_META_ENABLED(false))
594 {
595 do_bind_race(false, connectx6_leader, bind4_racer);
596 }
597
598 T_DECL(ipv6_udp_connectx4_connect6_race, "race bind calls with UDP sockets", T_META_ENABLED(false))
599 {
600 do_bind_race(false, connectx4_leader, connect6_racer);
601 }
602
603 T_DECL(ipv6_udp_connectx6_connect4_race, "race bind calls with UDP sockets", T_META_ENABLED(false))
604 {
605 do_bind_race(false, connectx6_leader, connect4_racer);
606 }
607