xref: /openbmc/linux/tools/testing/vsock/vsock_test.c (revision c9dc580c)
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 
23 #include "timeout.h"
24 #include "control.h"
25 #include "util.h"
26 
27 static void test_stream_connection_reset(const struct test_opts *opts)
28 {
29 	union {
30 		struct sockaddr sa;
31 		struct sockaddr_vm svm;
32 	} addr = {
33 		.svm = {
34 			.svm_family = AF_VSOCK,
35 			.svm_port = 1234,
36 			.svm_cid = opts->peer_cid,
37 		},
38 	};
39 	int ret;
40 	int fd;
41 
42 	fd = socket(AF_VSOCK, SOCK_STREAM, 0);
43 
44 	timeout_begin(TIMEOUT);
45 	do {
46 		ret = connect(fd, &addr.sa, sizeof(addr.svm));
47 		timeout_check("connect");
48 	} while (ret < 0 && errno == EINTR);
49 	timeout_end();
50 
51 	if (ret != -1) {
52 		fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
53 		exit(EXIT_FAILURE);
54 	}
55 	if (errno != ECONNRESET) {
56 		fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
57 		exit(EXIT_FAILURE);
58 	}
59 
60 	close(fd);
61 }
62 
63 static void test_stream_bind_only_client(const struct test_opts *opts)
64 {
65 	union {
66 		struct sockaddr sa;
67 		struct sockaddr_vm svm;
68 	} addr = {
69 		.svm = {
70 			.svm_family = AF_VSOCK,
71 			.svm_port = 1234,
72 			.svm_cid = opts->peer_cid,
73 		},
74 	};
75 	int ret;
76 	int fd;
77 
78 	/* Wait for the server to be ready */
79 	control_expectln("BIND");
80 
81 	fd = socket(AF_VSOCK, SOCK_STREAM, 0);
82 
83 	timeout_begin(TIMEOUT);
84 	do {
85 		ret = connect(fd, &addr.sa, sizeof(addr.svm));
86 		timeout_check("connect");
87 	} while (ret < 0 && errno == EINTR);
88 	timeout_end();
89 
90 	if (ret != -1) {
91 		fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
92 		exit(EXIT_FAILURE);
93 	}
94 	if (errno != ECONNRESET) {
95 		fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
96 		exit(EXIT_FAILURE);
97 	}
98 
99 	/* Notify the server that the client has finished */
100 	control_writeln("DONE");
101 
102 	close(fd);
103 }
104 
105 static void test_stream_bind_only_server(const struct test_opts *opts)
106 {
107 	union {
108 		struct sockaddr sa;
109 		struct sockaddr_vm svm;
110 	} addr = {
111 		.svm = {
112 			.svm_family = AF_VSOCK,
113 			.svm_port = 1234,
114 			.svm_cid = VMADDR_CID_ANY,
115 		},
116 	};
117 	int fd;
118 
119 	fd = socket(AF_VSOCK, SOCK_STREAM, 0);
120 
121 	if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
122 		perror("bind");
123 		exit(EXIT_FAILURE);
124 	}
125 
126 	/* Notify the client that the server is ready */
127 	control_writeln("BIND");
128 
129 	/* Wait for the client to finish */
130 	control_expectln("DONE");
131 
132 	close(fd);
133 }
134 
135 static void test_stream_client_close_client(const struct test_opts *opts)
136 {
137 	int fd;
138 
139 	fd = vsock_stream_connect(opts->peer_cid, 1234);
140 	if (fd < 0) {
141 		perror("connect");
142 		exit(EXIT_FAILURE);
143 	}
144 
145 	send_byte(fd, 1, 0);
146 	close(fd);
147 }
148 
149 static void test_stream_client_close_server(const struct test_opts *opts)
150 {
151 	int fd;
152 
153 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
154 	if (fd < 0) {
155 		perror("accept");
156 		exit(EXIT_FAILURE);
157 	}
158 
159 	/* Wait for the remote to close the connection, before check
160 	 * -EPIPE error on send.
161 	 */
162 	vsock_wait_remote_close(fd);
163 
164 	send_byte(fd, -EPIPE, 0);
165 	recv_byte(fd, 1, 0);
166 	recv_byte(fd, 0, 0);
167 	close(fd);
168 }
169 
170 static void test_stream_server_close_client(const struct test_opts *opts)
171 {
172 	int fd;
173 
174 	fd = vsock_stream_connect(opts->peer_cid, 1234);
175 	if (fd < 0) {
176 		perror("connect");
177 		exit(EXIT_FAILURE);
178 	}
179 
180 	/* Wait for the remote to close the connection, before check
181 	 * -EPIPE error on send.
182 	 */
183 	vsock_wait_remote_close(fd);
184 
185 	send_byte(fd, -EPIPE, 0);
186 	recv_byte(fd, 1, 0);
187 	recv_byte(fd, 0, 0);
188 	close(fd);
189 }
190 
191 static void test_stream_server_close_server(const struct test_opts *opts)
192 {
193 	int fd;
194 
195 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
196 	if (fd < 0) {
197 		perror("accept");
198 		exit(EXIT_FAILURE);
199 	}
200 
201 	send_byte(fd, 1, 0);
202 	close(fd);
203 }
204 
205 /* With the standard socket sizes, VMCI is able to support about 100
206  * concurrent stream connections.
207  */
208 #define MULTICONN_NFDS 100
209 
210 static void test_stream_multiconn_client(const struct test_opts *opts)
211 {
212 	int fds[MULTICONN_NFDS];
213 	int i;
214 
215 	for (i = 0; i < MULTICONN_NFDS; i++) {
216 		fds[i] = vsock_stream_connect(opts->peer_cid, 1234);
217 		if (fds[i] < 0) {
218 			perror("connect");
219 			exit(EXIT_FAILURE);
220 		}
221 	}
222 
223 	for (i = 0; i < MULTICONN_NFDS; i++) {
224 		if (i % 2)
225 			recv_byte(fds[i], 1, 0);
226 		else
227 			send_byte(fds[i], 1, 0);
228 	}
229 
230 	for (i = 0; i < MULTICONN_NFDS; i++)
231 		close(fds[i]);
232 }
233 
234 static void test_stream_multiconn_server(const struct test_opts *opts)
235 {
236 	int fds[MULTICONN_NFDS];
237 	int i;
238 
239 	for (i = 0; i < MULTICONN_NFDS; i++) {
240 		fds[i] = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
241 		if (fds[i] < 0) {
242 			perror("accept");
243 			exit(EXIT_FAILURE);
244 		}
245 	}
246 
247 	for (i = 0; i < MULTICONN_NFDS; i++) {
248 		if (i % 2)
249 			send_byte(fds[i], 1, 0);
250 		else
251 			recv_byte(fds[i], 1, 0);
252 	}
253 
254 	for (i = 0; i < MULTICONN_NFDS; i++)
255 		close(fds[i]);
256 }
257 
258 static void test_stream_msg_peek_client(const struct test_opts *opts)
259 {
260 	int fd;
261 
262 	fd = vsock_stream_connect(opts->peer_cid, 1234);
263 	if (fd < 0) {
264 		perror("connect");
265 		exit(EXIT_FAILURE);
266 	}
267 
268 	send_byte(fd, 1, 0);
269 	close(fd);
270 }
271 
272 static void test_stream_msg_peek_server(const struct test_opts *opts)
273 {
274 	int fd;
275 
276 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
277 	if (fd < 0) {
278 		perror("accept");
279 		exit(EXIT_FAILURE);
280 	}
281 
282 	recv_byte(fd, 1, MSG_PEEK);
283 	recv_byte(fd, 1, 0);
284 	close(fd);
285 }
286 
287 #define SOCK_BUF_SIZE (2 * 1024 * 1024)
288 #define MAX_MSG_SIZE (32 * 1024)
289 
290 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
291 {
292 	unsigned long curr_hash;
293 	int page_size;
294 	int msg_count;
295 	int fd;
296 
297 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
298 	if (fd < 0) {
299 		perror("connect");
300 		exit(EXIT_FAILURE);
301 	}
302 
303 	/* Wait, until receiver sets buffer size. */
304 	control_expectln("SRVREADY");
305 
306 	curr_hash = 0;
307 	page_size = getpagesize();
308 	msg_count = SOCK_BUF_SIZE / MAX_MSG_SIZE;
309 
310 	for (int i = 0; i < msg_count; i++) {
311 		ssize_t send_size;
312 		size_t buf_size;
313 		int flags;
314 		void *buf;
315 
316 		/* Use "small" buffers and "big" buffers. */
317 		if (i & 1)
318 			buf_size = page_size +
319 					(rand() % (MAX_MSG_SIZE - page_size));
320 		else
321 			buf_size = 1 + (rand() % page_size);
322 
323 		buf = malloc(buf_size);
324 
325 		if (!buf) {
326 			perror("malloc");
327 			exit(EXIT_FAILURE);
328 		}
329 
330 		memset(buf, rand() & 0xff, buf_size);
331 		/* Set at least one MSG_EOR + some random. */
332 		if (i == (msg_count / 2) || (rand() & 1)) {
333 			flags = MSG_EOR;
334 			curr_hash++;
335 		} else {
336 			flags = 0;
337 		}
338 
339 		send_size = send(fd, buf, buf_size, flags);
340 
341 		if (send_size < 0) {
342 			perror("send");
343 			exit(EXIT_FAILURE);
344 		}
345 
346 		if (send_size != buf_size) {
347 			fprintf(stderr, "Invalid send size\n");
348 			exit(EXIT_FAILURE);
349 		}
350 
351 		/*
352 		 * Hash sum is computed at both client and server in
353 		 * the same way:
354 		 * H += hash('message data')
355 		 * Such hash "controls" both data integrity and message
356 		 * bounds. After data exchange, both sums are compared
357 		 * using control socket, and if message bounds wasn't
358 		 * broken - two values must be equal.
359 		 */
360 		curr_hash += hash_djb2(buf, buf_size);
361 		free(buf);
362 	}
363 
364 	control_writeln("SENDDONE");
365 	control_writeulong(curr_hash);
366 	close(fd);
367 }
368 
369 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
370 {
371 	unsigned long sock_buf_size;
372 	unsigned long remote_hash;
373 	unsigned long curr_hash;
374 	int fd;
375 	char buf[MAX_MSG_SIZE];
376 	struct msghdr msg = {0};
377 	struct iovec iov = {0};
378 
379 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
380 	if (fd < 0) {
381 		perror("accept");
382 		exit(EXIT_FAILURE);
383 	}
384 
385 	sock_buf_size = SOCK_BUF_SIZE;
386 
387 	if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
388 		       &sock_buf_size, sizeof(sock_buf_size))) {
389 		perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
390 		exit(EXIT_FAILURE);
391 	}
392 
393 	if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
394 		       &sock_buf_size, sizeof(sock_buf_size))) {
395 		perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
396 		exit(EXIT_FAILURE);
397 	}
398 
399 	/* Ready to receive data. */
400 	control_writeln("SRVREADY");
401 	/* Wait, until peer sends whole data. */
402 	control_expectln("SENDDONE");
403 	iov.iov_base = buf;
404 	iov.iov_len = sizeof(buf);
405 	msg.msg_iov = &iov;
406 	msg.msg_iovlen = 1;
407 
408 	curr_hash = 0;
409 
410 	while (1) {
411 		ssize_t recv_size;
412 
413 		recv_size = recvmsg(fd, &msg, 0);
414 
415 		if (!recv_size)
416 			break;
417 
418 		if (recv_size < 0) {
419 			perror("recvmsg");
420 			exit(EXIT_FAILURE);
421 		}
422 
423 		if (msg.msg_flags & MSG_EOR)
424 			curr_hash++;
425 
426 		curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
427 	}
428 
429 	close(fd);
430 	remote_hash = control_readulong();
431 
432 	if (curr_hash != remote_hash) {
433 		fprintf(stderr, "Message bounds broken\n");
434 		exit(EXIT_FAILURE);
435 	}
436 }
437 
438 #define MESSAGE_TRUNC_SZ 32
439 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
440 {
441 	int fd;
442 	char buf[MESSAGE_TRUNC_SZ];
443 
444 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
445 	if (fd < 0) {
446 		perror("connect");
447 		exit(EXIT_FAILURE);
448 	}
449 
450 	if (send(fd, buf, sizeof(buf), 0) != sizeof(buf)) {
451 		perror("send failed");
452 		exit(EXIT_FAILURE);
453 	}
454 
455 	control_writeln("SENDDONE");
456 	close(fd);
457 }
458 
459 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
460 {
461 	int fd;
462 	char buf[MESSAGE_TRUNC_SZ / 2];
463 	struct msghdr msg = {0};
464 	struct iovec iov = {0};
465 
466 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
467 	if (fd < 0) {
468 		perror("accept");
469 		exit(EXIT_FAILURE);
470 	}
471 
472 	control_expectln("SENDDONE");
473 	iov.iov_base = buf;
474 	iov.iov_len = sizeof(buf);
475 	msg.msg_iov = &iov;
476 	msg.msg_iovlen = 1;
477 
478 	ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
479 
480 	if (ret != MESSAGE_TRUNC_SZ) {
481 		printf("%zi\n", ret);
482 		perror("MSG_TRUNC doesn't work");
483 		exit(EXIT_FAILURE);
484 	}
485 
486 	if (!(msg.msg_flags & MSG_TRUNC)) {
487 		fprintf(stderr, "MSG_TRUNC expected\n");
488 		exit(EXIT_FAILURE);
489 	}
490 
491 	close(fd);
492 }
493 
494 static time_t current_nsec(void)
495 {
496 	struct timespec ts;
497 
498 	if (clock_gettime(CLOCK_REALTIME, &ts)) {
499 		perror("clock_gettime(3) failed");
500 		exit(EXIT_FAILURE);
501 	}
502 
503 	return (ts.tv_sec * 1000000000ULL) + ts.tv_nsec;
504 }
505 
506 #define RCVTIMEO_TIMEOUT_SEC 1
507 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
508 
509 static void test_seqpacket_timeout_client(const struct test_opts *opts)
510 {
511 	int fd;
512 	struct timeval tv;
513 	char dummy;
514 	time_t read_enter_ns;
515 	time_t read_overhead_ns;
516 
517 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
518 	if (fd < 0) {
519 		perror("connect");
520 		exit(EXIT_FAILURE);
521 	}
522 
523 	tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
524 	tv.tv_usec = 0;
525 
526 	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) {
527 		perror("setsockopt(SO_RCVTIMEO)");
528 		exit(EXIT_FAILURE);
529 	}
530 
531 	read_enter_ns = current_nsec();
532 
533 	if (read(fd, &dummy, sizeof(dummy)) != -1) {
534 		fprintf(stderr,
535 			"expected 'dummy' read(2) failure\n");
536 		exit(EXIT_FAILURE);
537 	}
538 
539 	if (errno != EAGAIN) {
540 		perror("EAGAIN expected");
541 		exit(EXIT_FAILURE);
542 	}
543 
544 	read_overhead_ns = current_nsec() - read_enter_ns -
545 			1000000000ULL * RCVTIMEO_TIMEOUT_SEC;
546 
547 	if (read_overhead_ns > READ_OVERHEAD_NSEC) {
548 		fprintf(stderr,
549 			"too much time in read(2), %lu > %i ns\n",
550 			read_overhead_ns, READ_OVERHEAD_NSEC);
551 		exit(EXIT_FAILURE);
552 	}
553 
554 	control_writeln("WAITDONE");
555 	close(fd);
556 }
557 
558 static void test_seqpacket_timeout_server(const struct test_opts *opts)
559 {
560 	int fd;
561 
562 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
563 	if (fd < 0) {
564 		perror("accept");
565 		exit(EXIT_FAILURE);
566 	}
567 
568 	control_expectln("WAITDONE");
569 	close(fd);
570 }
571 
572 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
573 {
574 	unsigned long sock_buf_size;
575 	ssize_t send_size;
576 	socklen_t len;
577 	void *data;
578 	int fd;
579 
580 	len = sizeof(sock_buf_size);
581 
582 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
583 	if (fd < 0) {
584 		perror("connect");
585 		exit(EXIT_FAILURE);
586 	}
587 
588 	if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
589 		       &sock_buf_size, &len)) {
590 		perror("getsockopt");
591 		exit(EXIT_FAILURE);
592 	}
593 
594 	sock_buf_size++;
595 
596 	data = malloc(sock_buf_size);
597 	if (!data) {
598 		perror("malloc");
599 		exit(EXIT_FAILURE);
600 	}
601 
602 	send_size = send(fd, data, sock_buf_size, 0);
603 	if (send_size != -1) {
604 		fprintf(stderr, "expected 'send(2)' failure, got %zi\n",
605 			send_size);
606 		exit(EXIT_FAILURE);
607 	}
608 
609 	if (errno != EMSGSIZE) {
610 		fprintf(stderr, "expected EMSGSIZE in 'errno', got %i\n",
611 			errno);
612 		exit(EXIT_FAILURE);
613 	}
614 
615 	control_writeln("CLISENT");
616 
617 	free(data);
618 	close(fd);
619 }
620 
621 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
622 {
623 	int fd;
624 
625 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
626 	if (fd < 0) {
627 		perror("accept");
628 		exit(EXIT_FAILURE);
629 	}
630 
631 	control_expectln("CLISENT");
632 
633 	close(fd);
634 }
635 
636 #define BUF_PATTERN_1 'a'
637 #define BUF_PATTERN_2 'b'
638 
639 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
640 {
641 	int fd;
642 	unsigned char *buf1;
643 	unsigned char *buf2;
644 	int buf_size = getpagesize() * 3;
645 
646 	fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
647 	if (fd < 0) {
648 		perror("connect");
649 		exit(EXIT_FAILURE);
650 	}
651 
652 	buf1 = malloc(buf_size);
653 	if (!buf1) {
654 		perror("'malloc()' for 'buf1'");
655 		exit(EXIT_FAILURE);
656 	}
657 
658 	buf2 = malloc(buf_size);
659 	if (!buf2) {
660 		perror("'malloc()' for 'buf2'");
661 		exit(EXIT_FAILURE);
662 	}
663 
664 	memset(buf1, BUF_PATTERN_1, buf_size);
665 	memset(buf2, BUF_PATTERN_2, buf_size);
666 
667 	if (send(fd, buf1, buf_size, 0) != buf_size) {
668 		perror("send failed");
669 		exit(EXIT_FAILURE);
670 	}
671 
672 	if (send(fd, buf2, buf_size, 0) != buf_size) {
673 		perror("send failed");
674 		exit(EXIT_FAILURE);
675 	}
676 
677 	close(fd);
678 }
679 
680 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
681 {
682 	int fd;
683 	unsigned char *broken_buf;
684 	unsigned char *valid_buf;
685 	int page_size = getpagesize();
686 	int buf_size = page_size * 3;
687 	ssize_t res;
688 	int prot = PROT_READ | PROT_WRITE;
689 	int flags = MAP_PRIVATE | MAP_ANONYMOUS;
690 	int i;
691 
692 	fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
693 	if (fd < 0) {
694 		perror("accept");
695 		exit(EXIT_FAILURE);
696 	}
697 
698 	/* Setup first buffer. */
699 	broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
700 	if (broken_buf == MAP_FAILED) {
701 		perror("mmap for 'broken_buf'");
702 		exit(EXIT_FAILURE);
703 	}
704 
705 	/* Unmap "hole" in buffer. */
706 	if (munmap(broken_buf + page_size, page_size)) {
707 		perror("'broken_buf' setup");
708 		exit(EXIT_FAILURE);
709 	}
710 
711 	valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
712 	if (valid_buf == MAP_FAILED) {
713 		perror("mmap for 'valid_buf'");
714 		exit(EXIT_FAILURE);
715 	}
716 
717 	/* Try to fill buffer with unmapped middle. */
718 	res = read(fd, broken_buf, buf_size);
719 	if (res != -1) {
720 		fprintf(stderr,
721 			"expected 'broken_buf' read(2) failure, got %zi\n",
722 			res);
723 		exit(EXIT_FAILURE);
724 	}
725 
726 	if (errno != ENOMEM) {
727 		perror("unexpected errno of 'broken_buf'");
728 		exit(EXIT_FAILURE);
729 	}
730 
731 	/* Try to fill valid buffer. */
732 	res = read(fd, valid_buf, buf_size);
733 	if (res < 0) {
734 		perror("unexpected 'valid_buf' read(2) failure");
735 		exit(EXIT_FAILURE);
736 	}
737 
738 	if (res != buf_size) {
739 		fprintf(stderr,
740 			"invalid 'valid_buf' read(2), expected %i, got %zi\n",
741 			buf_size, res);
742 		exit(EXIT_FAILURE);
743 	}
744 
745 	for (i = 0; i < buf_size; i++) {
746 		if (valid_buf[i] != BUF_PATTERN_2) {
747 			fprintf(stderr,
748 				"invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
749 				i, BUF_PATTERN_2, valid_buf[i]);
750 			exit(EXIT_FAILURE);
751 		}
752 	}
753 
754 	/* Unmap buffers. */
755 	munmap(broken_buf, page_size);
756 	munmap(broken_buf + page_size * 2, page_size);
757 	munmap(valid_buf, buf_size);
758 	close(fd);
759 }
760 
761 #define RCVLOWAT_BUF_SIZE 128
762 
763 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
764 {
765 	int fd;
766 	int i;
767 
768 	fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
769 	if (fd < 0) {
770 		perror("accept");
771 		exit(EXIT_FAILURE);
772 	}
773 
774 	/* Send 1 byte. */
775 	send_byte(fd, 1, 0);
776 
777 	control_writeln("SRVSENT");
778 
779 	/* Wait until client is ready to receive rest of data. */
780 	control_expectln("CLNSENT");
781 
782 	for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
783 		send_byte(fd, 1, 0);
784 
785 	/* Keep socket in active state. */
786 	control_expectln("POLLDONE");
787 
788 	close(fd);
789 }
790 
791 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
792 {
793 	unsigned long lowat_val = RCVLOWAT_BUF_SIZE;
794 	char buf[RCVLOWAT_BUF_SIZE];
795 	struct pollfd fds;
796 	ssize_t read_res;
797 	short poll_flags;
798 	int fd;
799 
800 	fd = vsock_stream_connect(opts->peer_cid, 1234);
801 	if (fd < 0) {
802 		perror("connect");
803 		exit(EXIT_FAILURE);
804 	}
805 
806 	if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
807 		       &lowat_val, sizeof(lowat_val))) {
808 		perror("setsockopt(SO_RCVLOWAT)");
809 		exit(EXIT_FAILURE);
810 	}
811 
812 	control_expectln("SRVSENT");
813 
814 	/* At this point, server sent 1 byte. */
815 	fds.fd = fd;
816 	poll_flags = POLLIN | POLLRDNORM;
817 	fds.events = poll_flags;
818 
819 	/* Try to wait for 1 sec. */
820 	if (poll(&fds, 1, 1000) < 0) {
821 		perror("poll");
822 		exit(EXIT_FAILURE);
823 	}
824 
825 	/* poll() must return nothing. */
826 	if (fds.revents) {
827 		fprintf(stderr, "Unexpected poll result %hx\n",
828 			fds.revents);
829 		exit(EXIT_FAILURE);
830 	}
831 
832 	/* Tell server to send rest of data. */
833 	control_writeln("CLNSENT");
834 
835 	/* Poll for data. */
836 	if (poll(&fds, 1, 10000) < 0) {
837 		perror("poll");
838 		exit(EXIT_FAILURE);
839 	}
840 
841 	/* Only these two bits are expected. */
842 	if (fds.revents != poll_flags) {
843 		fprintf(stderr, "Unexpected poll result %hx\n",
844 			fds.revents);
845 		exit(EXIT_FAILURE);
846 	}
847 
848 	/* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
849 	 * will be returned.
850 	 */
851 	read_res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
852 	if (read_res != RCVLOWAT_BUF_SIZE) {
853 		fprintf(stderr, "Unexpected recv result %zi\n",
854 			read_res);
855 		exit(EXIT_FAILURE);
856 	}
857 
858 	control_writeln("POLLDONE");
859 
860 	close(fd);
861 }
862 
863 static struct test_case test_cases[] = {
864 	{
865 		.name = "SOCK_STREAM connection reset",
866 		.run_client = test_stream_connection_reset,
867 	},
868 	{
869 		.name = "SOCK_STREAM bind only",
870 		.run_client = test_stream_bind_only_client,
871 		.run_server = test_stream_bind_only_server,
872 	},
873 	{
874 		.name = "SOCK_STREAM client close",
875 		.run_client = test_stream_client_close_client,
876 		.run_server = test_stream_client_close_server,
877 	},
878 	{
879 		.name = "SOCK_STREAM server close",
880 		.run_client = test_stream_server_close_client,
881 		.run_server = test_stream_server_close_server,
882 	},
883 	{
884 		.name = "SOCK_STREAM multiple connections",
885 		.run_client = test_stream_multiconn_client,
886 		.run_server = test_stream_multiconn_server,
887 	},
888 	{
889 		.name = "SOCK_STREAM MSG_PEEK",
890 		.run_client = test_stream_msg_peek_client,
891 		.run_server = test_stream_msg_peek_server,
892 	},
893 	{
894 		.name = "SOCK_SEQPACKET msg bounds",
895 		.run_client = test_seqpacket_msg_bounds_client,
896 		.run_server = test_seqpacket_msg_bounds_server,
897 	},
898 	{
899 		.name = "SOCK_SEQPACKET MSG_TRUNC flag",
900 		.run_client = test_seqpacket_msg_trunc_client,
901 		.run_server = test_seqpacket_msg_trunc_server,
902 	},
903 	{
904 		.name = "SOCK_SEQPACKET timeout",
905 		.run_client = test_seqpacket_timeout_client,
906 		.run_server = test_seqpacket_timeout_server,
907 	},
908 	{
909 		.name = "SOCK_SEQPACKET invalid receive buffer",
910 		.run_client = test_seqpacket_invalid_rec_buffer_client,
911 		.run_server = test_seqpacket_invalid_rec_buffer_server,
912 	},
913 	{
914 		.name = "SOCK_STREAM poll() + SO_RCVLOWAT",
915 		.run_client = test_stream_poll_rcvlowat_client,
916 		.run_server = test_stream_poll_rcvlowat_server,
917 	},
918 	{
919 		.name = "SOCK_SEQPACKET big message",
920 		.run_client = test_seqpacket_bigmsg_client,
921 		.run_server = test_seqpacket_bigmsg_server,
922 	},
923 	{},
924 };
925 
926 static const char optstring[] = "";
927 static const struct option longopts[] = {
928 	{
929 		.name = "control-host",
930 		.has_arg = required_argument,
931 		.val = 'H',
932 	},
933 	{
934 		.name = "control-port",
935 		.has_arg = required_argument,
936 		.val = 'P',
937 	},
938 	{
939 		.name = "mode",
940 		.has_arg = required_argument,
941 		.val = 'm',
942 	},
943 	{
944 		.name = "peer-cid",
945 		.has_arg = required_argument,
946 		.val = 'p',
947 	},
948 	{
949 		.name = "list",
950 		.has_arg = no_argument,
951 		.val = 'l',
952 	},
953 	{
954 		.name = "skip",
955 		.has_arg = required_argument,
956 		.val = 's',
957 	},
958 	{
959 		.name = "help",
960 		.has_arg = no_argument,
961 		.val = '?',
962 	},
963 	{},
964 };
965 
966 static void usage(void)
967 {
968 	fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--list] [--skip=<test_id>]\n"
969 		"\n"
970 		"  Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
971 		"  Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
972 		"\n"
973 		"Run vsock.ko tests.  Must be launched in both guest\n"
974 		"and host.  One side must use --mode=client and\n"
975 		"the other side must use --mode=server.\n"
976 		"\n"
977 		"A TCP control socket connection is used to coordinate tests\n"
978 		"between the client and the server.  The server requires a\n"
979 		"listen address and the client requires an address to\n"
980 		"connect to.\n"
981 		"\n"
982 		"The CID of the other side must be given with --peer-cid=<cid>.\n"
983 		"\n"
984 		"Options:\n"
985 		"  --help                 This help message\n"
986 		"  --control-host <host>  Server IP address to connect to\n"
987 		"  --control-port <port>  Server port to listen on/connect to\n"
988 		"  --mode client|server   Server or client mode\n"
989 		"  --peer-cid <cid>       CID of the other side\n"
990 		"  --list                 List of tests that will be executed\n"
991 		"  --skip <test_id>       Test ID to skip;\n"
992 		"                         use multiple --skip options to skip more tests\n"
993 		);
994 	exit(EXIT_FAILURE);
995 }
996 
997 int main(int argc, char **argv)
998 {
999 	const char *control_host = NULL;
1000 	const char *control_port = NULL;
1001 	struct test_opts opts = {
1002 		.mode = TEST_MODE_UNSET,
1003 		.peer_cid = VMADDR_CID_ANY,
1004 	};
1005 
1006 	srand(time(NULL));
1007 	init_signals();
1008 
1009 	for (;;) {
1010 		int opt = getopt_long(argc, argv, optstring, longopts, NULL);
1011 
1012 		if (opt == -1)
1013 			break;
1014 
1015 		switch (opt) {
1016 		case 'H':
1017 			control_host = optarg;
1018 			break;
1019 		case 'm':
1020 			if (strcmp(optarg, "client") == 0)
1021 				opts.mode = TEST_MODE_CLIENT;
1022 			else if (strcmp(optarg, "server") == 0)
1023 				opts.mode = TEST_MODE_SERVER;
1024 			else {
1025 				fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
1026 				return EXIT_FAILURE;
1027 			}
1028 			break;
1029 		case 'p':
1030 			opts.peer_cid = parse_cid(optarg);
1031 			break;
1032 		case 'P':
1033 			control_port = optarg;
1034 			break;
1035 		case 'l':
1036 			list_tests(test_cases);
1037 			break;
1038 		case 's':
1039 			skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
1040 				  optarg);
1041 			break;
1042 		case '?':
1043 		default:
1044 			usage();
1045 		}
1046 	}
1047 
1048 	if (!control_port)
1049 		usage();
1050 	if (opts.mode == TEST_MODE_UNSET)
1051 		usage();
1052 	if (opts.peer_cid == VMADDR_CID_ANY)
1053 		usage();
1054 
1055 	if (!control_host) {
1056 		if (opts.mode != TEST_MODE_SERVER)
1057 			usage();
1058 		control_host = "0.0.0.0";
1059 	}
1060 
1061 	control_init(control_host, control_port,
1062 		     opts.mode == TEST_MODE_SERVER);
1063 
1064 	run_tests(test_cases, &opts);
1065 
1066 	control_cleanup();
1067 	return EXIT_SUCCESS;
1068 }
1069