qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] io: fix decoding when multiple websockets frames ar


From: Daniel P. Berrange
Subject: [Qemu-devel] [PATCH] io: fix decoding when multiple websockets frames arrive at once
Date: Mon, 30 Jan 2017 10:51:16 +0000

The qio_channel_websock_read_wire() method will read upto 4096
bytes off the socket and then decode the websockets header and
payload. The code was only decoding a single websockets frame,
even if the buffered data contained multiple frames. This meant
that decoding of subsequent frames was delayed until further
input arrived on the socket. This backlog of delayed frames
gets worse & worse over time.

Symptom was that when connecting to the VNC server via the
built-in websockets server, mouse/keyboard interaction would
start out fine, but slowly get more & more delayed until it
was unusable.

Signed-off-by: Daniel P. Berrange <address@hidden>
---
 io/channel-websock.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/io/channel-websock.c b/io/channel-websock.c
index e47279a..a06a4a8 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -570,21 +570,24 @@ static ssize_t 
qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
         ioc->encinput.offset += ret;
     }
 
-    if (ioc->payload_remain == 0) {
-        ret = qio_channel_websock_decode_header(ioc, errp);
+    while (ioc->encinput.offset != 0) {
+        if (ioc->payload_remain == 0) {
+            ret = qio_channel_websock_decode_header(ioc, errp);
+            if (ret < 0) {
+                return ret;
+            }
+            if (ret == 0) {
+                ioc->io_eof = TRUE;
+                break;
+            }
+        }
+
+        ret = qio_channel_websock_decode_payload(ioc, errp);
         if (ret < 0) {
             return ret;
         }
-        if (ret == 0) {
-            return 0;
-        }
     }
-
-    ret = qio_channel_websock_decode_payload(ioc, errp);
-    if (ret < 0) {
-        return ret;
-    }
-    return ret;
+    return 1;
 }
 
 
@@ -642,9 +645,6 @@ static gboolean qio_channel_websock_flush(QIOChannel *ioc,
         if (ret < 0) {
             goto cleanup;
         }
-        if (ret == 0) {
-            wioc->io_eof = TRUE;
-        }
     }
 
  cleanup:
-- 
2.9.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]