Commit 72b18fdf authored by Gernot Tenchio's avatar Gernot Tenchio

websockets: Use callback functions for encode/decode

parent 55234a37
...@@ -63,6 +63,9 @@ static int gettid() { ...@@ -63,6 +63,9 @@ static int gettid() {
return (int)syscall(SYS_gettid); return (int)syscall(SYS_gettid);
} }
typedef int (*wsEncodeFunc)(rfbClientPtr cl, const char *src, int len, char **dst);
typedef int (*wsDecodeFunc)(rfbClientPtr cl, char *dst, int len);
typedef struct ws_ctx_s { typedef struct ws_ctx_s {
char encodeBuf[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */ char encodeBuf[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */
char decodeBuf[8192]; /* TODO: what makes sense? */ char decodeBuf[8192]; /* TODO: what makes sense? */
...@@ -74,6 +77,8 @@ typedef struct ws_ctx_s { ...@@ -74,6 +77,8 @@ typedef struct ws_ctx_s {
int carrylen; int carrylen;
int version; int version;
int base64; int base64;
wsEncodeFunc encode;
wsDecodeFunc decode;
} ws_ctx_t; } ws_ctx_t;
typedef union ws_mask_s { typedef union ws_mask_s {
...@@ -147,6 +152,11 @@ struct timeval ...@@ -147,6 +152,11 @@ struct timeval
static rfbBool webSocketsHandshake(rfbClientPtr cl, char *scheme); static rfbBool webSocketsHandshake(rfbClientPtr cl, char *scheme);
void webSocketsGenMd5(char * target, char *key1, char *key2, char *key3); void webSocketsGenMd5(char * target, char *key1, char *key2, char *key3);
static int webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst);
static int webSocketsEncodeHixie(rfbClientPtr cl, const char *src, int len, char **dst);
static int webSocketsDecodeHybi(rfbClientPtr cl, char *dst, int len);
static int webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len);
static int static int
min (int a, int b) { min (int a, int b) {
return a < b ? a : b; return a < b ? a : b;
...@@ -234,6 +244,7 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme) ...@@ -234,6 +244,7 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme)
char *sec_ws_origin = NULL; char *sec_ws_origin = NULL;
char *sec_ws_key = NULL; char *sec_ws_key = NULL;
char sec_ws_version = 0; char sec_ws_version = 0;
ws_ctx_t *wsctx = NULL;
buf = (char *) malloc(WEBSOCKETS_MAX_HANDSHAKE_LEN); buf = (char *) malloc(WEBSOCKETS_MAX_HANDSHAKE_LEN);
if (!buf) { if (!buf) {
...@@ -380,9 +391,20 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme) ...@@ -380,9 +391,20 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme)
rfbLog("webSocketsHandshake: %s\n", response); rfbLog("webSocketsHandshake: %s\n", response);
free(response); free(response);
free(buf); free(buf);
cl->wsctx = (wsCtx *)calloc(1, sizeof(ws_ctx_t));
((ws_ctx_t *)cl->wsctx)->version = sec_ws_version ? WEBSOCKETS_VERSION_HYBI : WEBSOCKETS_VERSION_HIXIE;
((ws_ctx_t *)cl->wsctx)->base64 = base64; wsctx = calloc(1, sizeof(ws_ctx_t));
if (sec_ws_version) {
wsctx->version = WEBSOCKETS_VERSION_HYBI;
wsctx->encode = webSocketsEncodeHybi;
wsctx->decode = webSocketsDecodeHybi;
} else {
wsctx->version = WEBSOCKETS_VERSION_HIXIE;
wsctx->encode = webSocketsEncodeHixie;
wsctx->decode = webSocketsDecodeHixie;
}
wsctx->base64 = base64;
cl->wsctx = (wsCtx *)wsctx;
return TRUE; return TRUE;
} }
...@@ -432,7 +454,7 @@ webSocketsGenMd5(char * target, char *key1, char *key2, char *key3) ...@@ -432,7 +454,7 @@ webSocketsGenMd5(char * target, char *key1, char *key2, char *key3)
return; return;
} }
int static int
webSocketsEncodeHixie(rfbClientPtr cl, const char *src, int len, char **dst) webSocketsEncodeHixie(rfbClientPtr cl, const char *src, int len, char **dst)
{ {
int i, sz = 0; int i, sz = 0;
...@@ -499,7 +521,7 @@ ws_peek(rfbClientPtr cl, char *buf, int len) ...@@ -499,7 +521,7 @@ ws_peek(rfbClientPtr cl, char *buf, int len)
return n; return n;
} }
int static int
webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len) webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len)
{ {
int retlen = 0, n, i, avail, modlen, needlen, actual; int retlen = 0, n, i, avail, modlen, needlen, actual;
...@@ -650,7 +672,7 @@ webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len) ...@@ -650,7 +672,7 @@ webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len)
return retlen; return retlen;
} }
int static int
webSocketsDecodeHybi(rfbClientPtr cl, char *dst, int len) webSocketsDecodeHybi(rfbClientPtr cl, char *dst, int len)
{ {
char *buf, *payload, *rbuf; char *buf, *payload, *rbuf;
...@@ -780,7 +802,7 @@ spor: ...@@ -780,7 +802,7 @@ spor:
return result; return result;
} }
int static int
webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst) webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst)
{ {
int blen, ret = -1, sz = 0; int blen, ret = -1, sz = 0;
...@@ -846,23 +868,16 @@ webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst) ...@@ -846,23 +868,16 @@ webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst)
int int
webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst) webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst)
{ {
ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx; return ((ws_ctx_t *)cl->wsctx)->encode(cl, src, len, dst);
if (wsctx->version == WEBSOCKETS_VERSION_HIXIE)
return webSocketsEncodeHixie(cl, src, len, dst);
else
return webSocketsEncodeHybi(cl, src, len, dst);
} }
int int
webSocketsDecode(rfbClientPtr cl, char *dst, int len) webSocketsDecode(rfbClientPtr cl, char *dst, int len)
{ {
ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx; return ((ws_ctx_t *)cl->wsctx)->decode(cl, dst, len);
if (wsctx->version == WEBSOCKETS_VERSION_HIXIE)
return webSocketsDecodeHixie(cl, dst, len);
else
return webSocketsDecodeHybi(cl, dst, len);
} }
/* returns TRUE if client sent an close frame or a single end of marker /* returns TRUE if client sent an close frame or a single end of marker
* was received, FALSE otherwise * was received, FALSE otherwise
* *
......
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