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