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
26 #include "vsock_test_zerocopy.h"
27 #include "timeout.h"
28 #include "control.h"
29 #include "util.h"
30
test_stream_connection_reset(const struct test_opts * opts)31 static void test_stream_connection_reset(const struct test_opts *opts)
32 {
33 union {
34 struct sockaddr sa;
35 struct sockaddr_vm svm;
36 } addr = {
37 .svm = {
38 .svm_family = AF_VSOCK,
39 .svm_port = opts->peer_port,
40 .svm_cid = opts->peer_cid,
41 },
42 };
43 int ret;
44 int fd;
45
46 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
47
48 timeout_begin(TIMEOUT);
49 do {
50 ret = connect(fd, &addr.sa, sizeof(addr.svm));
51 timeout_check("connect");
52 } while (ret < 0 && errno == EINTR);
53 timeout_end();
54
55 if (ret != -1) {
56 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
57 exit(EXIT_FAILURE);
58 }
59 if (errno != ECONNRESET) {
60 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
61 exit(EXIT_FAILURE);
62 }
63
64 close(fd);
65 }
66
test_stream_bind_only_client(const struct test_opts * opts)67 static void test_stream_bind_only_client(const struct test_opts *opts)
68 {
69 union {
70 struct sockaddr sa;
71 struct sockaddr_vm svm;
72 } addr = {
73 .svm = {
74 .svm_family = AF_VSOCK,
75 .svm_port = opts->peer_port,
76 .svm_cid = opts->peer_cid,
77 },
78 };
79 int ret;
80 int fd;
81
82 /* Wait for the server to be ready */
83 control_expectln("BIND");
84
85 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
86
87 timeout_begin(TIMEOUT);
88 do {
89 ret = connect(fd, &addr.sa, sizeof(addr.svm));
90 timeout_check("connect");
91 } while (ret < 0 && errno == EINTR);
92 timeout_end();
93
94 if (ret != -1) {
95 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
96 exit(EXIT_FAILURE);
97 }
98 if (errno != ECONNRESET) {
99 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
100 exit(EXIT_FAILURE);
101 }
102
103 /* Notify the server that the client has finished */
104 control_writeln("DONE");
105
106 close(fd);
107 }
108
test_stream_bind_only_server(const struct test_opts * opts)109 static void test_stream_bind_only_server(const struct test_opts *opts)
110 {
111 union {
112 struct sockaddr sa;
113 struct sockaddr_vm svm;
114 } addr = {
115 .svm = {
116 .svm_family = AF_VSOCK,
117 .svm_port = opts->peer_port,
118 .svm_cid = VMADDR_CID_ANY,
119 },
120 };
121 int fd;
122
123 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
124
125 if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
126 perror("bind");
127 exit(EXIT_FAILURE);
128 }
129
130 /* Notify the client that the server is ready */
131 control_writeln("BIND");
132
133 /* Wait for the client to finish */
134 control_expectln("DONE");
135
136 close(fd);
137 }
138
test_stream_client_close_client(const struct test_opts * opts)139 static void test_stream_client_close_client(const struct test_opts *opts)
140 {
141 int fd;
142
143 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
144 if (fd < 0) {
145 perror("connect");
146 exit(EXIT_FAILURE);
147 }
148
149 send_byte(fd, 1, 0);
150 close(fd);
151 }
152
test_stream_client_close_server(const struct test_opts * opts)153 static void test_stream_client_close_server(const struct test_opts *opts)
154 {
155 int fd;
156
157 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
158 if (fd < 0) {
159 perror("accept");
160 exit(EXIT_FAILURE);
161 }
162
163 /* Wait for the remote to close the connection, before check
164 * -EPIPE error on send.
165 */
166 vsock_wait_remote_close(fd);
167
168 send_byte(fd, -EPIPE, 0);
169 recv_byte(fd, 1, 0);
170 recv_byte(fd, 0, 0);
171 close(fd);
172 }
173
test_stream_server_close_client(const struct test_opts * opts)174 static void test_stream_server_close_client(const struct test_opts *opts)
175 {
176 int fd;
177
178 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
179 if (fd < 0) {
180 perror("connect");
181 exit(EXIT_FAILURE);
182 }
183
184 /* Wait for the remote to close the connection, before check
185 * -EPIPE error on send.
186 */
187 vsock_wait_remote_close(fd);
188
189 send_byte(fd, -EPIPE, 0);
190 recv_byte(fd, 1, 0);
191 recv_byte(fd, 0, 0);
192 close(fd);
193 }
194
test_stream_server_close_server(const struct test_opts * opts)195 static void test_stream_server_close_server(const struct test_opts *opts)
196 {
197 int fd;
198
199 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
200 if (fd < 0) {
201 perror("accept");
202 exit(EXIT_FAILURE);
203 }
204
205 send_byte(fd, 1, 0);
206 close(fd);
207 }
208
209 /* With the standard socket sizes, VMCI is able to support about 100
210 * concurrent stream connections.
211 */
212 #define MULTICONN_NFDS 100
213
test_stream_multiconn_client(const struct test_opts * opts)214 static void test_stream_multiconn_client(const struct test_opts *opts)
215 {
216 int fds[MULTICONN_NFDS];
217 int i;
218
219 for (i = 0; i < MULTICONN_NFDS; i++) {
220 fds[i] = vsock_stream_connect(opts->peer_cid, opts->peer_port);
221 if (fds[i] < 0) {
222 perror("connect");
223 exit(EXIT_FAILURE);
224 }
225 }
226
227 for (i = 0; i < MULTICONN_NFDS; i++) {
228 if (i % 2)
229 recv_byte(fds[i], 1, 0);
230 else
231 send_byte(fds[i], 1, 0);
232 }
233
234 for (i = 0; i < MULTICONN_NFDS; i++)
235 close(fds[i]);
236 }
237
test_stream_multiconn_server(const struct test_opts * opts)238 static void test_stream_multiconn_server(const struct test_opts *opts)
239 {
240 int fds[MULTICONN_NFDS];
241 int i;
242
243 for (i = 0; i < MULTICONN_NFDS; i++) {
244 fds[i] = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
245 if (fds[i] < 0) {
246 perror("accept");
247 exit(EXIT_FAILURE);
248 }
249 }
250
251 for (i = 0; i < MULTICONN_NFDS; i++) {
252 if (i % 2)
253 send_byte(fds[i], 1, 0);
254 else
255 recv_byte(fds[i], 1, 0);
256 }
257
258 for (i = 0; i < MULTICONN_NFDS; i++)
259 close(fds[i]);
260 }
261
262 #define MSG_PEEK_BUF_LEN 64
263
test_msg_peek_client(const struct test_opts * opts,bool seqpacket)264 static void test_msg_peek_client(const struct test_opts *opts,
265 bool seqpacket)
266 {
267 unsigned char buf[MSG_PEEK_BUF_LEN];
268 int fd;
269 int i;
270
271 if (seqpacket)
272 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
273 else
274 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
275
276 if (fd < 0) {
277 perror("connect");
278 exit(EXIT_FAILURE);
279 }
280
281 for (i = 0; i < sizeof(buf); i++)
282 buf[i] = rand() & 0xFF;
283
284 control_expectln("SRVREADY");
285
286 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
287
288 close(fd);
289 }
290
test_msg_peek_server(const struct test_opts * opts,bool seqpacket)291 static void test_msg_peek_server(const struct test_opts *opts,
292 bool seqpacket)
293 {
294 unsigned char buf_half[MSG_PEEK_BUF_LEN / 2];
295 unsigned char buf_normal[MSG_PEEK_BUF_LEN];
296 unsigned char buf_peek[MSG_PEEK_BUF_LEN];
297 int fd;
298
299 if (seqpacket)
300 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
301 else
302 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
303
304 if (fd < 0) {
305 perror("accept");
306 exit(EXIT_FAILURE);
307 }
308
309 /* Peek from empty socket. */
310 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK | MSG_DONTWAIT,
311 -EAGAIN);
312
313 control_writeln("SRVREADY");
314
315 /* Peek part of data. */
316 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK, sizeof(buf_half));
317
318 /* Peek whole data. */
319 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK, sizeof(buf_peek));
320
321 /* Compare partial and full peek. */
322 if (memcmp(buf_half, buf_peek, sizeof(buf_half))) {
323 fprintf(stderr, "Partial peek data mismatch\n");
324 exit(EXIT_FAILURE);
325 }
326
327 if (seqpacket) {
328 /* This type of socket supports MSG_TRUNC flag,
329 * so check it with MSG_PEEK. We must get length
330 * of the message.
331 */
332 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK | MSG_TRUNC,
333 sizeof(buf_peek));
334 }
335
336 recv_buf(fd, buf_normal, sizeof(buf_normal), 0, sizeof(buf_normal));
337
338 /* Compare full peek and normal read. */
339 if (memcmp(buf_peek, buf_normal, sizeof(buf_peek))) {
340 fprintf(stderr, "Full peek data mismatch\n");
341 exit(EXIT_FAILURE);
342 }
343
344 close(fd);
345 }
346
test_stream_msg_peek_client(const struct test_opts * opts)347 static void test_stream_msg_peek_client(const struct test_opts *opts)
348 {
349 return test_msg_peek_client(opts, false);
350 }
351
test_stream_msg_peek_server(const struct test_opts * opts)352 static void test_stream_msg_peek_server(const struct test_opts *opts)
353 {
354 return test_msg_peek_server(opts, false);
355 }
356
357 #define SOCK_BUF_SIZE (2 * 1024 * 1024)
358 #define MAX_MSG_PAGES 4
359
test_seqpacket_msg_bounds_client(const struct test_opts * opts)360 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
361 {
362 unsigned long curr_hash;
363 size_t max_msg_size;
364 int page_size;
365 int msg_count;
366 int fd;
367
368 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
369 if (fd < 0) {
370 perror("connect");
371 exit(EXIT_FAILURE);
372 }
373
374 /* Wait, until receiver sets buffer size. */
375 control_expectln("SRVREADY");
376
377 curr_hash = 0;
378 page_size = getpagesize();
379 max_msg_size = MAX_MSG_PAGES * page_size;
380 msg_count = SOCK_BUF_SIZE / max_msg_size;
381
382 for (int i = 0; i < msg_count; i++) {
383 size_t buf_size;
384 int flags;
385 void *buf;
386
387 /* Use "small" buffers and "big" buffers. */
388 if (i & 1)
389 buf_size = page_size +
390 (rand() % (max_msg_size - page_size));
391 else
392 buf_size = 1 + (rand() % page_size);
393
394 buf = malloc(buf_size);
395
396 if (!buf) {
397 perror("malloc");
398 exit(EXIT_FAILURE);
399 }
400
401 memset(buf, rand() & 0xff, buf_size);
402 /* Set at least one MSG_EOR + some random. */
403 if (i == (msg_count / 2) || (rand() & 1)) {
404 flags = MSG_EOR;
405 curr_hash++;
406 } else {
407 flags = 0;
408 }
409
410 send_buf(fd, buf, buf_size, flags, buf_size);
411
412 /*
413 * Hash sum is computed at both client and server in
414 * the same way:
415 * H += hash('message data')
416 * Such hash "controls" both data integrity and message
417 * bounds. After data exchange, both sums are compared
418 * using control socket, and if message bounds wasn't
419 * broken - two values must be equal.
420 */
421 curr_hash += hash_djb2(buf, buf_size);
422 free(buf);
423 }
424
425 control_writeln("SENDDONE");
426 control_writeulong(curr_hash);
427 close(fd);
428 }
429
test_seqpacket_msg_bounds_server(const struct test_opts * opts)430 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
431 {
432 unsigned long sock_buf_size;
433 unsigned long remote_hash;
434 unsigned long curr_hash;
435 int fd;
436 struct msghdr msg = {0};
437 struct iovec iov = {0};
438
439 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
440 if (fd < 0) {
441 perror("accept");
442 exit(EXIT_FAILURE);
443 }
444
445 sock_buf_size = SOCK_BUF_SIZE;
446
447 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
448 &sock_buf_size, sizeof(sock_buf_size))) {
449 perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
450 exit(EXIT_FAILURE);
451 }
452
453 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
454 &sock_buf_size, sizeof(sock_buf_size))) {
455 perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
456 exit(EXIT_FAILURE);
457 }
458
459 /* Ready to receive data. */
460 control_writeln("SRVREADY");
461 /* Wait, until peer sends whole data. */
462 control_expectln("SENDDONE");
463 iov.iov_len = MAX_MSG_PAGES * getpagesize();
464 iov.iov_base = malloc(iov.iov_len);
465 if (!iov.iov_base) {
466 perror("malloc");
467 exit(EXIT_FAILURE);
468 }
469
470 msg.msg_iov = &iov;
471 msg.msg_iovlen = 1;
472
473 curr_hash = 0;
474
475 while (1) {
476 ssize_t recv_size;
477
478 recv_size = recvmsg(fd, &msg, 0);
479
480 if (!recv_size)
481 break;
482
483 if (recv_size < 0) {
484 perror("recvmsg");
485 exit(EXIT_FAILURE);
486 }
487
488 if (msg.msg_flags & MSG_EOR)
489 curr_hash++;
490
491 curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
492 }
493
494 free(iov.iov_base);
495 close(fd);
496 remote_hash = control_readulong();
497
498 if (curr_hash != remote_hash) {
499 fprintf(stderr, "Message bounds broken\n");
500 exit(EXIT_FAILURE);
501 }
502 }
503
504 #define MESSAGE_TRUNC_SZ 32
test_seqpacket_msg_trunc_client(const struct test_opts * opts)505 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
506 {
507 int fd;
508 char buf[MESSAGE_TRUNC_SZ];
509
510 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
511 if (fd < 0) {
512 perror("connect");
513 exit(EXIT_FAILURE);
514 }
515
516 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
517
518 control_writeln("SENDDONE");
519 close(fd);
520 }
521
test_seqpacket_msg_trunc_server(const struct test_opts * opts)522 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
523 {
524 int fd;
525 char buf[MESSAGE_TRUNC_SZ / 2];
526 struct msghdr msg = {0};
527 struct iovec iov = {0};
528
529 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
530 if (fd < 0) {
531 perror("accept");
532 exit(EXIT_FAILURE);
533 }
534
535 control_expectln("SENDDONE");
536 iov.iov_base = buf;
537 iov.iov_len = sizeof(buf);
538 msg.msg_iov = &iov;
539 msg.msg_iovlen = 1;
540
541 ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
542
543 if (ret != MESSAGE_TRUNC_SZ) {
544 printf("%zi\n", ret);
545 perror("MSG_TRUNC doesn't work");
546 exit(EXIT_FAILURE);
547 }
548
549 if (!(msg.msg_flags & MSG_TRUNC)) {
550 fprintf(stderr, "MSG_TRUNC expected\n");
551 exit(EXIT_FAILURE);
552 }
553
554 close(fd);
555 }
556
current_nsec(void)557 static time_t current_nsec(void)
558 {
559 struct timespec ts;
560
561 if (clock_gettime(CLOCK_REALTIME, &ts)) {
562 perror("clock_gettime(3) failed");
563 exit(EXIT_FAILURE);
564 }
565
566 return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
567 }
568
569 #define RCVTIMEO_TIMEOUT_SEC 1
570 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
571
test_seqpacket_timeout_client(const struct test_opts * opts)572 static void test_seqpacket_timeout_client(const struct test_opts *opts)
573 {
574 int fd;
575 struct timeval tv;
576 char dummy;
577 time_t read_enter_ns;
578 time_t read_overhead_ns;
579
580 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
581 if (fd < 0) {
582 perror("connect");
583 exit(EXIT_FAILURE);
584 }
585
586 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
587 tv.tv_usec = 0;
588
589 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
590 perror("setsockopt(SO_RCVTIMEO)");
591 exit(EXIT_FAILURE);
592 }
593
594 read_enter_ns = current_nsec();
595
596 if (read(fd, &dummy, sizeof(dummy)) != -1) {
597 fprintf(stderr,
598 "expected 'dummy' read(2) failure\n");
599 exit(EXIT_FAILURE);
600 }
601
602 if (errno != EAGAIN) {
603 perror("EAGAIN expected");
604 exit(EXIT_FAILURE);
605 }
606
607 read_overhead_ns = current_nsec() - read_enter_ns -
608 1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
609
610 if (read_overhead_ns > READ_OVERHEAD_NSEC) {
611 fprintf(stderr,
612 "too much time in read(2), %lu > %i ns\n",
613 read_overhead_ns, READ_OVERHEAD_NSEC);
614 exit(EXIT_FAILURE);
615 }
616
617 control_writeln("WAITDONE");
618 close(fd);
619 }
620
test_seqpacket_timeout_server(const struct test_opts * opts)621 static void test_seqpacket_timeout_server(const struct test_opts *opts)
622 {
623 int fd;
624
625 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
626 if (fd < 0) {
627 perror("accept");
628 exit(EXIT_FAILURE);
629 }
630
631 control_expectln("WAITDONE");
632 close(fd);
633 }
634
test_seqpacket_bigmsg_client(const struct test_opts * opts)635 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
636 {
637 unsigned long sock_buf_size;
638 socklen_t len;
639 void *data;
640 int fd;
641
642 len = sizeof(sock_buf_size);
643
644 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
645 if (fd < 0) {
646 perror("connect");
647 exit(EXIT_FAILURE);
648 }
649
650 if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
651 &sock_buf_size, &len)) {
652 perror("getsockopt");
653 exit(EXIT_FAILURE);
654 }
655
656 sock_buf_size++;
657
658 data = malloc(sock_buf_size);
659 if (!data) {
660 perror("malloc");
661 exit(EXIT_FAILURE);
662 }
663
664 send_buf(fd, data, sock_buf_size, 0, -EMSGSIZE);
665
666 control_writeln("CLISENT");
667
668 free(data);
669 close(fd);
670 }
671
test_seqpacket_bigmsg_server(const struct test_opts * opts)672 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
673 {
674 int fd;
675
676 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
677 if (fd < 0) {
678 perror("accept");
679 exit(EXIT_FAILURE);
680 }
681
682 control_expectln("CLISENT");
683
684 close(fd);
685 }
686
687 #define BUF_PATTERN_1 'a'
688 #define BUF_PATTERN_2 'b'
689
test_seqpacket_invalid_rec_buffer_client(const struct test_opts * opts)690 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
691 {
692 int fd;
693 unsigned char *buf1;
694 unsigned char *buf2;
695 int buf_size = getpagesize() * 3;
696
697 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
698 if (fd < 0) {
699 perror("connect");
700 exit(EXIT_FAILURE);
701 }
702
703 buf1 = malloc(buf_size);
704 if (!buf1) {
705 perror("'malloc()' for 'buf1'");
706 exit(EXIT_FAILURE);
707 }
708
709 buf2 = malloc(buf_size);
710 if (!buf2) {
711 perror("'malloc()' for 'buf2'");
712 exit(EXIT_FAILURE);
713 }
714
715 memset(buf1, BUF_PATTERN_1, buf_size);
716 memset(buf2, BUF_PATTERN_2, buf_size);
717
718 send_buf(fd, buf1, buf_size, 0, buf_size);
719
720 send_buf(fd, buf2, buf_size, 0, buf_size);
721
722 close(fd);
723 }
724
test_seqpacket_invalid_rec_buffer_server(const struct test_opts * opts)725 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
726 {
727 int fd;
728 unsigned char *broken_buf;
729 unsigned char *valid_buf;
730 int page_size = getpagesize();
731 int buf_size = page_size * 3;
732 ssize_t res;
733 int prot = PROT_READ | PROT_WRITE;
734 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
735 int i;
736
737 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
738 if (fd < 0) {
739 perror("accept");
740 exit(EXIT_FAILURE);
741 }
742
743 /* Setup first buffer. */
744 broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
745 if (broken_buf == MAP_FAILED) {
746 perror("mmap for 'broken_buf'");
747 exit(EXIT_FAILURE);
748 }
749
750 /* Unmap "hole" in buffer. */
751 if (munmap(broken_buf + page_size, page_size)) {
752 perror("'broken_buf' setup");
753 exit(EXIT_FAILURE);
754 }
755
756 valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
757 if (valid_buf == MAP_FAILED) {
758 perror("mmap for 'valid_buf'");
759 exit(EXIT_FAILURE);
760 }
761
762 /* Try to fill buffer with unmapped middle. */
763 res = read(fd, broken_buf, buf_size);
764 if (res != -1) {
765 fprintf(stderr,
766 "expected 'broken_buf' read(2) failure, got %zi\n",
767 res);
768 exit(EXIT_FAILURE);
769 }
770
771 if (errno != EFAULT) {
772 perror("unexpected errno of 'broken_buf'");
773 exit(EXIT_FAILURE);
774 }
775
776 /* Try to fill valid buffer. */
777 res = read(fd, valid_buf, buf_size);
778 if (res < 0) {
779 perror("unexpected 'valid_buf' read(2) failure");
780 exit(EXIT_FAILURE);
781 }
782
783 if (res != buf_size) {
784 fprintf(stderr,
785 "invalid 'valid_buf' read(2), expected %i, got %zi\n",
786 buf_size, res);
787 exit(EXIT_FAILURE);
788 }
789
790 for (i = 0; i < buf_size; i++) {
791 if (valid_buf[i] != BUF_PATTERN_2) {
792 fprintf(stderr,
793 "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
794 i, BUF_PATTERN_2, valid_buf[i]);
795 exit(EXIT_FAILURE);
796 }
797 }
798
799 /* Unmap buffers. */
800 munmap(broken_buf, page_size);
801 munmap(broken_buf + page_size * 2, page_size);
802 munmap(valid_buf, buf_size);
803 close(fd);
804 }
805
806 #define RCVLOWAT_BUF_SIZE 128
807
test_stream_poll_rcvlowat_server(const struct test_opts * opts)808 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
809 {
810 int fd;
811 int i;
812
813 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
814 if (fd < 0) {
815 perror("accept");
816 exit(EXIT_FAILURE);
817 }
818
819 /* Send 1 byte. */
820 send_byte(fd, 1, 0);
821
822 control_writeln("SRVSENT");
823
824 /* Wait until client is ready to receive rest of data. */
825 control_expectln("CLNSENT");
826
827 for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
828 send_byte(fd, 1, 0);
829
830 /* Keep socket in active state. */
831 control_expectln("POLLDONE");
832
833 close(fd);
834 }
835
test_stream_poll_rcvlowat_client(const struct test_opts * opts)836 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
837 {
838 unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
839 char buf[RCVLOWAT_BUF_SIZE];
840 struct pollfd fds;
841 short poll_flags;
842 int fd;
843
844 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
845 if (fd < 0) {
846 perror("connect");
847 exit(EXIT_FAILURE);
848 }
849
850 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
851 &lowat_val, sizeof(lowat_val))) {
852 perror("setsockopt(SO_RCVLOWAT)");
853 exit(EXIT_FAILURE);
854 }
855
856 control_expectln("SRVSENT");
857
858 /* At this point, server sent 1 byte. */
859 fds.fd = fd;
860 poll_flags = POLLIN | POLLRDNORM;
861 fds.events = poll_flags;
862
863 /* Try to wait for 1 sec. */
864 if (poll(&fds, 1, 1000) < 0) {
865 perror("poll");
866 exit(EXIT_FAILURE);
867 }
868
869 /* poll() must return nothing. */
870 if (fds.revents) {
871 fprintf(stderr, "Unexpected poll result %hx\n",
872 fds.revents);
873 exit(EXIT_FAILURE);
874 }
875
876 /* Tell server to send rest of data. */
877 control_writeln("CLNSENT");
878
879 /* Poll for data. */
880 if (poll(&fds, 1, 10000) < 0) {
881 perror("poll");
882 exit(EXIT_FAILURE);
883 }
884
885 /* Only these two bits are expected. */
886 if (fds.revents != poll_flags) {
887 fprintf(stderr, "Unexpected poll result %hx\n",
888 fds.revents);
889 exit(EXIT_FAILURE);
890 }
891
892 /* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
893 * will be returned.
894 */
895 recv_buf(fd, buf, sizeof(buf), MSG_DONTWAIT, RCVLOWAT_BUF_SIZE);
896
897 control_writeln("POLLDONE");
898
899 close(fd);
900 }
901
902 #define INV_BUF_TEST_DATA_LEN 512
903
test_inv_buf_client(const struct test_opts * opts,bool stream)904 static void test_inv_buf_client(const struct test_opts *opts, bool stream)
905 {
906 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
907 ssize_t expected_ret;
908 int fd;
909
910 if (stream)
911 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
912 else
913 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
914
915 if (fd < 0) {
916 perror("connect");
917 exit(EXIT_FAILURE);
918 }
919
920 control_expectln("SENDDONE");
921
922 /* Use invalid buffer here. */
923 recv_buf(fd, NULL, sizeof(data), 0, -EFAULT);
924
925 if (stream) {
926 /* For SOCK_STREAM we must continue reading. */
927 expected_ret = sizeof(data);
928 } else {
929 /* For SOCK_SEQPACKET socket's queue must be empty. */
930 expected_ret = -EAGAIN;
931 }
932
933 recv_buf(fd, data, sizeof(data), MSG_DONTWAIT, expected_ret);
934
935 control_writeln("DONE");
936
937 close(fd);
938 }
939
test_inv_buf_server(const struct test_opts * opts,bool stream)940 static void test_inv_buf_server(const struct test_opts *opts, bool stream)
941 {
942 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
943 int fd;
944
945 if (stream)
946 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
947 else
948 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
949
950 if (fd < 0) {
951 perror("accept");
952 exit(EXIT_FAILURE);
953 }
954
955 send_buf(fd, data, sizeof(data), 0, sizeof(data));
956
957 control_writeln("SENDDONE");
958
959 control_expectln("DONE");
960
961 close(fd);
962 }
963
test_stream_inv_buf_client(const struct test_opts * opts)964 static void test_stream_inv_buf_client(const struct test_opts *opts)
965 {
966 test_inv_buf_client(opts, true);
967 }
968
test_stream_inv_buf_server(const struct test_opts * opts)969 static void test_stream_inv_buf_server(const struct test_opts *opts)
970 {
971 test_inv_buf_server(opts, true);
972 }
973
test_seqpacket_inv_buf_client(const struct test_opts * opts)974 static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
975 {
976 test_inv_buf_client(opts, false);
977 }
978
test_seqpacket_inv_buf_server(const struct test_opts * opts)979 static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
980 {
981 test_inv_buf_server(opts, false);
982 }
983
984 #define HELLO_STR "HELLO"
985 #define WORLD_STR "WORLD"
986
test_stream_virtio_skb_merge_client(const struct test_opts * opts)987 static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
988 {
989 int fd;
990
991 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
992 if (fd < 0) {
993 perror("connect");
994 exit(EXIT_FAILURE);
995 }
996
997 /* Send first skbuff. */
998 send_buf(fd, HELLO_STR, strlen(HELLO_STR), 0, strlen(HELLO_STR));
999
1000 control_writeln("SEND0");
1001 /* Peer reads part of first skbuff. */
1002 control_expectln("REPLY0");
1003
1004 /* Send second skbuff, it will be appended to the first. */
1005 send_buf(fd, WORLD_STR, strlen(WORLD_STR), 0, strlen(WORLD_STR));
1006
1007 control_writeln("SEND1");
1008 /* Peer reads merged skbuff packet. */
1009 control_expectln("REPLY1");
1010
1011 close(fd);
1012 }
1013
test_stream_virtio_skb_merge_server(const struct test_opts * opts)1014 static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
1015 {
1016 size_t read = 0, to_read;
1017 unsigned char buf[64];
1018 int fd;
1019
1020 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1021 if (fd < 0) {
1022 perror("accept");
1023 exit(EXIT_FAILURE);
1024 }
1025
1026 control_expectln("SEND0");
1027
1028 /* Read skbuff partially. */
1029 to_read = 2;
1030 recv_buf(fd, buf + read, to_read, 0, to_read);
1031 read += to_read;
1032
1033 control_writeln("REPLY0");
1034 control_expectln("SEND1");
1035
1036 /* Read the rest of both buffers */
1037 to_read = strlen(HELLO_STR WORLD_STR) - read;
1038 recv_buf(fd, buf + read, to_read, 0, to_read);
1039 read += to_read;
1040
1041 /* No more bytes should be there */
1042 to_read = sizeof(buf) - read;
1043 recv_buf(fd, buf + read, to_read, MSG_DONTWAIT, -EAGAIN);
1044
1045 if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
1046 fprintf(stderr, "pattern mismatch\n");
1047 exit(EXIT_FAILURE);
1048 }
1049
1050 control_writeln("REPLY1");
1051
1052 close(fd);
1053 }
1054
test_seqpacket_msg_peek_client(const struct test_opts * opts)1055 static void test_seqpacket_msg_peek_client(const struct test_opts *opts)
1056 {
1057 return test_msg_peek_client(opts, true);
1058 }
1059
test_seqpacket_msg_peek_server(const struct test_opts * opts)1060 static void test_seqpacket_msg_peek_server(const struct test_opts *opts)
1061 {
1062 return test_msg_peek_server(opts, true);
1063 }
1064
1065 static sig_atomic_t have_sigpipe;
1066
sigpipe(int signo)1067 static void sigpipe(int signo)
1068 {
1069 have_sigpipe = 1;
1070 }
1071
test_stream_check_sigpipe(int fd)1072 static void test_stream_check_sigpipe(int fd)
1073 {
1074 ssize_t res;
1075
1076 have_sigpipe = 0;
1077
1078 res = send(fd, "A", 1, 0);
1079 if (res != -1) {
1080 fprintf(stderr, "expected send(2) failure, got %zi\n", res);
1081 exit(EXIT_FAILURE);
1082 }
1083
1084 if (!have_sigpipe) {
1085 fprintf(stderr, "SIGPIPE expected\n");
1086 exit(EXIT_FAILURE);
1087 }
1088
1089 have_sigpipe = 0;
1090
1091 res = send(fd, "A", 1, MSG_NOSIGNAL);
1092 if (res != -1) {
1093 fprintf(stderr, "expected send(2) failure, got %zi\n", res);
1094 exit(EXIT_FAILURE);
1095 }
1096
1097 if (have_sigpipe) {
1098 fprintf(stderr, "SIGPIPE not expected\n");
1099 exit(EXIT_FAILURE);
1100 }
1101 }
1102
test_stream_shutwr_client(const struct test_opts * opts)1103 static void test_stream_shutwr_client(const struct test_opts *opts)
1104 {
1105 int fd;
1106
1107 struct sigaction act = {
1108 .sa_handler = sigpipe,
1109 };
1110
1111 sigaction(SIGPIPE, &act, NULL);
1112
1113 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1114 if (fd < 0) {
1115 perror("connect");
1116 exit(EXIT_FAILURE);
1117 }
1118
1119 if (shutdown(fd, SHUT_WR)) {
1120 perror("shutdown");
1121 exit(EXIT_FAILURE);
1122 }
1123
1124 test_stream_check_sigpipe(fd);
1125
1126 control_writeln("CLIENTDONE");
1127
1128 close(fd);
1129 }
1130
test_stream_shutwr_server(const struct test_opts * opts)1131 static void test_stream_shutwr_server(const struct test_opts *opts)
1132 {
1133 int fd;
1134
1135 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1136 if (fd < 0) {
1137 perror("accept");
1138 exit(EXIT_FAILURE);
1139 }
1140
1141 control_expectln("CLIENTDONE");
1142
1143 close(fd);
1144 }
1145
test_stream_shutrd_client(const struct test_opts * opts)1146 static void test_stream_shutrd_client(const struct test_opts *opts)
1147 {
1148 int fd;
1149
1150 struct sigaction act = {
1151 .sa_handler = sigpipe,
1152 };
1153
1154 sigaction(SIGPIPE, &act, NULL);
1155
1156 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1157 if (fd < 0) {
1158 perror("connect");
1159 exit(EXIT_FAILURE);
1160 }
1161
1162 control_expectln("SHUTRDDONE");
1163
1164 test_stream_check_sigpipe(fd);
1165
1166 control_writeln("CLIENTDONE");
1167
1168 close(fd);
1169 }
1170
test_stream_shutrd_server(const struct test_opts * opts)1171 static void test_stream_shutrd_server(const struct test_opts *opts)
1172 {
1173 int fd;
1174
1175 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1176 if (fd < 0) {
1177 perror("accept");
1178 exit(EXIT_FAILURE);
1179 }
1180
1181 if (shutdown(fd, SHUT_RD)) {
1182 perror("shutdown");
1183 exit(EXIT_FAILURE);
1184 }
1185
1186 control_writeln("SHUTRDDONE");
1187 control_expectln("CLIENTDONE");
1188
1189 close(fd);
1190 }
1191
test_double_bind_connect_server(const struct test_opts * opts)1192 static void test_double_bind_connect_server(const struct test_opts *opts)
1193 {
1194 int listen_fd, client_fd, i;
1195 struct sockaddr_vm sa_client;
1196 socklen_t socklen_client = sizeof(sa_client);
1197
1198 listen_fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1199
1200 for (i = 0; i < 2; i++) {
1201 control_writeln("LISTENING");
1202
1203 timeout_begin(TIMEOUT);
1204 do {
1205 client_fd = accept(listen_fd, (struct sockaddr *)&sa_client,
1206 &socklen_client);
1207 timeout_check("accept");
1208 } while (client_fd < 0 && errno == EINTR);
1209 timeout_end();
1210
1211 if (client_fd < 0) {
1212 perror("accept");
1213 exit(EXIT_FAILURE);
1214 }
1215
1216 /* Waiting for remote peer to close connection */
1217 vsock_wait_remote_close(client_fd);
1218 }
1219
1220 close(listen_fd);
1221 }
1222
test_double_bind_connect_client(const struct test_opts * opts)1223 static void test_double_bind_connect_client(const struct test_opts *opts)
1224 {
1225 int i, client_fd;
1226
1227 for (i = 0; i < 2; i++) {
1228 /* Wait until server is ready to accept a new connection */
1229 control_expectln("LISTENING");
1230
1231 /* We use 'peer_port + 1' as "some" port for the 'bind()'
1232 * call. It is safe for overflow, but must be considered,
1233 * when running multiple test applications simultaneously
1234 * where 'peer-port' argument differs by 1.
1235 */
1236 client_fd = vsock_bind_connect(opts->peer_cid, opts->peer_port,
1237 opts->peer_port + 1, SOCK_STREAM);
1238
1239 close(client_fd);
1240 }
1241 }
1242
1243 #define MSG_BUF_IOCTL_LEN 64
test_unsent_bytes_server(const struct test_opts * opts,int type)1244 static void test_unsent_bytes_server(const struct test_opts *opts, int type)
1245 {
1246 unsigned char buf[MSG_BUF_IOCTL_LEN];
1247 int client_fd;
1248
1249 client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
1250 if (client_fd < 0) {
1251 perror("accept");
1252 exit(EXIT_FAILURE);
1253 }
1254
1255 recv_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
1256 control_writeln("RECEIVED");
1257
1258 close(client_fd);
1259 }
1260
test_unsent_bytes_client(const struct test_opts * opts,int type)1261 static void test_unsent_bytes_client(const struct test_opts *opts, int type)
1262 {
1263 unsigned char buf[MSG_BUF_IOCTL_LEN];
1264 int ret, fd, sock_bytes_unsent;
1265
1266 fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
1267 if (fd < 0) {
1268 perror("connect");
1269 exit(EXIT_FAILURE);
1270 }
1271
1272 for (int i = 0; i < sizeof(buf); i++)
1273 buf[i] = rand() & 0xFF;
1274
1275 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
1276 control_expectln("RECEIVED");
1277
1278 ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
1279 if (ret < 0) {
1280 if (errno == EOPNOTSUPP) {
1281 fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n");
1282 } else {
1283 perror("ioctl");
1284 exit(EXIT_FAILURE);
1285 }
1286 } else if (ret == 0 && sock_bytes_unsent != 0) {
1287 fprintf(stderr,
1288 "Unexpected 'SIOCOUTQ' value, expected 0, got %i\n",
1289 sock_bytes_unsent);
1290 exit(EXIT_FAILURE);
1291 }
1292
1293 close(fd);
1294 }
1295
test_stream_unsent_bytes_client(const struct test_opts * opts)1296 static void test_stream_unsent_bytes_client(const struct test_opts *opts)
1297 {
1298 test_unsent_bytes_client(opts, SOCK_STREAM);
1299 }
1300
test_stream_unsent_bytes_server(const struct test_opts * opts)1301 static void test_stream_unsent_bytes_server(const struct test_opts *opts)
1302 {
1303 test_unsent_bytes_server(opts, SOCK_STREAM);
1304 }
1305
test_seqpacket_unsent_bytes_client(const struct test_opts * opts)1306 static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts)
1307 {
1308 test_unsent_bytes_client(opts, SOCK_SEQPACKET);
1309 }
1310
test_seqpacket_unsent_bytes_server(const struct test_opts * opts)1311 static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
1312 {
1313 test_unsent_bytes_server(opts, SOCK_SEQPACKET);
1314 }
1315
1316 #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
1317 /* This define is the same as in 'include/linux/virtio_vsock.h':
1318 * it is used to decide when to send credit update message during
1319 * reading from rx queue of a socket. Value and its usage in
1320 * kernel is important for this test.
1321 */
1322 #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
1323
test_stream_rcvlowat_def_cred_upd_client(const struct test_opts * opts)1324 static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opts)
1325 {
1326 size_t buf_size;
1327 void *buf;
1328 int fd;
1329
1330 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1331 if (fd < 0) {
1332 perror("connect");
1333 exit(EXIT_FAILURE);
1334 }
1335
1336 /* Send 1 byte more than peer's buffer size. */
1337 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE + 1;
1338
1339 buf = malloc(buf_size);
1340 if (!buf) {
1341 perror("malloc");
1342 exit(EXIT_FAILURE);
1343 }
1344
1345 /* Wait until peer sets needed buffer size. */
1346 recv_byte(fd, 1, 0);
1347
1348 if (send(fd, buf, buf_size, 0) != buf_size) {
1349 perror("send failed");
1350 exit(EXIT_FAILURE);
1351 }
1352
1353 free(buf);
1354 close(fd);
1355 }
1356
test_stream_credit_update_test(const struct test_opts * opts,bool low_rx_bytes_test)1357 static void test_stream_credit_update_test(const struct test_opts *opts,
1358 bool low_rx_bytes_test)
1359 {
1360 size_t recv_buf_size;
1361 struct pollfd fds;
1362 size_t buf_size;
1363 void *buf;
1364 int fd;
1365
1366 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1367 if (fd < 0) {
1368 perror("accept");
1369 exit(EXIT_FAILURE);
1370 }
1371
1372 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE;
1373
1374 if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
1375 &buf_size, sizeof(buf_size))) {
1376 perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
1377 exit(EXIT_FAILURE);
1378 }
1379
1380 if (low_rx_bytes_test) {
1381 /* Set new SO_RCVLOWAT here. This enables sending credit
1382 * update when number of bytes if our rx queue become <
1383 * SO_RCVLOWAT value.
1384 */
1385 recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1386
1387 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
1388 &recv_buf_size, sizeof(recv_buf_size))) {
1389 perror("setsockopt(SO_RCVLOWAT)");
1390 exit(EXIT_FAILURE);
1391 }
1392 }
1393
1394 /* Send one dummy byte here, because 'setsockopt()' above also
1395 * sends special packet which tells sender to update our buffer
1396 * size. This 'send_byte()' will serialize such packet with data
1397 * reads in a loop below. Sender starts transmission only when
1398 * it receives this single byte.
1399 */
1400 send_byte(fd, 1, 0);
1401
1402 buf = malloc(buf_size);
1403 if (!buf) {
1404 perror("malloc");
1405 exit(EXIT_FAILURE);
1406 }
1407
1408 /* Wait until there will be 128KB of data in rx queue. */
1409 while (1) {
1410 ssize_t res;
1411
1412 res = recv(fd, buf, buf_size, MSG_PEEK);
1413 if (res == buf_size)
1414 break;
1415
1416 if (res <= 0) {
1417 fprintf(stderr, "unexpected 'recv()' return: %zi\n", res);
1418 exit(EXIT_FAILURE);
1419 }
1420 }
1421
1422 /* There is 128KB of data in the socket's rx queue, dequeue first
1423 * 64KB, credit update is sent if 'low_rx_bytes_test' == true.
1424 * Otherwise, credit update is sent in 'if (!low_rx_bytes_test)'.
1425 */
1426 recv_buf_size = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1427 recv_buf(fd, buf, recv_buf_size, 0, recv_buf_size);
1428
1429 if (!low_rx_bytes_test) {
1430 recv_buf_size++;
1431
1432 /* Updating SO_RCVLOWAT will send credit update. */
1433 if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
1434 &recv_buf_size, sizeof(recv_buf_size))) {
1435 perror("setsockopt(SO_RCVLOWAT)");
1436 exit(EXIT_FAILURE);
1437 }
1438 }
1439
1440 fds.fd = fd;
1441 fds.events = POLLIN | POLLRDNORM | POLLERR |
1442 POLLRDHUP | POLLHUP;
1443
1444 /* This 'poll()' will return once we receive last byte
1445 * sent by client.
1446 */
1447 if (poll(&fds, 1, -1) < 0) {
1448 perror("poll");
1449 exit(EXIT_FAILURE);
1450 }
1451
1452 if (fds.revents & POLLERR) {
1453 fprintf(stderr, "'poll()' error\n");
1454 exit(EXIT_FAILURE);
1455 }
1456
1457 if (fds.revents & (POLLIN | POLLRDNORM)) {
1458 recv_buf(fd, buf, recv_buf_size, MSG_DONTWAIT, recv_buf_size);
1459 } else {
1460 /* These flags must be set, as there is at
1461 * least 64KB of data ready to read.
1462 */
1463 fprintf(stderr, "POLLIN | POLLRDNORM expected\n");
1464 exit(EXIT_FAILURE);
1465 }
1466
1467 free(buf);
1468 close(fd);
1469 }
1470
test_stream_cred_upd_on_low_rx_bytes(const struct test_opts * opts)1471 static void test_stream_cred_upd_on_low_rx_bytes(const struct test_opts *opts)
1472 {
1473 test_stream_credit_update_test(opts, true);
1474 }
1475
test_stream_cred_upd_on_set_rcvlowat(const struct test_opts * opts)1476 static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)
1477 {
1478 test_stream_credit_update_test(opts, false);
1479 }
1480
1481 static struct test_case test_cases[] = {
1482 {
1483 .name = "SOCK_STREAM connection reset",
1484 .run_client = test_stream_connection_reset,
1485 },
1486 {
1487 .name = "SOCK_STREAM bind only",
1488 .run_client = test_stream_bind_only_client,
1489 .run_server = test_stream_bind_only_server,
1490 },
1491 {
1492 .name = "SOCK_STREAM client close",
1493 .run_client = test_stream_client_close_client,
1494 .run_server = test_stream_client_close_server,
1495 },
1496 {
1497 .name = "SOCK_STREAM server close",
1498 .run_client = test_stream_server_close_client,
1499 .run_server = test_stream_server_close_server,
1500 },
1501 {
1502 .name = "SOCK_STREAM multiple connections",
1503 .run_client = test_stream_multiconn_client,
1504 .run_server = test_stream_multiconn_server,
1505 },
1506 {
1507 .name = "SOCK_STREAM MSG_PEEK",
1508 .run_client = test_stream_msg_peek_client,
1509 .run_server = test_stream_msg_peek_server,
1510 },
1511 {
1512 .name = "SOCK_SEQPACKET msg bounds",
1513 .run_client = test_seqpacket_msg_bounds_client,
1514 .run_server = test_seqpacket_msg_bounds_server,
1515 },
1516 {
1517 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
1518 .run_client = test_seqpacket_msg_trunc_client,
1519 .run_server = test_seqpacket_msg_trunc_server,
1520 },
1521 {
1522 .name = "SOCK_SEQPACKET timeout",
1523 .run_client = test_seqpacket_timeout_client,
1524 .run_server = test_seqpacket_timeout_server,
1525 },
1526 {
1527 .name = "SOCK_SEQPACKET invalid receive buffer",
1528 .run_client = test_seqpacket_invalid_rec_buffer_client,
1529 .run_server = test_seqpacket_invalid_rec_buffer_server,
1530 },
1531 {
1532 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1533 .run_client = test_stream_poll_rcvlowat_client,
1534 .run_server = test_stream_poll_rcvlowat_server,
1535 },
1536 {
1537 .name = "SOCK_SEQPACKET big message",
1538 .run_client = test_seqpacket_bigmsg_client,
1539 .run_server = test_seqpacket_bigmsg_server,
1540 },
1541 {
1542 .name = "SOCK_STREAM test invalid buffer",
1543 .run_client = test_stream_inv_buf_client,
1544 .run_server = test_stream_inv_buf_server,
1545 },
1546 {
1547 .name = "SOCK_SEQPACKET test invalid buffer",
1548 .run_client = test_seqpacket_inv_buf_client,
1549 .run_server = test_seqpacket_inv_buf_server,
1550 },
1551 {
1552 .name = "SOCK_STREAM virtio skb merge",
1553 .run_client = test_stream_virtio_skb_merge_client,
1554 .run_server = test_stream_virtio_skb_merge_server,
1555 },
1556 {
1557 .name = "SOCK_SEQPACKET MSG_PEEK",
1558 .run_client = test_seqpacket_msg_peek_client,
1559 .run_server = test_seqpacket_msg_peek_server,
1560 },
1561 {
1562 .name = "SOCK_STREAM SHUT_WR",
1563 .run_client = test_stream_shutwr_client,
1564 .run_server = test_stream_shutwr_server,
1565 },
1566 {
1567 .name = "SOCK_STREAM SHUT_RD",
1568 .run_client = test_stream_shutrd_client,
1569 .run_server = test_stream_shutrd_server,
1570 },
1571 {
1572 .name = "SOCK_STREAM MSG_ZEROCOPY",
1573 .run_client = test_stream_msgzcopy_client,
1574 .run_server = test_stream_msgzcopy_server,
1575 },
1576 {
1577 .name = "SOCK_SEQPACKET MSG_ZEROCOPY",
1578 .run_client = test_seqpacket_msgzcopy_client,
1579 .run_server = test_seqpacket_msgzcopy_server,
1580 },
1581 {
1582 .name = "SOCK_STREAM MSG_ZEROCOPY empty MSG_ERRQUEUE",
1583 .run_client = test_stream_msgzcopy_empty_errq_client,
1584 .run_server = test_stream_msgzcopy_empty_errq_server,
1585 },
1586 {
1587 .name = "SOCK_STREAM double bind connect",
1588 .run_client = test_double_bind_connect_client,
1589 .run_server = test_double_bind_connect_server,
1590 },
1591 {
1592 .name = "SOCK_STREAM virtio credit update + SO_RCVLOWAT",
1593 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1594 .run_server = test_stream_cred_upd_on_set_rcvlowat,
1595 },
1596 {
1597 .name = "SOCK_STREAM virtio credit update + low rx_bytes",
1598 .run_client = test_stream_rcvlowat_def_cred_upd_client,
1599 .run_server = test_stream_cred_upd_on_low_rx_bytes,
1600 },
1601 {
1602 .name = "SOCK_STREAM ioctl(SIOCOUTQ) 0 unsent bytes",
1603 .run_client = test_stream_unsent_bytes_client,
1604 .run_server = test_stream_unsent_bytes_server,
1605 },
1606 {
1607 .name = "SOCK_SEQPACKET ioctl(SIOCOUTQ) 0 unsent bytes",
1608 .run_client = test_seqpacket_unsent_bytes_client,
1609 .run_server = test_seqpacket_unsent_bytes_server,
1610 },
1611 {},
1612 };
1613
1614 static const char optstring[] = "";
1615 static const struct option longopts[] = {
1616 {
1617 .name = "control-host",
1618 .has_arg = required_argument,
1619 .val = 'H',
1620 },
1621 {
1622 .name = "control-port",
1623 .has_arg = required_argument,
1624 .val = 'P',
1625 },
1626 {
1627 .name = "mode",
1628 .has_arg = required_argument,
1629 .val = 'm',
1630 },
1631 {
1632 .name = "peer-cid",
1633 .has_arg = required_argument,
1634 .val = 'p',
1635 },
1636 {
1637 .name = "peer-port",
1638 .has_arg = required_argument,
1639 .val = 'q',
1640 },
1641 {
1642 .name = "list",
1643 .has_arg = no_argument,
1644 .val = 'l',
1645 },
1646 {
1647 .name = "skip",
1648 .has_arg = required_argument,
1649 .val = 's',
1650 },
1651 {
1652 .name = "help",
1653 .has_arg = no_argument,
1654 .val = '?',
1655 },
1656 {},
1657 };
1658
usage(void)1659 static void usage(void)
1660 {
1661 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"
1662 "\n"
1663 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
1664 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
1665 "\n"
1666 "Run vsock.ko tests. Must be launched in both guest\n"
1667 "and host. One side must use --mode=client and\n"
1668 "the other side must use --mode=server.\n"
1669 "\n"
1670 "A TCP control socket connection is used to coordinate tests\n"
1671 "between the client and the server. The server requires a\n"
1672 "listen address and the client requires an address to\n"
1673 "connect to.\n"
1674 "\n"
1675 "The CID of the other side must be given with --peer-cid=<cid>.\n"
1676 "During the test, two AF_VSOCK ports will be used: the port\n"
1677 "specified with --peer-port=<port> (or the default port)\n"
1678 "and the next one.\n"
1679 "\n"
1680 "Options:\n"
1681 " --help This help message\n"
1682 " --control-host <host> Server IP address to connect to\n"
1683 " --control-port <port> Server port to listen on/connect to\n"
1684 " --mode client|server Server or client mode\n"
1685 " --peer-cid <cid> CID of the other side\n"
1686 " --peer-port <port> AF_VSOCK port used for the test [default: %d]\n"
1687 " --list List of tests that will be executed\n"
1688 " --skip <test_id> Test ID to skip;\n"
1689 " use multiple --skip options to skip more tests\n",
1690 DEFAULT_PEER_PORT
1691 );
1692 exit(EXIT_FAILURE);
1693 }
1694
main(int argc,char ** argv)1695 int main(int argc, char **argv)
1696 {
1697 const char *control_host = NULL;
1698 const char *control_port = NULL;
1699 struct test_opts opts = {
1700 .mode = TEST_MODE_UNSET,
1701 .peer_cid = VMADDR_CID_ANY,
1702 .peer_port = DEFAULT_PEER_PORT,
1703 };
1704
1705 srand(time(NULL));
1706 init_signals();
1707
1708 for (;;) {
1709 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
1710
1711 if (opt == -1)
1712 break;
1713
1714 switch (opt) {
1715 case 'H':
1716 control_host = optarg;
1717 break;
1718 case 'm':
1719 if (strcmp(optarg, "client") == 0)
1720 opts.mode = TEST_MODE_CLIENT;
1721 else if (strcmp(optarg, "server") == 0)
1722 opts.mode = TEST_MODE_SERVER;
1723 else {
1724 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
1725 return EXIT_FAILURE;
1726 }
1727 break;
1728 case 'p':
1729 opts.peer_cid = parse_cid(optarg);
1730 break;
1731 case 'q':
1732 opts.peer_port = parse_port(optarg);
1733 break;
1734 case 'P':
1735 control_port = optarg;
1736 break;
1737 case 'l':
1738 list_tests(test_cases);
1739 break;
1740 case 's':
1741 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
1742 optarg);
1743 break;
1744 case '?':
1745 default:
1746 usage();
1747 }
1748 }
1749
1750 if (!control_port)
1751 usage();
1752 if (opts.mode == TEST_MODE_UNSET)
1753 usage();
1754 if (opts.peer_cid == VMADDR_CID_ANY)
1755 usage();
1756
1757 if (!control_host) {
1758 if (opts.mode != TEST_MODE_SERVER)
1759 usage();
1760 control_host = "0.0.0.0";
1761 }
1762
1763 control_init(control_host, control_port,
1764 opts.mode == TEST_MODE_SERVER);
1765
1766 run_tests(test_cases, &opts);
1767
1768 control_cleanup();
1769 return EXIT_SUCCESS;
1770 }
1771