From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Brandon Carpenter <brandon.carpenter@cypherpath.com>,
"Daniel P . Berrange" <berrange@redhat.com>
Subject: [Qemu-devel] [PULL v1 05/11] io: Small updates in preparation for websocket changes
Date: Wed, 4 Oct 2017 13:25:09 +0100 [thread overview]
Message-ID: <20171004122515.20627-6-berrange@redhat.com> (raw)
In-Reply-To: <20171004122515.20627-1-berrange@redhat.com>
From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
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 <brandon.carpenter@cypherpath.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
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
-/* 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
typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader;
@@ -586,7 +584,7 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
return;
}
- header.ws.b0 = (1 << QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN) |
+ header.ws.b0 = 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(QIOChannelWebsock *ioc)
}
-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(QIOChannelWebsock *ioc,
return QIO_CHANNEL_ERR_BLOCK;
}
- fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>
- QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;
+ fin = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN;
opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;
- has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>
- QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;
+ has_mask = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK;
payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;
if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
@@ -655,7 +651,7 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *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 != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
@@ -687,8 +683,8 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
}
-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(QIOChannelWebsock *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;
}
@@ -809,8 +805,8 @@ static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
if (ret < 0) {
return ret;
}
- if (ret == 0 &&
- ioc->encinput.offset == 0) {
+ if (ret == 0 && ioc->encinput.offset == 0) {
+ ioc->io_eof = TRUE;
return 0;
}
ioc->encinput.offset += ret;
@@ -822,10 +818,6 @@ static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
if (ret < 0) {
return ret;
}
- if (ret == 0) {
- ioc->io_eof = TRUE;
- break;
- }
}
ret = qio_channel_websock_decode_payload(ioc, errp);
@@ -1090,14 +1082,12 @@ struct QIOChannelWebsockSource {
};
static gboolean
-qio_channel_websock_source_prepare(GSource *source,
- gint *timeout)
+qio_channel_websock_source_check(GSource *source)
{
QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
GIOCondition cond = 0;
- *timeout = -1;
- if (wsource->wioc->rawinput.offset) {
+ if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) {
cond |= G_IO_IN;
}
if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
@@ -1108,19 +1098,11 @@ qio_channel_websock_source_prepare(GSource *source,
}
static gboolean
-qio_channel_websock_source_check(GSource *source)
+qio_channel_websock_source_prepare(GSource *source,
+ gint *timeout)
{
- QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
- GIOCondition cond = 0;
-
- if (wsource->wioc->rawinput.offset) {
- cond |= G_IO_IN;
- }
- if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
- cond |= G_IO_OUT;
- }
-
- return cond & wsource->condition;
+ *timeout = -1;
+ return qio_channel_websock_source_check(source);
}
static gboolean
@@ -1130,17 +1112,9 @@ qio_channel_websock_source_dispatch(GSource *source,
{
QIOChannelFunc func = (QIOChannelFunc)callback;
QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
- GIOCondition cond = 0;
-
- if (wsource->wioc->rawinput.offset) {
- cond |= G_IO_IN;
- }
- if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
- cond |= G_IO_OUT;
- }
return (*func)(QIO_CHANNEL(wsource->wioc),
- (cond & wsource->condition),
+ qio_channel_websock_source_check(source),
user_data);
}
--
2.13.5
next prev parent reply other threads:[~2017-10-04 12:25 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-04 12:25 [Qemu-devel] [PULL v1 00/11] Merge qio 2017/10/04 Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 01/11] io: send proper HTTP response for websocket errors Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 02/11] io: include full error message in websocket handshake trace Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 03/11] io: use case insensitive check for Connection & Upgrade websock headers Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 04/11] ui: Always remove an old VNC channel watch before adding a new one Daniel P. Berrange
2017-10-04 12:25 ` Daniel P. Berrange [this message]
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 06/11] io: Add support for fragmented websocket binary frames Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 07/11] io: Allow empty websocket payload Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 08/11] io: Ignore websocket PING and PONG frames Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 09/11] io: Reply to ping frames Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 10/11] io: Attempt to send websocket close messages to client Daniel P. Berrange
2017-10-04 12:25 ` [Qemu-devel] [PULL v1 11/11] io: add trace events for websockets frame handling Daniel P. Berrange
2017-10-05 14:30 ` [Qemu-devel] [PULL v1 00/11] Merge qio 2017/10/04 Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171004122515.20627-6-berrange@redhat.com \
--to=berrange@redhat.com \
--cc=brandon.carpenter@cypherpath.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.