]> git.saurik.com Git - apple/xnu.git/blob - tests/vsock.c
xnu-7195.81.3.tar.gz
[apple/xnu.git] / tests / vsock.c
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
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
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
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
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
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
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
113 vsock_close(int socket)
114 {
115 int result = close(socket);
116 T_ASSERT_POSIX_SUCCESS(result, "vsock close");
117 }
118
119 static void
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
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
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
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 /* Sysctl */
739
740 static const char* pcblist = "net.vsock.pcblist";
741
742 T_DECL(vsock_pcblist_simple, "vsock pcblist sysctl - simple")
743 {
744 // Create some socket to discover in the pcblist.
745 struct sockaddr_vm addr;
746 int socket;
747 int result = vsock_listen(VMADDR_CID_ANY, 88899, &addr, 10, &socket);
748 T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
749
750 // Get the buffer length for the pcblist.
751 size_t length = 0;
752 result = sysctlbyname(pcblist, 0, &length, 0, 0);
753 if (result == ENOENT) {
754 T_SKIP("%s missing", pcblist);
755 }
756 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
757
758 // Allocate the buffer.
759 struct xvsockpgen *buffer = malloc(length);
760 T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
761
762 // Populate the buffer with the pcblist.
763 result = sysctlbyname(pcblist, buffer, &length, 0, 0);
764 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
765
766 // The socket should exist in the list.
767 bool exists = vsock_address_exists(buffer, addr);
768 T_ASSERT_TRUE(exists, "vsock pcblist contains the specified socket");
769
770 vsock_close(socket);
771 free(buffer);
772 }
773
774 T_DECL(vsock_pcblist_added, "vsock pcblist sysctl - socket added")
775 {
776 // Get the buffer length for the pcblist.
777 size_t length = 0;
778 int result = sysctlbyname(pcblist, 0, &length, 0, 0);
779 if (result == ENOENT) {
780 T_SKIP("%s missing", pcblist);
781 }
782 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
783
784 // Create some socket to discover in the pcblist after making the first sysctl.
785 struct sockaddr_vm addr;
786 int socket;
787 result = vsock_listen(VMADDR_CID_ANY, 77799, &addr, 10, &socket);
788 T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
789
790 // Allocate the buffer.
791 struct xvsockpgen *buffer = malloc(length);
792 T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
793
794 // Populate the buffer with the pcblist.
795 result = sysctlbyname(pcblist, buffer, &length, 0, 0);
796 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
797
798 // The socket was created after the buffer and cannot fit.
799 bool exists = vsock_address_exists(buffer, addr);
800 T_ASSERT_FALSE(exists, "vsock pcblist should not contain the new socket");
801
802 vsock_close(socket);
803 free(buffer);
804 }
805
806 T_DECL(vsock_pcblist_removed, "vsock pcblist sysctl - socket removed")
807 {
808 // Create some socket to be removed after making the first sysctl.
809 struct sockaddr_vm addr;
810 int socket;
811 int result = vsock_listen(VMADDR_CID_ANY, 66699, &addr, 10, &socket);
812 T_ASSERT_POSIX_SUCCESS(result, "vsock listen on a port");
813
814 // Get the buffer length for the pcblist.
815 size_t length = 0;
816 result = sysctlbyname(pcblist, 0, &length, 0, 0);
817 if (result == ENOENT) {
818 T_SKIP("%s missing", pcblist);
819 }
820 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist get buffer size (result %d)", result);
821
822 // Close the socket early.
823 vsock_close(socket);
824
825 // Allocate the buffer.
826 struct xvsockpgen *buffer = malloc(length);
827 T_ASSERT_NOTNULL(buffer, "allocated buffer is not null");
828
829 // Populate the buffer with the pcblist.
830 result = sysctlbyname(pcblist, buffer, &length, 0, 0);
831 T_ASSERT_POSIX_SUCCESS(result, "vsock pcblist populate buffer");
832
833 // The socket was destroyed before populating the list and should not exist.
834 bool exists = vsock_address_exists(buffer, addr);
835 T_ASSERT_FALSE(exists, "vsock pcblist should not contain the deleted socket");
836
837 free(buffer);
838 }