Commit 6836ccb2 authored by Floris Bos's avatar Floris Bos

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: 's avatarFloris Bos <bos@je-eigen-domein.nl>
parent a48035a1
...@@ -550,7 +550,15 @@ clientInput(void *data) ...@@ -550,7 +550,15 @@ clientInput(void *data)
rfbSendFileTransferChunk(cl); rfbSendFileTransferChunk(cl);
if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds)) if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
{
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
do {
rfbProcessClientMessage(cl);
} while (webSocketsHasDataInBuffer(cl));
#else
rfbProcessClientMessage(cl); rfbProcessClientMessage(cl);
#endif
}
} }
/* Get rid of the output thread. */ /* Get rid of the output thread. */
......
...@@ -391,7 +391,15 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) ...@@ -391,7 +391,15 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
if (FD_ISSET(cl->sock, &(rfbScreen->allFds))) if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
{ {
if (FD_ISSET(cl->sock, &fds)) if (FD_ISSET(cl->sock, &fds))
{
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
do {
rfbProcessClientMessage(cl);
} while (webSocketsHasDataInBuffer(cl));
#else
rfbProcessClientMessage(cl); rfbProcessClientMessage(cl);
#endif
}
else else
rfbSendFileTransferChunk(cl); rfbSendFileTransferChunk(cl);
} }
......
...@@ -905,3 +905,16 @@ webSocketCheckDisconnect(rfbClientPtr cl) ...@@ -905,3 +905,16 @@ webSocketCheckDisconnect(rfbClientPtr cl)
return FALSE; 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);
}
...@@ -765,6 +765,7 @@ extern rfbBool webSocketsCheck(rfbClientPtr cl); ...@@ -765,6 +765,7 @@ extern rfbBool webSocketsCheck(rfbClientPtr cl);
extern rfbBool webSocketCheckDisconnect(rfbClientPtr cl); extern rfbBool webSocketCheckDisconnect(rfbClientPtr cl);
extern int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst); extern int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst);
extern int webSocketsDecode(rfbClientPtr cl, char *dst, int len); extern int webSocketsDecode(rfbClientPtr cl, char *dst, int len);
extern rfbBool webSocketsHasDataInBuffer(rfbClientPtr cl);
#endif #endif
/* rfbserver.c */ /* rfbserver.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment