[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [PATCH 4/4] Implement negotiation of structured replies



On Sat, Mar 11, 2023 at 03:07:05PM +0200, w@uter.be wrote:
> From: Wouter Verhelst <w@uter.be>
> 
> This should make it possible for us to use structured replies!
> 
> Signed-off-by: Wouter Verhelst <w@uter.be>
> ---
>  cliserv.h    | 13 +++++++------
>  nbd-server.c | 28 ++++++++++++++++++++++++++++
>  nbd.h        |  1 +
>  3 files changed, 36 insertions(+), 6 deletions(-)
> 

> +/**
> +  * Handle an NBD_OPT_STRUCTURED_REPLY message
> +  */
> +static void handle_structured_reply(CLIENT *client, uint32_t opt, GArray *servers, uint32_t cflags) {
> +	uint32_t len;
> +	int i;
> +
> +	socket_read(client, &len, sizeof(len));
> +	len = ntohl(len);
> +	if(len) {
> +		send_reply(client, opt, NBD_REP_ERR_INVALID, -1, "NBD_OPT_STRUCTURED_REPLY with nonzero data length is not a valid request");
> +		char buf[1024];
> +		consume(client, len, buf, sizeof buf);
> +	}
> +	if(client->clientflags & F_STRUCTURED) {
> +		send_reply(client, opt, NBD_REP_ERR_INVALID, -1, "NBD_OPT_STRUCTURED_REPLY has already been called");
> +	}

Missing an early 'return;', results in the server sending an
unexpected ACK after the error which gets the client out of sync.
Easy proof-of-concept, with libnbd 1.15.5 or newer:

$ ./nbd-server -d -r 10809 $PWD/README.md
$ nbdsh --opt-mode
nbd> h.connect_uri('nbd://localhost')
nbd> h.opt_structured_reply()    # sees the error; ack stays queued
False
nbd> h.opt_structured_reply()    # sees the stale ack; new error and ack queued
True
nbd> h.opt_structured_reply()    # sees the stale error; another error and ack queued
True
nbd> h.opt_go()                  # sees the stale ack; then queue is unexpected and client dies
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/eblake/libnbd/python/nbd.py", line 1072, in opt_go
    return libnbdmod.opt_go(self._o)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
nbd.Error: nbd_opt_go: server replied with error to opt_go request: Transport endpoint is not connected (ENOTCONN)

With the return added,

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


Reply to: