brintos

brintos / linux-shallow public Read only

0
0
Text · 38.3 KiB · 8d38dbf Raw
1771 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * vsock_test - vsock.ko test suite4 *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 31static 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 67static 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 109static 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 139static 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 153static 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 check164	 * -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 174static 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 check185	 * -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 195static 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 100210 * concurrent stream connections.211 */212#define MULTICONN_NFDS 100213 214static 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		else231			send_byte(fds[i], 1, 0);232	}233 234	for (i = 0; i < MULTICONN_NFDS; i++)235		close(fds[i]);236}237 238static 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		else255			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 64263 264static 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	else274		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 291static 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	else302		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 length330		 * 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 347static void test_stream_msg_peek_client(const struct test_opts *opts)348{349	return test_msg_peek_client(opts, false);350}351 352static 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 4359 360static 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		else392			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 in414		 * the same way:415		 * H += hash('message data')416		 * Such hash "controls" both data integrity and message417		 * bounds. After data exchange, both sums are compared418		 * using control socket, and if message bounds wasn't419		 * 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 430static 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 32505static 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 522static 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 557static 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 1570#define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */571 572static 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 621static 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 635static 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 672static 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 690static 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 725static 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 128807 808static 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 836static 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, EAGAIN893	 * 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 512903 904static 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	else913		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 940static 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	else948		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 964static void test_stream_inv_buf_client(const struct test_opts *opts)965{966	test_inv_buf_client(opts, true);967}968 969static void test_stream_inv_buf_server(const struct test_opts *opts)970{971	test_inv_buf_server(opts, true);972}973 974static void test_seqpacket_inv_buf_client(const struct test_opts *opts)975{976	test_inv_buf_client(opts, false);977}978 979static 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 987static 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 1014static 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 1055static void test_seqpacket_msg_peek_client(const struct test_opts *opts)1056{1057	return test_msg_peek_client(opts, true);1058}1059 1060static void test_seqpacket_msg_peek_server(const struct test_opts *opts)1061{1062	return test_msg_peek_server(opts, true);1063}1064 1065static sig_atomic_t have_sigpipe;1066 1067static void sigpipe(int signo)1068{1069	have_sigpipe = 1;1070}1071 1072static 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 1103static 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 1131static 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 1146static 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 1171static 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 1192static 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 1223static 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 simultaneously1234		 * 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 641244static 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 1261static 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 1296static void test_stream_unsent_bytes_client(const struct test_opts *opts)1297{1298	test_unsent_bytes_client(opts, SOCK_STREAM);1299}1300 1301static void test_stream_unsent_bytes_server(const struct test_opts *opts)1302{1303	test_unsent_bytes_server(opts, SOCK_STREAM);1304}1305 1306static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts)1307{1308	test_unsent_bytes_client(opts, SOCK_SEQPACKET);1309}1310 1311static 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 during1319 * reading from rx queue of a socket. Value and its usage in1320 * kernel is important for this test.1321 */1322#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE	(1024 * 64)1323 1324static 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 1357static 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 credit1382		 * 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 also1395	 * sends special packet which tells sender to update our buffer1396	 * size. This 'send_byte()' will serialize such packet with data1397	 * reads in a loop below. Sender starts transmission only when1398	 * 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 first1423	 * 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 byte1445	 * 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 at1461		 * 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 1471static 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 1476static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)1477{1478	test_stream_credit_update_test(opts, false);1479}1480 1481static 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 1614static const char optstring[] = "";1615static 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 1659static 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_PORT1691		);1692	exit(EXIT_FAILURE);1693}1694 1695int 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