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