From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41438) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c1bx3-0001oQ-6A for qemu-devel@nongnu.org; Tue, 01 Nov 2016 12:30:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c1bx1-0006gW-GD for qemu-devel@nongnu.org; Tue, 01 Nov 2016 12:30:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43204) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c1bx1-0006fV-81 for qemu-devel@nongnu.org; Tue, 01 Nov 2016 12:30:15 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 861A013AA1 for ; Tue, 1 Nov 2016 16:30:14 +0000 (UTC) From: Paolo Bonzini Date: Tue, 1 Nov 2016 17:29:30 +0100 Message-Id: <1478017783-7703-18-git-send-email-pbonzini@redhat.com> In-Reply-To: <1478017783-7703-1-git-send-email-pbonzini@redhat.com> References: <1478017783-7703-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 17/30] nbd: Let client skip portions of server reply List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org From: Eric Blake The server has a nice helper function nbd_negotiate_drop_sync() which lets it easily ignore fluff from the client (such as the payload to an unknown option request). We can't quite make it common, since it depends on nbd_negotiate_read() which handles coroutine magic, but we can copy the idea into the client where we have places where we want to ignore data (such as the description tacked on the end of NBD_REP_SERVER). Signed-off-by: Eric Blake Message-Id: <1476469998-28592-11-git-send-email-eblake@redhat.com> Signed-off-by: Paolo Bonzini --- nbd/client.c | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index 651e08c..5d94e34 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -75,6 +75,32 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); */ +/* Discard length bytes from channel. Return -errno on failure, or + * the amount of bytes consumed. */ +static ssize_t drop_sync(QIOChannel *ioc, size_t size) +{ + ssize_t ret, dropped = size; + char small[1024]; + char *buffer; + + buffer = sizeof(small) < size ? small : g_malloc(MIN(65536, size)); + while (size > 0) { + ret = read_sync(ioc, buffer, MIN(65536, size)); + if (ret < 0) { + goto cleanup; + } + assert(ret <= size); + size -= ret; + } + ret = dropped; + + cleanup: + if (buffer != small) { + g_free(buffer); + } + return ret; +} + /* Send an option request. * * The request is for option @opt, with @data containing @len bytes of @@ -285,19 +311,12 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) } (*name)[namelen] = '\0'; len -= namelen; - if (len) { - char *buf = g_malloc(len + 1); - if (read_sync(ioc, buf, len) != len) { - error_setg(errp, "failed to read export description"); - g_free(*name); - g_free(buf); - *name = NULL; - nbd_send_opt_abort(ioc); - return -1; - } - buf[len] = '\0'; - TRACE("Ignoring export description: %s", buf); - g_free(buf); + if (drop_sync(ioc, len) != len) { + error_setg(errp, "failed to read export description"); + g_free(*name); + *name = NULL; + nbd_send_opt_abort(ioc); + return -1; } } else { error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x", @@ -577,7 +596,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, } TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags); - if (read_sync(ioc, &buf, 124) != 124) { + if (drop_sync(ioc, 124) != 124) { error_setg(errp, "Failed to read reserved block"); goto fail; } -- 2.7.4