Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added handshakeType to tell the server about the expected timeout is use. #455

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions libvncserver/websockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ Connection: Upgrade\r\n\
Sec-WebSocket-Accept: %s\r\n\
\r\n"

#define WEBSOCKETS_CLIENT_CONNECT_WAIT_MS 100
#define WEBSOCKETS_CLIENT_SEND_WAIT_MS 100
#define WEBSOCKETS_CLIENT_CONNECT_WAIT_MS 500
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In most use cases 500 ms is more than acceptable, but, generally speaking, we should maybe put all of these constants to a config.h.in file so that a developer could set them to their liking at compile time.

We should probably address this in a future PR, my comment is more to remember.

#define WEBSOCKETS_MAX_HANDSHAKE_LEN 4096

#if defined(__linux__) && defined(NEED_TIMEVAL)
Expand Down Expand Up @@ -119,8 +118,17 @@ webSocketsCheck (rfbClientPtr cl)
char bbuf[4], *scheme;
int ret;

ret = rfbPeekExactTimeout(cl, bbuf, 4,
WEBSOCKETS_CLIENT_CONNECT_WAIT_MS);
int timeout = WEBSOCKETS_CLIENT_CONNECT_WAIT_MS;
switch (cl->screen->handshake_type) {
case RFB_HANDSHAKE_AUTO:
timeout = cl->screen->maxClientWait ? cl->screen->maxClientWait : rfbMaxClientWait;
break;
case RFB_HANDSHAKE_WEBSOCKET:
timeout = WEBSOCKETS_CLIENT_CONNECT_WAIT_MS;
break;
}

ret = rfbPeekExactTimeout(cl, bbuf, 4, timeout);
if ((ret < 0) && (errno == ETIMEDOUT)) {
rfbLog("Normal socket connection\n");
return TRUE;
Expand All @@ -138,7 +146,7 @@ webSocketsCheck (rfbClientPtr cl)
rfbErr("webSocketsHandshake: rfbssl_init failed\n");
return FALSE;
}
ret = rfbPeekExactTimeout(cl, bbuf, 4, WEBSOCKETS_CLIENT_CONNECT_WAIT_MS);
ret = rfbPeekExactTimeout(cl, bbuf, 4, timeout);
scheme = "wss";
} else {
scheme = "ws";
Expand Down Expand Up @@ -183,8 +191,7 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme)
}

while (len < WEBSOCKETS_MAX_HANDSHAKE_LEN-1) {
if ((n = rfbReadExactTimeout(cl, buf+len, 1,
WEBSOCKETS_CLIENT_SEND_WAIT_MS)) <= 0) {
if ((n = rfbReadExact(cl, buf+len, 1)) <= 0) {
if ((n < 0) && (errno == ETIMEDOUT)) {
break;
}
Expand Down
15 changes: 15 additions & 0 deletions rfb/rfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ enum rfbSocketState {
RFB_SOCKET_SHUTDOWN
};

enum rfbHandshakeType {
RFB_HANDSHAKE_AUTO,
RFB_HANDSHAKE_WEBSOCKET,
};

typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl);
typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
Expand Down Expand Up @@ -372,6 +377,16 @@ typedef struct _rfbScreenInfo
#ifdef LIBVNCSERVER_HAVE_LIBZ
rfbSetXCutTextUTF8ProcPtr setXCutTextUTF8;
#endif
/** This setting specifies the handshake type to expect.
* WebSocket clients are detected by the presence of a special handshake.
* The handshake can only be detected by waiting some time for it. Normal
* RFB clients do not transmit an initial handshake.
*
* RFB_HANDSHAKE_AUTO - wait 100ms for WS handshake. Then fall back to normal RFB.
* RFB_HANDSHAKE_WEBSOCKET - wait 500ms for WS handshake.
*
sgh marked this conversation as resolved.
Show resolved Hide resolved
*/
enum rfbHandshakeType handshake_type;
} rfbScreenInfo, *rfbScreenInfoPtr;


Expand Down