1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
3 #include <darwintest.h>
5 #include <sys/socket.h>
7 #include <netinet/in.h>
16 s
= socket(AF_INET6
, SOCK_DGRAM
, 0);
18 T_ASSERT_POSIX_SUCCESS(s
, "socket(AF_INET6, SOCK_DGRAM, 0)");
23 sockv6_bind(int s
, in_port_t port
)
25 struct sockaddr_in6 sin6
;
27 bzero(&sin6
, sizeof(sin6
));
28 sin6
.sin6_len
= sizeof(sin6
);
29 sin6
.sin6_family
= AF_INET6
;
30 sin6
.sin6_port
= port
;
31 return bind(s
, (const struct sockaddr
*)&sin6
, sizeof(sin6
));
35 sockv6_set_v6only(int s
)
40 ret
= setsockopt(s
, IPPROTO_IPV6
, IPV6_V6ONLY
, &on
, sizeof(on
));
42 T_ASSERT_POSIX_SUCCESS(ret
, "setsockopt(%d, IPV6_ONLY)", s
);
46 alloc_and_bind_ports(in_port_t port_start
, in_port_t port_end
,
52 for (in_port_t i
= port_start
; success
&& i
<= port_end
; i
++) {
58 sockv6_set_v6only(s6
);
59 if (sockv6_bind(s6
, i
) != 0) {
60 /* find the next available port */
63 s6_other
= sockv6_open();
64 ret
= sockv6_bind(s6_other
, i
);
67 T_ASSERT_TRUE(ret
!= 0, "socket %d bind %d", s6_other
, i
);
69 * After bind fails, try binding to a different port.
70 * For non-root user, this will panic without the fix for
71 * <rdar://problem/35243417>.
73 if (sockv6_bind(s6_other
, i
+ 1) == 0) {
75 if (bound_count
>= bind_attempts
) {
87 T_ASSERT_TRUE(bound_count
== bind_attempts
,
88 "number of successful binds %d (out of %d)",
89 bound_count
, bind_attempts
);
94 T_DECL(socket_bind_35243417
,
95 "bind IPv6 only UDP socket, then bind IPv6 socket.",
97 T_META_CHECK_LEAKS(false))
99 alloc_and_bind_ports(1, 65534, 10);
102 T_DECL(socket_bind_35243417_root
,
103 "bind IPv6 only UDP socket, then bind IPv6 socket.",
106 alloc_and_bind_ports(1, 65534, 10);