xref: /xnu-10002.41.9/tests/vsock.c (revision 699cd48037512bf4380799317ca44ca453c82f57)
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 {
455 	int socket;
456 	int result = vsock_connect(VMADDR_CID_HYPERVISOR, 4444, &socket);
457 	T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening hypervisor port");
458 }
459 
460 T_DECL(connect_getsockname, "vsock connect - getsockname")
461 {
462 	int socket;
463 	int result = vsock_connect(VMADDR_CID_HOST, 9999, &socket);
464 	T_ASSERT_POSIX_FAILURE(result, EAGAIN, "vsock connect non-listening");
465 
466 	vsock_getsockname(socket);
467 }
468 
469 T_DECL(connect_timeout, "vsock connect with timeout")
470 {
471 	int socket = vsock_new_socket();
472 
473 	struct timeval timeout = (struct timeval) {
474 		.tv_sec = 0,
475 		.tv_usec = 1,
476 	};
477 	int result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
478 	T_ASSERT_POSIX_SUCCESS(result, "vsock set socket timeout");
479 
480 	struct sockaddr_vm addr = (struct sockaddr_vm) {
481 		.svm_cid = VMADDR_CID_HOST,
482 		.svm_port = 4321,
483 	};
484 	result = connect(socket, (struct sockaddr *)&addr, sizeof(addr));
485 	T_ASSERT_POSIX_FAILURE(result, ETIMEDOUT, "vsock connect timeout");
486 }
487 
488 T_DECL(connect_non_blocking, "vsock connect non-blocking")
489 {
490 	int socket = vsock_new_socket();
491 
492 	const uint32_t port = 4321;
493 	const uint32_t cid = vsock_get_local_cid(socket);
494 
495 	// Listen.
496 	struct sockaddr_vm listen_addr;
497 	int listen_socket;
498 	long result = vsock_listen(cid, port, &listen_addr, 10, &listen_socket);
499 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen");
500 
501 	// Set non-blocking.
502 	long arg = fcntl(socket, F_GETFL, NULL);
503 	T_ASSERT_GT(arg, -1L, "vsock get args");
504 	arg |= O_NONBLOCK;
505 	result = fcntl(socket, F_SETFL, arg);
506 	T_ASSERT_GT(arg, -1L, "vsock set args");
507 
508 	// Connect.
509 	struct sockaddr_vm addr = (struct sockaddr_vm) {
510 		.svm_cid = cid,
511 		.svm_port = port,
512 	};
513 	result = connect(socket, (struct sockaddr *)&addr, sizeof(addr));
514 	if (result != 0 && errno != EINPROGRESS) {
515 		T_ASSERT_FAIL("vsock connect should succeed or return EINPROGRESS. errno: %u", errno);
516 	}
517 
518 	vsock_close(socket);
519 	vsock_close(listen_socket);
520 }
521 
522 /* Shutdown */
523 
524 T_DECL(shutdown_not_connected, "vsock shutdown - not connected")
525 {
526 	int how[] = {SHUT_RD, SHUT_WR, SHUT_RDWR};
527 	for (unsigned long i = 0; i < COUNT_ELEMS(how); i++) {
528 		int socket = vsock_new_socket();
529 		int result = shutdown(socket, how[i]);
530 		T_ASSERT_POSIX_FAILURE(result, ENOTCONN, "vsock cannot shutdown");
531 	}
532 }
533 
534 T_DECL(shutdown_reads, "vsock shutdown - reads")
535 {
536 	int socketA, socketB;
537 	vsock_connect_peers(VMADDR_CID_ANY, 8989, 10, &socketA, &socketB);
538 
539 	char *msg = "This is test message.\n";
540 
541 	// 'A' sends a message.
542 	vsock_send(socketA, msg);
543 
544 	// 'B' shutsdown reads.
545 	int result = shutdown(socketB, SHUT_RD);
546 	T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown reads");
547 
548 	// 'B' reads nothing.
549 	char buffer[1024] = {0};
550 	ssize_t read_bytes = read(socketB, buffer, 1024);
551 	T_ASSERT_EQ_LONG(0L, read_bytes, "read zero bytes");
552 
553 	// 'B' can still send.
554 	vsock_send(socketB, msg);
555 
556 	vsock_close(socketA);
557 	vsock_close(socketB);
558 }
559 
560 T_DECL(shutdown_writes, "vsock shutdown - writes")
561 {
562 	int socketA, socketB;
563 	vsock_connect_peers(VMADDR_CID_ANY, 8787, 10, &socketA, &socketB);
564 
565 	char *msg = "This is test message.\n";
566 
567 	// 'A' sends a message.
568 	vsock_send(socketA, msg);
569 
570 	// 'B' sends a message.
571 	vsock_send(socketB, msg);
572 
573 	// send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code.
574 	vsock_disable_sigpipe(socketB);
575 
576 	// 'B' shutsdown writes.
577 	int result = shutdown(socketB, SHUT_WR);
578 	T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown writes");
579 
580 	// 'B' fails to write.
581 	ssize_t sent_bytes = send(socketB, msg, strlen(msg), 0);
582 	T_ASSERT_POSIX_FAILURE(sent_bytes, EPIPE, "vsock cannot write");
583 
584 	// 'B' can still read.
585 	char buffer[1024] = {0};
586 	ssize_t read_bytes = read(socketB, buffer, 1024);
587 	T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes");
588 
589 	vsock_close(socketA);
590 	vsock_close(socketB);
591 }
592 
593 T_DECL(shutdown_both, "vsock shutdown - both")
594 {
595 	int socketA, socketB;
596 	vsock_connect_peers(VMADDR_CID_ANY, 8686, 10, &socketA, &socketB);
597 
598 	char *msg = "This is test message.\n";
599 	char buffer[1024] = {0};
600 
601 	// 'A' sends a message.
602 	vsock_send(socketA, msg);
603 
604 	// 'B' sends a message.
605 	vsock_send(socketB, msg);
606 
607 	// 'B' reads a message.
608 	ssize_t read_bytes = read(socketB, buffer, 1024);
609 	T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes");
610 	T_ASSERT_EQ_STR(msg, buffer, "same message");
611 
612 	// 'A' sends a message.
613 	vsock_send(socketA, msg);
614 
615 	// send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code.
616 	vsock_disable_sigpipe(socketB);
617 
618 	// 'B' shutsdown reads and writes.
619 	int result = shutdown(socketB, SHUT_RDWR);
620 	T_ASSERT_POSIX_SUCCESS(result, "vsock shutdown reads and writes");
621 
622 	// 'B' fails to write.
623 	ssize_t sent_bytes = send(socketB, msg, strlen(msg), 0);
624 	T_ASSERT_POSIX_FAILURE(sent_bytes, EPIPE, "vsock cannot write");
625 
626 	// 'B' reads nothing.
627 	read_bytes = read(socketB, buffer, 1024);
628 	T_ASSERT_EQ_LONG(0L, read_bytes, "read zero bytes");
629 
630 	vsock_close(socketA);
631 	vsock_close(socketB);
632 }
633 
634 /* Communication */
635 
636 T_DECL(talk_self, "vsock talk to self")
637 {
638 	int socketA, socketB;
639 	vsock_connect_peers(VMADDR_CID_ANY, 4545, 10, &socketA, &socketB);
640 
641 	char buffer[1024] = {0};
642 
643 	for (int i = 0; i < 64; i++) {
644 		// Send a message.
645 		char *msg = (char*)malloc(64 * sizeof(char));
646 		sprintf(msg, "This is test message %d\n", i);
647 		vsock_send(socketA, msg);
648 
649 		// Receive a message.
650 		ssize_t read_bytes = read(socketB, buffer, 1024);
651 		T_ASSERT_EQ_LONG(strlen(msg), (unsigned long)read_bytes, "read all bytes");
652 		T_ASSERT_EQ_STR(msg, buffer, "same message");
653 		free(msg);
654 	}
655 
656 	vsock_close(socketA);
657 	vsock_close(socketB);
658 }
659 
660 T_DECL(talk_self_double, "vsock talk to self - double sends")
661 {
662 	int socketA, socketB;
663 	vsock_connect_peers(VMADDR_CID_ANY, 4646, 10, &socketA, &socketB);
664 
665 	char buffer[1024] = {0};
666 
667 	for (int i = 0; i < 64; i++) {
668 		// Send a message.
669 		char *msg = (char*)malloc(64 * sizeof(char));
670 		sprintf(msg, "This is test message %d\n", i);
671 		vsock_send(socketA, msg);
672 
673 		// Send the same message.
674 		vsock_send(socketA, msg);
675 
676 		// Receive a message.
677 		ssize_t read_bytes = read(socketB, buffer, 1024);
678 		T_ASSERT_EQ_LONG(strlen(msg) * 2, (unsigned long)read_bytes, "read all bytes");
679 		char *expected_msg = (char*)malloc(64 * sizeof(char));
680 		sprintf(expected_msg, "%s%s", msg, msg);
681 		T_ASSERT_EQ_STR(expected_msg, buffer, "same message");
682 		free(msg);
683 		free(expected_msg);
684 	}
685 
686 	vsock_close(socketA);
687 	vsock_close(socketB);
688 }
689 
690 T_DECL(talk_self_early_close, "vsock talk to self - peer closes early")
691 {
692 	int socketA, socketB;
693 	vsock_connect_peers(VMADDR_CID_ANY, 4646, 10, &socketA, &socketB);
694 
695 	char *msg = "This is a message.";
696 	vsock_send(socketA, msg);
697 
698 	// send() hits us with a SIGPIPE if peer closes. ignore this and catch the error code.
699 	vsock_disable_sigpipe(socketA);
700 
701 	vsock_close(socketB);
702 
703 	ssize_t result = send(socketA, msg, strlen(msg), 0);
704 	T_ASSERT_POSIX_FAILURE(result, EPIPE, "vsock peer closed");
705 
706 	vsock_close(socketA);
707 }
708 
709 T_DECL(talk_self_connections, "vsock talk to self - too many connections")
710 {
711 	const uint32_t port = 4747;
712 	const int backlog = 1;
713 
714 	struct sockaddr_vm listen_addr;
715 	int listen_socket;
716 	int result = vsock_listen(VMADDR_CID_ANY, port, &listen_addr, backlog, &listen_socket);
717 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen");
718 
719 	const uint32_t connection_cid = vsock_get_local_cid(listen_socket);
720 
721 	// One backlog.
722 	int connected_socket = vsock_new_socket();
723 	struct sockaddr_vm addr = (struct sockaddr_vm) {
724 		.svm_cid = connection_cid,
725 		.svm_port = port,
726 	};
727 	result = connect(connected_socket, (struct sockaddr *)&addr, sizeof(addr));
728 	T_ASSERT_POSIX_SUCCESS(result, "vsock connection successful");
729 
730 	int bad_socket = vsock_new_socket();
731 	result = connect(bad_socket, (struct sockaddr *)&addr, sizeof(addr));
732 	T_ASSERT_POSIX_FAILURE(result, ECONNREFUSED, "vsock connection refused");
733 
734 	vsock_close(connected_socket);
735 	vsock_close(listen_socket);
736 }
737 
738 // rdar://84098487 (SEED: Web: Virtio-socket sent data lost after 128KB)
739 T_DECL(talk_self_large_writes, "vsock talk to self with large writes")
740 {
741 	int socketA, socketB;
742 	vsock_connect_peers(VMADDR_CID_ANY, 4848, 10, &socketA, &socketB);
743 
744 	size_t size = 65536 * 4;
745 	char buffer[65536 * 4] = {0};
746 	void *random = malloc(size);
747 
748 	for (int i = 0; i < 64; i++) {
749 		// Send a message.
750 		ssize_t sent = write(socketA, random, size);
751 		T_ASSERT_EQ_LONG(size, sent, "sent all bytes");
752 
753 		// Receive a message.
754 		ssize_t read_bytes = read(socketB, buffer, size);
755 		T_ASSERT_EQ_LONG(size, (unsigned long)read_bytes, "read all bytes");
756 
757 		// Sent and received same data.
758 		T_ASSERT_EQ_INT(0, memcmp(random, buffer, size), "sent and received same data");
759 	}
760 
761 	free(random);
762 	vsock_close(socketA);
763 	vsock_close(socketB);
764 }
765 
766 /* Sysctl */
767 
768 static const char* pcblist = "net.vsock.pcblist";
769 
770 T_DECL(vsock_pcblist_simple, "vsock pcblist sysctl - simple")
771 {
772 	// Create some socket to discover in the pcblist.
773 	struct sockaddr_vm addr;
774 	int socket;
775 	int result = vsock_listen(VMADDR_CID_ANY, 88899, &addr, 10, &socket);
776 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
777 
778 	// Get the buffer length for the pcblist.
779 	size_t length = 0;
780 	result = sysctlbyname(pcblist, 0, &length, 0, 0);
781 	if (result == ENOENT) {
782 		T_SKIP("%s missing", pcblist);
783 	}
784 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
785 
786 	// Allocate the buffer.
787 	struct xvsockpgen *buffer = malloc(length);
788 	T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
789 
790 	// Populate the buffer with the pcblist.
791 	result = sysctlbyname(pcblist, buffer, &length, 0, 0);
792 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
793 
794 	// The socket should exist in the list.
795 	bool exists = vsock_address_exists(buffer, addr);
796 	T_ASSERT_TRUE(exists, "vsock pcblist contains the specified socket");
797 
798 	vsock_close(socket);
799 	free(buffer);
800 }
801 
802 T_DECL(vsock_pcblist_added, "vsock pcblist sysctl - socket added")
803 {
804 	// Get the buffer length for the pcblist.
805 	size_t length = 0;
806 	int result = sysctlbyname(pcblist, 0, &length, 0, 0);
807 	if (result == ENOENT) {
808 		T_SKIP("%s missing", pcblist);
809 	}
810 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
811 
812 	// Create some socket to discover in the pcblist after making the first sysctl.
813 	struct sockaddr_vm addr;
814 	int socket;
815 	result = vsock_listen(VMADDR_CID_ANY, 77799, &addr, 10, &socket);
816 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
817 
818 	// Allocate the buffer.
819 	struct xvsockpgen *buffer = malloc(length);
820 	T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
821 
822 	// Populate the buffer with the pcblist.
823 	result = sysctlbyname(pcblist, buffer, &length, 0, 0);
824 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
825 
826 	// The socket was created after the buffer and cannot fit.
827 	bool exists = vsock_address_exists(buffer, addr);
828 	T_ASSERT_FALSE(exists, "vsock pcblist should not contain the new socket");
829 
830 	vsock_close(socket);
831 	free(buffer);
832 }
833 
834 T_DECL(vsock_pcblist_removed, "vsock pcblist sysctl - socket removed")
835 {
836 	// Create some socket to be removed after making the first sysctl.
837 	struct sockaddr_vm addr;
838 	int socket;
839 	int result = vsock_listen(VMADDR_CID_ANY, 66699, &addr, 10, &socket);
840 	T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
841 
842 	// Get the buffer length for the pcblist.
843 	size_t length = 0;
844 	result = sysctlbyname(pcblist, 0, &length, 0, 0);
845 	if (result == ENOENT) {
846 		T_SKIP("%s missing", pcblist);
847 	}
848 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
849 
850 	// Close the socket early.
851 	vsock_close(socket);
852 
853 	// Allocate the buffer.
854 	struct xvsockpgen *buffer = malloc(length);
855 	T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
856 
857 	// Populate the buffer with the pcblist.
858 	result = sysctlbyname(pcblist, buffer, &length, 0, 0);
859 	T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
860 
861 	// The socket was destroyed before populating the list and should not exist.
862 	bool exists = vsock_address_exists(buffer, addr);
863 	T_ASSERT_FALSE(exists, "vsock pcblist should not contain the deleted socket");
864 
865 	free(buffer);
866 }
867