xref: /xnu-12377.1.9/tests/vsock.c (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1*f6217f89SApple OSS Distributions /*
2*f6217f89SApple OSS Distributions  * Copyright (c) 2020 Apple Inc. All rights reserved.
3*f6217f89SApple OSS Distributions  *
4*f6217f89SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*f6217f89SApple OSS Distributions  *
6*f6217f89SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*f6217f89SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*f6217f89SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*f6217f89SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*f6217f89SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*f6217f89SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*f6217f89SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*f6217f89SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*f6217f89SApple OSS Distributions  *
15*f6217f89SApple OSS Distributions  * Please obtain a copy of the License at
16*f6217f89SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*f6217f89SApple OSS Distributions  *
18*f6217f89SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*f6217f89SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*f6217f89SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*f6217f89SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*f6217f89SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*f6217f89SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*f6217f89SApple OSS Distributions  * limitations under the License.
25*f6217f89SApple OSS Distributions  *
26*f6217f89SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*f6217f89SApple OSS Distributions  */
28*f6217f89SApple OSS Distributions 
29*f6217f89SApple OSS Distributions #include <vsock_helpers.h>
30*f6217f89SApple OSS Distributions 
31*f6217f89SApple OSS Distributions T_GLOBAL_META(
32*f6217f89SApple OSS Distributions 	T_META_RUN_CONCURRENTLY(true),
33*f6217f89SApple OSS Distributions 	T_META_NAMESPACE("xnu.vsock")
34*f6217f89SApple OSS Distributions 	);
35*f6217f89SApple OSS Distributions 
36*f6217f89SApple OSS Distributions /* New Socket */
37*f6217f89SApple OSS Distributions 
38*f6217f89SApple OSS Distributions T_DECL(new_socket_getsockname, "vsock new - getsockname")
39*f6217f89SApple OSS Distributions {
40*f6217f89SApple OSS Distributions 	int socket = vsock_new_socket();
41*f6217f89SApple OSS Distributions 
42*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
43*f6217f89SApple OSS Distributions 	socklen_t length = sizeof(struct sockaddr_vm);
44*f6217f89SApple OSS Distributions 	int result = getsockname(socket, (struct sockaddr *)&addr, &length);
45*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock getsockname");
46*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_INT(addr.svm_port, VMADDR_PORT_ANY, "name is any port");
47*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_INT(addr.svm_cid, VMADDR_CID_ANY, "name is any cid");
48*f6217f89SApple OSS Distributions }
49*f6217f89SApple OSS Distributions 
50*f6217f89SApple OSS Distributions T_DECL(new_socket_getpeername, "vsock new - getpeername")
51*f6217f89SApple OSS Distributions {
52*f6217f89SApple OSS Distributions 	int socket = vsock_new_socket();
53*f6217f89SApple OSS Distributions 
54*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
55*f6217f89SApple OSS Distributions 	socklen_t length = sizeof(struct sockaddr_vm);
56*f6217f89SApple OSS Distributions 	int result = getpeername(socket, (struct sockaddr *)&addr, &length);
57*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, ENOTCONN, "vsock getpeername");
58*f6217f89SApple OSS Distributions }
59*f6217f89SApple OSS Distributions 
60*f6217f89SApple OSS Distributions /* Ioctl */
61*f6217f89SApple OSS Distributions 
62*f6217f89SApple OSS Distributions T_DECL(ioctl_cid, "vsock ioctl cid")
63*f6217f89SApple OSS Distributions {
64*f6217f89SApple OSS Distributions 	int socket = vsock_new_socket();
65*f6217f89SApple OSS Distributions 	vsock_get_local_cid(socket);
66*f6217f89SApple OSS Distributions }
67*f6217f89SApple OSS Distributions 
68*f6217f89SApple OSS Distributions /* Socketpair */
69*f6217f89SApple OSS Distributions 
70*f6217f89SApple OSS Distributions T_DECL(socketpair, "vsock socketpair")
71*f6217f89SApple OSS Distributions {
72*f6217f89SApple OSS Distributions 	int pair[2];
73*f6217f89SApple OSS Distributions 	int error = socketpair(AF_VSOCK, SOCK_STREAM, 0, pair);
74*f6217f89SApple OSS Distributions 	if (error < 0 && errno == ENODEV) {
75*f6217f89SApple OSS Distributions 		T_SKIP("no vsock transport available");
76*f6217f89SApple OSS Distributions 	}
77*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(error, EOPNOTSUPP, "vsock socketpair not supported");
78*f6217f89SApple OSS Distributions }
79*f6217f89SApple OSS Distributions 
80*f6217f89SApple OSS Distributions /* Bind */
81*f6217f89SApple OSS Distributions 
82*f6217f89SApple OSS Distributions T_DECL(bind, "vsock bind to specific port")
83*f6217f89SApple OSS Distributions {
84*f6217f89SApple OSS Distributions 	int socket;
85*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
86*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
87*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_ANY, port, &addr, &socket);
88*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to specific port");
89*f6217f89SApple OSS Distributions }
90*f6217f89SApple OSS Distributions 
91*f6217f89SApple OSS Distributions T_DECL(bind_any, "vsock bind to any port")
92*f6217f89SApple OSS Distributions {
93*f6217f89SApple OSS Distributions 	int socket;
94*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
95*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_ANY, VMADDR_PORT_ANY, &addr, &socket);
96*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to any port");
97*f6217f89SApple OSS Distributions }
98*f6217f89SApple OSS Distributions 
99*f6217f89SApple OSS Distributions T_DECL(bind_getsockname, "vsock bind - getsockname")
100*f6217f89SApple OSS Distributions {
101*f6217f89SApple OSS Distributions 	int socket;
102*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
103*f6217f89SApple OSS Distributions 	const uint32_t port = VMADDR_PORT_ANY;
104*f6217f89SApple OSS Distributions 	const uint32_t cid = VMADDR_CID_ANY;
105*f6217f89SApple OSS Distributions 	int result = vsock_bind(cid, port, &addr, &socket);
106*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to any port");
107*f6217f89SApple OSS Distributions 
108*f6217f89SApple OSS Distributions 	struct sockaddr_vm bound_addr = vsock_getsockname(socket);
109*f6217f89SApple OSS Distributions 	T_ASSERT_NE_INT(bound_addr.svm_port, port, "bound to unique local port");
110*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_INT(bound_addr.svm_cid, cid, "bound to any cid");
111*f6217f89SApple OSS Distributions }
112*f6217f89SApple OSS Distributions 
113*f6217f89SApple OSS Distributions T_DECL(bind_hypervisor, "vsock do not bind to hypervisor cid")
114*f6217f89SApple OSS Distributions {
115*f6217f89SApple OSS Distributions 	int socket;
116*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
117*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_HYPERVISOR, VMADDR_PORT_ANY, &addr, &socket);
118*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EADDRNOTAVAIL, "vsock do not bind to hypervisor cid");
119*f6217f89SApple OSS Distributions }
120*f6217f89SApple OSS Distributions 
121*f6217f89SApple OSS Distributions T_DECL(bind_reserved, "vsock do not bind to reserved cid")
122*f6217f89SApple OSS Distributions {
123*f6217f89SApple OSS Distributions 	int socket;
124*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
125*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_RESERVED, VMADDR_PORT_ANY, &addr, &socket);
126*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EADDRNOTAVAIL, "vsock do not bind to reserved cid");
127*f6217f89SApple OSS Distributions }
128*f6217f89SApple OSS Distributions 
129*f6217f89SApple OSS Distributions T_DECL(bind_host, "vsock do not bind to host cid")
130*f6217f89SApple OSS Distributions {
131*f6217f89SApple OSS Distributions 	int socket;
132*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
133*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_HOST, VMADDR_PORT_ANY, &addr, &socket);
134*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EADDRNOTAVAIL, "vsock do not bind to host cid");
135*f6217f89SApple OSS Distributions }
136*f6217f89SApple OSS Distributions 
137*f6217f89SApple OSS Distributions T_DECL(bind_zero, "vsock bind to port zero", T_META_ASROOT(true))
138*f6217f89SApple OSS Distributions {
139*f6217f89SApple OSS Distributions 	const uint32_t port = 0;
140*f6217f89SApple OSS Distributions 
141*f6217f89SApple OSS Distributions 	int socket;
142*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
143*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_ANY, port, &addr, &socket);
144*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to port zero");
145*f6217f89SApple OSS Distributions 
146*f6217f89SApple OSS Distributions 	struct sockaddr_vm bound_addr;
147*f6217f89SApple OSS Distributions 	socklen_t length = sizeof(struct sockaddr_vm);
148*f6217f89SApple OSS Distributions 	result = getsockname(socket, (struct sockaddr *)&bound_addr, &length);
149*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock getsockname");
150*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_INT((int) sizeof(bound_addr), length, "correct address length");
151*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_UINT(bound_addr.svm_port, port, "bound to local port zero");
152*f6217f89SApple OSS Distributions }
153*f6217f89SApple OSS Distributions 
154*f6217f89SApple OSS Distributions T_DECL(bind_double, "vsock double bind")
155*f6217f89SApple OSS Distributions {
156*f6217f89SApple OSS Distributions 	const uint32_t cid = VMADDR_CID_ANY;
157*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
158*f6217f89SApple OSS Distributions 
159*f6217f89SApple OSS Distributions 	int socket;
160*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
161*f6217f89SApple OSS Distributions 	int result = vsock_bind(cid, port, &addr, &socket);
162*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port");
163*f6217f89SApple OSS Distributions 
164*f6217f89SApple OSS Distributions 	result = bind(socket, (struct sockaddr *) &addr, sizeof(addr));
165*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EINVAL, "vsock bind to same port");
166*f6217f89SApple OSS Distributions }
167*f6217f89SApple OSS Distributions 
168*f6217f89SApple OSS Distributions T_DECL(bind_same, "vsock bind same address and port")
169*f6217f89SApple OSS Distributions {
170*f6217f89SApple OSS Distributions 	const uint32_t cid = VMADDR_CID_ANY;
171*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
172*f6217f89SApple OSS Distributions 
173*f6217f89SApple OSS Distributions 	int socket;
174*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
175*f6217f89SApple OSS Distributions 	int result = vsock_bind(cid, port, &addr, &socket);
176*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port");
177*f6217f89SApple OSS Distributions 
178*f6217f89SApple OSS Distributions 	result = vsock_bind(cid, port, &addr, &socket);
179*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EADDRINUSE, "vsock bind to same address and port");
180*f6217f89SApple OSS Distributions }
181*f6217f89SApple OSS Distributions 
182*f6217f89SApple OSS Distributions T_DECL(bind_port_reuse, "vsock bind port reuse")
183*f6217f89SApple OSS Distributions {
184*f6217f89SApple OSS Distributions 	const uint32_t cid = VMADDR_CID_ANY;
185*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
186*f6217f89SApple OSS Distributions 
187*f6217f89SApple OSS Distributions 	int socket;
188*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
189*f6217f89SApple OSS Distributions 	int result = vsock_bind(cid, port, &addr, &socket);
190*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port");
191*f6217f89SApple OSS Distributions 
192*f6217f89SApple OSS Distributions 	vsock_close(socket);
193*f6217f89SApple OSS Distributions 
194*f6217f89SApple OSS Distributions 	result = vsock_bind(cid, port, &addr, &socket);
195*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind to a port");
196*f6217f89SApple OSS Distributions }
197*f6217f89SApple OSS Distributions 
198*f6217f89SApple OSS Distributions T_DECL(bind_privileged_non_root, "vsock bind on privileged port - non-root", T_META_ASROOT(false))
199*f6217f89SApple OSS Distributions {
200*f6217f89SApple OSS Distributions 	if (geteuid() == 0) {
201*f6217f89SApple OSS Distributions 		T_SKIP("test requires non-root privileges to run.");
202*f6217f89SApple OSS Distributions 	}
203*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
204*f6217f89SApple OSS Distributions 	int socket;
205*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_ANY, 5, &addr, &socket);
206*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EACCES, "vsock bind privileged as non-root");
207*f6217f89SApple OSS Distributions }
208*f6217f89SApple OSS Distributions 
209*f6217f89SApple OSS Distributions T_DECL(bind_privileged_root, "vsock bind on privileged port - root", T_META_ASROOT(true))
210*f6217f89SApple OSS Distributions {
211*f6217f89SApple OSS Distributions 	if (geteuid() != 0) {
212*f6217f89SApple OSS Distributions 		T_SKIP("test requires root privileges to run.");
213*f6217f89SApple OSS Distributions 	}
214*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
215*f6217f89SApple OSS Distributions 	int socket;
216*f6217f89SApple OSS Distributions 	int result = vsock_bind(VMADDR_CID_ANY, 6, &addr, &socket);
217*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind privileged as root");
218*f6217f89SApple OSS Distributions }
219*f6217f89SApple OSS Distributions 
220*f6217f89SApple OSS Distributions T_DECL(bind_no_family, "vsock bind with unspecified family")
221*f6217f89SApple OSS Distributions {
222*f6217f89SApple OSS Distributions 	int result = vsock_bind_family(AF_UNSPEC);
223*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind with unspecified family");
224*f6217f89SApple OSS Distributions }
225*f6217f89SApple OSS Distributions 
226*f6217f89SApple OSS Distributions T_DECL(bind_vsock_family, "vsock bind with vsock family")
227*f6217f89SApple OSS Distributions {
228*f6217f89SApple OSS Distributions 	int result = vsock_bind_family(AF_VSOCK);
229*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock bind with vsock family");
230*f6217f89SApple OSS Distributions }
231*f6217f89SApple OSS Distributions 
232*f6217f89SApple OSS Distributions T_DECL(bind_wrong_family, "vsock bind with wrong family")
233*f6217f89SApple OSS Distributions {
234*f6217f89SApple OSS Distributions 	int result = vsock_bind_family(AF_INET);
235*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EAFNOSUPPORT, "vsock bind with wrong family");
236*f6217f89SApple OSS Distributions }
237*f6217f89SApple OSS Distributions 
238*f6217f89SApple OSS Distributions /* Listen */
239*f6217f89SApple OSS Distributions 
240*f6217f89SApple OSS Distributions T_DECL(listen, "vsock listen on specific port")
241*f6217f89SApple OSS Distributions {
242*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
243*f6217f89SApple OSS Distributions 	int socket;
244*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
245*f6217f89SApple OSS Distributions 	int result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket);
246*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen");
247*f6217f89SApple OSS Distributions }
248*f6217f89SApple OSS Distributions 
249*f6217f89SApple OSS Distributions T_DECL(listen_any, "vsock listen on any port")
250*f6217f89SApple OSS Distributions {
251*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
252*f6217f89SApple OSS Distributions 	int socket;
253*f6217f89SApple OSS Distributions 	int result = vsock_listen(VMADDR_CID_ANY, VMADDR_PORT_ANY, &addr, 10, &socket);
254*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen");
255*f6217f89SApple OSS Distributions }
256*f6217f89SApple OSS Distributions 
257*f6217f89SApple OSS Distributions /* Connect */
258*f6217f89SApple OSS Distributions 
259*f6217f89SApple OSS Distributions T_DECL(connect_non_hypervisor, "vsock connect to remote other than hypervisor")
260*f6217f89SApple OSS Distributions {
261*f6217f89SApple OSS Distributions 	int socket;
262*f6217f89SApple OSS Distributions 	int result = vsock_connect(5555, 1234, &socket);
263*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EFAULT, "vsock connect non-hypervisor");
264*f6217f89SApple OSS Distributions }
265*f6217f89SApple OSS Distributions 
266*f6217f89SApple OSS Distributions T_DECL(connect_non_listening_host, "vsock connect to non-listening host port")
267*f6217f89SApple OSS Distributions {
268*f6217f89SApple OSS Distributions 	int socket;
269*f6217f89SApple OSS Distributions 	int result = vsock_connect(VMADDR_CID_HOST, 7777, &socket);
270*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening host port");
271*f6217f89SApple OSS Distributions }
272*f6217f89SApple OSS Distributions 
273*f6217f89SApple OSS Distributions T_DECL(connect_non_listening_hypervisor, "vsock connect to non-listening hypervisor port")
274*f6217f89SApple OSS Distributions {
275*f6217f89SApple OSS Distributions 	int socket;
276*f6217f89SApple OSS Distributions 	int result = vsock_connect(VMADDR_CID_HYPERVISOR, 4444, &socket);
277*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening hypervisor port");
278*f6217f89SApple OSS Distributions }
279*f6217f89SApple OSS Distributions 
280*f6217f89SApple OSS Distributions T_DECL(connect_getsockname, "vsock connect - getsockname")
281*f6217f89SApple OSS Distributions {
282*f6217f89SApple OSS Distributions 	int socket;
283*f6217f89SApple OSS Distributions 	int result = vsock_connect(VMADDR_CID_HOST, 9999, &socket);
284*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening");
285*f6217f89SApple OSS Distributions 
286*f6217f89SApple OSS Distributions 	vsock_getsockname(socket);
287*f6217f89SApple OSS Distributions }
288*f6217f89SApple OSS Distributions 
289*f6217f89SApple OSS Distributions T_DECL(connect_timeout, "vsock connect with timeout")
290*f6217f89SApple OSS Distributions {
291*f6217f89SApple OSS Distributions 	int socket = vsock_new_socket();
292*f6217f89SApple OSS Distributions 
293*f6217f89SApple OSS Distributions 	struct timeval timeout = (struct timeval) {
294*f6217f89SApple OSS Distributions 		.tv_sec = 0,
295*f6217f89SApple OSS Distributions 		.tv_usec = 1,
296*f6217f89SApple OSS Distributions 	};
297*f6217f89SApple OSS Distributions 	int result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
298*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock set socket timeout");
299*f6217f89SApple OSS Distributions 
300*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
301*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr = (struct sockaddr_vm) {
302*f6217f89SApple OSS Distributions 		.svm_cid = VMADDR_CID_HOST,
303*f6217f89SApple OSS Distributions 		.svm_port = port,
304*f6217f89SApple OSS Distributions 	};
305*f6217f89SApple OSS Distributions 	result = connect(socket, (struct sockaddr *)&addr, sizeof(addr));
306*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, ETIMEDOUT, "vsock connect timeout");
307*f6217f89SApple OSS Distributions }
308*f6217f89SApple OSS Distributions 
309*f6217f89SApple OSS Distributions T_DECL(connect_non_blocking, "vsock connect non-blocking")
310*f6217f89SApple OSS Distributions {
311*f6217f89SApple OSS Distributions 	int socket = vsock_new_socket();
312*f6217f89SApple OSS Distributions 
313*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
314*f6217f89SApple OSS Distributions 	const uint32_t cid = vsock_get_local_cid(socket);
315*f6217f89SApple OSS Distributions 
316*f6217f89SApple OSS Distributions 	// Listen.
317*f6217f89SApple OSS Distributions 	struct sockaddr_vm listen_addr;
318*f6217f89SApple OSS Distributions 	int listen_socket;
319*f6217f89SApple OSS Distributions 	long result = vsock_listen(cid, port, &listen_addr, 10, &listen_socket);
320*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen");
321*f6217f89SApple OSS Distributions 
322*f6217f89SApple OSS Distributions 	// Set non-blocking.
323*f6217f89SApple OSS Distributions 	long arg = fcntl(socket, F_GETFL, NULL);
324*f6217f89SApple OSS Distributions 	T_ASSERT_GT(arg, -1L, "vsock get args");
325*f6217f89SApple OSS Distributions 	arg |= O_NONBLOCK;
326*f6217f89SApple OSS Distributions 	result = fcntl(socket, F_SETFL, arg);
327*f6217f89SApple OSS Distributions 	T_ASSERT_GT(arg, -1L, "vsock set args");
328*f6217f89SApple OSS Distributions 
329*f6217f89SApple OSS Distributions 	// Connect.
330*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr = (struct sockaddr_vm) {
331*f6217f89SApple OSS Distributions 		.svm_cid = cid,
332*f6217f89SApple OSS Distributions 		.svm_port = port,
333*f6217f89SApple OSS Distributions 	};
334*f6217f89SApple OSS Distributions 	result = connect(socket, (struct sockaddr *)&addr, sizeof(addr));
335*f6217f89SApple OSS Distributions 	if (result != 0 && errno != EINPROGRESS) {
336*f6217f89SApple OSS Distributions 		T_ASSERT_FAIL("vsock connect should succeed or return EINPROGRESS. errno: %u", errno);
337*f6217f89SApple OSS Distributions 	}
338*f6217f89SApple OSS Distributions 
339*f6217f89SApple OSS Distributions 	vsock_close(socket);
340*f6217f89SApple OSS Distributions 	vsock_close(listen_socket);
341*f6217f89SApple OSS Distributions }
342*f6217f89SApple OSS Distributions 
343*f6217f89SApple OSS Distributions /* Shutdown */
344*f6217f89SApple OSS Distributions 
345*f6217f89SApple OSS Distributions T_DECL(shutdown_not_connected, "vsock shutdown - not connected")
346*f6217f89SApple OSS Distributions {
347*f6217f89SApple OSS Distributions 	int how[] = {SHUT_RD, SHUT_WR, SHUT_RDWR};
348*f6217f89SApple OSS Distributions 	for (unsigned long i = 0; i < COUNT_ELEMS(how); i++) {
349*f6217f89SApple OSS Distributions 		int socket = vsock_new_socket();
350*f6217f89SApple OSS Distributions 		int result = shutdown(socket, how[i]);
351*f6217f89SApple OSS Distributions 		T_ASSERT_POSIX_FAILURE(result, ENOTCONN, "vsock cannot shutdown");
352*f6217f89SApple OSS Distributions 	}
353*f6217f89SApple OSS Distributions }
354*f6217f89SApple OSS Distributions 
355*f6217f89SApple OSS Distributions T_DECL(shutdown_reads, "vsock shutdown - reads")
356*f6217f89SApple OSS Distributions {
357*f6217f89SApple OSS Distributions 	int socketA, socketB;
358*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
359*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
360*f6217f89SApple OSS Distributions 
361*f6217f89SApple OSS Distributions 	char *msg = "This is test message.\n";
362*f6217f89SApple OSS Distributions 
363*f6217f89SApple OSS Distributions 	// 'A' sends a message.
364*f6217f89SApple OSS Distributions 	vsock_send(socketA, msg);
365*f6217f89SApple OSS Distributions 
366*f6217f89SApple OSS Distributions 	// 'B' shutsdown reads.
367*f6217f89SApple OSS Distributions 	int result = shutdown(socketB, SHUT_RD);
368*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown reads");
369*f6217f89SApple OSS Distributions 
370*f6217f89SApple OSS Distributions 	// 'B' reads nothing.
371*f6217f89SApple OSS Distributions 	char buffer[1024] = {0};
372*f6217f89SApple OSS Distributions 	ssize_t read_bytes = read(socketB, buffer, 1024);
373*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_LONG(0L, read_bytes, "read zero bytes");
374*f6217f89SApple OSS Distributions 
375*f6217f89SApple OSS Distributions 	// 'B' can still send.
376*f6217f89SApple OSS Distributions 	vsock_send(socketB, msg);
377*f6217f89SApple OSS Distributions 
378*f6217f89SApple OSS Distributions 	vsock_close(socketA);
379*f6217f89SApple OSS Distributions 	vsock_close(socketB);
380*f6217f89SApple OSS Distributions }
381*f6217f89SApple OSS Distributions 
382*f6217f89SApple OSS Distributions T_DECL(shutdown_writes, "vsock shutdown - writes")
383*f6217f89SApple OSS Distributions {
384*f6217f89SApple OSS Distributions 	int socketA, socketB;
385*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
386*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
387*f6217f89SApple OSS Distributions 
388*f6217f89SApple OSS Distributions 	char *msg = "This is test message.\n";
389*f6217f89SApple OSS Distributions 
390*f6217f89SApple OSS Distributions 	// 'A' sends a message.
391*f6217f89SApple OSS Distributions 	vsock_send(socketA, msg);
392*f6217f89SApple OSS Distributions 
393*f6217f89SApple OSS Distributions 	// 'B' sends a message.
394*f6217f89SApple OSS Distributions 	vsock_send(socketB, msg);
395*f6217f89SApple OSS Distributions 
396*f6217f89SApple OSS Distributions 	// send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code.
397*f6217f89SApple OSS Distributions 	vsock_disable_sigpipe(socketB);
398*f6217f89SApple OSS Distributions 
399*f6217f89SApple OSS Distributions 	// 'B' shutsdown writes.
400*f6217f89SApple OSS Distributions 	int result = shutdown(socketB, SHUT_WR);
401*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown writes");
402*f6217f89SApple OSS Distributions 
403*f6217f89SApple OSS Distributions 	// 'B' fails to write.
404*f6217f89SApple OSS Distributions 	ssize_t sent_bytes = send(socketB, msg, strlen(msg), 0);
405*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(sent_bytes, EPIPE, "vsock cannot write");
406*f6217f89SApple OSS Distributions 
407*f6217f89SApple OSS Distributions 	// 'B' can still read.
408*f6217f89SApple OSS Distributions 	char buffer[1024] = {0};
409*f6217f89SApple OSS Distributions 	ssize_t read_bytes = read(socketB, buffer, 1024);
410*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes");
411*f6217f89SApple OSS Distributions 
412*f6217f89SApple OSS Distributions 	vsock_close(socketA);
413*f6217f89SApple OSS Distributions 	vsock_close(socketB);
414*f6217f89SApple OSS Distributions }
415*f6217f89SApple OSS Distributions 
416*f6217f89SApple OSS Distributions T_DECL(shutdown_both, "vsock shutdown - both")
417*f6217f89SApple OSS Distributions {
418*f6217f89SApple OSS Distributions 	int socketA, socketB;
419*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
420*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
421*f6217f89SApple OSS Distributions 
422*f6217f89SApple OSS Distributions 	char *msg = "This is test message.\n";
423*f6217f89SApple OSS Distributions 	char buffer[1024] = {0};
424*f6217f89SApple OSS Distributions 
425*f6217f89SApple OSS Distributions 	// 'A' sends a message.
426*f6217f89SApple OSS Distributions 	vsock_send(socketA, msg);
427*f6217f89SApple OSS Distributions 
428*f6217f89SApple OSS Distributions 	// 'B' sends a message.
429*f6217f89SApple OSS Distributions 	vsock_send(socketB, msg);
430*f6217f89SApple OSS Distributions 
431*f6217f89SApple OSS Distributions 	// 'B' reads a message.
432*f6217f89SApple OSS Distributions 	ssize_t read_bytes = read(socketB, buffer, 1024);
433*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes");
434*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_STR(msg, buffer, "same message");
435*f6217f89SApple OSS Distributions 
436*f6217f89SApple OSS Distributions 	// 'A' sends a message.
437*f6217f89SApple OSS Distributions 	vsock_send(socketA, msg);
438*f6217f89SApple OSS Distributions 
439*f6217f89SApple OSS Distributions 	// send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code.
440*f6217f89SApple OSS Distributions 	vsock_disable_sigpipe(socketB);
441*f6217f89SApple OSS Distributions 
442*f6217f89SApple OSS Distributions 	// 'B' shutsdown reads and writes.
443*f6217f89SApple OSS Distributions 	int result = shutdown(socketB, SHUT_RDWR);
444*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown reads and writes");
445*f6217f89SApple OSS Distributions 
446*f6217f89SApple OSS Distributions 	// 'B' fails to write.
447*f6217f89SApple OSS Distributions 	ssize_t sent_bytes = send(socketB, msg, strlen(msg), 0);
448*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(sent_bytes, EPIPE, "vsock cannot write");
449*f6217f89SApple OSS Distributions 
450*f6217f89SApple OSS Distributions 	// 'B' reads nothing.
451*f6217f89SApple OSS Distributions 	read_bytes = read(socketB, buffer, 1024);
452*f6217f89SApple OSS Distributions 	T_ASSERT_EQ_LONG(0L, read_bytes, "read zero bytes");
453*f6217f89SApple OSS Distributions 
454*f6217f89SApple OSS Distributions 	vsock_close(socketA);
455*f6217f89SApple OSS Distributions 	vsock_close(socketB);
456*f6217f89SApple OSS Distributions }
457*f6217f89SApple OSS Distributions 
458*f6217f89SApple OSS Distributions /* Communication */
459*f6217f89SApple OSS Distributions 
460*f6217f89SApple OSS Distributions T_DECL(talk_self, "vsock talk to self")
461*f6217f89SApple OSS Distributions {
462*f6217f89SApple OSS Distributions 	int socketA, socketB;
463*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
464*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
465*f6217f89SApple OSS Distributions 
466*f6217f89SApple OSS Distributions 	char buffer[1024] = {0};
467*f6217f89SApple OSS Distributions 
468*f6217f89SApple OSS Distributions 	for (int i = 0; i < 64; i++) {
469*f6217f89SApple OSS Distributions 		// Send a message.
470*f6217f89SApple OSS Distributions 		char *msg = (char*)malloc(64 * sizeof(char));
471*f6217f89SApple OSS Distributions 		sprintf(msg, "This is test message %d\n", i);
472*f6217f89SApple OSS Distributions 		vsock_send(socketA, msg);
473*f6217f89SApple OSS Distributions 
474*f6217f89SApple OSS Distributions 		// Receive a message.
475*f6217f89SApple OSS Distributions 		ssize_t read_bytes = read(socketB, buffer, 1024);
476*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes");
477*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_STR(msg, buffer, "same message");
478*f6217f89SApple OSS Distributions 		free(msg);
479*f6217f89SApple OSS Distributions 	}
480*f6217f89SApple OSS Distributions 
481*f6217f89SApple OSS Distributions 	vsock_close(socketA);
482*f6217f89SApple OSS Distributions 	vsock_close(socketB);
483*f6217f89SApple OSS Distributions }
484*f6217f89SApple OSS Distributions 
485*f6217f89SApple OSS Distributions T_DECL(talk_self_double, "vsock talk to self - double sends")
486*f6217f89SApple OSS Distributions {
487*f6217f89SApple OSS Distributions 	int socketA, socketB;
488*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
489*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
490*f6217f89SApple OSS Distributions 
491*f6217f89SApple OSS Distributions 	char buffer[1024] = {0};
492*f6217f89SApple OSS Distributions 
493*f6217f89SApple OSS Distributions 	for (int i = 0; i < 64; i++) {
494*f6217f89SApple OSS Distributions 		// Send a message.
495*f6217f89SApple OSS Distributions 		char *msg = (char*)malloc(64 * sizeof(char));
496*f6217f89SApple OSS Distributions 		sprintf(msg, "This is test message %d\n", i);
497*f6217f89SApple OSS Distributions 		vsock_send(socketA, msg);
498*f6217f89SApple OSS Distributions 
499*f6217f89SApple OSS Distributions 		// Send the same message.
500*f6217f89SApple OSS Distributions 		vsock_send(socketA, msg);
501*f6217f89SApple OSS Distributions 
502*f6217f89SApple OSS Distributions 		// Receive a message.
503*f6217f89SApple OSS Distributions 		ssize_t read_bytes = read(socketB, buffer, 1024);
504*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_LONG(strlen(msg) * 2, (unsigned long)read_bytes, "read all bytes");
505*f6217f89SApple OSS Distributions 		char *expected_msg = (char*)malloc(64 * sizeof(char));
506*f6217f89SApple OSS Distributions 		sprintf(expected_msg, "%s%s", msg, msg);
507*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_STR(expected_msg, buffer, "same message");
508*f6217f89SApple OSS Distributions 		free(msg);
509*f6217f89SApple OSS Distributions 		free(expected_msg);
510*f6217f89SApple OSS Distributions 	}
511*f6217f89SApple OSS Distributions 
512*f6217f89SApple OSS Distributions 	vsock_close(socketA);
513*f6217f89SApple OSS Distributions 	vsock_close(socketB);
514*f6217f89SApple OSS Distributions }
515*f6217f89SApple OSS Distributions 
516*f6217f89SApple OSS Distributions T_DECL(talk_self_early_close, "vsock talk to self - peer closes early")
517*f6217f89SApple OSS Distributions {
518*f6217f89SApple OSS Distributions 	int socketA, socketB;
519*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
520*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
521*f6217f89SApple OSS Distributions 
522*f6217f89SApple OSS Distributions 	char *msg = "This is a message.";
523*f6217f89SApple OSS Distributions 	vsock_send(socketA, msg);
524*f6217f89SApple OSS Distributions 
525*f6217f89SApple OSS Distributions 	// send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code.
526*f6217f89SApple OSS Distributions 	vsock_disable_sigpipe(socketA);
527*f6217f89SApple OSS Distributions 
528*f6217f89SApple OSS Distributions 	vsock_close(socketB);
529*f6217f89SApple OSS Distributions 
530*f6217f89SApple OSS Distributions 	ssize_t result = send(socketA, msg, strlen(msg), 0);
531*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EPIPE, "vsock peer closed");
532*f6217f89SApple OSS Distributions 
533*f6217f89SApple OSS Distributions 	vsock_close(socketA);
534*f6217f89SApple OSS Distributions }
535*f6217f89SApple OSS Distributions 
536*f6217f89SApple OSS Distributions T_DECL(talk_self_connections, "vsock talk to self - too many connections")
537*f6217f89SApple OSS Distributions {
538*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
539*f6217f89SApple OSS Distributions 	const int backlog = 1;
540*f6217f89SApple OSS Distributions 
541*f6217f89SApple OSS Distributions 	struct sockaddr_vm listen_addr;
542*f6217f89SApple OSS Distributions 	int listen_socket;
543*f6217f89SApple OSS Distributions 	int result = vsock_listen(VMADDR_CID_ANY, port, &listen_addr, backlog, &listen_socket);
544*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen");
545*f6217f89SApple OSS Distributions 
546*f6217f89SApple OSS Distributions 	const uint32_t connection_cid = vsock_get_local_cid(listen_socket);
547*f6217f89SApple OSS Distributions 
548*f6217f89SApple OSS Distributions 	// One backlog.
549*f6217f89SApple OSS Distributions 	int connected_socket = vsock_new_socket();
550*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr = (struct sockaddr_vm) {
551*f6217f89SApple OSS Distributions 		.svm_cid = connection_cid,
552*f6217f89SApple OSS Distributions 		.svm_port = port,
553*f6217f89SApple OSS Distributions 	};
554*f6217f89SApple OSS Distributions 	result = connect(connected_socket, (struct sockaddr *)&addr, sizeof(addr));
555*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock connection successful");
556*f6217f89SApple OSS Distributions 
557*f6217f89SApple OSS Distributions 	int bad_socket = vsock_new_socket();
558*f6217f89SApple OSS Distributions 	result = connect(bad_socket, (struct sockaddr *)&addr, sizeof(addr));
559*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, ECONNREFUSED, "vsock connection refused");
560*f6217f89SApple OSS Distributions 
561*f6217f89SApple OSS Distributions 	vsock_close(connected_socket);
562*f6217f89SApple OSS Distributions 	vsock_close(listen_socket);
563*f6217f89SApple OSS Distributions }
564*f6217f89SApple OSS Distributions 
565*f6217f89SApple OSS Distributions // rdar://84098487 (SEED: Web: Virtio-socket sent data lost after 128KB)
566*f6217f89SApple OSS Distributions T_DECL(talk_self_large_writes, "vsock talk to self with large writes")
567*f6217f89SApple OSS Distributions {
568*f6217f89SApple OSS Distributions 	int socketA, socketB;
569*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
570*f6217f89SApple OSS Distributions 	vsock_connect_peers(VMADDR_CID_ANY, port, 10, &socketA, &socketB);
571*f6217f89SApple OSS Distributions 
572*f6217f89SApple OSS Distributions 	size_t size = 65536 * 4;
573*f6217f89SApple OSS Distributions 	char buffer[65536 * 4] = {0};
574*f6217f89SApple OSS Distributions 	void *random = malloc(size);
575*f6217f89SApple OSS Distributions 
576*f6217f89SApple OSS Distributions 	for (int i = 0; i < 64; i++) {
577*f6217f89SApple OSS Distributions 		// Send a message.
578*f6217f89SApple OSS Distributions 		ssize_t sent = write(socketA, random, size);
579*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_LONG(size, sent, "sent all bytes");
580*f6217f89SApple OSS Distributions 
581*f6217f89SApple OSS Distributions 		// Receive a message.
582*f6217f89SApple OSS Distributions 		ssize_t read_bytes = read(socketB, buffer, size);
583*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_LONG(size, (unsigned long)read_bytes, "read all bytes");
584*f6217f89SApple OSS Distributions 
585*f6217f89SApple OSS Distributions 		// Sent and received same data.
586*f6217f89SApple OSS Distributions 		T_ASSERT_EQ_INT(0, memcmp(random, buffer, size), "sent and received same data");
587*f6217f89SApple OSS Distributions 	}
588*f6217f89SApple OSS Distributions 
589*f6217f89SApple OSS Distributions 	free(random);
590*f6217f89SApple OSS Distributions 	vsock_close(socketA);
591*f6217f89SApple OSS Distributions 	vsock_close(socketB);
592*f6217f89SApple OSS Distributions }
593*f6217f89SApple OSS Distributions 
594*f6217f89SApple OSS Distributions /* Sysctl */
595*f6217f89SApple OSS Distributions 
596*f6217f89SApple OSS Distributions static const char* pcblist = "net.vsock.pcblist";
597*f6217f89SApple OSS Distributions 
598*f6217f89SApple OSS Distributions T_DECL(vsock_pcblist_simple, "vsock pcblist sysctl - simple")
599*f6217f89SApple OSS Distributions {
600*f6217f89SApple OSS Distributions 	// Create some socket to discover in the pcblist.
601*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
602*f6217f89SApple OSS Distributions 	int socket;
603*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
604*f6217f89SApple OSS Distributions 	int result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket);
605*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
606*f6217f89SApple OSS Distributions 
607*f6217f89SApple OSS Distributions 	// Get the buffer length for the pcblist.
608*f6217f89SApple OSS Distributions 	size_t length = 0;
609*f6217f89SApple OSS Distributions 	result = sysctlbyname(pcblist, 0, &length, 0, 0);
610*f6217f89SApple OSS Distributions 	if (result == ENOENT) {
611*f6217f89SApple OSS Distributions 		T_SKIP("%s missing", pcblist);
612*f6217f89SApple OSS Distributions 	}
613*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
614*f6217f89SApple OSS Distributions 
615*f6217f89SApple OSS Distributions 	// Allocate the buffer.
616*f6217f89SApple OSS Distributions 	struct xvsockpgen *buffer = malloc(length);
617*f6217f89SApple OSS Distributions 	T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
618*f6217f89SApple OSS Distributions 
619*f6217f89SApple OSS Distributions 	// Populate the buffer with the pcblist.
620*f6217f89SApple OSS Distributions 	result = sysctlbyname(pcblist, buffer, &length, 0, 0);
621*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
622*f6217f89SApple OSS Distributions 
623*f6217f89SApple OSS Distributions 	// The socket should exist in the list.
624*f6217f89SApple OSS Distributions 	bool exists = vsock_address_exists(buffer, addr);
625*f6217f89SApple OSS Distributions 	T_ASSERT_TRUE(exists, "vsock pcblist contains the specified socket");
626*f6217f89SApple OSS Distributions 
627*f6217f89SApple OSS Distributions 	vsock_close(socket);
628*f6217f89SApple OSS Distributions 	free(buffer);
629*f6217f89SApple OSS Distributions }
630*f6217f89SApple OSS Distributions 
631*f6217f89SApple OSS Distributions T_DECL(vsock_pcblist_added, "vsock pcblist sysctl - socket added")
632*f6217f89SApple OSS Distributions {
633*f6217f89SApple OSS Distributions 	// Get the buffer length for the pcblist.
634*f6217f89SApple OSS Distributions 	size_t length = 0;
635*f6217f89SApple OSS Distributions 	int result = sysctlbyname(pcblist, 0, &length, 0, 0);
636*f6217f89SApple OSS Distributions 	if (result == ENOENT) {
637*f6217f89SApple OSS Distributions 		T_SKIP("%s missing", pcblist);
638*f6217f89SApple OSS Distributions 	}
639*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
640*f6217f89SApple OSS Distributions 
641*f6217f89SApple OSS Distributions 	// Create some socket to discover in the pcblist after making the first sysctl.
642*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
643*f6217f89SApple OSS Distributions 	int socket;
644*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
645*f6217f89SApple OSS Distributions 	result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket);
646*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
647*f6217f89SApple OSS Distributions 
648*f6217f89SApple OSS Distributions 	// Allocate the buffer.
649*f6217f89SApple OSS Distributions 	struct xvsockpgen *buffer = malloc(length);
650*f6217f89SApple OSS Distributions 	T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
651*f6217f89SApple OSS Distributions 
652*f6217f89SApple OSS Distributions 	// Populate the buffer with the pcblist.
653*f6217f89SApple OSS Distributions 	result = sysctlbyname(pcblist, buffer, &length, 0, 0);
654*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
655*f6217f89SApple OSS Distributions 
656*f6217f89SApple OSS Distributions 	// The socket was created after the buffer and cannot fit.
657*f6217f89SApple OSS Distributions 	bool exists = vsock_address_exists(buffer, addr);
658*f6217f89SApple OSS Distributions 	T_ASSERT_FALSE(exists, "vsock pcblist should not contain the new socket");
659*f6217f89SApple OSS Distributions 
660*f6217f89SApple OSS Distributions 	vsock_close(socket);
661*f6217f89SApple OSS Distributions 	free(buffer);
662*f6217f89SApple OSS Distributions }
663*f6217f89SApple OSS Distributions 
664*f6217f89SApple OSS Distributions T_DECL(vsock_pcblist_removed, "vsock pcblist sysctl - socket removed")
665*f6217f89SApple OSS Distributions {
666*f6217f89SApple OSS Distributions 	// Create some socket to be removed after making the first sysctl.
667*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
668*f6217f89SApple OSS Distributions 	int socket;
669*f6217f89SApple OSS Distributions 	const uint32_t port = vsock_get_available_port();
670*f6217f89SApple OSS Distributions 	int result = vsock_listen(VMADDR_CID_ANY, port, &addr, 10, &socket);
671*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
672*f6217f89SApple OSS Distributions 
673*f6217f89SApple OSS Distributions 	// Get the buffer length for the pcblist.
674*f6217f89SApple OSS Distributions 	size_t length = 0;
675*f6217f89SApple OSS Distributions 	result = sysctlbyname(pcblist, 0, &length, 0, 0);
676*f6217f89SApple OSS Distributions 	if (result == ENOENT) {
677*f6217f89SApple OSS Distributions 		T_SKIP("%s missing", pcblist);
678*f6217f89SApple OSS Distributions 	}
679*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
680*f6217f89SApple OSS Distributions 
681*f6217f89SApple OSS Distributions 	// Close the socket early.
682*f6217f89SApple OSS Distributions 	vsock_close(socket);
683*f6217f89SApple OSS Distributions 
684*f6217f89SApple OSS Distributions 	// Allocate the buffer.
685*f6217f89SApple OSS Distributions 	struct xvsockpgen *buffer = malloc(length);
686*f6217f89SApple OSS Distributions 	T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
687*f6217f89SApple OSS Distributions 
688*f6217f89SApple OSS Distributions 	// Populate the buffer with the pcblist.
689*f6217f89SApple OSS Distributions 	result = sysctlbyname(pcblist, buffer, &length, 0, 0);
690*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
691*f6217f89SApple OSS Distributions 
692*f6217f89SApple OSS Distributions 	// The socket was destroyed before populating the list and should not exist.
693*f6217f89SApple OSS Distributions 	bool exists = vsock_address_exists(buffer, addr);
694*f6217f89SApple OSS Distributions 	T_ASSERT_FALSE(exists, "vsock pcblist should not contain the deleted socket");
695*f6217f89SApple OSS Distributions 
696*f6217f89SApple OSS Distributions 	free(buffer);
697*f6217f89SApple OSS Distributions }
698*f6217f89SApple OSS Distributions 
699*f6217f89SApple OSS Distributions T_DECL(vsock_private_connect_without_entitlement, "vsock private connect should fail without entitlement")
700*f6217f89SApple OSS Distributions {
701*f6217f89SApple OSS Distributions 	int socket;
702*f6217f89SApple OSS Distributions 	int result = vsock_private_connect(VMADDR_CID_HOST, 1234, &socket);
703*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EPERM, "vsock connect without entitlement");
704*f6217f89SApple OSS Distributions }
705*f6217f89SApple OSS Distributions 
706*f6217f89SApple OSS Distributions T_DECL(vsock_private_bind_without_entitlement, "vsock private bind should fail without entitlement")
707*f6217f89SApple OSS Distributions {
708*f6217f89SApple OSS Distributions 	int socket;
709*f6217f89SApple OSS Distributions 	struct sockaddr_vm addr;
710*f6217f89SApple OSS Distributions 	int result = vsock_private_bind(VMADDR_CID_ANY, 1234, &addr, &socket);
711*f6217f89SApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(result, EPERM, "vsock bind without entitlement");
712*f6217f89SApple OSS Distributions }
713