Merge branch 'Enhance-virtio-vsock-connection-semantics'
Sebastien Boeuf says: ==================== Enhance virtio-vsock connection semantics This series improves the semantics behind the way virtio-vsock server accepts connections coming from the client. Whenever the server receives a connection request from the client, if it is bound to the socket but not yet listening, it will answer with a RST packet. The point is to ensure each request from the client is quickly processed so that the client can decide about the strategy of retrying or not. The series includes along with the improvement patch a new test to ensure the behavior is consistent across all hypervisors drivers. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8c8da5b8ea
|
@ -1153,6 +1153,7 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
|
|||
virtio_transport_free_pkt(pkt);
|
||||
break;
|
||||
default:
|
||||
(void)virtio_transport_reset_no_sock(t, pkt);
|
||||
virtio_transport_free_pkt(pkt);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,78 @@ static void test_stream_connection_reset(const struct test_opts *opts)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_bind_only_client(const struct test_opts *opts)
|
||||
{
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_vm svm;
|
||||
} addr = {
|
||||
.svm = {
|
||||
.svm_family = AF_VSOCK,
|
||||
.svm_port = 1234,
|
||||
.svm_cid = opts->peer_cid,
|
||||
},
|
||||
};
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
/* Wait for the server to be ready */
|
||||
control_expectln("BIND");
|
||||
|
||||
fd = socket(AF_VSOCK, SOCK_STREAM, 0);
|
||||
|
||||
timeout_begin(TIMEOUT);
|
||||
do {
|
||||
ret = connect(fd, &addr.sa, sizeof(addr.svm));
|
||||
timeout_check("connect");
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
timeout_end();
|
||||
|
||||
if (ret != -1) {
|
||||
fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (errno != ECONNRESET) {
|
||||
fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Notify the server that the client has finished */
|
||||
control_writeln("DONE");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_bind_only_server(const struct test_opts *opts)
|
||||
{
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_vm svm;
|
||||
} addr = {
|
||||
.svm = {
|
||||
.svm_family = AF_VSOCK,
|
||||
.svm_port = 1234,
|
||||
.svm_cid = VMADDR_CID_ANY,
|
||||
},
|
||||
};
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_VSOCK, SOCK_STREAM, 0);
|
||||
|
||||
if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
|
||||
perror("bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Notify the client that the server is ready */
|
||||
control_writeln("BIND");
|
||||
|
||||
/* Wait for the client to finish */
|
||||
control_expectln("DONE");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_client_close_client(const struct test_opts *opts)
|
||||
{
|
||||
int fd;
|
||||
|
@ -212,6 +284,11 @@ static struct test_case test_cases[] = {
|
|||
.name = "SOCK_STREAM connection reset",
|
||||
.run_client = test_stream_connection_reset,
|
||||
},
|
||||
{
|
||||
.name = "SOCK_STREAM bind only",
|
||||
.run_client = test_stream_bind_only_client,
|
||||
.run_server = test_stream_bind_only_server,
|
||||
},
|
||||
{
|
||||
.name = "SOCK_STREAM client close",
|
||||
.run_client = test_stream_client_close_client,
|
||||
|
|
Loading…
Reference in New Issue