~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/vsock/vsock_test.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php