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