From nobody Tue Feb 10 23:01:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507120199126458.70311519375434; Wed, 4 Oct 2017 05:29:59 -0700 (PDT) Received: from localhost ([::1]:34959 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzioD-00067J-9R for importer@patchew.org; Wed, 04 Oct 2017 08:29:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55172) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzijx-0002li-Lu for qemu-devel@nongnu.org; Wed, 04 Oct 2017 08:25:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dzijw-0005R0-1X for qemu-devel@nongnu.org; Wed, 04 Oct 2017 08:25:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:18403) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dzijv-0005PM-OS for qemu-devel@nongnu.org; Wed, 04 Oct 2017 08:25:27 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DAA3890E65; Wed, 4 Oct 2017 12:25:26 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id AFFB25C1A1; Wed, 4 Oct 2017 12:25:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DAA3890E65 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Wed, 4 Oct 2017 13:25:09 +0100 Message-Id: <20171004122515.20627-6-berrange@redhat.com> In-Reply-To: <20171004122515.20627-1-berrange@redhat.com> References: <20171004122515.20627-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 04 Oct 2017 12:25:27 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v1 05/11] io: Small updates in preparation for websocket changes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Brandon Carpenter Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Brandon Carpenter Gets rid of unnecessary bit shifting and performs proper EOF checking to avoid a large number of repeated calls to recvmsg() when a client abruptly terminates a connection (bug fix). Signed-off-by: Brandon Carpenter Signed-off-by: Daniel P. Berrange --- io/channel-websock.c | 64 ++++++++++++++++--------------------------------= ---- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/io/channel-websock.c b/io/channel-websock.c index 2258557a21..4e5afb2e95 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -110,13 +110,11 @@ /* Magic 7-bit length to indicate use of 64-bit payload length */ #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT 127 =20 -/* Bitmasks & shifts for accessing header fields */ +/* Bitmasks for accessing header fields */ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN 0x80 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f -#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN 7 -#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK 7 =20 typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader; =20 @@ -586,7 +584,7 @@ static void qio_channel_websock_encode(QIOChannelWebsoc= k *ioc) return; } =20 - header.ws.b0 =3D (1 << QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN) | + header.ws.b0 =3D QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN | (QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE); if (ioc->rawoutput.offset < @@ -613,8 +611,8 @@ static void qio_channel_websock_encode(QIOChannelWebsoc= k *ioc) } =20 =20 -static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc, - Error **errp) +static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc, + Error **errp) { unsigned char opcode, fin, has_mask; size_t header_size; @@ -633,11 +631,9 @@ static ssize_t qio_channel_websock_decode_header(QIOCh= annelWebsock *ioc, return QIO_CHANNEL_ERR_BLOCK; } =20 - fin =3D (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >> - QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN; + fin =3D header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN; opcode =3D header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE; - has_mask =3D (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) = >> - QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK; + has_mask =3D header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK; payload_len =3D header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_= LEN; =20 if (opcode =3D=3D QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) { @@ -655,7 +651,7 @@ static ssize_t qio_channel_websock_decode_header(QIOCha= nnelWebsock *ioc, return -1; } if (!has_mask) { - error_setg(errp, "websocket frames must be masked"); + error_setg(errp, "client websocket frames must be masked"); return -1; } if (opcode !=3D QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) { @@ -687,8 +683,8 @@ static ssize_t qio_channel_websock_decode_header(QIOCha= nnelWebsock *ioc, } =20 =20 -static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc, - Error **errp) +static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc, + Error **errp) { size_t i; size_t payload_len; @@ -729,7 +725,7 @@ static ssize_t qio_channel_websock_decode_payload(QIOCh= annelWebsock *ioc, buffer_reserve(&ioc->rawinput, payload_len); buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len); buffer_advance(&ioc->encinput, payload_len); - return payload_len; + return 0; } =20 =20 @@ -809,8 +805,8 @@ static ssize_t qio_channel_websock_read_wire(QIOChannel= Websock *ioc, if (ret < 0) { return ret; } - if (ret =3D=3D 0 && - ioc->encinput.offset =3D=3D 0) { + if (ret =3D=3D 0 && ioc->encinput.offset =3D=3D 0) { + ioc->io_eof =3D TRUE; return 0; } ioc->encinput.offset +=3D ret; @@ -822,10 +818,6 @@ static ssize_t qio_channel_websock_read_wire(QIOChanne= lWebsock *ioc, if (ret < 0) { return ret; } - if (ret =3D=3D 0) { - ioc->io_eof =3D TRUE; - break; - } } =20 ret =3D qio_channel_websock_decode_payload(ioc, errp); @@ -1090,14 +1082,12 @@ struct QIOChannelWebsockSource { }; =20 static gboolean -qio_channel_websock_source_prepare(GSource *source, - gint *timeout) +qio_channel_websock_source_check(GSource *source) { QIOChannelWebsockSource *wsource =3D (QIOChannelWebsockSource *)source; GIOCondition cond =3D 0; - *timeout =3D -1; =20 - if (wsource->wioc->rawinput.offset) { + if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) { cond |=3D G_IO_IN; } if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { @@ -1108,19 +1098,11 @@ qio_channel_websock_source_prepare(GSource *source, } =20 static gboolean -qio_channel_websock_source_check(GSource *source) +qio_channel_websock_source_prepare(GSource *source, + gint *timeout) { - QIOChannelWebsockSource *wsource =3D (QIOChannelWebsockSource *)source; - GIOCondition cond =3D 0; - - if (wsource->wioc->rawinput.offset) { - cond |=3D G_IO_IN; - } - if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { - cond |=3D G_IO_OUT; - } - - return cond & wsource->condition; + *timeout =3D -1; + return qio_channel_websock_source_check(source); } =20 static gboolean @@ -1130,17 +1112,9 @@ qio_channel_websock_source_dispatch(GSource *source, { QIOChannelFunc func =3D (QIOChannelFunc)callback; QIOChannelWebsockSource *wsource =3D (QIOChannelWebsockSource *)source; - GIOCondition cond =3D 0; - - if (wsource->wioc->rawinput.offset) { - cond |=3D G_IO_IN; - } - if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { - cond |=3D G_IO_OUT; - } =20 return (*func)(QIO_CHANNEL(wsource->wioc), - (cond & wsource->condition), + qio_channel_websock_source_check(source), user_data); } =20 --=20 2.13.5