diff options
| author | Filippo Storniolo <[email protected]> | 2023-11-03 18:55:51 +0100 | 
|---|---|---|
| committer | David S. Miller <[email protected]> | 2023-11-07 22:27:07 +0000 | 
| commit | d80f63f690257b04b4fe3731b90dbf34a9ebb93f (patch) | |
| tree | 17b39006bbf109634fd944cca078e3d84b3aa163 | |
| parent | 84d5fb9741316ca53f0f7c23b82f30e0bb33c38e (diff) | |
test/vsock: add dobule bind connect test
This add bind connect test which creates a listening server socket
and tries to connect a client with a bound local port to it twice.
Co-developed-by: Luigi Leonardi <[email protected]>
Signed-off-by: Luigi Leonardi <[email protected]>
Signed-off-by: Filippo Storniolo <[email protected]>
Reviewed-by: Stefano Garzarella <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
| -rw-r--r-- | tools/testing/vsock/util.c | 47 | ||||
| -rw-r--r-- | tools/testing/vsock/util.h | 3 | ||||
| -rw-r--r-- | tools/testing/vsock/vsock_test.c | 50 | 
3 files changed, 100 insertions, 0 deletions
| diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c index 2fc96f29bdf2..ae2b33c21c45 100644 --- a/tools/testing/vsock/util.c +++ b/tools/testing/vsock/util.c @@ -85,6 +85,48 @@ void vsock_wait_remote_close(int fd)  	close(epollfd);  } +/* Bind to <bind_port>, connect to <cid, port> and return the file descriptor. */ +int vsock_bind_connect(unsigned int cid, unsigned int port, unsigned int bind_port, int type) +{ +	struct sockaddr_vm sa_client = { +		.svm_family = AF_VSOCK, +		.svm_cid = VMADDR_CID_ANY, +		.svm_port = bind_port, +	}; +	struct sockaddr_vm sa_server = { +		.svm_family = AF_VSOCK, +		.svm_cid = cid, +		.svm_port = port, +	}; + +	int client_fd, ret; + +	client_fd = socket(AF_VSOCK, type, 0); +	if (client_fd < 0) { +		perror("socket"); +		exit(EXIT_FAILURE); +	} + +	if (bind(client_fd, (struct sockaddr *)&sa_client, sizeof(sa_client))) { +		perror("bind"); +		exit(EXIT_FAILURE); +	} + +	timeout_begin(TIMEOUT); +	do { +		ret = connect(client_fd, (struct sockaddr *)&sa_server, sizeof(sa_server)); +		timeout_check("connect"); +	} while (ret < 0 && errno == EINTR); +	timeout_end(); + +	if (ret < 0) { +		perror("connect"); +		exit(EXIT_FAILURE); +	} + +	return client_fd; +} +  /* Connect to <cid, port> and return the file descriptor. */  static int vsock_connect(unsigned int cid, unsigned int port, int type)  { @@ -223,6 +265,11 @@ int vsock_stream_accept(unsigned int cid, unsigned int port,  	return vsock_accept(cid, port, clientaddrp, SOCK_STREAM);  } +int vsock_stream_listen(unsigned int cid, unsigned int port) +{ +	return vsock_listen(cid, port, SOCK_STREAM); +} +  int vsock_seqpacket_accept(unsigned int cid, unsigned int port,  			   struct sockaddr_vm *clientaddrp)  { diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h index a77175d25864..03c88d0cb861 100644 --- a/tools/testing/vsock/util.h +++ b/tools/testing/vsock/util.h @@ -36,9 +36,12 @@ struct test_case {  void init_signals(void);  unsigned int parse_cid(const char *str);  int vsock_stream_connect(unsigned int cid, unsigned int port); +int vsock_bind_connect(unsigned int cid, unsigned int port, +		       unsigned int bind_port, int type);  int vsock_seqpacket_connect(unsigned int cid, unsigned int port);  int vsock_stream_accept(unsigned int cid, unsigned int port,  			struct sockaddr_vm *clientaddrp); +int vsock_stream_listen(unsigned int cid, unsigned int port);  int vsock_seqpacket_accept(unsigned int cid, unsigned int port,  			   struct sockaddr_vm *clientaddrp);  void vsock_wait_remote_close(int fd); diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index c1f7bc9abd22..5b0e93f9996c 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -1180,6 +1180,51 @@ static void test_stream_shutrd_server(const struct test_opts *opts)  	close(fd);  } +static void test_double_bind_connect_server(const struct test_opts *opts) +{ +	int listen_fd, client_fd, i; +	struct sockaddr_vm sa_client; +	socklen_t socklen_client = sizeof(sa_client); + +	listen_fd = vsock_stream_listen(VMADDR_CID_ANY, 1234); + +	for (i = 0; i < 2; i++) { +		control_writeln("LISTENING"); + +		timeout_begin(TIMEOUT); +		do { +			client_fd = accept(listen_fd, (struct sockaddr *)&sa_client, +					   &socklen_client); +			timeout_check("accept"); +		} while (client_fd < 0 && errno == EINTR); +		timeout_end(); + +		if (client_fd < 0) { +			perror("accept"); +			exit(EXIT_FAILURE); +		} + +		/* Waiting for remote peer to close connection */ +		vsock_wait_remote_close(client_fd); +	} + +	close(listen_fd); +} + +static void test_double_bind_connect_client(const struct test_opts *opts) +{ +	int i, client_fd; + +	for (i = 0; i < 2; i++) { +		/* Wait until server is ready to accept a new connection */ +		control_expectln("LISTENING"); + +		client_fd = vsock_bind_connect(opts->peer_cid, 1234, 4321, SOCK_STREAM); + +		close(client_fd); +	} +} +  static struct test_case test_cases[] = {  	{  		.name = "SOCK_STREAM connection reset", @@ -1285,6 +1330,11 @@ static struct test_case test_cases[] = {  		.run_client = test_stream_msgzcopy_empty_errq_client,  		.run_server = test_stream_msgzcopy_empty_errq_server,  	}, +	{ +		.name = "SOCK_STREAM double bind connect", +		.run_client = test_double_bind_connect_client, +		.run_server = test_double_bind_connect_server, +	},  	{},  }; |