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 /* SIOCOUTQ isn't guaranteed to instantly track sent data. Even though
1268 * the "RECEIVED" message means that the other side has received the
1269 * data, there can be a delay in our kernel before updating the "unsent
1270 * bytes" counter. Repeat SIOCOUTQ until it returns 0.
1271 */
1272 timeout_begin(TIMEOUT);
1273 do {
1274 ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
1275 if (ret < 0) {
1276 if (errno == EOPNOTSUPP) {
1277 fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n");
1278 break;
1279 }
1280 perror("ioctl");
1281 exit(EXIT_FAILURE);
1282 }
1283 timeout_check("SIOCOUTQ");
1284 } while (sock_bytes_unsent != 0);
1285 timeout_end();
1286 close(fd);
1287 }
1288
test_stream_unsent_bytes_client(const struct test_opts * opts)1289 static void test_stream_unsent_bytes_client(const struct test_opts *opts)
1290 {
1291 test_unsent_bytes_client(opts, SOCK_STREAM);
1292 }
1293
test_stream_unsent_bytes_server(const struct test_opts * opts)1294 static void test_stream_unsent_bytes_server(const struct test_opts *opts)
1295 {
1296 test_unsent_bytes_server(opts, SOCK_STREAM);
1297 }
1298
test_seqpacket_unsent_bytes_client(const struct test_opts * opts)1299 static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts)
1300 {
1301 test_unsent_bytes_client(opts, SOCK_SEQPACKET);
1302 }
1303
test_seqpacket_unsent_bytes_server(const struct test_opts * opts)1304 static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
1305 {
1306 test_unsent_bytes_server(opts, SOCK_SEQPACKET);
1307 }
1308
1309 #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
1310 /* This define is the same as in 'include/linux/virtio_vsock.h':
1311 * it is used to decide when to send credit update message during
1312 * reading from rx queue of a socket. Value and its usage in
1313 * kernel is important for this test.
1314 */
1315 #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
1316
test_stream_rcvlowat_def_cred_upd_client(const struct test_opts * opts)1317 static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opts)
1318 {
1319 size_t buf_size;
1320 void *buf;
1321 int fd;
1322
1323 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1324 if (fd < 0) {
1325 perror("connect");
1326 exit(EXIT_FAILURE);
1327 }
1328
1329 /* Send 1 byte more than peer's buffer size. */
1330 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE + 1;
1331
1332 buf = malloc(buf_size);
1333 if (!buf) {
1334 perror("malloc");
1335 exit(EXIT_FAILURE);
1336 }
1337
1338 /* Wait until peer sets needed buffer size. */
1339 recv_byte(fd, 1, 0);
1340
1341 if (send(fd, buf, buf_size, 0) != buf_size) {
1342 perror("send failed");
1343 exit(EXIT_FAILURE);
1344 }
1345
1346 free(buf);
1347 close(fd);
1348 }
1349
test_stream_credit_update_test(const struct test_opts * opts,bool low_rx_bytes_test)1350 static void test_stream_credit_update_test(const struct test_opts *opts,
1351 bool low_rx_bytes_test)
1352 {
1353 int recv_buf_size;
1354 struct pollfd fds;
1355 size_t buf_size;
1356 unsigned long long sock_buf_size;
1357 void *buf;
1358 int fd;
1359
1360 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1361 if (fd < 0) {
1362 perror("accept");
1363 exit(EXIT_FAILURE);
1364 }
1365
1366 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE;
1367
1368 /* size_t can be < unsigned long long */
1369 sock_buf_size = buf_size;
1370
1371 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
1372 sock_buf_size,
1373 "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
1374
1375 if (low_rx_bytes_test) {
1376 /* Set new SO_RCVLOWAT here. This enables sending credit
1377 * update when number of bytes if our rx queue become <
1378 * SO_RCVLOWAT value.
1379 */
1380 recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1381
1382 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
1383 recv_buf_size, "setsockopt(SO_RCVLOWAT)");
1384 }
1385
1386 /* Send one dummy byte here, because 'setsockopt()' above also
1387 * sends special packet which tells sender to update our buffer
1388 * size. This 'send_byte()' will serialize such packet with data
1389 * reads in a loop below. Sender starts transmission only when
1390 * it receives this single byte.
1391 */
1392 send_byte(fd, 1, 0);
1393
1394 buf = malloc(buf_size);
1395 if (!buf) {
1396 perror("malloc");
1397 exit(EXIT_FAILURE);
1398 }
1399
1400 /* Wait until there will be 128KB of data in rx queue. */
1401 while (1) {
1402 ssize_t res;
1403
1404 res = recv(fd, buf, buf_size, MSG_PEEK);
1405 if (res == buf_size)
1406 break;
1407
1408 if (res <= 0) {
1409 fprintf(stderr, "unexpected 'recv()' return: %zi\n", res);
1410 exit(EXIT_FAILURE);
1411 }
1412 }
1413
1414 /* There is 128KB of data in the socket's rx queue, dequeue first
1415 * 64KB, credit update is sent if 'low_rx_bytes_test' == true.
1416 * Otherwise, credit update is sent in 'if (!low_rx_bytes_test)'.
1417 */
1418 recv_buf_size = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1419 recv_buf(fd, buf, recv_buf_size, 0, recv_buf_size);
1420
1421 if (!low_rx_bytes_test) {
1422 recv_buf_size++;
1423
1424 /* Updating SO_RCVLOWAT will send credit update. */
1425 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
1426 recv_buf_size, "setsockopt(SO_RCVLOWAT)");
1427 }
1428
1429 fds.fd = fd;
1430 fds.events = POLLIN | POLLRDNORM | POLLERR |
1431 POLLRDHUP | POLLHUP;
1432
1433 /* This 'poll()' will return once we receive last byte
1434 * sent by client.
1435 */
1436 if (poll(&fds, 1, -1) < 0) {
1437 perror("poll");
1438 exit(EXIT_FAILURE);
1439 }
1440
1441 if (fds.revents & POLLERR) {
1442 fprintf(stderr, "'poll()' error\n");
1443 exit(EXIT_FAILURE);
1444 }
1445
1446 if (fds.revents & (POLLIN | POLLRDNORM)) {
1447 recv_buf(fd, buf, recv_buf_size, MSG_DONTWAIT, recv_buf_size);
1448 } else {
1449 /* These flags must be set, as there is at
1450 * least 64KB of data ready to read.
1451 */
1452 fprintf(stderr, "POLLIN | POLLRDNORM expected\n");
1453 exit(EXIT_FAILURE);
1454 }
1455
1456 free(buf);
1457 close(fd);
1458 }
1459
test_stream_cred_upd_on_low_rx_bytes(const struct test_opts * opts)1460 static void test_stream_cred_upd_on_low_rx_bytes(const struct test_opts *opts)
1461 {
1462 test_stream_credit_update_test(opts, true);
1463 }
1464
test_stream_cred_upd_on_set_rcvlowat(const struct test_opts * opts)1465 static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)
1466 {
1467 test_stream_credit_update_test(opts, false);
1468 }
1469
1470 /* The goal of test leak_acceptq is to stress the race between connect() and
1471 * close(listener). Implementation of client/server loops boils down to:
1472 *
1473 * client server
1474 * ------ ------
1475 * write(CONTINUE)
1476 * expect(CONTINUE)
1477 * listen()
1478 * write(LISTENING)
1479 * expect(LISTENING)
1480 * connect() close()
1481 */
1482 #define ACCEPTQ_LEAK_RACE_TIMEOUT 2 /* seconds */
1483
test_stream_leak_acceptq_client(const struct test_opts * opts)1484 static void test_stream_leak_acceptq_client(const struct test_opts *opts)
1485 {
1486 time_t tout;
1487 int fd;
1488
1489 tout = current_nsec() + ACCEPTQ_LEAK_RACE_TIMEOUT * NSEC_PER_SEC;
1490 do {
1491 control_writeulong(CONTROL_CONTINUE);
1492
1493 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1494 if (fd >= 0)
1495 close(fd);
1496 } while (current_nsec() < tout);
1497
1498 control_writeulong(CONTROL_DONE);
1499 }
1500
1501 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_leak_acceptq_server(const struct test_opts * opts)1502 static void test_stream_leak_acceptq_server(const struct test_opts *opts)
1503 {
1504 int fd;
1505
1506 while (control_readulong() == CONTROL_CONTINUE) {
1507 fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1508 control_writeln("LISTENING");
1509 close(fd);
1510 }
1511 }
1512
1513 /* 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)1514 static void test_stream_msgzcopy_leak_errq_client(const struct test_opts *opts)
1515 {
1516 struct pollfd fds = { 0 };
1517 int fd;
1518
1519 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1520 if (fd < 0) {
1521 perror("connect");
1522 exit(EXIT_FAILURE);
1523 }
1524
1525 enable_so_zerocopy_check(fd);
1526 send_byte(fd, 1, MSG_ZEROCOPY);
1527
1528 fds.fd = fd;
1529 fds.events = 0;
1530 if (poll(&fds, 1, -1) < 0) {
1531 perror("poll");
1532 exit(EXIT_FAILURE);
1533 }
1534
1535 close(fd);
1536 }
1537
test_stream_msgzcopy_leak_errq_server(const struct test_opts * opts)1538 static void test_stream_msgzcopy_leak_errq_server(const struct test_opts *opts)
1539 {
1540 int fd;
1541
1542 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1543 if (fd < 0) {
1544 perror("accept");
1545 exit(EXIT_FAILURE);
1546 }
1547
1548 recv_byte(fd, 1, 0);
1549 vsock_wait_remote_close(fd);
1550 close(fd);
1551 }
1552
1553 /* Test msgzcopy_leak_zcskb is meant to exercise sendmsg() error handling path,
1554 * that might leak an skb. The idea is to fail virtio_transport_init_zcopy_skb()
1555 * by hitting net.core.optmem_max limit in sock_omalloc(), specifically
1556 *
1557 * vsock_connectible_sendmsg
1558 * virtio_transport_stream_enqueue
1559 * virtio_transport_send_pkt_info
1560 * virtio_transport_init_zcopy_skb
1561 * . msg_zerocopy_realloc
1562 * . msg_zerocopy_alloc
1563 * . sock_omalloc
1564 * . sk_omem_alloc + size > sysctl_optmem_max
1565 * return -ENOMEM
1566 *
1567 * We abuse the implementation detail of net/socket.c:____sys_sendmsg().
1568 * sk_omem_alloc can be precisely bumped by sock_kmalloc(), as it is used to
1569 * fetch user-provided control data.
1570 *
1571 * While this approach works for now, it relies on assumptions regarding the
1572 * implementation and configuration (for example, order of net.core.optmem_max
1573 * can not exceed MAX_PAGE_ORDER), which may not hold in the future. A more
1574 * resilient testing could be implemented by leveraging the Fault injection
1575 * framework (CONFIG_FAULT_INJECTION), e.g.
1576 *
1577 * client# echo N > /sys/kernel/debug/failslab/ignore-gfp-wait
1578 * client# echo 0 > /sys/kernel/debug/failslab/verbose
1579 *
1580 * void client(const struct test_opts *opts)
1581 * {
1582 * char buf[16];
1583 * int f, s, i;
1584 *
1585 * f = open("/proc/self/fail-nth", O_WRONLY);
1586 *
1587 * for (i = 1; i < 32; i++) {
1588 * control_writeulong(CONTROL_CONTINUE);
1589 *
1590 * s = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1591 * enable_so_zerocopy_check(s);
1592 *
1593 * sprintf(buf, "%d", i);
1594 * write(f, buf, strlen(buf));
1595 *
1596 * send(s, &(char){ 0 }, 1, MSG_ZEROCOPY);
1597 *
1598 * write(f, "0", 1);
1599 * close(s);
1600 * }
1601 *
1602 * control_writeulong(CONTROL_DONE);
1603 * close(f);
1604 * }
1605 *
1606 * void server(const struct test_opts *opts)
1607 * {
1608 * int fd;
1609 *
1610 * while (control_readulong() == CONTROL_CONTINUE) {
1611 * fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1612 * vsock_wait_remote_close(fd);
1613 * close(fd);
1614 * }
1615 * }
1616 *
1617 * Refer to Documentation/fault-injection/fault-injection.rst.
1618 */
1619 #define MAX_PAGE_ORDER 10 /* usually */
1620 #define PAGE_SIZE 4096
1621
1622 /* 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)1623 static void test_stream_msgzcopy_leak_zcskb_client(const struct test_opts *opts)
1624 {
1625 size_t optmem_max, ctl_len, chunk_size;
1626 struct msghdr msg = { 0 };
1627 struct iovec iov;
1628 char *chunk;
1629 int fd, res;
1630 FILE *f;
1631
1632 f = fopen("/proc/sys/net/core/optmem_max", "r");
1633 if (!f) {
1634 perror("fopen(optmem_max)");
1635 exit(EXIT_FAILURE);
1636 }
1637
1638 if (fscanf(f, "%zu", &optmem_max) != 1) {
1639 fprintf(stderr, "fscanf(optmem_max) failed\n");
1640 exit(EXIT_FAILURE);
1641 }
1642
1643 fclose(f);
1644
1645 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1646 if (fd < 0) {
1647 perror("connect");
1648 exit(EXIT_FAILURE);
1649 }
1650
1651 enable_so_zerocopy_check(fd);
1652
1653 ctl_len = optmem_max - 1;
1654 if (ctl_len > PAGE_SIZE << MAX_PAGE_ORDER) {
1655 fprintf(stderr, "Try with net.core.optmem_max = 100000\n");
1656 exit(EXIT_FAILURE);
1657 }
1658
1659 chunk_size = CMSG_SPACE(ctl_len);
1660 chunk = malloc(chunk_size);
1661 if (!chunk) {
1662 perror("malloc");
1663 exit(EXIT_FAILURE);
1664 }
1665 memset(chunk, 0, chunk_size);
1666
1667 iov.iov_base = &(char){ 0 };
1668 iov.iov_len = 1;
1669
1670 msg.msg_iov = &iov;
1671 msg.msg_iovlen = 1;
1672 msg.msg_control = chunk;
1673 msg.msg_controllen = ctl_len;
1674
1675 errno = 0;
1676 res = sendmsg(fd, &msg, MSG_ZEROCOPY);
1677 if (res >= 0 || errno != ENOMEM) {
1678 fprintf(stderr, "Expected ENOMEM, got errno=%d res=%d\n",
1679 errno, res);
1680 exit(EXIT_FAILURE);
1681 }
1682
1683 close(fd);
1684 }
1685
test_stream_msgzcopy_leak_zcskb_server(const struct test_opts * opts)1686 static void test_stream_msgzcopy_leak_zcskb_server(const struct test_opts *opts)
1687 {
1688 int fd;
1689
1690 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1691 if (fd < 0) {
1692 perror("accept");
1693 exit(EXIT_FAILURE);
1694 }
1695
1696 vsock_wait_remote_close(fd);
1697 close(fd);
1698 }
1699
1700 #define MAX_PORT_RETRIES 24 /* net/vmw_vsock/af_vsock.c */
1701
1702 /* Test attempts to trigger a transport release for an unbound socket. This can
1703 * lead to a reference count mishandling.
1704 */
test_stream_transport_uaf_client(const struct test_opts * opts)1705 static void test_stream_transport_uaf_client(const struct test_opts *opts)
1706 {
1707 int sockets[MAX_PORT_RETRIES];
1708 struct sockaddr_vm addr;
1709 int fd, i, alen;
1710
1711 fd = vsock_bind(VMADDR_CID_ANY, VMADDR_PORT_ANY, SOCK_STREAM);
1712
1713 alen = sizeof(addr);
1714 if (getsockname(fd, (struct sockaddr *)&addr, &alen)) {
1715 perror("getsockname");
1716 exit(EXIT_FAILURE);
1717 }
1718
1719 for (i = 0; i < MAX_PORT_RETRIES; ++i)
1720 sockets[i] = vsock_bind(VMADDR_CID_ANY, ++addr.svm_port,
1721 SOCK_STREAM);
1722
1723 close(fd);
1724 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1725 if (fd < 0) {
1726 perror("socket");
1727 exit(EXIT_FAILURE);
1728 }
1729
1730 if (!vsock_connect_fd(fd, addr.svm_cid, addr.svm_port)) {
1731 perror("Unexpected connect() #1 success");
1732 exit(EXIT_FAILURE);
1733 }
1734
1735 /* Vulnerable system may crash now. */
1736 if (!vsock_connect_fd(fd, VMADDR_CID_HOST, VMADDR_PORT_ANY)) {
1737 perror("Unexpected connect() #2 success");
1738 exit(EXIT_FAILURE);
1739 }
1740
1741 close(fd);
1742 while (i--)
1743 close(sockets[i]);
1744
1745 control_writeln("DONE");
1746 }
1747
test_stream_transport_uaf_server(const struct test_opts * opts)1748 static void test_stream_transport_uaf_server(const struct test_opts *opts)
1749 {
1750 control_expectln("DONE");
1751 }
1752
test_stream_connect_retry_client(const struct test_opts * opts)1753 static void test_stream_connect_retry_client(const struct test_opts *opts)
1754 {
1755 int fd;
1756
1757 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1758 if (fd < 0) {
1759 perror("socket");
1760 exit(EXIT_FAILURE);
1761 }
1762
1763 if (!vsock_connect_fd(fd, opts->peer_cid, opts->peer_port)) {
1764 fprintf(stderr, "Unexpected connect() #1 success\n");
1765 exit(EXIT_FAILURE);
1766 }
1767
1768 control_writeln("LISTEN");
1769 control_expectln("LISTENING");
1770
1771 if (vsock_connect_fd(fd, opts->peer_cid, opts->peer_port)) {
1772 perror("connect() #2");
1773 exit(EXIT_FAILURE);
1774 }
1775
1776 close(fd);
1777 }
1778
test_stream_connect_retry_server(const struct test_opts * opts)1779 static void test_stream_connect_retry_server(const struct test_opts *opts)
1780 {
1781 int fd;
1782
1783 control_expectln("LISTEN");
1784
1785 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1786 if (fd < 0) {
1787 perror("accept");
1788 exit(EXIT_FAILURE);
1789 }
1790
1791 vsock_wait_remote_close(fd);
1792 close(fd);
1793 }
1794
test_stream_linger_client(const struct test_opts * opts)1795 static void test_stream_linger_client(const struct test_opts *opts)
1796 {
1797 struct linger optval = {
1798 .l_onoff = 1,
1799 .l_linger = 1
1800 };
1801 int fd;
1802
1803 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1804 if (fd < 0) {
1805 perror("connect");
1806 exit(EXIT_FAILURE);
1807 }
1808
1809 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &optval, sizeof(optval))) {
1810 perror("setsockopt(SO_LINGER)");
1811 exit(EXIT_FAILURE);
1812 }
1813
1814 close(fd);
1815 }
1816
test_stream_linger_server(const struct test_opts * opts)1817 static void test_stream_linger_server(const struct test_opts *opts)
1818 {
1819 int fd;
1820
1821 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1822 if (fd < 0) {
1823 perror("accept");
1824 exit(EXIT_FAILURE);
1825 }
1826
1827 vsock_wait_remote_close(fd);
1828 close(fd);
1829 }
1830
1831 static struct test_case test_cases[] = {
1832 {
1833 .name = "SOCK_STREAM connection reset",
1834 .run_client = test_stream_connection_reset,
1835 },
1836 {
1837 .name = "SOCK_STREAM bind only",
1838 .run_client = test_stream_bind_only_client,
1839 .run_server = test_stream_bind_only_server,
1840 },
1841 {
1842 .name = "SOCK_STREAM client close",
1843 .run_client = test_stream_client_close_client,
1844 .run_server = test_stream_client_close_server,
1845 },
1846 {
1847 .name = "SOCK_STREAM server close",
1848 .run_client = test_stream_server_close_client,
1849 .run_server = test_stream_server_close_server,
1850 },
1851 {
1852 .name = "SOCK_STREAM multiple connections",
1853 .run_client = test_stream_multiconn_client,
1854 .run_server = test_stream_multiconn_server,
1855 },
1856 {
1857 .name = "SOCK_STREAM MSG_PEEK",
1858 .run_client = test_stream_msg_peek_client,
1859 .run_server = test_stream_msg_peek_server,
1860 },
1861 {
1862 .name = "SOCK_SEQPACKET msg bounds",
1863 .run_client = test_seqpacket_msg_bounds_client,
1864 .run_server = test_seqpacket_msg_bounds_server,
1865 },
1866 {
1867 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
1868 .run_client = test_seqpacket_msg_trunc_client,
1869 .run_server = test_seqpacket_msg_trunc_server,
1870 },
1871 {
1872 .name = "SOCK_SEQPACKET timeout",
1873 .run_client = test_seqpacket_timeout_client,
1874 .run_server = test_seqpacket_timeout_server,
1875 },
1876 {
1877 .name = "SOCK_SEQPACKET invalid receive buffer",
1878 .run_client = test_seqpacket_invalid_rec_buffer_client,
1879 .run_server = test_seqpacket_invalid_rec_buffer_server,
1880 },
1881 {
1882 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1883 .run_client = test_stream_poll_rcvlowat_client,
1884 .run_server = test_stream_poll_rcvlowat_server,
1885 },
1886 {
1887 .name = "SOCK_SEQPACKET big message",
1888 .run_client = test_seqpacket_bigmsg_client,
1889 .run_server = test_seqpacket_bigmsg_server,
1890 },
1891 {
1892 .name = "SOCK_STREAM test invalid buffer",
1893 .run_client = test_stream_inv_buf_client,
1894 .run_server = test_stream_inv_buf_server,
1895 },
1896 {
1897 .name = "SOCK_SEQPACKET test invalid buffer",
1898 .run_client = test_seqpacket_inv_buf_client,
1899 .run_server = test_seqpacket_inv_buf_server,
1900 },
1901 {
1902 .name = "SOCK_STREAM virtio skb merge",
1903 .run_client = test_stream_virtio_skb_merge_client,
1904 .run_server = test_stream_virtio_skb_merge_server,
1905 },
1906 {
1907 .name = "SOCK_SEQPACKET MSG_PEEK",
1908 .run_client = test_seqpacket_msg_peek_client,
1909 .run_server = test_seqpacket_msg_peek_server,
1910 },
1911 {
1912 .name = "SOCK_STREAM SHUT_WR",
1913 .run_client = test_stream_shutwr_client,
1914 .run_server = test_stream_shutwr_server,
1915 },
1916 {
1917 .name = "SOCK_STREAM SHUT_RD",
1918 .run_client = test_stream_shutrd_client,
1919 .run_server = test_stream_shutrd_server,
1920 },
1921 {
1922 .name = "SOCK_STREAM MSG_ZEROCOPY",
1923 .run_client = test_stream_msgzcopy_client,
1924 .run_server = test_stream_msgzcopy_server,
1925 },
1926 {
1927 .name = "SOCK_SEQPACKET MSG_ZEROCOPY",
1928 .run_client = test_seqpacket_msgzcopy_client,
1929 .run_server = test_seqpacket_msgzcopy_server,
1930 },
1931 {
1932 .name = "SOCK_STREAM MSG_ZEROCOPY empty MSG_ERRQUEUE",
1933 .run_client = test_stream_msgzcopy_empty_errq_client,
1934 .run_server = test_stream_msgzcopy_empty_errq_server,
1935 },
1936 {
1937 .name = "SOCK_STREAM double bind connect",
1938 .run_client = test_double_bind_connect_client,
1939 .run_server = test_double_bind_connect_server,
1940 },
1941 {
1942 .name = "SOCK_STREAM virtio credit update + SO_RCVLOWAT",
1943 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1944 .run_server = test_stream_cred_upd_on_set_rcvlowat,
1945 },
1946 {
1947 .name = "SOCK_STREAM virtio credit update + low rx_bytes",
1948 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1949 .run_server = test_stream_cred_upd_on_low_rx_bytes,
1950 },
1951 {
1952 .name = "SOCK_STREAM ioctl(SIOCOUTQ) 0 unsent bytes",
1953 .run_client = test_stream_unsent_bytes_client,
1954 .run_server = test_stream_unsent_bytes_server,
1955 },
1956 {
1957 .name = "SOCK_SEQPACKET ioctl(SIOCOUTQ) 0 unsent bytes",
1958 .run_client = test_seqpacket_unsent_bytes_client,
1959 .run_server = test_seqpacket_unsent_bytes_server,
1960 },
1961 {
1962 .name = "SOCK_STREAM leak accept queue",
1963 .run_client = test_stream_leak_acceptq_client,
1964 .run_server = test_stream_leak_acceptq_server,
1965 },
1966 {
1967 .name = "SOCK_STREAM MSG_ZEROCOPY leak MSG_ERRQUEUE",
1968 .run_client = test_stream_msgzcopy_leak_errq_client,
1969 .run_server = test_stream_msgzcopy_leak_errq_server,
1970 },
1971 {
1972 .name = "SOCK_STREAM MSG_ZEROCOPY leak completion skb",
1973 .run_client = test_stream_msgzcopy_leak_zcskb_client,
1974 .run_server = test_stream_msgzcopy_leak_zcskb_server,
1975 },
1976 {
1977 .name = "SOCK_STREAM transport release use-after-free",
1978 .run_client = test_stream_transport_uaf_client,
1979 .run_server = test_stream_transport_uaf_server,
1980 },
1981 {
1982 .name = "SOCK_STREAM retry failed connect()",
1983 .run_client = test_stream_connect_retry_client,
1984 .run_server = test_stream_connect_retry_server,
1985 },
1986 {
1987 .name = "SOCK_STREAM SO_LINGER null-ptr-deref",
1988 .run_client = test_stream_linger_client,
1989 .run_server = test_stream_linger_server,
1990 },
1991 {},
1992 };
1993
1994 static const char optstring[] = "";
1995 static const struct option longopts[] = {
1996 {
1997 .name = "control-host",
1998 .has_arg = required_argument,
1999 .val = 'H',
2000 },
2001 {
2002 .name = "control-port",
2003 .has_arg = required_argument,
2004 .val = 'P',
2005 },
2006 {
2007 .name = "mode",
2008 .has_arg = required_argument,
2009 .val = 'm',
2010 },
2011 {
2012 .name = "peer-cid",
2013 .has_arg = required_argument,
2014 .val = 'p',
2015 },
2016 {
2017 .name = "peer-port",
2018 .has_arg = required_argument,
2019 .val = 'q',
2020 },
2021 {
2022 .name = "list",
2023 .has_arg = no_argument,
2024 .val = 'l',
2025 },
2026 {
2027 .name = "skip",
2028 .has_arg = required_argument,
2029 .val = 's',
2030 },
2031 {
2032 .name = "pick",
2033 .has_arg = required_argument,
2034 .val = 't',
2035 },
2036 {
2037 .name = "help",
2038 .has_arg = no_argument,
2039 .val = '?',
2040 },
2041 {},
2042 };
2043
usage(void)2044 static void usage(void)
2045 {
2046 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"
2047 "\n"
2048 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
2049 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
2050 "\n"
2051 "Run vsock.ko tests. Must be launched in both guest\n"
2052 "and host. One side must use --mode=client and\n"
2053 "the other side must use --mode=server.\n"
2054 "\n"
2055 "A TCP control socket connection is used to coordinate tests\n"
2056 "between the client and the server. The server requires a\n"
2057 "listen address and the client requires an address to\n"
2058 "connect to.\n"
2059 "\n"
2060 "The CID of the other side must be given with --peer-cid=<cid>.\n"
2061 "During the test, two AF_VSOCK ports will be used: the port\n"
2062 "specified with --peer-port=<port> (or the default port)\n"
2063 "and the next one.\n"
2064 "\n"
2065 "Options:\n"
2066 " --help This help message\n"
2067 " --control-host <host> Server IP address to connect to\n"
2068 " --control-port <port> Server port to listen on/connect to\n"
2069 " --mode client|server Server or client mode\n"
2070 " --peer-cid <cid> CID of the other side\n"
2071 " --peer-port <port> AF_VSOCK port used for the test [default: %d]\n"
2072 " --list List of tests that will be executed\n"
2073 " --pick <test_id> Test ID to execute selectively;\n"
2074 " use multiple --pick options to select more tests\n"
2075 " --skip <test_id> Test ID to skip;\n"
2076 " use multiple --skip options to skip more tests\n",
2077 DEFAULT_PEER_PORT
2078 );
2079 exit(EXIT_FAILURE);
2080 }
2081
main(int argc,char ** argv)2082 int main(int argc, char **argv)
2083 {
2084 const char *control_host = NULL;
2085 const char *control_port = NULL;
2086 struct test_opts opts = {
2087 .mode = TEST_MODE_UNSET,
2088 .peer_cid = VMADDR_CID_ANY,
2089 .peer_port = DEFAULT_PEER_PORT,
2090 };
2091
2092 srand(time(NULL));
2093 init_signals();
2094
2095 for (;;) {
2096 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
2097
2098 if (opt == -1)
2099 break;
2100
2101 switch (opt) {
2102 case 'H':
2103 control_host = optarg;
2104 break;
2105 case 'm':
2106 if (strcmp(optarg, "client") == 0)
2107 opts.mode = TEST_MODE_CLIENT;
2108 else if (strcmp(optarg, "server") == 0)
2109 opts.mode = TEST_MODE_SERVER;
2110 else {
2111 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
2112 return EXIT_FAILURE;
2113 }
2114 break;
2115 case 'p':
2116 opts.peer_cid = parse_cid(optarg);
2117 break;
2118 case 'q':
2119 opts.peer_port = parse_port(optarg);
2120 break;
2121 case 'P':
2122 control_port = optarg;
2123 break;
2124 case 'l':
2125 list_tests(test_cases);
2126 break;
2127 case 's':
2128 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
2129 optarg);
2130 break;
2131 case 't':
2132 pick_test(test_cases, ARRAY_SIZE(test_cases) - 1,
2133 optarg);
2134 break;
2135 case '?':
2136 default:
2137 usage();
2138 }
2139 }
2140
2141 if (!control_port)
2142 usage();
2143 if (opts.mode == TEST_MODE_UNSET)
2144 usage();
2145 if (opts.peer_cid == VMADDR_CID_ANY)
2146 usage();
2147
2148 if (!control_host) {
2149 if (opts.mode != TEST_MODE_SERVER)
2150 usage();
2151 control_host = "0.0.0.0";
2152 }
2153
2154 control_init(control_host, control_port,
2155 opts.mode == TEST_MODE_SERVER);
2156
2157 run_tests(test_cases, &opts);
2158
2159 control_cleanup();
2160 return EXIT_SUCCESS;
2161 }
2162