|
|
9bac43 |
From 977ae916454f470780f7562b61c98718e2d0d49c Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
9bac43 |
Date: Wed, 20 Dec 2017 17:56:47 +0100
|
|
|
9bac43 |
Subject: [PATCH 07/42] io: Small updates in preparation for websocket changes
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
9bac43 |
Message-id: <20171220175702.29663-6-berrange@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 78459
|
|
|
9bac43 |
O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 05/20] io: Small updates in preparation for websocket changes
|
|
|
9bac43 |
Bugzilla: 1518649
|
|
|
9bac43 |
RH-Acked-by: John Snow <jsnow@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
Gets rid of unnecessary bit shifting and performs proper EOF checking to
|
|
|
9bac43 |
avoid a large number of repeated calls to recvmsg() when a client
|
|
|
9bac43 |
abruptly terminates a connection (bug fix).
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
|
|
|
9bac43 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
9bac43 |
(cherry picked from commit eefa3d8ef649f9055611361e2201cca49f8c3433)
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
io/channel-websock.c | 64 ++++++++++++++++------------------------------------
|
|
|
9bac43 |
1 file changed, 19 insertions(+), 45 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/io/channel-websock.c b/io/channel-websock.c
|
|
|
9bac43 |
index 2258557..4e5afb2 100644
|
|
|
9bac43 |
--- a/io/channel-websock.c
|
|
|
9bac43 |
+++ b/io/channel-websock.c
|
|
|
9bac43 |
@@ -110,13 +110,11 @@
|
|
|
9bac43 |
/* Magic 7-bit length to indicate use of 64-bit payload length */
|
|
|
9bac43 |
#define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT 127
|
|
|
9bac43 |
|
|
|
9bac43 |
-/* Bitmasks & shifts for accessing header fields */
|
|
|
9bac43 |
+/* Bitmasks for accessing header fields */
|
|
|
9bac43 |
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN 0x80
|
|
|
9bac43 |
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f
|
|
|
9bac43 |
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80
|
|
|
9bac43 |
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f
|
|
|
9bac43 |
-#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN 7
|
|
|
9bac43 |
-#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK 7
|
|
|
9bac43 |
|
|
|
9bac43 |
typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader;
|
|
|
9bac43 |
|
|
|
9bac43 |
@@ -586,7 +584,7 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
|
|
|
9bac43 |
return;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
- header.ws.b0 = (1 << QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN) |
|
|
|
9bac43 |
+ header.ws.b0 = QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN |
|
|
|
9bac43 |
(QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &
|
|
|
9bac43 |
QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
|
|
|
9bac43 |
if (ioc->rawoutput.offset <
|
|
|
9bac43 |
@@ -613,8 +611,8 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
|
|
|
9bac43 |
-static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
- Error **errp)
|
|
|
9bac43 |
+static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
+ Error **errp)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
unsigned char opcode, fin, has_mask;
|
|
|
9bac43 |
size_t header_size;
|
|
|
9bac43 |
@@ -633,11 +631,9 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
return QIO_CHANNEL_ERR_BLOCK;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
- fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>
|
|
|
9bac43 |
- QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;
|
|
|
9bac43 |
+ fin = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN;
|
|
|
9bac43 |
opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;
|
|
|
9bac43 |
- has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>
|
|
|
9bac43 |
- QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;
|
|
|
9bac43 |
+ has_mask = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK;
|
|
|
9bac43 |
payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;
|
|
|
9bac43 |
|
|
|
9bac43 |
if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
|
|
|
9bac43 |
@@ -655,7 +651,7 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
return -1;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
if (!has_mask) {
|
|
|
9bac43 |
- error_setg(errp, "websocket frames must be masked");
|
|
|
9bac43 |
+ error_setg(errp, "client websocket frames must be masked");
|
|
|
9bac43 |
return -1;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
|
|
|
9bac43 |
@@ -687,8 +683,8 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
|
|
|
9bac43 |
-static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
- Error **errp)
|
|
|
9bac43 |
+static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
+ Error **errp)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
size_t i;
|
|
|
9bac43 |
size_t payload_len;
|
|
|
9bac43 |
@@ -729,7 +725,7 @@ static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
buffer_reserve(&ioc->rawinput, payload_len);
|
|
|
9bac43 |
buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
|
|
|
9bac43 |
buffer_advance(&ioc->encinput, payload_len);
|
|
|
9bac43 |
- return payload_len;
|
|
|
9bac43 |
+ return 0;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
|
|
|
9bac43 |
@@ -809,8 +805,8 @@ static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
if (ret < 0) {
|
|
|
9bac43 |
return ret;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
- if (ret == 0 &&
|
|
|
9bac43 |
- ioc->encinput.offset == 0) {
|
|
|
9bac43 |
+ if (ret == 0 && ioc->encinput.offset == 0) {
|
|
|
9bac43 |
+ ioc->io_eof = TRUE;
|
|
|
9bac43 |
return 0;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
ioc->encinput.offset += ret;
|
|
|
9bac43 |
@@ -822,10 +818,6 @@ static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
|
|
|
9bac43 |
if (ret < 0) {
|
|
|
9bac43 |
return ret;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
- if (ret == 0) {
|
|
|
9bac43 |
- ioc->io_eof = TRUE;
|
|
|
9bac43 |
- break;
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
ret = qio_channel_websock_decode_payload(ioc, errp);
|
|
|
9bac43 |
@@ -1090,14 +1082,12 @@ struct QIOChannelWebsockSource {
|
|
|
9bac43 |
};
|
|
|
9bac43 |
|
|
|
9bac43 |
static gboolean
|
|
|
9bac43 |
-qio_channel_websock_source_prepare(GSource *source,
|
|
|
9bac43 |
- gint *timeout)
|
|
|
9bac43 |
+qio_channel_websock_source_check(GSource *source)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
|
|
|
9bac43 |
GIOCondition cond = 0;
|
|
|
9bac43 |
- *timeout = -1;
|
|
|
9bac43 |
|
|
|
9bac43 |
- if (wsource->wioc->rawinput.offset) {
|
|
|
9bac43 |
+ if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) {
|
|
|
9bac43 |
cond |= G_IO_IN;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
|
|
9bac43 |
@@ -1108,19 +1098,11 @@ qio_channel_websock_source_prepare(GSource *source,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
static gboolean
|
|
|
9bac43 |
-qio_channel_websock_source_check(GSource *source)
|
|
|
9bac43 |
+qio_channel_websock_source_prepare(GSource *source,
|
|
|
9bac43 |
+ gint *timeout)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
- QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
|
|
|
9bac43 |
- GIOCondition cond = 0;
|
|
|
9bac43 |
-
|
|
|
9bac43 |
- if (wsource->wioc->rawinput.offset) {
|
|
|
9bac43 |
- cond |= G_IO_IN;
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
- if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
|
|
9bac43 |
- cond |= G_IO_OUT;
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
-
|
|
|
9bac43 |
- return cond & wsource->condition;
|
|
|
9bac43 |
+ *timeout = -1;
|
|
|
9bac43 |
+ return qio_channel_websock_source_check(source);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
static gboolean
|
|
|
9bac43 |
@@ -1130,17 +1112,9 @@ qio_channel_websock_source_dispatch(GSource *source,
|
|
|
9bac43 |
{
|
|
|
9bac43 |
QIOChannelFunc func = (QIOChannelFunc)callback;
|
|
|
9bac43 |
QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
|
|
|
9bac43 |
- GIOCondition cond = 0;
|
|
|
9bac43 |
-
|
|
|
9bac43 |
- if (wsource->wioc->rawinput.offset) {
|
|
|
9bac43 |
- cond |= G_IO_IN;
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
- if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
|
|
9bac43 |
- cond |= G_IO_OUT;
|
|
|
9bac43 |
- }
|
|
|
9bac43 |
|
|
|
9bac43 |
return (*func)(QIO_CHANNEL(wsource->wioc),
|
|
|
9bac43 |
- (cond & wsource->condition),
|
|
|
9bac43 |
+ qio_channel_websock_source_check(source),
|
|
|
9bac43 |
user_data);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|