1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * vsock test utilities 4 * 5 * Copyright (C) 2017 Red Hat, Inc. 6 * 7 * Author: Stefan Hajnoczi <stefanha@redhat.com> 8 */ 9 10 #include <errno.h> 11 #include <stdio.h> 12 #include <stdint.h> 13 #include <stdlib.h> 14 #include <signal.h> 15 #include <unistd.h> 16 #include <assert.h> 17 #include <sys/epoll.h> 18 19 #include "timeout.h" 20 #include "control.h" 21 #include "util.h" 22 23 /* Install signal handlers */ 24 void init_signals(void) 25 { 26 struct sigaction act = { 27 .sa_handler = sigalrm, 28 }; 29 30 sigaction(SIGALRM, &act, NULL); 31 signal(SIGPIPE, SIG_IGN); 32 } 33 34 /* Parse a CID in string representation */ 35 unsigned int parse_cid(const char *str) 36 { 37 char *endptr = NULL; 38 unsigned long n; 39 40 errno = 0; 41 n = strtoul(str, &endptr, 10); 42 if (errno || *endptr != '\0') { 43 fprintf(stderr, "malformed CID \"%s\"\n", str); 44 exit(EXIT_FAILURE); 45 } 46 return n; 47 } 48 49 /* Wait for the remote to close the connection */ 50 void vsock_wait_remote_close(int fd) 51 { 52 struct epoll_event ev; 53 int epollfd, nfds; 54 55 epollfd = epoll_create1(0); 56 if (epollfd == -1) { 57 perror("epoll_create1"); 58 exit(EXIT_FAILURE); 59 } 60 61 ev.events = EPOLLRDHUP | EPOLLHUP; 62 ev.data.fd = fd; 63 if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { 64 perror("epoll_ctl"); 65 exit(EXIT_FAILURE); 66 } 67 68 nfds = epoll_wait(epollfd, &ev, 1, TIMEOUT * 1000); 69 if (nfds == -1) { 70 perror("epoll_wait"); 71 exit(EXIT_FAILURE); 72 } 73 74 if (nfds == 0) { 75 fprintf(stderr, "epoll_wait timed out\n"); 76 exit(EXIT_FAILURE); 77 } 78 79 assert(nfds == 1); 80 assert(ev.events & (EPOLLRDHUP | EPOLLHUP)); 81 assert(ev.data.fd == fd); 82 83 close(epollfd); 84 } 85 86 /* Connect to <cid, port> and return the file descriptor. */ 87 static int vsock_connect(unsigned int cid, unsigned int port, int type) 88 { 89 union { 90 struct sockaddr sa; 91 struct sockaddr_vm svm; 92 } addr = { 93 .svm = { 94 .svm_family = AF_VSOCK, 95 .svm_port = port, 96 .svm_cid = cid, 97 }, 98 }; 99 int ret; 100 int fd; 101 102 control_expectln("LISTENING"); 103 104 fd = socket(AF_VSOCK, type, 0); 105 106 timeout_begin(TIMEOUT); 107 do { 108 ret = connect(fd, &addr.sa, sizeof(addr.svm)); 109 timeout_check("connect"); 110 } while (ret < 0 && errno == EINTR); 111 timeout_end(); 112 113 if (ret < 0) { 114 int old_errno = errno; 115 116 close(fd); 117 fd = -1; 118 errno = old_errno; 119 } 120 return fd; 121 } 122 123 int vsock_stream_connect(unsigned int cid, unsigned int port) 124 { 125 return vsock_connect(cid, port, SOCK_STREAM); 126 } 127 128 int vsock_seqpacket_connect(unsigned int cid, unsigned int port) 129 { 130 return vsock_connect(cid, port, SOCK_SEQPACKET); 131 } 132 133 /* Listen on <cid, port> and return the first incoming connection. The remote 134 * address is stored to clientaddrp. clientaddrp may be NULL. 135 */ 136 static int vsock_accept(unsigned int cid, unsigned int port, 137 struct sockaddr_vm *clientaddrp, int type) 138 { 139 union { 140 struct sockaddr sa; 141 struct sockaddr_vm svm; 142 } addr = { 143 .svm = { 144 .svm_family = AF_VSOCK, 145 .svm_port = port, 146 .svm_cid = cid, 147 }, 148 }; 149 union { 150 struct sockaddr sa; 151 struct sockaddr_vm svm; 152 } clientaddr; 153 socklen_t clientaddr_len = sizeof(clientaddr.svm); 154 int fd; 155 int client_fd; 156 int old_errno; 157 158 fd = socket(AF_VSOCK, type, 0); 159 160 if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) { 161 perror("bind"); 162 exit(EXIT_FAILURE); 163 } 164 165 if (listen(fd, 1) < 0) { 166 perror("listen"); 167 exit(EXIT_FAILURE); 168 } 169 170 control_writeln("LISTENING"); 171 172 timeout_begin(TIMEOUT); 173 do { 174 client_fd = accept(fd, &clientaddr.sa, &clientaddr_len); 175 timeout_check("accept"); 176 } while (client_fd < 0 && errno == EINTR); 177 timeout_end(); 178 179 old_errno = errno; 180 close(fd); 181 errno = old_errno; 182 183 if (client_fd < 0) 184 return client_fd; 185 186 if (clientaddr_len != sizeof(clientaddr.svm)) { 187 fprintf(stderr, "unexpected addrlen from accept(2), %zu\n", 188 (size_t)clientaddr_len); 189 exit(EXIT_FAILURE); 190 } 191 if (clientaddr.sa.sa_family != AF_VSOCK) { 192 fprintf(stderr, "expected AF_VSOCK from accept(2), got %d\n", 193 clientaddr.sa.sa_family); 194 exit(EXIT_FAILURE); 195 } 196 197 if (clientaddrp) 198 *clientaddrp = clientaddr.svm; 199 return client_fd; 200 } 201 202 int vsock_stream_accept(unsigned int cid, unsigned int port, 203 struct sockaddr_vm *clientaddrp) 204 { 205 return vsock_accept(cid, port, clientaddrp, SOCK_STREAM); 206 } 207 208 int vsock_seqpacket_accept(unsigned int cid, unsigned int port, 209 struct sockaddr_vm *clientaddrp) 210 { 211 return vsock_accept(cid, port, clientaddrp, SOCK_SEQPACKET); 212 } 213 214 /* Transmit bytes from a buffer and check the return value. 215 * 216 * expected_ret: 217 * <0 Negative errno (for testing errors) 218 * 0 End-of-file 219 * >0 Success (bytes successfully written) 220 */ 221 void send_buf(int fd, const void *buf, size_t len, int flags, 222 ssize_t expected_ret) 223 { 224 ssize_t nwritten = 0; 225 ssize_t ret; 226 227 timeout_begin(TIMEOUT); 228 do { 229 ret = send(fd, buf + nwritten, len - nwritten, flags); 230 timeout_check("send"); 231 232 if (ret == 0 || (ret < 0 && errno != EINTR)) 233 break; 234 235 nwritten += ret; 236 } while (nwritten < len); 237 timeout_end(); 238 239 if (expected_ret < 0) { 240 if (ret != -1) { 241 fprintf(stderr, "bogus send(2) return value %zd (expected %zd)\n", 242 ret, expected_ret); 243 exit(EXIT_FAILURE); 244 } 245 if (errno != -expected_ret) { 246 perror("send"); 247 exit(EXIT_FAILURE); 248 } 249 return; 250 } 251 252 if (ret < 0) { 253 perror("send"); 254 exit(EXIT_FAILURE); 255 } 256 257 if (nwritten != expected_ret) { 258 if (ret == 0) 259 fprintf(stderr, "unexpected EOF while sending bytes\n"); 260 261 fprintf(stderr, "bogus send(2) bytes written %zd (expected %zd)\n", 262 nwritten, expected_ret); 263 exit(EXIT_FAILURE); 264 } 265 } 266 267 /* Receive bytes in a buffer and check the return value. 268 * 269 * expected_ret: 270 * <0 Negative errno (for testing errors) 271 * 0 End-of-file 272 * >0 Success (bytes successfully read) 273 */ 274 void recv_buf(int fd, void *buf, size_t len, int flags, ssize_t expected_ret) 275 { 276 ssize_t nread = 0; 277 ssize_t ret; 278 279 timeout_begin(TIMEOUT); 280 do { 281 ret = recv(fd, buf + nread, len - nread, flags); 282 timeout_check("recv"); 283 284 if (ret == 0 || (ret < 0 && errno != EINTR)) 285 break; 286 287 nread += ret; 288 } while (nread < len); 289 timeout_end(); 290 291 if (expected_ret < 0) { 292 if (ret != -1) { 293 fprintf(stderr, "bogus recv(2) return value %zd (expected %zd)\n", 294 ret, expected_ret); 295 exit(EXIT_FAILURE); 296 } 297 if (errno != -expected_ret) { 298 perror("recv"); 299 exit(EXIT_FAILURE); 300 } 301 return; 302 } 303 304 if (ret < 0) { 305 perror("recv"); 306 exit(EXIT_FAILURE); 307 } 308 309 if (nread != expected_ret) { 310 if (ret == 0) 311 fprintf(stderr, "unexpected EOF while receiving bytes\n"); 312 313 fprintf(stderr, "bogus recv(2) bytes read %zd (expected %zd)\n", 314 nread, expected_ret); 315 exit(EXIT_FAILURE); 316 } 317 } 318 319 /* Transmit one byte and check the return value. 320 * 321 * expected_ret: 322 * <0 Negative errno (for testing errors) 323 * 0 End-of-file 324 * 1 Success 325 */ 326 void send_byte(int fd, int expected_ret, int flags) 327 { 328 const uint8_t byte = 'A'; 329 330 send_buf(fd, &byte, sizeof(byte), flags, expected_ret); 331 } 332 333 /* Receive one byte and check the return value. 334 * 335 * expected_ret: 336 * <0 Negative errno (for testing errors) 337 * 0 End-of-file 338 * 1 Success 339 */ 340 void recv_byte(int fd, int expected_ret, int flags) 341 { 342 uint8_t byte; 343 344 recv_buf(fd, &byte, sizeof(byte), flags, expected_ret); 345 346 if (byte != 'A') { 347 fprintf(stderr, "unexpected byte read %c\n", byte); 348 exit(EXIT_FAILURE); 349 } 350 } 351 352 /* Run test cases. The program terminates if a failure occurs. */ 353 void run_tests(const struct test_case *test_cases, 354 const struct test_opts *opts) 355 { 356 int i; 357 358 for (i = 0; test_cases[i].name; i++) { 359 void (*run)(const struct test_opts *opts); 360 char *line; 361 362 printf("%d - %s...", i, test_cases[i].name); 363 fflush(stdout); 364 365 /* Full barrier before executing the next test. This 366 * ensures that client and server are executing the 367 * same test case. In particular, it means whoever is 368 * faster will not see the peer still executing the 369 * last test. This is important because port numbers 370 * can be used by multiple test cases. 371 */ 372 if (test_cases[i].skip) 373 control_writeln("SKIP"); 374 else 375 control_writeln("NEXT"); 376 377 line = control_readln(); 378 if (control_cmpln(line, "SKIP", false) || test_cases[i].skip) { 379 380 printf("skipped\n"); 381 382 free(line); 383 continue; 384 } 385 386 control_cmpln(line, "NEXT", true); 387 free(line); 388 389 if (opts->mode == TEST_MODE_CLIENT) 390 run = test_cases[i].run_client; 391 else 392 run = test_cases[i].run_server; 393 394 if (run) 395 run(opts); 396 397 printf("ok\n"); 398 } 399 } 400 401 void list_tests(const struct test_case *test_cases) 402 { 403 int i; 404 405 printf("ID\tTest name\n"); 406 407 for (i = 0; test_cases[i].name; i++) 408 printf("%d\t%s\n", i, test_cases[i].name); 409 410 exit(EXIT_FAILURE); 411 } 412 413 void skip_test(struct test_case *test_cases, size_t test_cases_len, 414 const char *test_id_str) 415 { 416 unsigned long test_id; 417 char *endptr = NULL; 418 419 errno = 0; 420 test_id = strtoul(test_id_str, &endptr, 10); 421 if (errno || *endptr != '\0') { 422 fprintf(stderr, "malformed test ID \"%s\"\n", test_id_str); 423 exit(EXIT_FAILURE); 424 } 425 426 if (test_id >= test_cases_len) { 427 fprintf(stderr, "test ID (%lu) larger than the max allowed (%lu)\n", 428 test_id, test_cases_len - 1); 429 exit(EXIT_FAILURE); 430 } 431 432 test_cases[test_id].skip = true; 433 } 434 435 unsigned long hash_djb2(const void *data, size_t len) 436 { 437 unsigned long hash = 5381; 438 int i = 0; 439 440 while (i < len) { 441 hash = ((hash << 5) + hash) + ((unsigned char *)data)[i]; 442 i++; 443 } 444 445 return hash; 446 } 447