Skip to content

Commit 902b539

Browse files
committed
Added handshakeType to allow increase wait for ws/wss handshake.
For long latency clients then may not be able to deliver the websocket handshake before we fall back to regular the RFB protocol. So to not introduce a multisecond delay for all conenction a handshakeType setting is introduced to tell which type of handshake we expect. The problem is that a RFB client will be quiet "forever" until the server sends it's signature. On the other hand a websocket client will send it's HTTP websocket handshake immediately. Before the server for sure know the the type of client the connect procedure cannot continue. There is no other option than to wait for some amount of time when the client type is auto detected.
1 parent 242fda8 commit 902b539

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

libvncserver/websockets.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ Connection: Upgrade\r\n\
8080
Sec-WebSocket-Accept: %s\r\n\
8181
\r\n"
8282

83-
#define WEBSOCKETS_CLIENT_CONNECT_WAIT_MS 100
84-
#define WEBSOCKETS_CLIENT_SEND_WAIT_MS 100
83+
#define WEBSOCKETS_CLIENT_CONNECT_WAIT_MS 500
8584
#define WEBSOCKETS_MAX_HANDSHAKE_LEN 4096
8685

8786
#if defined(__linux__) && defined(NEED_TIMEVAL)
@@ -125,8 +124,17 @@ webSocketsCheck (rfbClientPtr cl)
125124
char bbuf[4], *scheme;
126125
int ret;
127126

128-
ret = rfbPeekExactTimeout(cl, bbuf, 4,
129-
WEBSOCKETS_CLIENT_CONNECT_WAIT_MS);
127+
int timeout = WEBSOCKETS_CLIENT_CONNECT_WAIT_MS;
128+
switch (cl->screen->handshake_type) {
129+
case RFB_HANDSHAKE_AUTO:
130+
timeout = cl->screen->maxClientWait ? cl->screen->maxClientWait : rfbMaxClientWait;
131+
break;
132+
case RFB_HANDSHAKE_WEBSOCKET:
133+
timeout = WEBSOCKETS_CLIENT_CONNECT_WAIT_MS;
134+
break;
135+
}
136+
137+
ret = rfbPeekExactTimeout(cl, bbuf, 4, timeout);
130138
if ((ret < 0) && (errno == ETIMEDOUT)) {
131139
rfbLog("Normal socket connection\n");
132140
return TRUE;
@@ -144,7 +152,7 @@ webSocketsCheck (rfbClientPtr cl)
144152
rfbErr("webSocketsHandshake: rfbssl_init failed\n");
145153
return FALSE;
146154
}
147-
ret = rfbPeekExactTimeout(cl, bbuf, 4, WEBSOCKETS_CLIENT_CONNECT_WAIT_MS);
155+
ret = rfbPeekExactTimeout(cl, bbuf, 4, timeout);
148156
scheme = "wss";
149157
} else {
150158
scheme = "ws";
@@ -189,8 +197,7 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme)
189197
}
190198

191199
while (len < WEBSOCKETS_MAX_HANDSHAKE_LEN-1) {
192-
if ((n = rfbReadExactTimeout(cl, buf+len, 1,
193-
WEBSOCKETS_CLIENT_SEND_WAIT_MS)) <= 0) {
200+
if ((n = rfbReadExact(cl, buf+len, 1)) <= 0) {
194201
if ((n < 0) && (errno == ETIMEDOUT)) {
195202
break;
196203
}

rfb/rfb.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ enum rfbSocketState {
100100
RFB_SOCKET_SHUTDOWN
101101
};
102102

103+
enum rfbHandshakeType {
104+
RFB_HANDSHAKE_AUTO,
105+
RFB_HANDSHAKE_WEBSOCKET,
106+
};
107+
103108
typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl);
104109
typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl);
105110
typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl);
@@ -366,6 +371,9 @@ typedef struct _rfbScreenInfo
366371
#elif defined(LIBVNCSERVER_HAVE_WIN32THREADS)
367372
uintptr_t listener_thread;
368373
#endif
374+
375+
enum rfbHandshakeType handshake_type;
376+
369377
} rfbScreenInfo, *rfbScreenInfoPtr;
370378

371379

0 commit comments

Comments
 (0)