/*
 * websockets.c - deal with WebSockets clients.
 *
 * This code should be independent of any changes in the RFB protocol. It is
 * an additional handshake and framing of normal sockets:
 *   http://www.whatwg.org/specs/web-socket-protocol/
 *
 */

/*
 *  Copyright (C) 2010 Joel Martin
 *
 *  This is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This software is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this software; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 *  USA.
 */

#ifdef __STRICT_ANSI__
#define _BSD_SOURCE
#endif

#include <rfb/rfb.h>
/* errno */
#include <errno.h>

#ifndef _MSC_VER
#include <resolv.h> /* __b64_ntop */
#endif

#ifdef LIBVNCSERVER_HAVE_ENDIAN_H
#include <endian.h>
#elif LIBVNCSERVER_HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#endif

#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#include <string.h>
#include <unistd.h>
#include "rfb/rfbconfig.h"
#include "rfbssl.h"
#include "rfbcrypto.h"

#define WS_NTOH64(n) htobe64(n)
#define WS_NTOH32(n) htobe32(n)
#define WS_NTOH16(n) htobe16(n)
#define WS_HTON64(n) htobe64(n)
#define WS_HTON16(n) htobe16(n)

#define B64LEN(__x) (((__x + 2) / 3) * 12 / 3)
#define WSHLENMAX 14  /* 2 + sizeof(uint64_t) + sizeof(uint32_t) */

enum {
  WEBSOCKETS_VERSION_HIXIE,
  WEBSOCKETS_VERSION_HYBI
};

#if 0
#include <sys/syscall.h>
static int gettid() {
    return (int)syscall(SYS_gettid);
}
#endif

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 {
    char codeBuf[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */
    char readbuf[8192];
    int readbufstart;
    int readbuflen;
    int dblen;
    char carryBuf[3];                      /* For base64 carry-over */
    int carrylen;
    int version;
    int base64;
    wsEncodeFunc encode;
    wsDecodeFunc decode;
} ws_ctx_t;

typedef union ws_mask_s {
  char c[4];
  uint32_t u;
} ws_mask_t;

/* XXX: The union and the structs do not need to be named.
 *      We are working around a bug present in GCC < 4.6 which prevented
 *      it from recognizing anonymous structs and unions.
 *      See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4784
 */
typedef struct __attribute__ ((__packed__)) ws_header_s {
  unsigned char b0;
  unsigned char b1;
  union {
    struct __attribute__ ((__packed__)) {
      uint16_t l16;
      ws_mask_t m16;
    } s16;
    struct __attribute__ ((__packed__)) {
      uint64_t l64;
      ws_mask_t m64;
    } s64;
    ws_mask_t m;
  } u;
} ws_header_t;

enum
{
    WS_OPCODE_CONTINUATION = 0x0,
    WS_OPCODE_TEXT_FRAME,
    WS_OPCODE_BINARY_FRAME,
    WS_OPCODE_CLOSE = 0x8,
    WS_OPCODE_PING,
    WS_OPCODE_PONG
};

#define FLASH_POLICY_RESPONSE "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\n"
#define SZ_FLASH_POLICY_RESPONSE 93

/*
 * draft-ietf-hybi-thewebsocketprotocol-10
 * 5.2.2. Sending the Server's Opening Handshake
 */
#define GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

#define SERVER_HANDSHAKE_HIXIE "HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
Upgrade: WebSocket\r\n\
Connection: Upgrade\r\n\
%sWebSocket-Origin: %s\r\n\
%sWebSocket-Location: %s://%s%s\r\n\
%sWebSocket-Protocol: %s\r\n\
\r\n%s"

#define SERVER_HANDSHAKE_HYBI "HTTP/1.1 101 Switching Protocols\r\n\
Upgrade: websocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Accept: %s\r\n\
Sec-WebSocket-Protocol: %s\r\n\
\r\n"


#define WEBSOCKETS_CLIENT_CONNECT_WAIT_MS 100
#define WEBSOCKETS_CLIENT_SEND_WAIT_MS 100
#define WEBSOCKETS_MAX_HANDSHAKE_LEN 4096

#if defined(__linux__) && defined(NEED_TIMEVAL)
struct timeval
{
   long int tv_sec,tv_usec;
}
;
#endif

static rfbBool webSocketsHandshake(rfbClientPtr cl, char *scheme);
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
min (int a, int b) {
    return a < b ? a : b;
}

static void webSocketsGenSha1Key(char *target, int size, char *key)
{
    struct iovec iov[2];
    unsigned char hash[20];

    iov[0].iov_base = key;
    iov[0].iov_len = strlen(key);
    iov[1].iov_base = GUID;
    iov[1].iov_len = sizeof(GUID) - 1;
    digestsha1(iov, 2, hash);
    if (-1 == __b64_ntop(hash, sizeof(hash), target, size))
	rfbErr("b64_ntop failed\n");
}

/*
 * rfbWebSocketsHandshake is called to handle new WebSockets connections
 */

rfbBool
webSocketsCheck (rfbClientPtr cl)
{
    char bbuf[4], *scheme;
    int ret;

    ret = rfbPeekExactTimeout(cl, bbuf, 4,
                                   WEBSOCKETS_CLIENT_CONNECT_WAIT_MS);
    if ((ret < 0) && (errno == ETIMEDOUT)) {
      rfbLog("Normal socket connection\n");
      return TRUE;
    } else if (ret <= 0) {
      rfbErr("webSocketsHandshake: unknown connection error\n");
      return FALSE;
    }

    if (strncmp(bbuf, "<", 1) == 0) {
        rfbLog("Got Flash policy request, sending response\n");
        if (rfbWriteExact(cl, FLASH_POLICY_RESPONSE,
                          SZ_FLASH_POLICY_RESPONSE) < 0) {
            rfbErr("webSocketsHandshake: failed sending Flash policy response");
        }
        return FALSE;
    } else if (strncmp(bbuf, "\x16", 1) == 0 || strncmp(bbuf, "\x80", 1) == 0) {
        rfbLog("Got TLS/SSL WebSockets connection\n");
        if (-1 == rfbssl_init(cl)) {
	  rfbErr("webSocketsHandshake: rfbssl_init failed\n");
	  return FALSE;
	}
	ret = rfbPeekExactTimeout(cl, bbuf, 4, WEBSOCKETS_CLIENT_CONNECT_WAIT_MS);
        scheme = "wss";
    } else {
        scheme = "ws";
    }

    if (strncmp(bbuf, "GET ", 4) != 0) {
      rfbErr("webSocketsHandshake: invalid client header\n");
      return FALSE;
    }

    rfbLog("Got '%s' WebSockets handshake\n", scheme);

    if (!webSocketsHandshake(cl, scheme)) {
        return FALSE;
    }
    /* Start WebSockets framing */
    return TRUE;
}

static rfbBool
webSocketsHandshake(rfbClientPtr cl, char *scheme)
{
    char *buf, *response, *line;
    int n, linestart = 0, len = 0, llen, base64 = TRUE;
    char prefix[5], trailer[17];
    char *path = NULL, *host = NULL, *origin = NULL, *protocol = NULL;
    char *key1 = NULL, *key2 = NULL, *key3 = NULL;
    char *sec_ws_origin = NULL;
    char *sec_ws_key = NULL;
    char sec_ws_version = 0;
    ws_ctx_t *wsctx = NULL;

    buf = (char *) malloc(WEBSOCKETS_MAX_HANDSHAKE_LEN);
    if (!buf) {
        rfbLogPerror("webSocketsHandshake: malloc");
        return FALSE;
    }
    response = (char *) malloc(WEBSOCKETS_MAX_HANDSHAKE_LEN);
    if (!response) {
        free(buf);
        rfbLogPerror("webSocketsHandshake: malloc");
        return FALSE;
    }

    while (len < WEBSOCKETS_MAX_HANDSHAKE_LEN-1) {
        if ((n = rfbReadExactTimeout(cl, buf+len, 1,
                                     WEBSOCKETS_CLIENT_SEND_WAIT_MS)) <= 0) {
            if ((n < 0) && (errno == ETIMEDOUT)) {
                break;
            }
            if (n == 0)
                rfbLog("webSocketsHandshake: client gone\n");
            else
                rfbLogPerror("webSocketsHandshake: read");
            free(response);
            free(buf);
            return FALSE;
        }

        len += 1;
        llen = len - linestart;
        if (((llen >= 2)) && (buf[len-1] == '\n')) {
            line = buf+linestart;
            if ((llen == 2) && (strncmp("\r\n", line, 2) == 0)) {
                if (key1 && key2) {
                    if ((n = rfbReadExact(cl, buf+len, 8)) <= 0) {
                        if ((n < 0) && (errno == ETIMEDOUT)) {
                            break;
                        }
                        if (n == 0)
                            rfbLog("webSocketsHandshake: client gone\n");
                        else
                            rfbLogPerror("webSocketsHandshake: read");
                        free(response);
                        free(buf);
                        return FALSE;
                    }
                    rfbLog("Got key3\n");
                    key3 = buf+len;
                    len += 8;
                } else {
                    buf[len] = '\0';
                }
                break;
            } else if ((llen >= 16) && ((strncmp("GET ", line, min(llen,4))) == 0)) {
                /* 16 = 4 ("GET ") + 1 ("/.*") + 11 (" HTTP/1.1\r\n") */
                path = line+4;
                buf[len-11] = '\0'; /* Trim trailing " HTTP/1.1\r\n" */
                cl->wspath = strdup(path);
                /* rfbLog("Got path: %s\n", path); */
            } else if ((strncasecmp("host: ", line, min(llen,6))) == 0) {
                host = line+6;
                buf[len-2] = '\0';
                /* rfbLog("Got host: %s\n", host); */
            } else if ((strncasecmp("origin: ", line, min(llen,8))) == 0) {
                origin = line+8;
                buf[len-2] = '\0';
                /* rfbLog("Got origin: %s\n", origin); */
            } else if ((strncasecmp("sec-websocket-key1: ", line, min(llen,20))) == 0) {
                key1 = line+20;
                buf[len-2] = '\0';
                /* rfbLog("Got key1: %s\n", key1); */
            } else if ((strncasecmp("sec-websocket-key2: ", line, min(llen,20))) == 0) {
                key2 = line+20;
                buf[len-2] = '\0';
                /* rfbLog("Got key2: %s\n", key2); */
            /* HyBI */

	    } else if ((strncasecmp("sec-websocket-protocol: ", line, min(llen,24))) == 0) {
                protocol = line+24;
                buf[len-2] = '\0';
                rfbLog("Got protocol: %s\n", protocol);
            } else if ((strncasecmp("sec-websocket-origin: ", line, min(llen,22))) == 0) {
		sec_ws_origin = line+22;
                buf[len-2] = '\0';
            } else if ((strncasecmp("sec-websocket-key: ", line, min(llen,19))) == 0) {
		sec_ws_key = line+19;
                buf[len-2] = '\0';
            } else if ((strncasecmp("sec-websocket-version: ", line, min(llen,23))) == 0) {
		sec_ws_version = strtol(line+23, NULL, 10);
                buf[len-2] = '\0';
	    }

            linestart = len;
        }
    }

    if (!(path && host && (origin || sec_ws_origin))) {
        rfbErr("webSocketsHandshake: incomplete client handshake\n");
        free(response);
        free(buf);
        return FALSE;
    }

    if ((protocol) && (strstr(protocol, "binary"))) {
        if (! sec_ws_version) {
            rfbErr("webSocketsHandshake: 'binary' protocol not supported with Hixie\n");
            free(response);
            free(buf);
            return FALSE;
        }
        rfbLog("  - webSocketsHandshake: using binary/raw encoding\n");
        base64 = FALSE;
        protocol = "binary";
    } else {
        rfbLog("  - webSocketsHandshake: using base64 encoding\n");
        base64 = TRUE;
        if ((protocol) && (strstr(protocol, "base64"))) {
            protocol = "base64";
        } else {
            protocol = "";
        }
    }

    /*
     * Generate the WebSockets server response based on the the headers sent
     * by the client.
     */

    if (sec_ws_version) {
	char accept[B64LEN(SHA1_HASH_SIZE) + 1];
	rfbLog("  - WebSockets client version hybi-%02d\n", sec_ws_version);
	webSocketsGenSha1Key(accept, sizeof(accept), sec_ws_key);
	len = snprintf(response, WEBSOCKETS_MAX_HANDSHAKE_LEN,
		 SERVER_HANDSHAKE_HYBI, accept, protocol);
    } else {
	/* older hixie handshake, this could be removed if
	 * a final standard is established */
	if (!(key1 && key2 && key3)) {
	    rfbLog("  - WebSockets client version hixie-75\n");
	    prefix[0] = '\0';
	    trailer[0] = '\0';
	} else {
	    rfbLog("  - WebSockets client version hixie-76\n");
	    snprintf(prefix, 5, "Sec-");
	    webSocketsGenMd5(trailer, key1, key2, key3);
	}
	len = snprintf(response, WEBSOCKETS_MAX_HANDSHAKE_LEN,
		 SERVER_HANDSHAKE_HIXIE, prefix, origin, prefix, scheme,
		 host, path, prefix, protocol, trailer);
    }

    if (rfbWriteExact(cl, response, len) < 0) {
        rfbErr("webSocketsHandshake: failed sending WebSockets response\n");
        free(response);
        free(buf);
        return FALSE;
    }
    /* rfbLog("webSocketsHandshake: %s\n", response); */
    free(response);
    free(buf);


    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;
}
 
void
webSocketsGenMd5(char * target, char *key1, char *key2, char *key3)
{
    unsigned int i, spaces1 = 0, spaces2 = 0;
    unsigned long num1 = 0, num2 = 0;
    unsigned char buf[17];
    struct iovec iov[1];

    for (i=0; i < strlen(key1); i++) {
        if (key1[i] == ' ') {
            spaces1 += 1;
        }
        if ((key1[i] >= 48) && (key1[i] <= 57)) {
            num1 = num1 * 10 + (key1[i] - 48);
        }
    }
    num1 = num1 / spaces1;

    for (i=0; i < strlen(key2); i++) {
        if (key2[i] == ' ') {
            spaces2 += 1;
        }
        if ((key2[i] >= 48) && (key2[i] <= 57)) {
            num2 = num2 * 10 + (key2[i] - 48);
        }
    }
    num2 = num2 / spaces2;

    /* Pack it big-endian */
    buf[0] = (num1 & 0xff000000) >> 24;
    buf[1] = (num1 & 0xff0000) >> 16;
    buf[2] = (num1 & 0xff00) >> 8;
    buf[3] =  num1 & 0xff;

    buf[4] = (num2 & 0xff000000) >> 24;
    buf[5] = (num2 & 0xff0000) >> 16;
    buf[6] = (num2 & 0xff00) >> 8;
    buf[7] =  num2 & 0xff;

    strncpy((char *)buf+8, key3, 8);
    buf[16] = '\0';

    iov[0].iov_base = buf;
    iov[0].iov_len = 16;
    digestmd5(iov, 1, target);
    target[16] = '\0';

    return;
}

static int
webSocketsEncodeHixie(rfbClientPtr cl, const char *src, int len, char **dst)
{
    int sz = 0;
    ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;

    wsctx->codeBuf[sz++] = '\x00';
    len = __b64_ntop((unsigned char *)src, len, wsctx->codeBuf+sz, sizeof(wsctx->codeBuf) - (sz + 1));
    if (len < 0) {
        return len;
    }
    sz += len;

    wsctx->codeBuf[sz++] = '\xff';
    *dst = wsctx->codeBuf;
    return sz;
}

static int
ws_read(rfbClientPtr cl, char *buf, int len)
{
    int n;
    if (cl->sslctx) {
	n = rfbssl_read(cl, buf, len);
    } else {
	n = read(cl->sock, buf, len);
    }
    return n;
}

static int
ws_peek(rfbClientPtr cl, char *buf, int len)
{
    int n;
    if (cl->sslctx) {
	n = rfbssl_peek(cl, buf, len);
    } else {
	while (-1 == (n = recv(cl->sock, buf, len, MSG_PEEK))) {
	    if (errno != EAGAIN)
		break;
	}
    }
    return n;
}

static int
webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len)
{
    int retlen = 0, n, i, avail, modlen, needlen;
    char *buf, *end = NULL;
    ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;

    buf = wsctx->codeBuf;

    n = ws_peek(cl, buf, len*2+2);

    if (n <= 0) {
        /* save errno because rfbErr() will tamper it */
        int olderrno = errno;
        rfbErr("%s: peek (%d) %m\n", __func__, errno);
        errno = olderrno;
        return n;
    }


    /* Base64 encoded WebSockets stream */

    if (buf[0] == '\xff') {
        i = ws_read(cl, buf, 1); /* Consume marker */
        buf++;
        n--;
    }
    if (n == 0) {
        errno = EAGAIN;
        return -1;
    }
    if (buf[0] == '\x00') {
        i = ws_read(cl, buf, 1); /* Consume marker */
        buf++;
        n--;
    }
    if (n == 0) {
        errno = EAGAIN;
        return -1;
    }

    /* end = memchr(buf, '\xff', len*2+2); */
    end = memchr(buf, '\xff', n);
    if (!end) {
        end = buf + n;
    }
    avail = end - buf;

    len -= wsctx->carrylen;

    /* Determine how much base64 data we need */
    modlen = len + (len+2)/3;
    needlen = modlen;
    if (needlen % 4) {
        needlen += 4 - (needlen % 4);
    }

    if (needlen > avail) {
        /* rfbLog("Waiting for more base64 data\n"); */
        errno = EAGAIN;
        return -1;
    }

    /* Any carryover from previous decode */
    for (i=0; i < wsctx->carrylen; i++) {
        /* rfbLog("Adding carryover %d\n", wsctx->carryBuf[i]); */
        dst[i] = wsctx->carryBuf[i];
        retlen += 1;
    }

    /* Decode the rest of what we need */
    buf[needlen] = '\x00';  /* Replace end marker with end of string */
    /* rfbLog("buf: %s\n", buf); */
    n = __b64_pton(buf, (unsigned char *)dst+retlen, 2+len);
    if (n < len) {
        rfbErr("Base64 decode error\n");
        errno = EIO;
        return -1;
    }
    retlen += n;

    /* Consume the data from socket */
    i = ws_read(cl, buf, needlen);

    wsctx->carrylen = n - len;
    retlen -= wsctx->carrylen;
    for (i=0; i < wsctx->carrylen; i++) {
        /* rfbLog("Saving carryover %d\n", dst[retlen + i]); */
        wsctx->carryBuf[i] = dst[retlen + i];
    }

    /* rfbLog("<< webSocketsDecode, retlen: %d\n", retlen); */
    return retlen;
}

static int
webSocketsDecodeHybi(rfbClientPtr cl, char *dst, int len)
{
    char *buf, *payload;
    uint32_t *payload32;
    int ret = -1, result = -1;
    int total = 0;
    ws_mask_t mask;
    ws_header_t *header;
    int i;
    unsigned char opcode;
    ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;
    int flength, fhlen;
    /* int fin; */ /* not used atm */ 

    /* rfbLog(" <== %s[%d]: %d cl: %p, wsctx: %p-%p (%d)\n", __func__, gettid(), len, cl, wsctx, (char *)wsctx + sizeof(ws_ctx_t), sizeof(ws_ctx_t)); */

    if (wsctx->readbuflen) {
      /* simply return what we have */
      if (wsctx->readbuflen > len) {
	memcpy(dst, wsctx->readbuf +  wsctx->readbufstart, len);
	result = len;
	wsctx->readbuflen -= len;
	wsctx->readbufstart += len;
      } else {
	memcpy(dst, wsctx->readbuf +  wsctx->readbufstart, wsctx->readbuflen);
	result = wsctx->readbuflen;
	wsctx->readbuflen = 0;
	wsctx->readbufstart = 0;
      }
      goto spor;
    }

    buf = wsctx->codeBuf;
    header = (ws_header_t *)wsctx->codeBuf;

    ret = ws_peek(cl, buf, B64LEN(len) + WSHLENMAX);

    if (ret < 2) {
        /* save errno because rfbErr() will tamper it */
        if (-1 == ret) {
            int olderrno = errno;
            rfbErr("%s: peek; %m\n", __func__);
            errno = olderrno;
        } else if (0 == ret) {
            result = 0;
        } else {
            errno = EAGAIN;
        }
        goto spor;
    }

    opcode = header->b0 & 0x0f;
    /* fin = (header->b0 & 0x80) >> 7; */ /* not used atm */
    flength = header->b1 & 0x7f;

    /*
     * 4.3. Client-to-Server Masking
     *
     * The client MUST mask all frames sent to the server.  A server MUST
     * close the connection upon receiving a frame with the MASK bit set to 0.
    **/
    if (!(header->b1 & 0x80)) {
	rfbErr("%s: got frame without mask\n", __func__, ret);
	errno = EIO;
	goto spor;
    }

    if (flength < 126) {
	fhlen = 2;
	mask = header->u.m;
    } else if (flength == 126 && 4 <= ret) {
	flength = WS_NTOH16(header->u.s16.l16);
	fhlen = 4;
	mask = header->u.s16.m16;
    } else if (flength == 127 && 10 <= ret) {
	flength = WS_NTOH64(header->u.s64.l64);
	fhlen = 10;
	mask = header->u.s64.m64;
    } else {
      /* Incomplete frame header */
      rfbErr("%s: incomplete frame header\n", __func__, ret);
      errno = EIO;
      goto spor;
    }

    /* absolute length of frame */
    total = fhlen + flength + 4;
    payload = buf + fhlen + 4; /* header length + mask */

    if (-1 == (ret = ws_read(cl, buf, total))) {
      int olderrno = errno;
      rfbErr("%s: read; %m", __func__);
      errno = olderrno;
      return ret;
    } else if (ret < total) {
      /* GT TODO: hmm? */
      rfbLog("%s: read; got partial data\n", __func__);
    } else {
      buf[ret] = '\0';
    }

    /* process 1 frame (32 bit op) */
    payload32 = (uint32_t *)payload;
    for (i = 0; i < flength / 4; i++) {
	payload32[i] ^= mask.u;
    }
    /* process the remaining bytes (if any) */
    for (i*=4; i < flength; i++) {
	payload[i] ^= mask.c[i % 4];
    }

    switch (opcode) {
      case WS_OPCODE_CLOSE:
	rfbLog("got closure, reason %d\n", WS_NTOH16(((uint16_t *)payload)[0]));
	errno = ECONNRESET;
	break;
      case WS_OPCODE_TEXT_FRAME:
	if (-1 == (flength = __b64_pton(payload, (unsigned char *)wsctx->codeBuf, sizeof(wsctx->codeBuf)))) {
	  rfbErr("%s: Base64 decode error; %m\n", __func__);
	  break;
	}
	payload = wsctx->codeBuf;
	/* fall through */
      case WS_OPCODE_BINARY_FRAME:
	if (flength > len) {
	  memcpy(wsctx->readbuf, payload + len, flength - len);
	  wsctx->readbufstart = 0;
	  wsctx->readbuflen = flength - len;
	  flength = len;
	}
	memcpy(dst, payload, flength);
	result = flength;
	break;
      default:
	rfbErr("%s: unhandled opcode %d, b0: %02x, b1: %02x\n", __func__, (int)opcode, header->b0, header->b1);
    }

    /* single point of return, if someone has questions :-) */
spor:
    /* rfbLog("%s: ret: %d/%d\n", __func__, result, len); */
    return result;
}

static int
webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst)
{
    int blen, ret = -1, sz = 0;
    unsigned char opcode = '\0'; /* TODO: option! */
    ws_header_t *header;
    ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;


    /* Optional opcode:
     *   0x0 - continuation
     *   0x1 - text frame (base64 encode buf)
     *   0x2 - binary frame (use raw buf)
     *   0x8 - connection close
     *   0x9 - ping
     *   0xA - pong
    **/
    if (!len) {
	  /* nothing to encode */
	  return 0;
    }

    header = (ws_header_t *)wsctx->codeBuf;

    if (wsctx->base64) {
	opcode = WS_OPCODE_TEXT_FRAME;
	/* calculate the resulting size */
	blen = B64LEN(len);
    } else {
	opcode = WS_OPCODE_BINARY_FRAME;
	blen = len;
    }

    header->b0 = 0x80 | (opcode & 0x0f);
    if (blen <= 125) {
      header->b1 = (uint8_t)blen;
      sz = 2;
    } else if (blen <= 65536) {
      header->b1 = 0x7e;
      header->u.s16.l16 = WS_HTON16((uint16_t)blen);
      sz = 4;
    } else {
      header->b1 = 0x7f;
      header->u.s64.l64 = WS_HTON64(blen);
      sz = 10;
    }

    if (wsctx->base64) {
        if (-1 == (ret = __b64_ntop((unsigned char *)src, len, wsctx->codeBuf + sz, sizeof(wsctx->codeBuf) - sz))) {
	  rfbErr("%s: Base 64 encode failed\n", __func__);
	} else {
	  if (ret != blen)
	    rfbErr("%s: Base 64 encode; something weird happened\n", __func__);
	  ret += sz;
	}
    } else {
      memcpy(wsctx->codeBuf + sz, src, len);
      ret =  sz + len;
    }

    *dst = wsctx->codeBuf;
    return ret;
}

int
webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst)
{
    return ((ws_ctx_t *)cl->wsctx)->encode(cl, src, len, dst);
}

int
webSocketsDecode(rfbClientPtr cl, char *dst, int len)
{
    return ((ws_ctx_t *)cl->wsctx)->decode(cl, dst, len);
}


/* returns TRUE if client sent a close frame or a single 'end of frame'
 * marker was received, FALSE otherwise
 *
 * Note: This is a Hixie-only hack!
 **/
rfbBool
webSocketCheckDisconnect(rfbClientPtr cl)
{
    ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;
    /* With Base64 encoding we need at least 4 bytes */
    char peekbuf[4];
    int n;

    if (wsctx->version == WEBSOCKETS_VERSION_HYBI)
	return FALSE;

    if (cl->sslctx)
	n = rfbssl_peek(cl, peekbuf, 4);
    else
	n = recv(cl->sock, peekbuf, 4, MSG_PEEK);

    if (n <= 0) {
	if (n != 0)
	    rfbErr("%s: peek; %m", __func__);
	rfbCloseClient(cl);
	return TRUE;
    }

    if (peekbuf[0] == '\xff') {
	int doclose = 0;
	/* Make sure we don't miss a client disconnect on an end frame
	 * marker. Because we use a peek buffer in some cases it is not
	 * applicable to wait for more data per select(). */
	switch (n) {
	    case 3:
		if (peekbuf[1] == '\xff' && peekbuf[2] == '\x00')
		    doclose = 1;
		break;
	    case 2:
		if (peekbuf[1] == '\x00')
		    doclose = 1;
		break;
	    default:
		return FALSE;
	}

	if (cl->sslctx)
	    n = rfbssl_read(cl, peekbuf, n);
	else
	    n = read(cl->sock, peekbuf, n);

	if (doclose) {
	    rfbErr("%s: websocket close frame received\n", __func__);
	    rfbCloseClient(cl);
	}
	return TRUE;
    }
    return FALSE;
}

