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