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