Browse Source

add decode support for continuation frames

use FIN bit and implement opcode 0x00

make consistent use of uint64_t for big frame sizes
pull/3/head
Andreas Weigel 6 years ago committed by Christian Beier
parent
commit
5d9d6a8712
No known key found for this signature in database
GPG Key ID: 421BB3B45C6067F8
  1. 3
      libvncserver/websockets.c
  2. 137
      libvncserver/ws_decode.c
  3. 32
      libvncserver/ws_decode.h
  4. 15
      test/wsmaketestframe.py
  5. 29
      test/wstest.c
  6. 54
      test/wstestdata.inc

3
libvncserver/websockets.c

@ -339,12 +339,11 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme)
free(buf);
wsctx = calloc(1, sizeof(ws_ctx_t));
wsctx->version = WEBSOCKETS_VERSION_HYBI;
wsctx->encode = webSocketsEncodeHybi;
wsctx->decode = webSocketsDecodeHybi;
wsctx->ctxInfo.readFunc = ws_read;
wsctx->base64 = base64;
hybiDecodeCleanup(wsctx);
hybiDecodeCleanupComplete(wsctx);
cl->wsctx = (wsCtx *)wsctx;
return TRUE;
}

137
libvncserver/ws_decode.c

@ -8,17 +8,27 @@
#define WS_HYBI_HEADER_LEN_EXTENDED 4 + WS_HYBI_MASK_LEN
#define WS_HYBI_HEADER_LEN_LONG 10 + WS_HYBI_MASK_LEN
static int
static inline int
isControlFrame(ws_ctx_t *wsctx)
{
return 0 != (wsctx->header.opcode & 0x08);
}
static uint64_t
hybiRemaining(ws_ctx_t *wsctx)
{
return wsctx->nToRead - wsctx->nReadRaw;
}
void
hybiDecodeCleanup(ws_ctx_t *wsctx)
static void
hybiDecodeCleanupBasics(ws_ctx_t *wsctx)
{
/* keep opcode, cleanup rest */
wsctx->header.opcode = WS_OPCODE_INVALID;
wsctx->header.payloadLen = 0;
wsctx->header.mask.u = 0;
wsctx->header.headerLen = 0;
wsctx->header.data = NULL;
wsctx->nReadRaw = 0;
wsctx->nToRead= 0;
wsctx->carrylen = 0;
@ -26,9 +36,24 @@ hybiDecodeCleanup(ws_ctx_t *wsctx)
wsctx->readlen = 0;
wsctx->hybiDecodeState = WS_HYBI_STATE_HEADER_PENDING;
wsctx->writePos = NULL;
rfbLog("cleaned up wsctx\n");
}
static void
hybiDecodeCleanupForContinuation(ws_ctx_t *wsctx)
{
hybiDecodeCleanupBasics(wsctx);
rfbLog("clean up frame, but expect continuation with opcode %d\n", wsctx->continuation_opcode);
}
void
hybiDecodeCleanupComplete(ws_ctx_t *wsctx)
{
hybiDecodeCleanupBasics(wsctx);
wsctx->continuation_opcode = WS_OPCODE_INVALID;
rfbLog("cleaned up wsctx completely\n");
}
/**
* Return payload data that has been decoded/unmasked from
* a websocket frame.
@ -94,10 +119,9 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
{
int ret;
char *headerDst = wsctx->codeBufDecode + wsctx->nReadRaw;
int n = WSHLENMAX - wsctx->nReadRaw;
int n = ((uint64_t)WSHLENMAX) - wsctx->nReadRaw;
rfbLog("header_read to %p with len=%d\n", headerDst, n);
//ret = ws_read(cl, headerDst, n);
ret = wsctx->ctxInfo.readFunc(wsctx->ctxInfo.ctxPtr, headerDst, n);
rfbLog("read %d bytes from socket\n", ret);
if (ret <= 0) {
@ -106,29 +130,65 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
int olderrno = errno;
rfbErr("%s: read; %s\n", __func__, strerror(errno));
errno = olderrno;
*sockRet = -1;
goto err_cleanup_state;
} else {
*sockRet = 0;
goto err_cleanup_state_sock_closed;
}
return WS_HYBI_STATE_ERR;
}
wsctx->nReadRaw += ret;
if (wsctx->nReadRaw < 2) {
/* cannot decode header with less than two bytes */
errno = EAGAIN;
*sockRet = -1;
return WS_HYBI_STATE_HEADER_PENDING;
goto ret_header_pending;
}
/* first two header bytes received; interpret header data and get rest */
wsctx->header.data = (ws_header_t *)wsctx->codeBufDecode;
wsctx->header.opcode = wsctx->header.data->b0 & 0x0f;
wsctx->header.fin = (wsctx->header.data->b0 & 0x80) >> 7;
if (isControlFrame(wsctx)) {
rfbLog("is control frame\n");
/* is a control frame, leave remembered continuation opcode unchanged;
* just check if there is a wrong fragmentation */
if (wsctx->header.fin == 0) {
/* we only accept text/binary continuation frames; RFC6455:
* Control frames (see Section 5.5) MAY be injected in the middle of
* a fragmented message. Control frames themselves MUST NOT be
* fragmented. */
rfbErr("control frame with FIN bit cleared received, aborting\n");
errno = EPROTO;
goto err_cleanup_state;
}
} else {
rfbLog("not a control frame\n");
/* not a control frame, check for continuation opcode */
if (wsctx->header.opcode == WS_OPCODE_CONTINUATION) {
rfbLog("cont_frame\n");
/* do we have state (i.e., opcode) for continuation frame? */
if (wsctx->continuation_opcode == WS_OPCODE_INVALID) {
rfbErr("no continuation state\n");
errno = EPROTO;
goto err_cleanup_state;
}
/* fin = (header->b0 & 0x80) >> 7; */ /* not used atm */
wsctx->header.payloadLen = wsctx->header.data->b1 & 0x7f;
rfbLog("first header bytes received; opcode=%d lenbyte=%d\n", wsctx->header.opcode, wsctx->header.payloadLen);
/* otherwise, set opcode = continuation_opcode */
wsctx->header.opcode = wsctx->continuation_opcode;
rfbLog("set opcode to continuation_opcode: %d\n", wsctx->header.opcode);
} else {
if (wsctx->header.fin == 0) {
wsctx->continuation_opcode = wsctx->header.opcode;
} else {
wsctx->continuation_opcode = WS_OPCODE_INVALID;
}
rfbLog("set continuation_opcode to %d\n", wsctx->continuation_opcode);
}
}
wsctx->header.payloadLen = (uint64_t)(wsctx->header.data->b1 & 0x7f);
rfbLog("first header bytes received; opcode=%d lenbyte=%d fin=%d\n", wsctx->header.opcode, wsctx->header.payloadLen, wsctx->header.fin);
/*
* 4.3. Client-to-Server Masking
@ -139,8 +199,7 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
if (!(wsctx->header.data->b1 & 0x80)) {
rfbErr("%s: got frame without mask; ret=%d\n", __func__, ret);
errno = EPROTO;
*sockRet = -1;
return WS_HYBI_STATE_ERR;
goto err_cleanup_state;
}
@ -158,22 +217,27 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
} else {
/* Incomplete frame header, try again */
rfbErr("%s: incomplete frame header; ret=%d\n", __func__, ret);
errno = EAGAIN;
*sockRet = -1;
return WS_HYBI_STATE_HEADER_PENDING;
goto ret_header_pending;
}
char *h = wsctx->codeBufDecode;
int i;
rfbLog("Header:\n");
for (i=0; i <10; i++) {
rfbLog("0x%02X\n", (unsigned char)h[i]);
}
rfbLog("\n");
/* while RFC 6455 mandates that lengths MUST be encoded with the minimum
* number of bytes, it does not specify for the server how to react on
* 'wrongly' encoded frames --- this implementation rejects them*/
if ((wsctx->header.headerLen > WS_HYBI_HEADER_LEN_SHORT
&& wsctx->header.payloadLen < 126)
&& wsctx->header.payloadLen < (uint64_t)126)
|| (wsctx->header.headerLen > WS_HYBI_HEADER_LEN_EXTENDED
&& wsctx->header.payloadLen < 65536)) {
&& wsctx->header.payloadLen < (uint64_t)65536)) {
rfbErr("%s: invalid length field; headerLen=%d payloadLen=%llu\n", __func__, wsctx->header.headerLen, wsctx->header.payloadLen);
errno = EPROTO;
*sockRet = -1;
return WS_HYBI_STATE_ERR;
goto err_cleanup_state;
}
/* absolute length of frame */
@ -186,9 +250,20 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
wsctx->readPos = (unsigned char *)(wsctx->codeBufDecode + wsctx->header.headerLen);
*nPayload = wsctx->nReadRaw - wsctx->header.headerLen;
rfbLog("header complete: state=%d flen=%d writeTo=%p nPayload=%d\n", wsctx->hybiDecodeState, wsctx->nToRead, wsctx->writePos, *nPayload);
rfbLog("header complete: state=%d flen=%llu writeTo=%p nPayload=%d\n", wsctx->hybiDecodeState, wsctx->nToRead, wsctx->writePos, *nPayload);
return WS_HYBI_STATE_DATA_NEEDED;
ret_header_pending:
errno = EAGAIN;
*sockRet = -1;
return WS_HYBI_STATE_HEADER_PENDING;
err_cleanup_state:
*sockRet = -1;
err_cleanup_state_sock_closed:
hybiDecodeCleanupComplete(wsctx);
return WS_HYBI_STATE_ERR;
}
static int
@ -248,6 +323,7 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet, int nInBuf)
/* -1 accounts for potential '\0' terminator for base64 decoding */
bufsize = wsctx->codeBufDecode + ARRAYSIZE(wsctx->codeBufDecode) - wsctx->writePos - 1;
rfbLog("bufsize=%d\n", bufsize);
if (hybiRemaining(wsctx) > bufsize) {
nextRead = bufsize;
} else {
@ -453,11 +529,18 @@ spor:
/* rfbLog("%s: ret: %d/%d\n", __func__, result, len); */
if (wsctx->hybiDecodeState == WS_HYBI_STATE_FRAME_COMPLETE) {
rfbLog("frame received successfully, cleaning up: read=%d hlen=%d plen=%d\n", wsctx->header.nRead, wsctx->header.headerLen, wsctx->header.payloadLen);
/* frame finished, cleanup state */
hybiDecodeCleanup(wsctx);
if (wsctx->header.fin && !isControlFrame(wsctx)) {
/* frame finished, cleanup state */
hybiDecodeCleanupComplete(wsctx);
} else {
/* always retain continuation opcode for unfinished data frames
* or control frames, which may interleave with data frames */
hybiDecodeCleanupForContinuation(wsctx);
}
} else if (wsctx->hybiDecodeState == WS_HYBI_STATE_ERR) {
hybiDecodeCleanup(wsctx);
hybiDecodeCleanupComplete(wsctx);
}
rfbLog("%s_exit: len=%d; "
"CTX: readlen=%d readPos=%p "
"writePos=%p "

32
libvncserver/ws_decode.h

@ -27,16 +27,11 @@
#endif
#define B64LEN(__x) (((__x + 2) / 3) * 12 / 3)
#define WSHLENMAX 14 /* 2 + sizeof(uint64_t) + sizeof(uint32_t) */
#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])))))
enum {
WEBSOCKETS_VERSION_HIXIE,
WEBSOCKETS_VERSION_HYBI
};
struct ws_ctx_s;
typedef struct ws_ctx_s ws_ctx_t;
@ -111,9 +106,11 @@ typedef struct ws_header_data_s {
/** length of frame header including payload len, but without mask */
int headerLen;
/** length of the payload data */
int payloadLen;
uint64_t payloadLen;
/** opcode */
unsigned char opcode;
/** fin bit */
unsigned char fin;
} ws_header_data_t;
typedef struct ws_ctx_s {
@ -125,11 +122,11 @@ typedef struct ws_ctx_s {
int hybiDecodeState;
char carryBuf[3]; /* For base64 carry-over */
int carrylen;
int version;
int base64;
ws_header_data_t header;
int nReadRaw;
int nToRead;
uint64_t nReadRaw;
uint64_t nToRead;
unsigned char continuation_opcode;
wsEncodeFunc encode;
wsDecodeFunc decode;
ctxInfo_t ctxInfo;
@ -137,15 +134,16 @@ typedef struct ws_ctx_s {
enum
{
WS_OPCODE_CONTINUATION = 0x0,
WS_OPCODE_TEXT_FRAME,
WS_OPCODE_BINARY_FRAME,
WS_OPCODE_CLOSE = 0x8,
WS_OPCODE_PING,
WS_OPCODE_PONG
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 hybiDecodeCleanup(ws_ctx_t *wsctx);
void hybiDecodeCleanupComplete(ws_ctx_t *wsctx);
#endif

15
test/wsmaketestframe.py

@ -42,12 +42,12 @@ def add_field(s, name, value, first=False):
class Testframe():
def __init__(self, frame, descr, modify_bytes={}, experrno=0, mask=True):
def __init__(self, frame, descr, modify_bytes={}, experrno=0, mask=True, opcode_overwrite=False):
self.frame = frame
self.descr = descr
self.modify_bytes = modify_bytes
self.experrno = experrno
self.b64 = True if frame.opcode == 1 else False
self.b64 = True if frame.opcode == 1 or opcode_overwrite == 1 else False
self.mask = mask
def to_carray_initializer(self, buf):
@ -110,7 +110,14 @@ flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB
### invalid header values
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Invalid frame: Wrong masking", experrno="EPROTO", mask=False))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("..Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 16 bit len field", experrno="EPROTO", modify_bytes={ 1: 0xFE, 2: 0x00, 3: 0x0F}))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("........Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 64 bit len field", experrno="EPROTO", modify_bytes={ 1: 0xFF, 2: 0x00, 3: 0x00, 4: 0x00, 5: 0x00, 6: 0x80, 7: 0x40}))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("........Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 64 bit len field", experrno="EPROTO", modify_bytes={ 1: 0xFF, 2: 0x00, 3: 0x00, 4: 0x00, 5: 0x00, 6: 0x00, 7: 0x00, 8: 0x80, 9: 0x40}))
frag1 = websockets.framing.Frame(0, 1, bytearray("This is a fragmented websocket...", encoding="utf-8"))
frag2 = websockets.framing.Frame(0, 0, bytearray("... and it goes on...", encoding="utf-8"))
frag3 = websockets.framing.Frame(1, 0, bytearray("and on and stop", encoding="utf-8"))
flist.append(Testframe(frag1, "Continuation test frag1"))
flist.append(Testframe(frag2, "Continuation test frag2", opcode_overwrite=1))
flist.append(Testframe(frag3, "Continuation test frag3", opcode_overwrite=1))
s = "struct ws_frame_test tests[] = {\n"
for i in range(len(flist)):
@ -120,5 +127,5 @@ for i in range(len(flist)):
s += "\n"
s += "};\n"
with open("wstestdata.c", "w") as cdatafile:
with open("wstestdata.inc", "w") as cdatafile:
cdatafile.write(s)

29
test/wstest.c

@ -98,10 +98,10 @@ static int emu_read(void *ctx, char *dst, size_t len)
rfbLog("emu_read called with dst=%p and len=%lu\n", dst, len);
if (ft->simulate_sock_malfunction_at > 0 && ft->simulate_sock_malfunction_at == ft->i) {
rfbLog("simulating IO error with errno=%d\n", ft->errno_val);
errno = ft->errno_val;
errno = ft->errno_val;
return -1;
}
/* return something */
r = rand();
modu = (ft->frame + ft->frame_len) - ft->pos;
@ -130,7 +130,7 @@ static uint64_t run_test(struct ws_frame_test *ft, ws_ctx_t *ctx)
while (nleft > 0) {
rfbLog("calling ws_decode with dst=%p, len=%lu\n", dst, nleft);
n = ctx->decode(ctx, dst, nleft);
rfbLog("read n=%ld\n", n);
rfbLog("read n=%ld\n", n);
if (n == 0) {
if (ft->close_sock_at > 0) {
return OK;
@ -155,7 +155,7 @@ static uint64_t run_test(struct ws_frame_test *ft, ws_ctx_t *ctx)
rfbLog("read n=%ld from decode; dst=%p, nleft=%lu\n", n, dst, nleft);
}
}
if (memcmp(ft->expectedDecodeBuf, dstbuf, ft->raw_payload_len) != 0) {
ft->expectedDecodeBuf[ft->raw_payload_len] = '\0';
dstbuf[ft->raw_payload_len] = '\0';
@ -168,24 +168,23 @@ static uint64_t run_test(struct ws_frame_test *ft, ws_ctx_t *ctx)
int main()
{
{
ws_ctx_t ctx;
int retall= 0;
int i;
srand(RND_SEED);
srand(RND_SEED);
hybiDecodeCleanupComplete(&ctx);
ctx.decode = webSocketsDecodeHybi;
ctx.ctxInfo.readFunc = emu_read;
rfbLog = logtest;
rfbErr = logtest;
for (i = 0; i < ARRAYSIZE(tests); i++) {
int ret;
/* reset output log buffer to begin */
el_pos = el_log;
rfbLog = logtest;
rfbErr = logtest;
hybiDecodeCleanup(&ctx);
ctx.decode = webSocketsDecodeHybi;
ctx.version = WEBSOCKETS_VERSION_HYBI;
ctx.ctxInfo.readFunc = emu_read;
ret = run_test(&tests[i], &ctx);
printf("%s: \"%s\"\n", ret == 0 ? "PASS" : "FAIL", tests[i].descr);
@ -198,7 +197,7 @@ int main()
return retall;
}
#else
#else
int main() {
return 0;

54
test/wstestdata.inc

@ -1,6 +1,6 @@
struct ws_frame_test tests[] = {
{
.frame={0X81,0X88,0XB7,0XDB,0X16,0X16,0XE1,0X9C,0X40,0X6C,0XD3,0X9C,0X7A,0X26},
.frame={0X81,0X88,0X2F,0X2A,0X17,0X41,0X79,0X6D,0X41,0X3B,0X4B,0X6D,0X7B,0X71},
.expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
.frame_len=14,
.raw_payload_len=6,
@ -12,7 +12,7 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X81,0XFE,0X00,0XD4,0X67,0XFE,0X8A,0X31,0X35,0X90,0XC0,0X59,0X05,0XA9,0XDF,0X48,0X2E,0XB9,0XD8,0X47,0X3D,0XA6,0XC7,0X56,0X3E,0XCC,0XB3,0X44,0X03,0XB9,0XCC,0X41,0X05,0X97,0XC8,0X45,0X03,0XA9,0XC4,0X5E,0X2E,0XB9,0XBB,0X47,0X04,0X93,0XDF,0X56,0X03,0XB9,0XDC,0X05,0X03,0XBD,0XC8,0X59,0X05,0X93,0XDB,0X56,0X3D,0XA6,0XD0,0X5D,0X05,0X97,0XC8,0X5F,0X05,0XCC,0XDC,0X4B,0X2E,0XB9,0XC0,0X5D,0X02,0XA9,0XB3,0X44,0X3D,0XBD,0XC8,0X01,0X06,0XB9,0XDF,0X56,0X2A,0XAA,0XC3,0X03,0X2E,0XB9,0XC0,0X04,0X03,0XB9,0XDF,0X56,0X05,0XB9,0XDC,0X44,0X2E,0XB9,0XD0,0X41,0X3D,0XA9,0XF2,0X5A,0X2B,0X97,0XC8,0X76,0X04,0X93,0XCC,0X45,0X3D,0XAA,0XC3,0X56,0X3D,0XB9,0XB3,0X5D,0X04,0X87,0XC8,0X5B,0X05,0XCC,0XBF,0X01,0X3E,0XA9,0XE6,0X44,0X2E,0XB9,0XBB,0X00,0X3E,0XCC,0XED,0X56,0X05,0XA9,0XB3,0X48,0X3D,0XAD,0XC8,0X01,0X3D,0XA6,0XE2,0X01,0X2E,0XB9,0XCC,0X44,0X3D,0XBD,0XC8,0X5D,0X03,0X93,0XDC,0X44,0X2E,0XB9,0XEE,0X47,0X3D,0XA6,0XC7,0X56,0X3E,0X93,0XDC,0X04,0X05,0XCC,0XBF,0X5A,0X2E,0XB6,0XD8,0X5E,0X3D,0XAD,0XCB,0X49,0X2A,0X94,0XD3,0X56,0X3E,0X90,0XE6,0X01,0X3D,0XAD,0XC8,0X42,0X3D,0XA9,0XBE,0X56,0X3D,0X93,0XE6,0X5D,0X05,0XB9,0XDB,0X44},
.frame={0X81,0XFE,0X00,0XD4,0X66,0X27,0XE5,0X24,0X34,0X49,0XAF,0X4C,0X04,0X70,0XB0,0X5D,0X2F,0X60,0XB7,0X52,0X3C,0X7F,0XA8,0X43,0X3F,0X15,0XDC,0X51,0X02,0X60,0XA3,0X54,0X04,0X4E,0XA7,0X50,0X02,0X70,0XAB,0X4B,0X2F,0X60,0XD4,0X52,0X05,0X4A,0XB0,0X43,0X02,0X60,0XB3,0X10,0X02,0X64,0XA7,0X4C,0X04,0X4A,0XB4,0X43,0X3C,0X7F,0XBF,0X48,0X04,0X4E,0XA7,0X4A,0X04,0X15,0XB3,0X5E,0X2F,0X60,0XAF,0X48,0X03,0X70,0XDC,0X51,0X3C,0X64,0XA7,0X14,0X07,0X60,0XB0,0X43,0X2B,0X73,0XAC,0X16,0X2F,0X60,0XAF,0X11,0X02,0X60,0XB0,0X43,0X04,0X60,0XB3,0X51,0X2F,0X60,0XBF,0X54,0X3C,0X70,0X9D,0X4F,0X2A,0X4E,0XA7,0X63,0X05,0X4A,0XA3,0X50,0X3C,0X73,0XAC,0X43,0X3C,0X60,0XDC,0X48,0X05,0X5E,0XA7,0X4E,0X04,0X15,0XD0,0X14,0X3F,0X70,0X89,0X51,0X2F,0X60,0XD4,0X15,0X3F,0X15,0X82,0X43,0X04,0X70,0XDC,0X5D,0X3C,0X74,0XA7,0X14,0X3C,0X7F,0X8D,0X14,0X2F,0X60,0XA3,0X51,0X3C,0X64,0XA7,0X48,0X02,0X4A,0XB3,0X51,0X2F,0X60,0X81,0X52,0X3C,0X7F,0XA8,0X43,0X3F,0X4A,0XB3,0X11,0X04,0X15,0XD0,0X4F,0X2F,0X6F,0XB7,0X4B,0X3C,0X74,0XA4,0X5C,0X2B,0X4D,0XBC,0X43,0X3F,0X49,0X89,0X14,0X3C,0X74,0XA7,0X57,0X3C,0X70,0XD1,0X43,0X3C,0X4A,0X89,0X48,0X04,0X60,0XB4,0X51},
.expectedDecodeBuf={0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E,0X20,0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E},
.frame_len=220,
.raw_payload_len=159,
@ -24,7 +24,7 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X82,0X86,0X90,0X5E,0X2B,0X8E,0XC4,0X3B,0X58,0XFA,0XF9,0X2A},
.frame={0X82,0X86,0XDD,0X9B,0XD8,0X56,0X89,0XFE,0XAB,0X22,0XB4,0XEF},
.expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
.frame_len=12,
.raw_payload_len=6,
@ -36,7 +36,7 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X82,0XFE,0X00,0X9F,0X7D,0X97,0X6B,0XA2,0X3B,0XE5,0X0A,0XCF,0X18,0XA5,0X4B,0XC6,0X12,0XF2,0X18,0X82,0X1E,0XF8,0X05,0XD6,0X1C,0XFE,0X05,0X82,0X10,0XE2,0X08,0XCA,0X5D,0XFA,0X04,0XD0,0X18,0XB7,0X1F,0XC7,0X05,0XE3,0X4B,0XC3,0X13,0XF3,0X4B,0XC7,0X0B,0XF2,0X05,0X82,0X1A,0XF8,0X0E,0XD1,0X5D,0XF5,0X0E,0XDB,0X12,0XF9,0X0F,0X82,0X09,0XFF,0X0E,0X82,0X4C,0XA5,0X5D,0X82,0X1F,0XEE,0X1F,0XC7,0X5D,0XFB,0X0E,0XCC,0X5D,0XF1,0X02,0XC7,0X11,0XF3,0X45,0X82,0X3B,0XE5,0X0A,0XCF,0X18,0XA5,0X4B,0XC6,0X12,0XF2,0X18,0X82,0X1E,0XF8,0X05,0XD6,0X1C,0XFE,0X05,0X82,0X10,0XE2,0X08,0XCA,0X5D,0XFA,0X04,0XD0,0X18,0XB7,0X1F,0XC7,0X05,0XE3,0X4B,0XC3,0X13,0XF3,0X4B,0XC7,0X0B,0XF2,0X05,0X82,0X1A,0XF8,0X0E,0XD1,0X5D,0XF5,0X0E,0XDB,0X12,0XF9,0X0F,0X82,0X09,0XFF,0X0E,0X82,0X4C,0XA5,0X5D,0X82,0X1F,0XEE,0X1F,0XC7,0X5D,0XFB,0X0E,0XCC,0X5D,0XF1,0X02,0XC7,0X11,0XF3,0X45},
.frame={0X82,0XFE,0X00,0X9F,0XB5,0X6E,0X7F,0X4C,0XF3,0X1C,0X1E,0X21,0XD0,0X5C,0X5F,0X28,0XDA,0X0B,0X0C,0X6C,0XD6,0X01,0X11,0X38,0XD4,0X07,0X11,0X6C,0XD8,0X1B,0X1C,0X24,0X95,0X03,0X10,0X3E,0XD0,0X4E,0X0B,0X29,0XCD,0X1A,0X5F,0X2D,0XDB,0X0A,0X5F,0X29,0XC3,0X0B,0X11,0X6C,0XD2,0X01,0X1A,0X3F,0X95,0X0C,0X1A,0X35,0XDA,0X00,0X1B,0X6C,0XC1,0X06,0X1A,0X6C,0X84,0X5C,0X49,0X6C,0XD7,0X17,0X0B,0X29,0X95,0X02,0X1A,0X22,0X95,0X08,0X16,0X29,0XD9,0X0A,0X51,0X6C,0XF3,0X1C,0X1E,0X21,0XD0,0X5C,0X5F,0X28,0XDA,0X0B,0X0C,0X6C,0XD6,0X01,0X11,0X38,0XD4,0X07,0X11,0X6C,0XD8,0X1B,0X1C,0X24,0X95,0X03,0X10,0X3E,0XD0,0X4E,0X0B,0X29,0XCD,0X1A,0X5F,0X2D,0XDB,0X0A,0X5F,0X29,0XC3,0X0B,0X11,0X6C,0XD2,0X01,0X1A,0X3F,0X95,0X0C,0X1A,0X35,0XDA,0X00,0X1B,0X6C,0XC1,0X06,0X1A,0X6C,0X84,0X5C,0X49,0X6C,0XD7,0X17,0X0B,0X29,0X95,0X02,0X1A,0X22,0X95,0X08,0X16,0X29,0XD9,0X0A,0X51},
.expectedDecodeBuf={0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E,0X20,0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E},
.frame_len=167,
.raw_payload_len=159,
@ -48,7 +48,7 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X88,0X82,0X71,0X1D,0X00,0XFE,0X72,0XF6},
.frame={0X88,0X82,0X6B,0X33,0X77,0X94,0X68,0XD8},
.expectedDecodeBuf={0X03,0XEB},
.frame_len=8,
.raw_payload_len=2,
@ -60,7 +60,7 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X88,0XAD,0XD0,0X8D,0X26,0XD8,0XD3,0X66,0X6F,0XFF,0XBD,0XAD,0X47,0XF8,0XB3,0XE1,0X49,0XAB,0XB5,0XAD,0X54,0XBD,0XB1,0XFE,0X49,0XB6,0XF0,0XEC,0X48,0XBC,0XF0,0XE0,0X53,0XBB,0XB8,0XAD,0X4B,0XB7,0XA2,0XE8,0X06,0XAC,0XB8,0XEC,0X48,0XF8,0XA4,0XE5,0X47,0XAC,0XF1},
.frame={0X88,0XAD,0X4B,0XA1,0XCE,0XE8,0X48,0X4A,0X87,0XCF,0X26,0X81,0XAF,0XC8,0X28,0XCD,0XA1,0X9B,0X2E,0X81,0XBC,0X8D,0X2A,0XD2,0XA1,0X86,0X6B,0XC0,0XA0,0X8C,0X6B,0XCC,0XBB,0X8B,0X23,0X81,0XA3,0X87,0X39,0XC4,0XEE,0X9C,0X23,0XC0,0XA0,0XC8,0X3F,0XC9,0XAF,0X9C,0X6A},
.expectedDecodeBuf={0X03,0XEB,0X49,0X27,0X6D,0X20,0X61,0X20,0X63,0X6C,0X6F,0X73,0X65,0X20,0X72,0X65,0X61,0X73,0X6F,0X6E,0X20,0X61,0X6E,0X64,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X68,0X61,0X6E,0X20,0X74,0X68,0X61,0X74,0X21},
.frame_len=51,
.raw_payload_len=45,
@ -84,7 +84,7 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X81,0XFE,0X00,0X0F,0X24,0X22,0X8D,0X9C,0X11,0X6F,0XA3,0XC6,0X6E,0X4E,0X88,0XB0,0X48,0X55,0XA2,0XC6,0X72,0X56},
.frame={0X81,0XFE,0X00,0X0F,0X71,0XE9,0X29,0X79,0X44,0XA4,0X07,0X23,0X3B,0X85,0X2C,0X55,0X1D,0X9E,0X06,0X23,0X27,0X9D},
.expectedDecodeBuf={0X2E,0XFE,0X00,0X0F,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D},
.frame_len=22,
.raw_payload_len=12,
@ -96,8 +96,8 @@ struct ws_frame_test tests[] = {
.close_sock_at=0
},
{
.frame={0X81,0XFF,0X00,0X00,0X00,0X00,0X80,0X40,0X7D,0XBB,0X03,0X56,0X7D,0XBB,0X03,0X56,0X7C,0X83,0X2D,0X0C,0X03,0XA2,0X06,0X7A,0X25,0XB9,0X2C,0X0C,0X1F,0XBA},
.expectedDecodeBuf={0X2E,0XFF,0X00,0X00,0X00,0X00,0X80,0X40,0X4C,0X6F,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D},
.frame={0X81,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X40,0X2F,0X40,0XF3,0X5B,0X2F,0X40,0XF2,0X63,0X01,0X1A,0X8D,0X42,0X2A,0X6C,0XAB,0X59,0X00,0X1A,0X91,0X5A},
.expectedDecodeBuf={0X2E,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X40,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D},
.frame_len=30,
.raw_payload_len=18,
.expected_errno=EPROTO,
@ -106,5 +106,41 @@ struct ws_frame_test tests[] = {
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X01,0XAC,0XC9,0X6E,0XC7,0X6E,0X9F,0X29,0XAF,0X1E,0XAA,0X17,0X85,0X1E,0XAA,0X17,0X85,0X06,0X80,0X29,0X9D,0X17,0X90,0X39,0XA3,0X1A,0X93,0X39,0XF2,0X5E,0X93,0X39,0X96,0X09,0XAD,0X5C,0X91,0X07,0XAA,0X5C,0XFE,0X04,0XA8,0X5C,0X91,0X5E,0X85,0X07,0XF3,0X1B},
.expectedDecodeBuf={0X54,0X68,0X69,0X73,0X20,0X69,0X73,0X20,0X61,0X20,0X66,0X72,0X61,0X67,0X6D,0X65,0X6E,0X74,0X65,0X64,0X20,0X77,0X65,0X62,0X73,0X6F,0X63,0X6B,0X65,0X74,0X2E,0X2E,0X2E},
.frame_len=50,
.raw_payload_len=33,
.expected_errno=0,
.descr="Continuation test frag1",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X00,0X9C,0X52,0XBC,0XD5,0X99,0X1E,0XD5,0XE1,0XEC,0X1B,0XFB,0X93,0XEC,0X08,0XFF,0X97,0XE9,0X36,0XFF,0X97,0XF7,0X30,0X8E,0X83,0XE3,0X1B,0XFB,0XEC,0XEC,0X1E,0XD5,0XE1,0XEC},
.expectedDecodeBuf={0X2E,0X2E,0X2E,0X20,0X61,0X6E,0X64,0X20,0X69,0X74,0X20,0X67,0X6F,0X65,0X73,0X20,0X6F,0X6E,0X2E,0X2E,0X2E},
.frame_len=34,
.raw_payload_len=21,
.expected_errno=0,
.descr="Continuation test frag2",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
},
{
.frame={0X80,0X94,0X3B,0X88,0XA1,0XE9,0X62,0XDF,0X94,0X82,0X72,0XCF,0X98,0X9C,0X72,0XCF,0XE7,0X9C,0X61,0XCB,0XE3,0X93,0X5F,0XCF,0X98,0X9E},
.expectedDecodeBuf={0X61,0X6E,0X64,0X20,0X6F,0X6E,0X20,0X61,0X6E,0X64,0X20,0X73,0X74,0X6F,0X70},
.frame_len=26,
.raw_payload_len=15,
.expected_errno=0,
.descr="Continuation test frag3",
.i=0,
.simulate_sock_malfunction_at=0,
.errno_val=0,
.close_sock_at=0
}
};

Loading…
Cancel
Save