1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * vsock_test - vsock.ko test suite
4 *
5 * Copyright (C) 2017 Red Hat, Inc.
6 *
7 * Author: Stefan Hajnoczi <stefanha@redhat.com>
8 */
9
10 #include <getopt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <linux/kernel.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <time.h>
20 #include <sys/mman.h>
21 #include <poll.h>
22 #include <signal.h>
23 #include <sys/ioctl.h>
24 #include <linux/sockios.h>
25 #include <linux/time64.h>
26
27 #include "vsock_test_zerocopy.h"
28 #include "timeout.h"
29 #include "control.h"
30 #include "util.h"
31
32 /* Basic messages for control_writeulong(), control_readulong() */
33 #define CONTROL_CONTINUE 1
34 #define CONTROL_DONE 0
35
test_stream_connection_reset(const struct test_opts * opts)36 static void test_stream_connection_reset(const struct test_opts *opts)
37 {
38 union {
39 struct sockaddr sa;
40 struct sockaddr_vm svm;
41 } addr = {
42 .svm = {
43 .svm_family = AF_VSOCK,
44 .svm_port = opts->peer_port,
45 .svm_cid = opts->peer_cid,
46 },
47 };
48 int ret;
49 int fd;
50
51 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
52
53 timeout_begin(TIMEOUT);
54 do {
55 ret = connect(fd, &addr.sa, sizeof(addr.svm));
56 timeout_check("connect");
57 } while (ret < 0 && errno == EINTR);
58 timeout_end();
59
60 if (ret != -1) {
61 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
62 exit(EXIT_FAILURE);
63 }
64 if (errno != ECONNRESET) {
65 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
66 exit(EXIT_FAILURE);
67 }
68
69 close(fd);
70 }
71
test_stream_bind_only_client(const struct test_opts * opts)72 static void test_stream_bind_only_client(const struct test_opts *opts)
73 {
74 union {
75 struct sockaddr sa;
76 struct sockaddr_vm svm;
77 } addr = {
78 .svm = {
79 .svm_family = AF_VSOCK,
80 .svm_port = opts->peer_port,
81 .svm_cid = opts->peer_cid,
82 },
83 };
84 int ret;
85 int fd;
86
87 /* Wait for the server to be ready */
88 control_expectln("BIND");
89
90 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
91
92 timeout_begin(TIMEOUT);
93 do {
94 ret = connect(fd, &addr.sa, sizeof(addr.svm));
95 timeout_check("connect");
96 } while (ret < 0 && errno == EINTR);
97 timeout_end();
98
99 if (ret != -1) {
100 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
101 exit(EXIT_FAILURE);
102 }
103 if (errno != ECONNRESET) {
104 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
105 exit(EXIT_FAILURE);
106 }
107
108 /* Notify the server that the client has finished */
109 control_writeln("DONE");
110
111 close(fd);
112 }
113
test_stream_bind_only_server(const struct test_opts * opts)114 static void test_stream_bind_only_server(const struct test_opts *opts)
115 {
116 int fd;
117
118 fd = vsock_bind(VMADDR_CID_ANY, opts->peer_port, SOCK_STREAM);
119
120 /* Notify the client that the server is ready */
121 control_writeln("BIND");
122
123 /* Wait for the client to finish */
124 control_expectln("DONE");
125
126 close(fd);
127 }
128
test_stream_client_close_client(const struct test_opts * opts)129 static void test_stream_client_close_client(const struct test_opts *opts)
130 {
131 int fd;
132
133 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
134 if (fd < 0) {
135 perror("connect");
136 exit(EXIT_FAILURE);
137 }
138
139 send_byte(fd, 1, 0);
140 close(fd);
141 }
142
test_stream_client_close_server(const struct test_opts * opts)143 static void test_stream_client_close_server(const struct test_opts *opts)
144 {
145 int fd;
146
147 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
148 if (fd < 0) {
149 perror("accept");
150 exit(EXIT_FAILURE);
151 }
152
153 /* Wait for the remote to close the connection, before check
154 * -EPIPE error on send.
155 */
156 vsock_wait_remote_close(fd);
157
158 send_byte(fd, -EPIPE, 0);
159 recv_byte(fd, 1, 0);
160 recv_byte(fd, 0, 0);
161 close(fd);
162 }
163
test_stream_server_close_client(const struct test_opts * opts)164 static void test_stream_server_close_client(const struct test_opts *opts)
165 {
166 int fd;
167
168 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
169 if (fd < 0) {
170 perror("connect");
171 exit(EXIT_FAILURE);
172 }
173
174 /* Wait for the remote to close the connection, before check
175 * -EPIPE error on send.
176 */
177 vsock_wait_remote_close(fd);
178
179 send_byte(fd, -EPIPE, 0);
180 recv_byte(fd, 1, 0);
181 recv_byte(fd, 0, 0);
182 close(fd);
183 }
184
test_stream_server_close_server(const struct test_opts * opts)185 static void test_stream_server_close_server(const struct test_opts *opts)
186 {
187 int fd;
188
189 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
190 if (fd < 0) {
191 perror("accept");
192 exit(EXIT_FAILURE);
193 }
194
195 send_byte(fd, 1, 0);
196 close(fd);
197 }
198
199 /* With the standard socket sizes, VMCI is able to support about 100
200 * concurrent stream connections.
201 */
202 #define MULTICONN_NFDS 100
203
test_stream_multiconn_client(const struct test_opts * opts)204 static void test_stream_multiconn_client(const struct test_opts *opts)
205 {
206 int fds[MULTICONN_NFDS];
207 int i;
208
209 for (i = 0; i < MULTICONN_NFDS; i++) {
210 fds[i] = vsock_stream_connect(opts->peer_cid, opts->peer_port);
211 if (fds[i] < 0) {
212 perror("connect");
213 exit(EXIT_FAILURE);
214 }
215 }
216
217 for (i = 0; i < MULTICONN_NFDS; i++) {
218 if (i % 2)
219 recv_byte(fds[i], 1, 0);
220 else
221 send_byte(fds[i], 1, 0);
222 }
223
224 for (i = 0; i < MULTICONN_NFDS; i++)
225 close(fds[i]);
226 }
227
test_stream_multiconn_server(const struct test_opts * opts)228 static void test_stream_multiconn_server(const struct test_opts *opts)
229 {
230 int fds[MULTICONN_NFDS];
231 int i;
232
233 for (i = 0; i < MULTICONN_NFDS; i++) {
234 fds[i] = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
235 if (fds[i] < 0) {
236 perror("accept");
237 exit(EXIT_FAILURE);
238 }
239 }
240
241 for (i = 0; i < MULTICONN_NFDS; i++) {
242 if (i % 2)
243 send_byte(fds[i], 1, 0);
244 else
245 recv_byte(fds[i], 1, 0);
246 }
247
248 for (i = 0; i < MULTICONN_NFDS; i++)
249 close(fds[i]);
250 }
251
252 #define MSG_PEEK_BUF_LEN 64
253
test_msg_peek_client(const struct test_opts * opts,bool seqpacket)254 static void test_msg_peek_client(const struct test_opts *opts,
255 bool seqpacket)
256 {
257 unsigned char buf[MSG_PEEK_BUF_LEN];
258 int fd;
259 int i;
260
261 if (seqpacket)
262 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
263 else
264 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
265
266 if (fd < 0) {
267 perror("connect");
268 exit(EXIT_FAILURE);
269 }
270
271 for (i = 0; i < sizeof(buf); i++)
272 buf[i] = rand() & 0xFF;
273
274 control_expectln("SRVREADY");
275
276 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
277
278 close(fd);
279 }
280
test_msg_peek_server(const struct test_opts * opts,bool seqpacket)281 static void test_msg_peek_server(const struct test_opts *opts,
282 bool seqpacket)
283 {
284 unsigned char buf_half[MSG_PEEK_BUF_LEN / 2];
285 unsigned char buf_normal[MSG_PEEK_BUF_LEN];
286 unsigned char buf_peek[MSG_PEEK_BUF_LEN];
287 int fd;
288
289 if (seqpacket)
290 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
291 else
292 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
293
294 if (fd < 0) {
295 perror("accept");
296 exit(EXIT_FAILURE);
297 }
298
299 /* Peek from empty socket. */
300 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK | MSG_DONTWAIT,
301 -EAGAIN);
302
303 control_writeln("SRVREADY");
304
305 /* Peek part of data. */
306 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK, sizeof(buf_half));
307
308 /* Peek whole data. */
309 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK, sizeof(buf_peek));
310
311 /* Compare partial and full peek. */
312 if (memcmp(buf_half, buf_peek, sizeof(buf_half))) {
313 fprintf(stderr, "Partial peek data mismatch\n");
314 exit(EXIT_FAILURE);
315 }
316
317 if (seqpacket) {
318 /* This type of socket supports MSG_TRUNC flag,
319 * so check it with MSG_PEEK. We must get length
320 * of the message.
321 */
322 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK | MSG_TRUNC,
323 sizeof(buf_peek));
324 }
325
326 recv_buf(fd, buf_normal, sizeof(buf_normal), 0, sizeof(buf_normal));
327
328 /* Compare full peek and normal read. */
329 if (memcmp(buf_peek, buf_normal, sizeof(buf_peek))) {
330 fprintf(stderr, "Full peek data mismatch\n");
331 exit(EXIT_FAILURE);
332 }
333
334 close(fd);
335 }
336
test_stream_msg_peek_client(const struct test_opts * opts)337 static void test_stream_msg_peek_client(const struct test_opts *opts)
338 {
339 return test_msg_peek_client(opts, false);
340 }
341
test_stream_msg_peek_server(const struct test_opts * opts)342 static void test_stream_msg_peek_server(const struct test_opts *opts)
343 {
344 return test_msg_peek_server(opts, false);
345 }
346
347 #define SOCK_BUF_SIZE (2 * 1024 * 1024)
348 #define MAX_MSG_PAGES 4
349
test_seqpacket_msg_bounds_client(const struct test_opts * opts)350 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
351 {
352 unsigned long curr_hash;
353 size_t max_msg_size;
354 int page_size;
355 int msg_count;
356 int fd;
357
358 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
359 if (fd < 0) {
360 perror("connect");
361 exit(EXIT_FAILURE);
362 }
363
364 /* Wait, until receiver sets buffer size. */
365 control_expectln("SRVREADY");
366
367 curr_hash = 0;
368 page_size = getpagesize();
369 max_msg_size = MAX_MSG_PAGES * page_size;
370 msg_count = SOCK_BUF_SIZE / max_msg_size;
371
372 for (int i = 0; i < msg_count; i++) {
373 size_t buf_size;
374 int flags;
375 void *buf;
376
377 /* Use "small" buffers and "big" buffers. */
378 if (i & 1)
379 buf_size = page_size +
380 (rand() % (max_msg_size - page_size));
381 else
382 buf_size = 1 + (rand() % page_size);
383
384 buf = malloc(buf_size);
385
386 if (!buf) {
387 perror("malloc");
388 exit(EXIT_FAILURE);
389 }
390
391 memset(buf, rand() & 0xff, buf_size);
392 /* Set at least one MSG_EOR + some random. */
393 if (i == (msg_count / 2) || (rand() & 1)) {
394 flags = MSG_EOR;
395 curr_hash++;
396 } else {
397 flags = 0;
398 }
399
400 send_buf(fd, buf, buf_size, flags, buf_size);
401
402 /*
403 * Hash sum is computed at both client and server in
404 * the same way:
405 * H += hash('message data')
406 * Such hash "controls" both data integrity and message
407 * bounds. After data exchange, both sums are compared
408 * using control socket, and if message bounds wasn't
409 * broken - two values must be equal.
410 */
411 curr_hash += hash_djb2(buf, buf_size);
412 free(buf);
413 }
414
415 control_writeln("SENDDONE");
416 control_writeulong(curr_hash);
417 close(fd);
418 }
419
test_seqpacket_msg_bounds_server(const struct test_opts * opts)420 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
421 {
422 unsigned long long sock_buf_size;
423 unsigned long remote_hash;
424 unsigned long curr_hash;
425 int fd;
426 struct msghdr msg = {0};
427 struct iovec iov = {0};
428
429 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
430 if (fd < 0) {
431 perror("accept");
432 exit(EXIT_FAILURE);
433 }
434
435 sock_buf_size = SOCK_BUF_SIZE;
436
437 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
438 sock_buf_size,
439 "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
440
441 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
442 sock_buf_size,
443 "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
444
445 /* Ready to receive data. */
446 control_writeln("SRVREADY");
447 /* Wait, until peer sends whole data. */
448 control_expectln("SENDDONE");
449 iov.iov_len = MAX_MSG_PAGES * getpagesize();
450 iov.iov_base = malloc(iov.iov_len);
451 if (!iov.iov_base) {
452 perror("malloc");
453 exit(EXIT_FAILURE);
454 }
455
456 msg.msg_iov = &iov;
457 msg.msg_iovlen = 1;
458
459 curr_hash = 0;
460
461 while (1) {
462 ssize_t recv_size;
463
464 recv_size = recvmsg(fd, &msg, 0);
465
466 if (!recv_size)
467 break;
468
469 if (recv_size < 0) {
470 perror("recvmsg");
471 exit(EXIT_FAILURE);
472 }
473
474 if (msg.msg_flags & MSG_EOR)
475 curr_hash++;
476
477 curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
478 }
479
480 free(iov.iov_base);
481 close(fd);
482 remote_hash = control_readulong();
483
484 if (curr_hash != remote_hash) {
485 fprintf(stderr, "Message bounds broken\n");
486 exit(EXIT_FAILURE);
487 }
488 }
489
490 #define MESSAGE_TRUNC_SZ 32
test_seqpacket_msg_trunc_client(const struct test_opts * opts)491 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
492 {
493 int fd;
494 char buf[MESSAGE_TRUNC_SZ];
495
496 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
497 if (fd < 0) {
498 perror("connect");
499 exit(EXIT_FAILURE);
500 }
501
502 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
503
504 control_writeln("SENDDONE");
505 close(fd);
506 }
507
test_seqpacket_msg_trunc_server(const struct test_opts * opts)508 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
509 {
510 int fd;
511 char buf[MESSAGE_TRUNC_SZ / 2];
512 struct msghdr msg = {0};
513 struct iovec iov = {0};
514
515 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
516 if (fd < 0) {
517 perror("accept");
518 exit(EXIT_FAILURE);
519 }
520
521 control_expectln("SENDDONE");
522 iov.iov_base = buf;
523 iov.iov_len = sizeof(buf);
524 msg.msg_iov = &iov;
525 msg.msg_iovlen = 1;
526
527 ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
528
529 if (ret != MESSAGE_TRUNC_SZ) {
530 printf("%zi\n", ret);
531 perror("MSG_TRUNC doesn't work");
532 exit(EXIT_FAILURE);
533 }
534
535 if (!(msg.msg_flags & MSG_TRUNC)) {
536 fprintf(stderr, "MSG_TRUNC expected\n");
537 exit(EXIT_FAILURE);
538 }
539
540 close(fd);
541 }
542
current_nsec(void)543 static time_t current_nsec(void)
544 {
545 struct timespec ts;
546
547 if (clock_gettime(CLOCK_REALTIME, &ts)) {
548 perror("clock_gettime(3) failed");
549 exit(EXIT_FAILURE);
550 }
551
552 return (ts.tv_sec * NSEC_PER_SEC) + ts.tv_nsec;
553 }
554
555 #define RCVTIMEO_TIMEOUT_SEC 1
556 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
557
test_seqpacket_timeout_client(const struct test_opts * opts)558 static void test_seqpacket_timeout_client(const struct test_opts *opts)
559 {
560 int fd;
561 struct timeval tv;
562 char dummy;
563 time_t read_enter_ns;
564 time_t read_overhead_ns;
565
566 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
567 if (fd < 0) {
568 perror("connect");
569 exit(EXIT_FAILURE);
570 }
571
572 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
573 tv.tv_usec = 0;
574
575 setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv,
576 "setsockopt(SO_RCVTIMEO)");
577
578 read_enter_ns = current_nsec();
579
580 if (read(fd, &dummy, sizeof(dummy)) != -1) {
581 fprintf(stderr,
582 "expected 'dummy' read(2) failure\n");
583 exit(EXIT_FAILURE);
584 }
585
586 if (errno != EAGAIN) {
587 perror("EAGAIN expected");
588 exit(EXIT_FAILURE);
589 }
590
591 read_overhead_ns = current_nsec() - read_enter_ns -
592 NSEC_PER_SEC * RCVTIMEO_TIMEOUT_SEC;
593
594 if (read_overhead_ns > READ_OVERHEAD_NSEC) {
595 fprintf(stderr,
596 "too much time in read(2), %lu > %i ns\n",
597 read_overhead_ns, READ_OVERHEAD_NSEC);
598 exit(EXIT_FAILURE);
599 }
600
601 control_writeln("WAITDONE");
602 close(fd);
603 }
604
test_seqpacket_timeout_server(const struct test_opts * opts)605 static void test_seqpacket_timeout_server(const struct test_opts *opts)
606 {
607 int fd;
608
609 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
610 if (fd < 0) {
611 perror("accept");
612 exit(EXIT_FAILURE);
613 }
614
615 control_expectln("WAITDONE");
616 close(fd);
617 }
618
test_seqpacket_bigmsg_client(const struct test_opts * opts)619 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
620 {
621 unsigned long long sock_buf_size;
622 size_t buf_size;
623 socklen_t len;
624 void *data;
625 int fd;
626
627 len = sizeof(sock_buf_size);
628
629 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
630 if (fd < 0) {
631 perror("connect");
632 exit(EXIT_FAILURE);
633 }
634
635 if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
636 &sock_buf_size, &len)) {
637 perror("getsockopt");
638 exit(EXIT_FAILURE);
639 }
640
641 sock_buf_size++;
642
643 /* size_t can be < unsigned long long */
644 buf_size = (size_t)sock_buf_size;
645 if (buf_size != sock_buf_size) {
646 fprintf(stderr, "Returned BUFFER_SIZE too large\n");
647 exit(EXIT_FAILURE);
648 }
649
650 data = malloc(buf_size);
651 if (!data) {
652 perror("malloc");
653 exit(EXIT_FAILURE);
654 }
655
656 send_buf(fd, data, buf_size, 0, -EMSGSIZE);
657
658 control_writeln("CLISENT");
659
660 free(data);
661 close(fd);
662 }
663
test_seqpacket_bigmsg_server(const struct test_opts * opts)664 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
665 {
666 int fd;
667
668 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
669 if (fd < 0) {
670 perror("accept");
671 exit(EXIT_FAILURE);
672 }
673
674 control_expectln("CLISENT");
675
676 close(fd);
677 }
678
679 #define BUF_PATTERN_1 'a'
680 #define BUF_PATTERN_2 'b'
681
test_seqpacket_invalid_rec_buffer_client(const struct test_opts * opts)682 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
683 {
684 int fd;
685 unsigned char *buf1;
686 unsigned char *buf2;
687 int buf_size = getpagesize() * 3;
688
689 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
690 if (fd < 0) {
691 perror("connect");
692 exit(EXIT_FAILURE);
693 }
694
695 buf1 = malloc(buf_size);
696 if (!buf1) {
697 perror("'malloc()' for 'buf1'");
698 exit(EXIT_FAILURE);
699 }
700
701 buf2 = malloc(buf_size);
702 if (!buf2) {
703 perror("'malloc()' for 'buf2'");
704 exit(EXIT_FAILURE);
705 }
706
707 memset(buf1, BUF_PATTERN_1, buf_size);
708 memset(buf2, BUF_PATTERN_2, buf_size);
709
710 send_buf(fd, buf1, buf_size, 0, buf_size);
711
712 send_buf(fd, buf2, buf_size, 0, buf_size);
713
714 close(fd);
715 }
716
test_seqpacket_invalid_rec_buffer_server(const struct test_opts * opts)717 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
718 {
719 int fd;
720 unsigned char *broken_buf;
721 unsigned char *valid_buf;
722 int page_size = getpagesize();
723 int buf_size = page_size * 3;
724 ssize_t res;
725 int prot = PROT_READ | PROT_WRITE;
726 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
727 int i;
728
729 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
730 if (fd < 0) {
731 perror("accept");
732 exit(EXIT_FAILURE);
733 }
734
735 /* Setup first buffer. */
736 broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
737 if (broken_buf == MAP_FAILED) {
738 perror("mmap for 'broken_buf'");
739 exit(EXIT_FAILURE);
740 }
741
742 /* Unmap "hole" in buffer. */
743 if (munmap(broken_buf + page_size, page_size)) {
744 perror("'broken_buf' setup");
745 exit(EXIT_FAILURE);
746 }
747
748 valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
749 if (valid_buf == MAP_FAILED) {
750 perror("mmap for 'valid_buf'");
751 exit(EXIT_FAILURE);
752 }
753
754 /* Try to fill buffer with unmapped middle. */
755 res = read(fd, broken_buf, buf_size);
756 if (res != -1) {
757 fprintf(stderr,
758 "expected 'broken_buf' read(2) failure, got %zi\n",
759 res);
760 exit(EXIT_FAILURE);
761 }
762
763 if (errno != EFAULT) {
764 perror("unexpected errno of 'broken_buf'");
765 exit(EXIT_FAILURE);
766 }
767
768 /* Try to fill valid buffer. */
769 res = read(fd, valid_buf, buf_size);
770 if (res < 0) {
771 perror("unexpected 'valid_buf' read(2) failure");
772 exit(EXIT_FAILURE);
773 }
774
775 if (res != buf_size) {
776 fprintf(stderr,
777 "invalid 'valid_buf' read(2), expected %i, got %zi\n",
778 buf_size, res);
779 exit(EXIT_FAILURE);
780 }
781
782 for (i = 0; i < buf_size; i++) {
783 if (valid_buf[i] != BUF_PATTERN_2) {
784 fprintf(stderr,
785 "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
786 i, BUF_PATTERN_2, valid_buf[i]);
787 exit(EXIT_FAILURE);
788 }
789 }
790
791 /* Unmap buffers. */
792 munmap(broken_buf, page_size);
793 munmap(broken_buf + page_size * 2, page_size);
794 munmap(valid_buf, buf_size);
795 close(fd);
796 }
797
798 #define RCVLOWAT_BUF_SIZE 128
799
test_stream_poll_rcvlowat_server(const struct test_opts * opts)800 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
801 {
802 int fd;
803 int i;
804
805 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
806 if (fd < 0) {
807 perror("accept");
808 exit(EXIT_FAILURE);
809 }
810
811 /* Send 1 byte. */
812 send_byte(fd, 1, 0);
813
814 control_writeln("SRVSENT");
815
816 /* Wait until client is ready to receive rest of data. */
817 control_expectln("CLNSENT");
818
819 for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
820 send_byte(fd, 1, 0);
821
822 /* Keep socket in active state. */
823 control_expectln("POLLDONE");
824
825 close(fd);
826 }
827
test_stream_poll_rcvlowat_client(const struct test_opts * opts)828 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
829 {
830 int lowat_val = RCVLOWAT_BUF_SIZE;
831 char buf[RCVLOWAT_BUF_SIZE];
832 struct pollfd fds;
833 short poll_flags;
834 int fd;
835
836 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
837 if (fd < 0) {
838 perror("connect");
839 exit(EXIT_FAILURE);
840 }
841
842 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
843 lowat_val, "setsockopt(SO_RCVLOWAT)");
844
845 control_expectln("SRVSENT");
846
847 /* At this point, server sent 1 byte. */
848 fds.fd = fd;
849 poll_flags = POLLIN | POLLRDNORM;
850 fds.events = poll_flags;
851
852 /* Try to wait for 1 sec. */
853 if (poll(&fds, 1, 1000) < 0) {
854 perror("poll");
855 exit(EXIT_FAILURE);
856 }
857
858 /* poll() must return nothing. */
859 if (fds.revents) {
860 fprintf(stderr, "Unexpected poll result %hx\n",
861 fds.revents);
862 exit(EXIT_FAILURE);
863 }
864
865 /* Tell server to send rest of data. */
866 control_writeln("CLNSENT");
867
868 /* Poll for data. */
869 if (poll(&fds, 1, 10000) < 0) {
870 perror("poll");
871 exit(EXIT_FAILURE);
872 }
873
874 /* Only these two bits are expected. */
875 if (fds.revents != poll_flags) {
876 fprintf(stderr, "Unexpected poll result %hx\n",
877 fds.revents);
878 exit(EXIT_FAILURE);
879 }
880
881 /* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
882 * will be returned.
883 */
884 recv_buf(fd, buf, sizeof(buf), MSG_DONTWAIT, RCVLOWAT_BUF_SIZE);
885
886 control_writeln("POLLDONE");
887
888 close(fd);
889 }
890
891 #define INV_BUF_TEST_DATA_LEN 512
892
test_inv_buf_client(const struct test_opts * opts,bool stream)893 static void test_inv_buf_client(const struct test_opts *opts, bool stream)
894 {
895 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
896 ssize_t expected_ret;
897 int fd;
898
899 if (stream)
900 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
901 else
902 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
903
904 if (fd < 0) {
905 perror("connect");
906 exit(EXIT_FAILURE);
907 }
908
909 control_expectln("SENDDONE");
910
911 /* Use invalid buffer here. */
912 recv_buf(fd, NULL, sizeof(data), 0, -EFAULT);
913
914 if (stream) {
915 /* For SOCK_STREAM we must continue reading. */
916 expected_ret = sizeof(data);
917 } else {
918 /* For SOCK_SEQPACKET socket's queue must be empty. */
919 expected_ret = -EAGAIN;
920 }
921
922 recv_buf(fd, data, sizeof(data), MSG_DONTWAIT, expected_ret);
923
924 control_writeln("DONE");
925
926 close(fd);
927 }
928
test_inv_buf_server(const struct test_opts * opts,bool stream)929 static void test_inv_buf_server(const struct test_opts *opts, bool stream)
930 {
931 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
932 int fd;
933
934 if (stream)
935 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
936 else
937 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
938
939 if (fd < 0) {
940 perror("accept");
941 exit(EXIT_FAILURE);
942 }
943
944 send_buf(fd, data, sizeof(data), 0, sizeof(data));
945
946 control_writeln("SENDDONE");
947
948 control_expectln("DONE");
949
950 close(fd);
951 }
952
test_stream_inv_buf_client(const struct test_opts * opts)953 static void test_stream_inv_buf_client(const struct test_opts *opts)
954 {
955 test_inv_buf_client(opts, true);
956 }
957
test_stream_inv_buf_server(const struct test_opts * opts)958 static void test_stream_inv_buf_server(const struct test_opts *opts)
959 {
960 test_inv_buf_server(opts, true);
961 }
962
test_seqpacket_inv_buf_client(const struct test_opts * opts)963 static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
964 {
965 test_inv_buf_client(opts, false);
966 }
967
test_seqpacket_inv_buf_server(const struct test_opts * opts)968 static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
969 {
970 test_inv_buf_server(opts, false);
971 }
972
973 #define HELLO_STR "HELLO"
974 #define WORLD_STR "WORLD"
975
test_stream_virtio_skb_merge_client(const struct test_opts * opts)976 static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
977 {
978 int fd;
979
980 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
981 if (fd < 0) {
982 perror("connect");
983 exit(EXIT_FAILURE);
984 }
985
986 /* Send first skbuff. */
987 send_buf(fd, HELLO_STR, strlen(HELLO_STR), 0, strlen(HELLO_STR));
988
989 control_writeln("SEND0");
990 /* Peer reads part of first skbuff. */
991 control_expectln("REPLY0");
992
993 /* Send second skbuff, it will be appended to the first. */
994 send_buf(fd, WORLD_STR, strlen(WORLD_STR), 0, strlen(WORLD_STR));
995
996 control_writeln("SEND1");
997 /* Peer reads merged skbuff packet. */
998 control_expectln("REPLY1");
999
1000 close(fd);
1001 }
1002
test_stream_virtio_skb_merge_server(const struct test_opts * opts)1003 static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
1004 {
1005 size_t read = 0, to_read;
1006 unsigned char buf[64];
1007 int fd;
1008
1009 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1010 if (fd < 0) {
1011 perror("accept");
1012 exit(EXIT_FAILURE);
1013 }
1014
1015 control_expectln("SEND0");
1016
1017 /* Read skbuff partially. */
1018 to_read = 2;
1019 recv_buf(fd, buf + read, to_read, 0, to_read);
1020 read += to_read;
1021
1022 control_writeln("REPLY0");
1023 control_expectln("SEND1");
1024
1025 /* Read the rest of both buffers */
1026 to_read = strlen(HELLO_STR WORLD_STR) - read;
1027 recv_buf(fd, buf + read, to_read, 0, to_read);
1028 read += to_read;
1029
1030 /* No more bytes should be there */
1031 to_read = sizeof(buf) - read;
1032 recv_buf(fd, buf + read, to_read, MSG_DONTWAIT, -EAGAIN);
1033
1034 if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
1035 fprintf(stderr, "pattern mismatch\n");
1036 exit(EXIT_FAILURE);
1037 }
1038
1039 control_writeln("REPLY1");
1040
1041 close(fd);
1042 }
1043
test_seqpacket_msg_peek_client(const struct test_opts * opts)1044 static void test_seqpacket_msg_peek_client(const struct test_opts *opts)
1045 {
1046 return test_msg_peek_client(opts, true);
1047 }
1048
test_seqpacket_msg_peek_server(const struct test_opts * opts)1049 static void test_seqpacket_msg_peek_server(const struct test_opts *opts)
1050 {
1051 return test_msg_peek_server(opts, true);
1052 }
1053
1054 static sig_atomic_t have_sigpipe;
1055
sigpipe(int signo)1056 static void sigpipe(int signo)
1057 {
1058 have_sigpipe = 1;
1059 }
1060
test_stream_check_sigpipe(int fd)1061 static void test_stream_check_sigpipe(int fd)
1062 {
1063 ssize_t res;
1064
1065 have_sigpipe = 0;
1066
1067 res = send(fd, "A", 1, 0);
1068 if (res != -1) {
1069 fprintf(stderr, "expected send(2) failure, got %zi\n", res);
1070 exit(EXIT_FAILURE);
1071 }
1072
1073 if (!have_sigpipe) {
1074 fprintf(stderr, "SIGPIPE expected\n");
1075 exit(EXIT_FAILURE);
1076 }
1077
1078 have_sigpipe = 0;
1079
1080 res = send(fd, "A", 1, MSG_NOSIGNAL);
1081 if (res != -1) {
1082 fprintf(stderr, "expected send(2) failure, got %zi\n", res);
1083 exit(EXIT_FAILURE);
1084 }
1085
1086 if (have_sigpipe) {
1087 fprintf(stderr, "SIGPIPE not expected\n");
1088 exit(EXIT_FAILURE);
1089 }
1090 }
1091
test_stream_shutwr_client(const struct test_opts * opts)1092 static void test_stream_shutwr_client(const struct test_opts *opts)
1093 {
1094 int fd;
1095
1096 struct sigaction act = {
1097 .sa_handler = sigpipe,
1098 };
1099
1100 sigaction(SIGPIPE, &act, NULL);
1101
1102 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1103 if (fd < 0) {
1104 perror("connect");
1105 exit(EXIT_FAILURE);
1106 }
1107
1108 if (shutdown(fd, SHUT_WR)) {
1109 perror("shutdown");
1110 exit(EXIT_FAILURE);
1111 }
1112
1113 test_stream_check_sigpipe(fd);
1114
1115 control_writeln("CLIENTDONE");
1116
1117 close(fd);
1118 }
1119
test_stream_shutwr_server(const struct test_opts * opts)1120 static void test_stream_shutwr_server(const struct test_opts *opts)
1121 {
1122 int fd;
1123
1124 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1125 if (fd < 0) {
1126 perror("accept");
1127 exit(EXIT_FAILURE);
1128 }
1129
1130 control_expectln("CLIENTDONE");
1131
1132 close(fd);
1133 }
1134
test_stream_shutrd_client(const struct test_opts * opts)1135 static void test_stream_shutrd_client(const struct test_opts *opts)
1136 {
1137 int fd;
1138
1139 struct sigaction act = {
1140 .sa_handler = sigpipe,
1141 };
1142
1143 sigaction(SIGPIPE, &act, NULL);
1144
1145 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1146 if (fd < 0) {
1147 perror("connect");
1148 exit(EXIT_FAILURE);
1149 }
1150
1151 control_expectln("SHUTRDDONE");
1152
1153 test_stream_check_sigpipe(fd);
1154
1155 control_writeln("CLIENTDONE");
1156
1157 close(fd);
1158 }
1159
test_stream_shutrd_server(const struct test_opts * opts)1160 static void test_stream_shutrd_server(const struct test_opts *opts)
1161 {
1162 int fd;
1163
1164 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1165 if (fd < 0) {
1166 perror("accept");
1167 exit(EXIT_FAILURE);
1168 }
1169
1170 if (shutdown(fd, SHUT_RD)) {
1171 perror("shutdown");
1172 exit(EXIT_FAILURE);
1173 }
1174
1175 control_writeln("SHUTRDDONE");
1176 control_expectln("CLIENTDONE");
1177
1178 close(fd);
1179 }
1180
test_double_bind_connect_server(const struct test_opts * opts)1181 static void test_double_bind_connect_server(const struct test_opts *opts)
1182 {
1183 int listen_fd, client_fd, i;
1184 struct sockaddr_vm sa_client;
1185 socklen_t socklen_client = sizeof(sa_client);
1186
1187 listen_fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1188
1189 for (i = 0; i < 2; i++) {
1190 control_writeln("LISTENING");
1191
1192 timeout_begin(TIMEOUT);
1193 do {
1194 client_fd = accept(listen_fd, (struct sockaddr *)&sa_client,
1195 &socklen_client);
1196 timeout_check("accept");
1197 } while (client_fd < 0 && errno == EINTR);
1198 timeout_end();
1199
1200 if (client_fd < 0) {
1201 perror("accept");
1202 exit(EXIT_FAILURE);
1203 }
1204
1205 /* Waiting for remote peer to close connection */
1206 vsock_wait_remote_close(client_fd);
1207 }
1208
1209 close(listen_fd);
1210 }
1211
test_double_bind_connect_client(const struct test_opts * opts)1212 static void test_double_bind_connect_client(const struct test_opts *opts)
1213 {
1214 int i, client_fd;
1215
1216 for (i = 0; i < 2; i++) {
1217 /* Wait until server is ready to accept a new connection */
1218 control_expectln("LISTENING");
1219
1220 /* We use 'peer_port + 1' as "some" port for the 'bind()'
1221 * call. It is safe for overflow, but must be considered,
1222 * when running multiple test applications simultaneously
1223 * where 'peer-port' argument differs by 1.
1224 */
1225 client_fd = vsock_bind_connect(opts->peer_cid, opts->peer_port,
1226 opts->peer_port + 1, SOCK_STREAM);
1227
1228 close(client_fd);
1229 }
1230 }
1231
1232 #define MSG_BUF_IOCTL_LEN 64
test_unsent_bytes_server(const struct test_opts * opts,int type)1233 static void test_unsent_bytes_server(const struct test_opts *opts, int type)
1234 {
1235 unsigned char buf[MSG_BUF_IOCTL_LEN];
1236 int client_fd;
1237
1238 client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
1239 if (client_fd < 0) {
1240 perror("accept");
1241 exit(EXIT_FAILURE);
1242 }
1243
1244 recv_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
1245 control_writeln("RECEIVED");
1246
1247 close(client_fd);
1248 }
1249
test_unsent_bytes_client(const struct test_opts * opts,int type)1250 static void test_unsent_bytes_client(const struct test_opts *opts, int type)
1251 {
1252 unsigned char buf[MSG_BUF_IOCTL_LEN];
1253 int ret, fd, sock_bytes_unsent;
1254
1255 fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
1256 if (fd < 0) {
1257 perror("connect");
1258 exit(EXIT_FAILURE);
1259 }
1260
1261 for (int i = 0; i < sizeof(buf); i++)
1262 buf[i] = rand() & 0xFF;
1263
1264 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
1265 control_expectln("RECEIVED");
1266
1267 ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
1268 if (ret < 0) {
1269 if (errno == EOPNOTSUPP) {
1270 fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n");
1271 } else {
1272 perror("ioctl");
1273 exit(EXIT_FAILURE);
1274 }
1275 } else if (ret == 0 && sock_bytes_unsent != 0) {
1276 fprintf(stderr,
1277 "Unexpected 'SIOCOUTQ' value, expected 0, got %i\n",
1278 sock_bytes_unsent);
1279 exit(EXIT_FAILURE);
1280 }
1281
1282 close(fd);
1283 }
1284
test_stream_unsent_bytes_client(const struct test_opts * opts)1285 static void test_stream_unsent_bytes_client(const struct test_opts *opts)
1286 {
1287 test_unsent_bytes_client(opts, SOCK_STREAM);
1288 }
1289
test_stream_unsent_bytes_server(const struct test_opts * opts)1290 static void test_stream_unsent_bytes_server(const struct test_opts *opts)
1291 {
1292 test_unsent_bytes_server(opts, SOCK_STREAM);
1293 }
1294
test_seqpacket_unsent_bytes_client(const struct test_opts * opts)1295 static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts)
1296 {
1297 test_unsent_bytes_client(opts, SOCK_SEQPACKET);
1298 }
1299
test_seqpacket_unsent_bytes_server(const struct test_opts * opts)1300 static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
1301 {
1302 test_unsent_bytes_server(opts, SOCK_SEQPACKET);
1303 }
1304
1305 #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
1306 /* This define is the same as in 'include/linux/virtio_vsock.h':
1307 * it is used to decide when to send credit update message during
1308 * reading from rx queue of a socket. Value and its usage in
1309 * kernel is important for this test.
1310 */
1311 #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
1312
test_stream_rcvlowat_def_cred_upd_client(const struct test_opts * opts)1313 static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opts)
1314 {
1315 size_t buf_size;
1316 void *buf;
1317 int fd;
1318
1319 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1320 if (fd < 0) {
1321 perror("connect");
1322 exit(EXIT_FAILURE);
1323 }
1324
1325 /* Send 1 byte more than peer's buffer size. */
1326 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE + 1;
1327
1328 buf = malloc(buf_size);
1329 if (!buf) {
1330 perror("malloc");
1331 exit(EXIT_FAILURE);
1332 }
1333
1334 /* Wait until peer sets needed buffer size. */
1335 recv_byte(fd, 1, 0);
1336
1337 if (send(fd, buf, buf_size, 0) != buf_size) {
1338 perror("send failed");
1339 exit(EXIT_FAILURE);
1340 }
1341
1342 free(buf);
1343 close(fd);
1344 }
1345
test_stream_credit_update_test(const struct test_opts * opts,bool low_rx_bytes_test)1346 static void test_stream_credit_update_test(const struct test_opts *opts,
1347 bool low_rx_bytes_test)
1348 {
1349 int recv_buf_size;
1350 struct pollfd fds;
1351 size_t buf_size;
1352 unsigned long long sock_buf_size;
1353 void *buf;
1354 int fd;
1355
1356 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1357 if (fd < 0) {
1358 perror("accept");
1359 exit(EXIT_FAILURE);
1360 }
1361
1362 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE;
1363
1364 /* size_t can be < unsigned long long */
1365 sock_buf_size = buf_size;
1366
1367 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
1368 sock_buf_size,
1369 "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
1370
1371 if (low_rx_bytes_test) {
1372 /* Set new SO_RCVLOWAT here. This enables sending credit
1373 * update when number of bytes if our rx queue become <
1374 * SO_RCVLOWAT value.
1375 */
1376 recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1377
1378 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
1379 recv_buf_size, "setsockopt(SO_RCVLOWAT)");
1380 }
1381
1382 /* Send one dummy byte here, because 'setsockopt()' above also
1383 * sends special packet which tells sender to update our buffer
1384 * size. This 'send_byte()' will serialize such packet with data
1385 * reads in a loop below. Sender starts transmission only when
1386 * it receives this single byte.
1387 */
1388 send_byte(fd, 1, 0);
1389
1390 buf = malloc(buf_size);
1391 if (!buf) {
1392 perror("malloc");
1393 exit(EXIT_FAILURE);
1394 }
1395
1396 /* Wait until there will be 128KB of data in rx queue. */
1397 while (1) {
1398 ssize_t res;
1399
1400 res = recv(fd, buf, buf_size, MSG_PEEK);
1401 if (res == buf_size)
1402 break;
1403
1404 if (res <= 0) {
1405 fprintf(stderr, "unexpected 'recv()' return: %zi\n", res);
1406 exit(EXIT_FAILURE);
1407 }
1408 }
1409
1410 /* There is 128KB of data in the socket's rx queue, dequeue first
1411 * 64KB, credit update is sent if 'low_rx_bytes_test' == true.
1412 * Otherwise, credit update is sent in 'if (!low_rx_bytes_test)'.
1413 */
1414 recv_buf_size = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1415 recv_buf(fd, buf, recv_buf_size, 0, recv_buf_size);
1416
1417 if (!low_rx_bytes_test) {
1418 recv_buf_size++;
1419
1420 /* Updating SO_RCVLOWAT will send credit update. */
1421 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
1422 recv_buf_size, "setsockopt(SO_RCVLOWAT)");
1423 }
1424
1425 fds.fd = fd;
1426 fds.events = POLLIN | POLLRDNORM | POLLERR |
1427 POLLRDHUP | POLLHUP;
1428
1429 /* This 'poll()' will return once we receive last byte
1430 * sent by client.
1431 */
1432 if (poll(&fds, 1, -1) < 0) {
1433 perror("poll");
1434 exit(EXIT_FAILURE);
1435 }
1436
1437 if (fds.revents & POLLERR) {
1438 fprintf(stderr, "'poll()' error\n");
1439 exit(EXIT_FAILURE);
1440 }
1441
1442 if (fds.revents & (POLLIN | POLLRDNORM)) {
1443 recv_buf(fd, buf, recv_buf_size, MSG_DONTWAIT, recv_buf_size);
1444 } else {
1445 /* These flags must be set, as there is at
1446 * least 64KB of data ready to read.
1447 */
1448 fprintf(stderr, "POLLIN | POLLRDNORM expected\n");
1449 exit(EXIT_FAILURE);
1450 }
1451
1452 free(buf);
1453 close(fd);
1454 }
1455
test_stream_cred_upd_on_low_rx_bytes(const struct test_opts * opts)1456 static void test_stream_cred_upd_on_low_rx_bytes(const struct test_opts *opts)
1457 {
1458 test_stream_credit_update_test(opts, true);
1459 }
1460
test_stream_cred_upd_on_set_rcvlowat(const struct test_opts * opts)1461 static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)
1462 {
1463 test_stream_credit_update_test(opts, false);
1464 }
1465
1466 /* The goal of test leak_acceptq is to stress the race between connect() and
1467 * close(listener). Implementation of client/server loops boils down to:
1468 *
1469 * client server
1470 * ------ ------
1471 * write(CONTINUE)
1472 * expect(CONTINUE)
1473 * listen()
1474 * write(LISTENING)
1475 * expect(LISTENING)
1476 * connect() close()
1477 */
1478 #define ACCEPTQ_LEAK_RACE_TIMEOUT 2 /* seconds */
1479
test_stream_leak_acceptq_client(const struct test_opts * opts)1480 static void test_stream_leak_acceptq_client(const struct test_opts *opts)
1481 {
1482 time_t tout;
1483 int fd;
1484
1485 tout = current_nsec() + ACCEPTQ_LEAK_RACE_TIMEOUT * NSEC_PER_SEC;
1486 do {
1487 control_writeulong(CONTROL_CONTINUE);
1488
1489 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1490 if (fd >= 0)
1491 close(fd);
1492 } while (current_nsec() < tout);
1493
1494 control_writeulong(CONTROL_DONE);
1495 }
1496
1497 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_leak_acceptq_server(const struct test_opts * opts)1498 static void test_stream_leak_acceptq_server(const struct test_opts *opts)
1499 {
1500 int fd;
1501
1502 while (control_readulong() == CONTROL_CONTINUE) {
1503 fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1504 control_writeln("LISTENING");
1505 close(fd);
1506 }
1507 }
1508
1509 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_msgzcopy_leak_errq_client(const struct test_opts * opts)1510 static void test_stream_msgzcopy_leak_errq_client(const struct test_opts *opts)
1511 {
1512 struct pollfd fds = { 0 };
1513 int fd;
1514
1515 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1516 if (fd < 0) {
1517 perror("connect");
1518 exit(EXIT_FAILURE);
1519 }
1520
1521 enable_so_zerocopy_check(fd);
1522 send_byte(fd, 1, MSG_ZEROCOPY);
1523
1524 fds.fd = fd;
1525 fds.events = 0;
1526 if (poll(&fds, 1, -1) < 0) {
1527 perror("poll");
1528 exit(EXIT_FAILURE);
1529 }
1530
1531 close(fd);
1532 }
1533
test_stream_msgzcopy_leak_errq_server(const struct test_opts * opts)1534 static void test_stream_msgzcopy_leak_errq_server(const struct test_opts *opts)
1535 {
1536 int fd;
1537
1538 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1539 if (fd < 0) {
1540 perror("accept");
1541 exit(EXIT_FAILURE);
1542 }
1543
1544 recv_byte(fd, 1, 0);
1545 vsock_wait_remote_close(fd);
1546 close(fd);
1547 }
1548
1549 /* Test msgzcopy_leak_zcskb is meant to exercise sendmsg() error handling path,
1550 * that might leak an skb. The idea is to fail virtio_transport_init_zcopy_skb()
1551 * by hitting net.core.optmem_max limit in sock_omalloc(), specifically
1552 *
1553 * vsock_connectible_sendmsg
1554 * virtio_transport_stream_enqueue
1555 * virtio_transport_send_pkt_info
1556 * virtio_transport_init_zcopy_skb
1557 * . msg_zerocopy_realloc
1558 * . msg_zerocopy_alloc
1559 * . sock_omalloc
1560 * . sk_omem_alloc + size > sysctl_optmem_max
1561 * return -ENOMEM
1562 *
1563 * We abuse the implementation detail of net/socket.c:____sys_sendmsg().
1564 * sk_omem_alloc can be precisely bumped by sock_kmalloc(), as it is used to
1565 * fetch user-provided control data.
1566 *
1567 * While this approach works for now, it relies on assumptions regarding the
1568 * implementation and configuration (for example, order of net.core.optmem_max
1569 * can not exceed MAX_PAGE_ORDER), which may not hold in the future. A more
1570 * resilient testing could be implemented by leveraging the Fault injection
1571 * framework (CONFIG_FAULT_INJECTION), e.g.
1572 *
1573 * client# echo N > /sys/kernel/debug/failslab/ignore-gfp-wait
1574 * client# echo 0 > /sys/kernel/debug/failslab/verbose
1575 *
1576 * void client(const struct test_opts *opts)
1577 * {
1578 * char buf[16];
1579 * int f, s, i;
1580 *
1581 * f = open("/proc/self/fail-nth", O_WRONLY);
1582 *
1583 * for (i = 1; i < 32; i++) {
1584 * control_writeulong(CONTROL_CONTINUE);
1585 *
1586 * s = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1587 * enable_so_zerocopy_check(s);
1588 *
1589 * sprintf(buf, "%d", i);
1590 * write(f, buf, strlen(buf));
1591 *
1592 * send(s, &(char){ 0 }, 1, MSG_ZEROCOPY);
1593 *
1594 * write(f, "0", 1);
1595 * close(s);
1596 * }
1597 *
1598 * control_writeulong(CONTROL_DONE);
1599 * close(f);
1600 * }
1601 *
1602 * void server(const struct test_opts *opts)
1603 * {
1604 * int fd;
1605 *
1606 * while (control_readulong() == CONTROL_CONTINUE) {
1607 * fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1608 * vsock_wait_remote_close(fd);
1609 * close(fd);
1610 * }
1611 * }
1612 *
1613 * Refer to Documentation/fault-injection/fault-injection.rst.
1614 */
1615 #define MAX_PAGE_ORDER 10 /* usually */
1616 #define PAGE_SIZE 4096
1617
1618 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_msgzcopy_leak_zcskb_client(const struct test_opts * opts)1619 static void test_stream_msgzcopy_leak_zcskb_client(const struct test_opts *opts)
1620 {
1621 size_t optmem_max, ctl_len, chunk_size;
1622 struct msghdr msg = { 0 };
1623 struct iovec iov;
1624 char *chunk;
1625 int fd, res;
1626 FILE *f;
1627
1628 f = fopen("/proc/sys/net/core/optmem_max", "r");
1629 if (!f) {
1630 perror("fopen(optmem_max)");
1631 exit(EXIT_FAILURE);
1632 }
1633
1634 if (fscanf(f, "%zu", &optmem_max) != 1) {
1635 fprintf(stderr, "fscanf(optmem_max) failed\n");
1636 exit(EXIT_FAILURE);
1637 }
1638
1639 fclose(f);
1640
1641 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1642 if (fd < 0) {
1643 perror("connect");
1644 exit(EXIT_FAILURE);
1645 }
1646
1647 enable_so_zerocopy_check(fd);
1648
1649 ctl_len = optmem_max - 1;
1650 if (ctl_len > PAGE_SIZE << MAX_PAGE_ORDER) {
1651 fprintf(stderr, "Try with net.core.optmem_max = 100000\n");
1652 exit(EXIT_FAILURE);
1653 }
1654
1655 chunk_size = CMSG_SPACE(ctl_len);
1656 chunk = malloc(chunk_size);
1657 if (!chunk) {
1658 perror("malloc");
1659 exit(EXIT_FAILURE);
1660 }
1661 memset(chunk, 0, chunk_size);
1662
1663 iov.iov_base = &(char){ 0 };
1664 iov.iov_len = 1;
1665
1666 msg.msg_iov = &iov;
1667 msg.msg_iovlen = 1;
1668 msg.msg_control = chunk;
1669 msg.msg_controllen = ctl_len;
1670
1671 errno = 0;
1672 res = sendmsg(fd, &msg, MSG_ZEROCOPY);
1673 if (res >= 0 || errno != ENOMEM) {
1674 fprintf(stderr, "Expected ENOMEM, got errno=%d res=%d\n",
1675 errno, res);
1676 exit(EXIT_FAILURE);
1677 }
1678
1679 close(fd);
1680 }
1681
test_stream_msgzcopy_leak_zcskb_server(const struct test_opts * opts)1682 static void test_stream_msgzcopy_leak_zcskb_server(const struct test_opts *opts)
1683 {
1684 int fd;
1685
1686 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1687 if (fd < 0) {
1688 perror("accept");
1689 exit(EXIT_FAILURE);
1690 }
1691
1692 vsock_wait_remote_close(fd);
1693 close(fd);
1694 }
1695
1696 #define MAX_PORT_RETRIES 24 /* net/vmw_vsock/af_vsock.c */
1697
1698 /* Test attempts to trigger a transport release for an unbound socket. This can
1699 * lead to a reference count mishandling.
1700 */
test_stream_transport_uaf_client(const struct test_opts * opts)1701 static void test_stream_transport_uaf_client(const struct test_opts *opts)
1702 {
1703 int sockets[MAX_PORT_RETRIES];
1704 struct sockaddr_vm addr;
1705 int fd, i, alen;
1706
1707 fd = vsock_bind(VMADDR_CID_ANY, VMADDR_PORT_ANY, SOCK_STREAM);
1708
1709 alen = sizeof(addr);
1710 if (getsockname(fd, (struct sockaddr *)&addr, &alen)) {
1711 perror("getsockname");
1712 exit(EXIT_FAILURE);
1713 }
1714
1715 for (i = 0; i < MAX_PORT_RETRIES; ++i)
1716 sockets[i] = vsock_bind(VMADDR_CID_ANY, ++addr.svm_port,
1717 SOCK_STREAM);
1718
1719 close(fd);
1720 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1721 if (fd < 0) {
1722 perror("socket");
1723 exit(EXIT_FAILURE);
1724 }
1725
1726 if (!vsock_connect_fd(fd, addr.svm_cid, addr.svm_port)) {
1727 perror("Unexpected connect() #1 success");
1728 exit(EXIT_FAILURE);
1729 }
1730
1731 /* Vulnerable system may crash now. */
1732 if (!vsock_connect_fd(fd, VMADDR_CID_HOST, VMADDR_PORT_ANY)) {
1733 perror("Unexpected connect() #2 success");
1734 exit(EXIT_FAILURE);
1735 }
1736
1737 close(fd);
1738 while (i--)
1739 close(sockets[i]);
1740
1741 control_writeln("DONE");
1742 }
1743
test_stream_transport_uaf_server(const struct test_opts * opts)1744 static void test_stream_transport_uaf_server(const struct test_opts *opts)
1745 {
1746 control_expectln("DONE");
1747 }
1748
test_stream_connect_retry_client(const struct test_opts * opts)1749 static void test_stream_connect_retry_client(const struct test_opts *opts)
1750 {
1751 int fd;
1752
1753 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1754 if (fd < 0) {
1755 perror("socket");
1756 exit(EXIT_FAILURE);
1757 }
1758
1759 if (!vsock_connect_fd(fd, opts->peer_cid, opts->peer_port)) {
1760 fprintf(stderr, "Unexpected connect() #1 success\n");
1761 exit(EXIT_FAILURE);
1762 }
1763
1764 control_writeln("LISTEN");
1765 control_expectln("LISTENING");
1766
1767 if (vsock_connect_fd(fd, opts->peer_cid, opts->peer_port)) {
1768 perror("connect() #2");
1769 exit(EXIT_FAILURE);
1770 }
1771
1772 close(fd);
1773 }
1774
test_stream_connect_retry_server(const struct test_opts * opts)1775 static void test_stream_connect_retry_server(const struct test_opts *opts)
1776 {
1777 int fd;
1778
1779 control_expectln("LISTEN");
1780
1781 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1782 if (fd < 0) {
1783 perror("accept");
1784 exit(EXIT_FAILURE);
1785 }
1786
1787 vsock_wait_remote_close(fd);
1788 close(fd);
1789 }
1790
test_stream_linger_client(const struct test_opts * opts)1791 static void test_stream_linger_client(const struct test_opts *opts)
1792 {
1793 struct linger optval = {
1794 .l_onoff = 1,
1795 .l_linger = 1
1796 };
1797 int fd;
1798
1799 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1800 if (fd < 0) {
1801 perror("connect");
1802 exit(EXIT_FAILURE);
1803 }
1804
1805 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &optval, sizeof(optval))) {
1806 perror("setsockopt(SO_LINGER)");
1807 exit(EXIT_FAILURE);
1808 }
1809
1810 close(fd);
1811 }
1812
test_stream_linger_server(const struct test_opts * opts)1813 static void test_stream_linger_server(const struct test_opts *opts)
1814 {
1815 int fd;
1816
1817 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1818 if (fd < 0) {
1819 perror("accept");
1820 exit(EXIT_FAILURE);
1821 }
1822
1823 vsock_wait_remote_close(fd);
1824 close(fd);
1825 }
1826
1827 static struct test_case test_cases[] = {
1828 {
1829 .name = "SOCK_STREAM connection reset",
1830 .run_client = test_stream_connection_reset,
1831 },
1832 {
1833 .name = "SOCK_STREAM bind only",
1834 .run_client = test_stream_bind_only_client,
1835 .run_server = test_stream_bind_only_server,
1836 },
1837 {
1838 .name = "SOCK_STREAM client close",
1839 .run_client = test_stream_client_close_client,
1840 .run_server = test_stream_client_close_server,
1841 },
1842 {
1843 .name = "SOCK_STREAM server close",
1844 .run_client = test_stream_server_close_client,
1845 .run_server = test_stream_server_close_server,
1846 },
1847 {
1848 .name = "SOCK_STREAM multiple connections",
1849 .run_client = test_stream_multiconn_client,
1850 .run_server = test_stream_multiconn_server,
1851 },
1852 {
1853 .name = "SOCK_STREAM MSG_PEEK",
1854 .run_client = test_stream_msg_peek_client,
1855 .run_server = test_stream_msg_peek_server,
1856 },
1857 {
1858 .name = "SOCK_SEQPACKET msg bounds",
1859 .run_client = test_seqpacket_msg_bounds_client,
1860 .run_server = test_seqpacket_msg_bounds_server,
1861 },
1862 {
1863 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
1864 .run_client = test_seqpacket_msg_trunc_client,
1865 .run_server = test_seqpacket_msg_trunc_server,
1866 },
1867 {
1868 .name = "SOCK_SEQPACKET timeout",
1869 .run_client = test_seqpacket_timeout_client,
1870 .run_server = test_seqpacket_timeout_server,
1871 },
1872 {
1873 .name = "SOCK_SEQPACKET invalid receive buffer",
1874 .run_client = test_seqpacket_invalid_rec_buffer_client,
1875 .run_server = test_seqpacket_invalid_rec_buffer_server,
1876 },
1877 {
1878 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1879 .run_client = test_stream_poll_rcvlowat_client,
1880 .run_server = test_stream_poll_rcvlowat_server,
1881 },
1882 {
1883 .name = "SOCK_SEQPACKET big message",
1884 .run_client = test_seqpacket_bigmsg_client,
1885 .run_server = test_seqpacket_bigmsg_server,
1886 },
1887 {
1888 .name = "SOCK_STREAM test invalid buffer",
1889 .run_client = test_stream_inv_buf_client,
1890 .run_server = test_stream_inv_buf_server,
1891 },
1892 {
1893 .name = "SOCK_SEQPACKET test invalid buffer",
1894 .run_client = test_seqpacket_inv_buf_client,
1895 .run_server = test_seqpacket_inv_buf_server,
1896 },
1897 {
1898 .name = "SOCK_STREAM virtio skb merge",
1899 .run_client = test_stream_virtio_skb_merge_client,
1900 .run_server = test_stream_virtio_skb_merge_server,
1901 },
1902 {
1903 .name = "SOCK_SEQPACKET MSG_PEEK",
1904 .run_client = test_seqpacket_msg_peek_client,
1905 .run_server = test_seqpacket_msg_peek_server,
1906 },
1907 {
1908 .name = "SOCK_STREAM SHUT_WR",
1909 .run_client = test_stream_shutwr_client,
1910 .run_server = test_stream_shutwr_server,
1911 },
1912 {
1913 .name = "SOCK_STREAM SHUT_RD",
1914 .run_client = test_stream_shutrd_client,
1915 .run_server = test_stream_shutrd_server,
1916 },
1917 {
1918 .name = "SOCK_STREAM MSG_ZEROCOPY",
1919 .run_client = test_stream_msgzcopy_client,
1920 .run_server = test_stream_msgzcopy_server,
1921 },
1922 {
1923 .name = "SOCK_SEQPACKET MSG_ZEROCOPY",
1924 .run_client = test_seqpacket_msgzcopy_client,
1925 .run_server = test_seqpacket_msgzcopy_server,
1926 },
1927 {
1928 .name = "SOCK_STREAM MSG_ZEROCOPY empty MSG_ERRQUEUE",
1929 .run_client = test_stream_msgzcopy_empty_errq_client,
1930 .run_server = test_stream_msgzcopy_empty_errq_server,
1931 },
1932 {
1933 .name = "SOCK_STREAM double bind connect",
1934 .run_client = test_double_bind_connect_client,
1935 .run_server = test_double_bind_connect_server,
1936 },
1937 {
1938 .name = "SOCK_STREAM virtio credit update + SO_RCVLOWAT",
1939 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1940 .run_server = test_stream_cred_upd_on_set_rcvlowat,
1941 },
1942 {
1943 .name = "SOCK_STREAM virtio credit update + low rx_bytes",
1944 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1945 .run_server = test_stream_cred_upd_on_low_rx_bytes,
1946 },
1947 {
1948 .name = "SOCK_STREAM ioctl(SIOCOUTQ) 0 unsent bytes",
1949 .run_client = test_stream_unsent_bytes_client,
1950 .run_server = test_stream_unsent_bytes_server,
1951 },
1952 {
1953 .name = "SOCK_SEQPACKET ioctl(SIOCOUTQ) 0 unsent bytes",
1954 .run_client = test_seqpacket_unsent_bytes_client,
1955 .run_server = test_seqpacket_unsent_bytes_server,
1956 },
1957 {
1958 .name = "SOCK_STREAM leak accept queue",
1959 .run_client = test_stream_leak_acceptq_client,
1960 .run_server = test_stream_leak_acceptq_server,
1961 },
1962 {
1963 .name = "SOCK_STREAM MSG_ZEROCOPY leak MSG_ERRQUEUE",
1964 .run_client = test_stream_msgzcopy_leak_errq_client,
1965 .run_server = test_stream_msgzcopy_leak_errq_server,
1966 },
1967 {
1968 .name = "SOCK_STREAM MSG_ZEROCOPY leak completion skb",
1969 .run_client = test_stream_msgzcopy_leak_zcskb_client,
1970 .run_server = test_stream_msgzcopy_leak_zcskb_server,
1971 },
1972 {
1973 .name = "SOCK_STREAM transport release use-after-free",
1974 .run_client = test_stream_transport_uaf_client,
1975 .run_server = test_stream_transport_uaf_server,
1976 },
1977 {
1978 .name = "SOCK_STREAM retry failed connect()",
1979 .run_client = test_stream_connect_retry_client,
1980 .run_server = test_stream_connect_retry_server,
1981 },
1982 {
1983 .name = "SOCK_STREAM SO_LINGER null-ptr-deref",
1984 .run_client = test_stream_linger_client,
1985 .run_server = test_stream_linger_server,
1986 },
1987 {},
1988 };
1989
1990 static const char optstring[] = "";
1991 static const struct option longopts[] = {
1992 {
1993 .name = "control-host",
1994 .has_arg = required_argument,
1995 .val = 'H',
1996 },
1997 {
1998 .name = "control-port",
1999 .has_arg = required_argument,
2000 .val = 'P',
2001 },
2002 {
2003 .name = "mode",
2004 .has_arg = required_argument,
2005 .val = 'm',
2006 },
2007 {
2008 .name = "peer-cid",
2009 .has_arg = required_argument,
2010 .val = 'p',
2011 },
2012 {
2013 .name = "peer-port",
2014 .has_arg = required_argument,
2015 .val = 'q',
2016 },
2017 {
2018 .name = "list",
2019 .has_arg = no_argument,
2020 .val = 'l',
2021 },
2022 {
2023 .name = "skip",
2024 .has_arg = required_argument,
2025 .val = 's',
2026 },
2027 {
2028 .name = "pick",
2029 .has_arg = required_argument,
2030 .val = 't',
2031 },
2032 {
2033 .name = "help",
2034 .has_arg = no_argument,
2035 .val = '?',
2036 },
2037 {},
2038 };
2039
usage(void)2040 static void usage(void)
2041 {
2042 fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--peer-port=<port>] [--list] [--skip=<test_id>]\n"
2043 "\n"
2044 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
2045 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
2046 "\n"
2047 "Run vsock.ko tests. Must be launched in both guest\n"
2048 "and host. One side must use --mode=client and\n"
2049 "the other side must use --mode=server.\n"
2050 "\n"
2051 "A TCP control socket connection is used to coordinate tests\n"
2052 "between the client and the server. The server requires a\n"
2053 "listen address and the client requires an address to\n"
2054 "connect to.\n"
2055 "\n"
2056 "The CID of the other side must be given with --peer-cid=<cid>.\n"
2057 "During the test, two AF_VSOCK ports will be used: the port\n"
2058 "specified with --peer-port=<port> (or the default port)\n"
2059 "and the next one.\n"
2060 "\n"
2061 "Options:\n"
2062 " --help This help message\n"
2063 " --control-host <host> Server IP address to connect to\n"
2064 " --control-port <port> Server port to listen on/connect to\n"
2065 " --mode client|server Server or client mode\n"
2066 " --peer-cid <cid> CID of the other side\n"
2067 " --peer-port <port> AF_VSOCK port used for the test [default: %d]\n"
2068 " --list List of tests that will be executed\n"
2069 " --pick <test_id> Test ID to execute selectively;\n"
2070 " use multiple --pick options to select more tests\n"
2071 " --skip <test_id> Test ID to skip;\n"
2072 " use multiple --skip options to skip more tests\n",
2073 DEFAULT_PEER_PORT
2074 );
2075 exit(EXIT_FAILURE);
2076 }
2077
main(int argc,char ** argv)2078 int main(int argc, char **argv)
2079 {
2080 const char *control_host = NULL;
2081 const char *control_port = NULL;
2082 struct test_opts opts = {
2083 .mode = TEST_MODE_UNSET,
2084 .peer_cid = VMADDR_CID_ANY,
2085 .peer_port = DEFAULT_PEER_PORT,
2086 };
2087
2088 srand(time(NULL));
2089 init_signals();
2090
2091 for (;;) {
2092 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
2093
2094 if (opt == -1)
2095 break;
2096
2097 switch (opt) {
2098 case 'H':
2099 control_host = optarg;
2100 break;
2101 case 'm':
2102 if (strcmp(optarg, "client") == 0)
2103 opts.mode = TEST_MODE_CLIENT;
2104 else if (strcmp(optarg, "server") == 0)
2105 opts.mode = TEST_MODE_SERVER;
2106 else {
2107 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
2108 return EXIT_FAILURE;
2109 }
2110 break;
2111 case 'p':
2112 opts.peer_cid = parse_cid(optarg);
2113 break;
2114 case 'q':
2115 opts.peer_port = parse_port(optarg);
2116 break;
2117 case 'P':
2118 control_port = optarg;
2119 break;
2120 case 'l':
2121 list_tests(test_cases);
2122 break;
2123 case 's':
2124 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
2125 optarg);
2126 break;
2127 case 't':
2128 pick_test(test_cases, ARRAY_SIZE(test_cases) - 1,
2129 optarg);
2130 break;
2131 case '?':
2132 default:
2133 usage();
2134 }
2135 }
2136
2137 if (!control_port)
2138 usage();
2139 if (opts.mode == TEST_MODE_UNSET)
2140 usage();
2141 if (opts.peer_cid == VMADDR_CID_ANY)
2142 usage();
2143
2144 if (!control_host) {
2145 if (opts.mode != TEST_MODE_SERVER)
2146 usage();
2147 control_host = "0.0.0.0";
2148 }
2149
2150 control_init(control_host, control_port,
2151 opts.mode == TEST_MODE_SERVER);
2152
2153 run_tests(test_cases, &opts);
2154
2155 control_cleanup();
2156 return EXIT_SUCCESS;
2157 }
2158