summaryrefslogtreecommitdiffstats
path: root/libvncserver/ws_decode.h
diff options
context:
space:
mode:
Diffstat (limited to 'libvncserver/ws_decode.h')
-rw-r--r--libvncserver/ws_decode.h145
1 files changed, 145 insertions, 0 deletions
diff --git a/libvncserver/ws_decode.h b/libvncserver/ws_decode.h
new file mode 100644
index 0000000..eb774a4
--- /dev/null
+++ b/libvncserver/ws_decode.h
@@ -0,0 +1,145 @@
+#ifndef _WS_DECODE_H_
+#define _WS_DECODE_H_
+
+#include <stdint.h>
+#include <rfb/rfb.h>
+
+#if defined(__APPLE__)
+
+#include <libkern/OSByteOrder.h>
+#define WS_NTOH64(n) OSSwapBigToHostInt64(n)
+#define WS_NTOH32(n) OSSwapBigToHostInt32(n)
+#define WS_NTOH16(n) OSSwapBigToHostInt16(n)
+#define WS_HTON64(n) OSSwapHostToBigInt64(n)
+#define WS_HTON16(n) OSSwapHostToBigInt16(n)
+
+#else
+
+#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)
+
+#endif
+
+#define B64LEN(__x) (((__x + 2) / 3) * 12 / 3)
+#define WSHLENMAX 14LL /* 2 + sizeof(uint64_t) + sizeof(uint32_t) */
+#define WS_HYBI_MASK_LEN 4
+
+#define ARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))) / (size_t)(!(sizeof(a) % sizeof((a[0])))))
+
+struct ws_ctx_s;
+typedef struct ws_ctx_s ws_ctx_t;
+
+typedef int (*wsEncodeFunc)(rfbClientPtr cl, const char *src, int len, char **dst);
+typedef int (*wsDecodeFunc)(ws_ctx_t *wsctx, char *dst, int len);
+
+typedef int (*wsReadFunc)(void *ctx, char *dst, size_t len);
+
+typedef struct ctxInfo_s{
+ void *ctxPtr;
+ wsReadFunc readFunc;
+} ctxInfo_t;
+
+enum {
+ /* header not yet received completely */
+ WS_HYBI_STATE_HEADER_PENDING,
+ /* data available */
+ WS_HYBI_STATE_DATA_AVAILABLE,
+ WS_HYBI_STATE_DATA_NEEDED,
+ /* received a complete frame */
+ WS_HYBI_STATE_FRAME_COMPLETE,
+ /* received part of a 'close' frame */
+ WS_HYBI_STATE_CLOSE_REASON_PENDING,
+ /* */
+ WS_HYBI_STATE_ERR
+};
+
+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
+#if __GNUC__
+__attribute__ ((__packed__))
+#endif
+ws_header_s {
+ unsigned char b0;
+ unsigned char b1;
+ union {
+ struct
+#if __GNUC__
+ __attribute__ ((__packed__))
+#endif
+ {
+ uint16_t l16;
+ ws_mask_t m16;
+ } s16;
+ struct
+#if __GNUC__
+__attribute__ ((__packed__))
+#endif
+ {
+ uint64_t l64;
+ ws_mask_t m64;
+ } s64;
+ ws_mask_t m;
+ } u;
+} ws_header_t;
+
+typedef struct ws_header_data_s {
+ ws_header_t *data;
+ /** bytes read */
+ int nRead;
+ /** mask value */
+ ws_mask_t mask;
+ /** length of frame header including payload len, but without mask */
+ int headerLen;
+ /** length of the payload data */
+ uint64_t payloadLen;
+ /** opcode */
+ unsigned char opcode;
+ /** fin bit */
+ unsigned char fin;
+} ws_header_data_t;
+
+struct ws_ctx_s {
+ char codeBufDecode[2048 + WSHLENMAX]; /* base64 + maximum frame header length */
+ char codeBufEncode[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */
+ char *writePos;
+ unsigned char *readPos;
+ int readlen;
+ int hybiDecodeState;
+ char carryBuf[3]; /* For base64 carry-over */
+ int carrylen;
+ int base64;
+ ws_header_data_t header;
+ uint64_t nReadPayload;
+ unsigned char continuation_opcode;
+ wsEncodeFunc encode;
+ wsDecodeFunc decode;
+ ctxInfo_t ctxInfo;
+};
+
+enum
+{
+ WS_OPCODE_CONTINUATION = 0x00,
+ WS_OPCODE_TEXT_FRAME = 0x01,
+ WS_OPCODE_BINARY_FRAME = 0x02,
+ WS_OPCODE_CLOSE = 0x08,
+ WS_OPCODE_PING = 0x09,
+ WS_OPCODE_PONG = 0x0A,
+ WS_OPCODE_INVALID = 0xFF
+};
+
+int webSocketsDecodeHybi(ws_ctx_t *wsctx, char *dst, int len);
+
+void hybiDecodeCleanupComplete(ws_ctx_t *wsctx);
+#endif