summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFloris Bos <bos@je-eigen-domein.nl>2015-01-17 22:49:48 +0100
committerFloris Bos <bos@je-eigen-domein.nl>2015-01-17 22:49:48 +0100
commit6836ccb208f8c16824b8c1e330acb077c70c98c6 (patch)
tree0be8f48f5160109fc10b19f5f9f90fbfd9e97c0e
parenta48035a1ce6b5fa9738e9f1762294ddfe52b8d57 (diff)
downloadlibtdevnc-6836ccb2.tar.gz
libtdevnc-6836ccb2.zip
Fix handling of multiple VNC commands per websockets frame
- When processing input, check if there is any extra data pending in the internal websocket frame and SSL buffers. - Prevents input events lagging behind because they get stuck in one of the buffers. Data pending in our own buffers cannot be detected with select() so was not processed until more input arrives from the network. - Closes # 55 Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
-rw-r--r--libvncserver/main.c8
-rw-r--r--libvncserver/sockets.c8
-rw-r--r--libvncserver/websockets.c13
-rw-r--r--rfb/rfb.h1
4 files changed, 30 insertions, 0 deletions
diff --git a/libvncserver/main.c b/libvncserver/main.c
index 9839c85..a8458e4 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -550,7 +550,15 @@ clientInput(void *data)
rfbSendFileTransferChunk(cl);
if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
+ {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ do {
+ rfbProcessClientMessage(cl);
+ } while (webSocketsHasDataInBuffer(cl));
+#else
rfbProcessClientMessage(cl);
+#endif
+ }
}
/* Get rid of the output thread. */
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index a9c5a2c..2bb655e 100644
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -391,7 +391,15 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
{
if (FD_ISSET(cl->sock, &fds))
+ {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ do {
+ rfbProcessClientMessage(cl);
+ } while (webSocketsHasDataInBuffer(cl));
+#else
rfbProcessClientMessage(cl);
+#endif
+ }
else
rfbSendFileTransferChunk(cl);
}
diff --git a/libvncserver/websockets.c b/libvncserver/websockets.c
index 34f04d7..3585ed5 100644
--- a/libvncserver/websockets.c
+++ b/libvncserver/websockets.c
@@ -905,3 +905,16 @@ webSocketCheckDisconnect(rfbClientPtr cl)
return FALSE;
}
+/* returns TRUE if there is data waiting to be read in our internal buffer
+ * or if is there any pending data in the buffer of the SSL implementation
+ */
+rfbBool
+webSocketsHasDataInBuffer(rfbClientPtr cl)
+{
+ ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;
+
+ if (wsctx && wsctx->readbuflen)
+ return TRUE;
+
+ return (cl->sslctx && rfbssl_pending(cl) > 0);
+}
diff --git a/rfb/rfb.h b/rfb/rfb.h
index f7919c6..0c34d74 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -765,6 +765,7 @@ extern rfbBool webSocketsCheck(rfbClientPtr cl);
extern rfbBool webSocketCheckDisconnect(rfbClientPtr cl);
extern int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst);
extern int webSocketsDecode(rfbClientPtr cl, char *dst, int len);
+extern rfbBool webSocketsHasDataInBuffer(rfbClientPtr cl);
#endif
/* rfbserver.c */