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