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