summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--CMakeLists.txt41
-rw-r--r--libvncserver/ws_decode.c44
-rw-r--r--libvncserver/ws_decode.h7
-rwxr-xr-xtest/wsmaketestframe.py44
-rw-r--r--test/wstest.c23
-rw-r--r--test/wstestdata.c110
7 files changed, 207 insertions, 64 deletions
diff --git a/.gitignore b/.gitignore
index a24f81a..03bdf0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,8 +67,6 @@ test/copyrecttest
test/cursortest
test/encodingstest
test/wstest
-test/wsmaketestframe.py
-test/wstestdata.in
/test/tjbench
/test/tjunittest
vncterm/LinuxVNC
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf6017d..8c6da06 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,7 +49,6 @@ option(WITH_IPv6 "Enable IPv6 Support" ON)
option(WITH_WEBSOCKETS "Build with websockets support" ON)
-
if(WITH_ZLIB)
find_package(ZLIB)
endif(WITH_ZLIB)
@@ -387,6 +386,7 @@ if(LIBVNCSERVER_WITH_WEBSOCKETS)
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
${LIBVNCSERVER_DIR}/websockets.c
+ ${LIBVNCSERVER_DIR}/ws_decode.c
${WSSRCS}
)
endif(LIBVNCSERVER_WITH_WEBSOCKETS)
@@ -500,11 +500,9 @@ foreach(e ${LIBVNCCLIENT_EXAMPLES})
target_link_libraries(client_examples_${e} vncclient ${CMAKE_THREAD_LIBS_INIT} ${SDL_LIBRARY} ${FFMPEG_LIBRARIES})
endforeach(e ${LIBVNCCLIENT_EXAMPLES})
-
#
# them tests
#
-
if(UNIX)
set(ADDITIONAL_TEST_LIBS m)
endif(UNIX)
@@ -512,18 +510,41 @@ endif(UNIX)
set(SIMPLETESTS
cargstest
copyrecttest
+ wstest
)
-if(CMAKE_USE_PTHREADS_INIT)
- set(SIMPLETESTS
- ${SIMPLETESTS}
- encodingstest
+add_test(NAME cargs COMMAND test_cargstest)
+add_test(NAME websockets_decode COMMAND test_wstest)
+
+if(CMAKE_USE_PTHREADS_INI)
+ list(APPEND SIMPLETESTS encodingstest)
+endif(CMAKE_USE_PTHREADS_INI)
+
+if(FOUND_LIBJPEG_TURBO)
+ list(APPEND SIMPLETESTS tjunittest tjbench)
+ set(tjunittest_add_src
+ ${TESTS_DIR}/tjutil.c
+ ${TESTS_DIR}/tjutil.h
+ ${COMMON_DIR}/turbojpeg.c
+ ${COMMON_DIR}/turbojpeg.h
)
-endif(CMAKE_USE_PTHREADS_INIT)
+
+ set(tjbench_add_src
+ ${TESTS_DIR}/tjbench.c
+ ${TESTS_DIR}/tjutil.c
+ ${TESTS_DIR}/tjutil.h
+ ${TESTS_DIR}/bmp.c
+ ${TESTS_DIR}/bmp.h
+ ${COMMON_DIR}/turbojpeg.c
+ ${COMMON_DIR}/turbojpeg.h
+ )
+
+ add_test(NAME turbojpeg COMMAND test_tjunittest)
+endif(FOUND_LIBJPEG_TURBO)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test)
foreach(t ${SIMPLETESTS})
- add_executable(test_${t} ${TESTS_DIR}/${t}.c)
+ add_executable(test_${t} ${TESTS_DIR}/${t}.c ${${t}_add_src})
set_target_properties(test_${t} PROPERTIES OUTPUT_NAME ${t})
set_target_properties(test_${t} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test)
target_link_libraries(test_${t} vncserver vncclient ${ADDITIONAL_TEST_LIBS})
@@ -561,8 +582,6 @@ if(FOUND_LIBJPEG_TURBO)
add_test(NAME turbojpeg COMMAND test_tjunittest)
endif(FOUND_LIBJPEG_TURBO)
-
-
#
# this gets the libraries needed by TARGET in "-libx -liby ..." form
#
diff --git a/libvncserver/ws_decode.c b/libvncserver/ws_decode.c
index 3bd17f4..472a44a 100644
--- a/libvncserver/ws_decode.c
+++ b/libvncserver/ws_decode.c
@@ -85,11 +85,12 @@ hybiReturnData(char *dst, int len, ws_ctx_t *wsctx, int *nWritten)
*
* @param[in] cl client ptr with ptr to raw socket and ws_ctx_t ptr
* @param[out] sockRet emulated recv return value
+ * @param[out] nPayload number of payload bytes already read
* @return next hybi decoding state; WS_HYBI_STATE_HEADER_PENDING indicates
* that the header was not received completely.
*/
static int
-hybiReadHeader(ws_ctx_t *wsctx, int *sockRet)
+hybiReadHeader(ws_ctx_t *wsctx, int *sockRet, int *nPayload)
{
int ret;
char *headerDst = wsctx->codeBufDecode + wsctx->nReadRaw;
@@ -184,7 +185,8 @@ hybiReadHeader(ws_ctx_t *wsctx, int *sockRet)
/* set payload pointer just after header */
wsctx->readPos = (unsigned char *)(wsctx->codeBufDecode + wsctx->header.headerLen);
- rfbLog("header complete: state=%d flen=%d writeTo=%p\n", wsctx->hybiDecodeState, wsctx->nToRead, wsctx->writePos);
+ *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);
return WS_HYBI_STATE_DATA_NEEDED;
}
@@ -217,21 +219,24 @@ hybiPayloadStart(ws_ctx_t *wsctx)
* - execute return data routine
*
* Sets errno corresponding to what it gets from the underlying
- * socket or EIO if some internal sanity check fails.
+ * socket or EPROTO if some invalid data is in the received frame
+ * or ECONNRESET if a close reason + message is received. EIO is used if
+ * an internal sanity check fails.
*
* @param[in] cl client ptr with raw socket reference
* @param[out] dst destination buffer
* @param[in] len size of destination buffer
* @param[out] sockRet emulated recv return value
+ * @param[in] nInBuf number of undecoded bytes before writePos from header read
* @return next hybi decode state
*/
static int
-hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
+hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet, int nInBuf)
{
int n;
int i;
- int toReturn;
- int toDecode;
+ int toReturn; /* number of data bytes to return */
+ int toDecode; /* number of bytes to decode starting at wsctx->writePos */
int bufsize;
int nextRead;
unsigned char *data;
@@ -253,7 +258,6 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
if (wsctx->nReadRaw < wsctx->nToRead) {
/* decode more data */
- //if (-1 == (n = ws_read(cl, wsctx->writePos, nextRead))) {
if (-1 == (n = wsctx->ctxInfo.readFunc(wsctx->ctxInfo.ctxPtr, wsctx->writePos, nextRead))) {
int olderrno = errno;
rfbErr("%s: read; %s", __func__, strerror(errno));
@@ -283,7 +287,9 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
}
}
- toDecode = wsctx->writePos - hybiPayloadStart(wsctx);
+ /* number of not yet unmasked payload bytes: what we read here + what was
+ * carried over + what was read with the header */
+ toDecode = n + wsctx->carrylen + nInBuf;
rfbLog("toDecode=%d from n=%d carrylen=%d headerLen=%d\n", toDecode, n, wsctx->carrylen, wsctx->header.headerLen);
if (toDecode < 0) {
rfbErr("%s: internal error; negative number of bytes to decode: %d", __func__, toDecode);
@@ -294,7 +300,7 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
/* for a possible base64 decoding, we decode multiples of 4 bytes until
* the whole frame is received and carry over any remaining bytes in the carry buf*/
- data = (unsigned char *)hybiPayloadStart(wsctx);
+ data = (unsigned char *)(wsctx->writePos - toDecode);
data32= (uint32_t *)data;
for (i = 0; i < (toDecode >> 2); i++) {
@@ -321,24 +327,25 @@ hybiReadAndDecode(ws_ctx_t *wsctx, char *dst, int len, int *sockRet)
}
rfbLog("carrying over %d bytes from %p to %p\n", wsctx->carrylen, wsctx->writePos + (i * 4), wsctx->carryBuf);
memcpy(wsctx->carryBuf, data + (i * 4), wsctx->carrylen);
+ wsctx->writePos -= wsctx->carrylen;
}
toReturn = toDecode - wsctx->carrylen;
switch (wsctx->header.opcode) {
case WS_OPCODE_CLOSE:
-
/* this data is not returned as payload data */
if (hybiWsFrameComplete(wsctx)) {
- rfbLog("got close cmd, reason %d\n", WS_NTOH16(((uint16_t *)data)[0]));
+ *(wsctx->writePos) = '\0';
+ rfbLog("got close cmd %d, reason %d: %s\n", (int)(wsctx->writePos - hybiPayloadStart(wsctx)), WS_NTOH16(((uint16_t *)hybiPayloadStart(wsctx))[0]), &hybiPayloadStart(wsctx)[2]);
errno = ECONNRESET;
*sockRet = -1;
return WS_HYBI_STATE_FRAME_COMPLETE;
} else {
- rfbErr("%s: close reason with long frame not supported", __func__);
- errno = EIO;
+ rfbLog("got close cmd; waiting for %d more bytes to arrive\n", hybiRemaining(wsctx));
*sockRet = -1;
- return WS_HYBI_STATE_ERR;
+ errno = EAGAIN;
+ return WS_HYBI_STATE_CLOSE_REASON_PENDING;
}
break;
case WS_OPCODE_TEXT_FRAME:
@@ -412,25 +419,26 @@ webSocketsDecodeHybi(ws_ctx_t *wsctx, char *dst, int len)
wsctx->nReadRaw, wsctx->carrylen, wsctx->carryBuf);
switch (wsctx->hybiDecodeState){
+ int nInBuf;
case WS_HYBI_STATE_HEADER_PENDING:
- wsctx->hybiDecodeState = hybiReadHeader(wsctx, &result);
+ wsctx->hybiDecodeState = hybiReadHeader(wsctx, &result, &nInBuf);
if (wsctx->hybiDecodeState == WS_HYBI_STATE_ERR) {
goto spor;
}
if (wsctx->hybiDecodeState != WS_HYBI_STATE_HEADER_PENDING) {
/* when header is complete, try to read some more data */
- wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result);
+ wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result, nInBuf);
}
break;
case WS_HYBI_STATE_DATA_AVAILABLE:
wsctx->hybiDecodeState = hybiReturnData(dst, len, wsctx, &result);
break;
case WS_HYBI_STATE_DATA_NEEDED:
- wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result);
+ wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result, 0);
break;
case WS_HYBI_STATE_CLOSE_REASON_PENDING:
- wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result);
+ wsctx->hybiDecodeState = hybiReadAndDecode(wsctx, dst, len, &result, 0);
break;
default:
/* invalid state */
diff --git a/libvncserver/ws_decode.h b/libvncserver/ws_decode.h
index fac3c68..0dcbc83 100644
--- a/libvncserver/ws_decode.h
+++ b/libvncserver/ws_decode.h
@@ -7,13 +7,6 @@
#include <resolv.h> /* __b64_ntop */
#endif
-
-
-enum {
- WEBSOCKETS_VERSION_HIXIE,
- WEBSOCKETS_VERSION_HYBI
-};
-
#if defined(__APPLE__)
#include <libkern/OSByteOrder.h>
diff --git a/test/wsmaketestframe.py b/test/wsmaketestframe.py
index d0053a2..3412754 100755
--- a/test/wsmaketestframe.py
+++ b/test/wsmaketestframe.py
@@ -26,6 +26,14 @@ import websockets
import base64
import errno
+'''
+ Create websocket frames for the wstest websocket decoding unit test.
+
+ Generates c ws_frame_test structure definitions
+ included by wstest.c.
+'''
+
+
def add_field(s, name, value, first=False):
deli = ",\n\t\t"
if first:
@@ -35,10 +43,9 @@ def add_field(s, name, value, first=False):
class Testframe():
- def __init__(self, frame, descr, retbytes=[], modify_bytes={}, experrno=0, mask=True):
+ def __init__(self, frame, descr, modify_bytes={}, experrno=0, mask=True):
self.frame = frame
self.descr = descr
- self.retbytes = retbytes
self.modify_bytes = modify_bytes
self.experrno = experrno
self.b64 = True if frame.opcode == 1 else False
@@ -53,7 +60,7 @@ class Testframe():
for k in self.modify_bytes:
values[k] = "0X{0:02X}".format(self.modify_bytes[k])
- return "{{{0}}}".format(", ".join(values))
+ return "{{{0}}}".format(",".join(values))
def set_frame_buf(self, buf):
@@ -61,14 +68,13 @@ class Testframe():
self.framelen = len(buf)
def __str__(self):
- #print("processing frame: {0}".format(self.descr))
+ print("processing frame: {0}".format(self.descr))
the_frame = self.frame
if self.b64:
olddata = self.frame.data
newdata = base64.b64encode(self.frame.data)
#print("converting\n{0}\nto{1}\n".format(olddata, newdata))
the_frame = websockets.framing.Frame(self.frame.fin, self.frame.opcode, base64.b64encode(olddata))
-
websockets.framing.write_frame(the_frame, self.set_frame_buf, self.mask)
s = "\t{\n"
s = add_field(s, "frame", "{0}".format(self.frame_carray), True)
@@ -77,8 +83,6 @@ class Testframe():
s = add_field(s, "raw_payload_len", len(self.frame.data))
s = add_field(s, "expected_errno", self.experrno)
s = add_field(s, "descr", "\"{0}\"".format(self.descr))
- s = add_field(s, "ret_bytes", "{{{0}}}".format(", ".join(self.retbytes)))
- s = add_field(s, "ret_bytes_len", len(self.retbytes))
s = add_field(s, "i", "0")
s = add_field(s, "simulate_sock_malfunction_at", "0")
s = add_field(s, "errno_val", "0")
@@ -89,25 +93,25 @@ class Testframe():
### create test frames
flist = []
### standard text frames with different lengths
-flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Short valid text frame", {}))
+flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Short valid text frame"))
flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")),
- "Mid-long valid text frame", {}))
-flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray([(x % 26) + 65 for x in range(100000)])), "100k text frame (ABC..YZABC..)", {}))
+ "Mid-long valid text frame"))
+#flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray([(x % 26) + 65 for x in range(100000)])), "100k text frame (ABC..YZABC..)"))
### standard binary frames with different lengths
-flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Testit", encoding="utf-8")), "Short valid binary frame", {}))
+flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Testit", encoding="utf-8")), "Short valid binary frame"))
flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")),
- "Mid-long valid binary frame", {}))
-flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray([(x % 26) + 65 for x in range(100000)])), "100k binary frame (ABC..YZABC..)", {}))
+ "Mid-long valid binary frame"))
+#flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray([(x % 26) + 65 for x in range(100000)])), "100k binary frame (ABC..YZABC..)"))
-### some conn reset frames, one with no close message, one with close message (the latter should cause an error)
-flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB]))), "Close frame (Reason 1003)", {}, experrno=errno.ECONNRESET))
-flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB])) + bytearray("I'm a close reason", encoding="utf-8")), "Close frame (Reason 1003) and msg", {}, experrno=errno.EIO))
+### some conn reset frames, one with no close message, one with close message
+flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB]))), "Close frame (Reason 1003)", experrno=errno.ECONNRESET))
+flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB])) + bytearray("I'm a close reason and much more than that!", encoding="utf-8")), "Close frame (Reason 1003) and msg", experrno=errno.ECONNRESET))
### invalid header values
-flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Invalid frame: Wrong masking", {}, experrno=errno.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=errno.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=errno.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("Testit", encoding="utf-8")), "Invalid frame: Wrong masking", experrno=errno.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=errno.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=errno.EPROTO, modify_bytes={ 1: 0xFF, 2: 0x00, 3: 0x00, 4: 0x00, 5: 0x00, 6: 0x80, 7: 0x40}))
s = "struct ws_frame_test tests[] = {\n"
for i in range(len(flist)):
@@ -117,5 +121,5 @@ for i in range(len(flist)):
s += "\n"
s += "};\n"
-with open("wstestdata.in", "w") as cdatafile:
+with open("wstestdata.c", "w") as cdatafile:
cdatafile.write(s)
diff --git a/test/wstest.c b/test/wstest.c
index 30324cb..4a5ba91 100644
--- a/test/wstest.c
+++ b/test/wstest.c
@@ -23,6 +23,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _WIN32
+
#include <ws_decode.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,11 +32,11 @@
#include <unistd.h>
#include <errno.h>
-#ifndef _WIN32
-
+/* incoming data frames should not be larger than that */
#define TEST_BUF_SIZE B64LEN(131072) + WSHLENMAX
+
+/* seed is fixed deliberately to get reproducible test cases */
#define RND_SEED 100
-#define WS_TMP_LOG "ws_tmp.log"
enum {
OK,
@@ -55,6 +57,7 @@ struct ws_frame_test {
char frame[TEST_BUF_SIZE];
char *pos;
char expectedDecodeBuf[TEST_BUF_SIZE];
+ uint64_t n_compare;
uint64_t frame_len;
uint64_t raw_payload_len;
int expected_errno;
@@ -67,6 +70,8 @@ struct ws_frame_test {
int close_sock_at;
};
+#include "wstestdata.c"
+
char el_log[1000000];
char *el_pos;
@@ -160,15 +165,15 @@ static uint64_t run_test(struct ws_frame_test *ft, ws_ctx_t *ctx)
return OK;
}
-#include "wstestdata.in"
int main()
{
ws_ctx_t ctx;
- int retall= 0;
+ int retall= 0;
+ int i;
srand(RND_SEED);
- for (int i = 0; i < ARRAYSIZE(tests); i++) {
+ for (i = 0; i < ARRAYSIZE(tests); i++) {
int ret;
el_pos = el_log;
@@ -192,4 +197,10 @@ int main()
return retall;
}
+#else
+
+int main() {
+ return 0;
+}
+
#endif
diff --git a/test/wstestdata.c b/test/wstestdata.c
new file mode 100644
index 0000000..628bdb1
--- /dev/null
+++ b/test/wstestdata.c
@@ -0,0 +1,110 @@
+struct ws_frame_test tests[] = {
+ {
+ .frame={0X81,0X88,0XB7,0XDB,0X16,0X16,0XE1,0X9C,0X40,0X6C,0XD3,0X9C,0X7A,0X26},
+ .expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
+ .frame_len=14,
+ .raw_payload_len=6,
+ .expected_errno=0,
+ .descr="Short valid text frame",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .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},
+ .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,
+ .expected_errno=0,
+ .descr="Mid-long valid text frame",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .close_sock_at=0
+ },
+ {
+ .frame={0X82,0X86,0X90,0X5E,0X2B,0X8E,0XC4,0X3B,0X58,0XFA,0XF9,0X2A},
+ .expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
+ .frame_len=12,
+ .raw_payload_len=6,
+ .expected_errno=0,
+ .descr="Short valid binary frame",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .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},
+ .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,
+ .expected_errno=0,
+ .descr="Mid-long valid binary frame",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .close_sock_at=0
+ },
+ {
+ .frame={0X88,0X82,0X71,0X1D,0X00,0XFE,0X72,0XF6},
+ .expectedDecodeBuf={0X03,0XEB},
+ .frame_len=8,
+ .raw_payload_len=2,
+ .expected_errno=104,
+ .descr="Close frame (Reason 1003)",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .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},
+ .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,
+ .expected_errno=104,
+ .descr="Close frame (Reason 1003) and msg",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .close_sock_at=0
+ },
+ {
+ .frame={0X81,0X08,0X56,0X47,0X56,0X7A,0X64,0X47,0X6C,0X30},
+ .expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74},
+ .frame_len=10,
+ .raw_payload_len=6,
+ .expected_errno=71,
+ .descr="Invalid frame: Wrong masking",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .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},
+ .expectedDecodeBuf={0X2E,0XFE,0X00,0X0F,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D},
+ .frame_len=22,
+ .raw_payload_len=12,
+ .expected_errno=71,
+ .descr="Invalid frame: Length of < 126 with add. 16 bit len field",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .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_len=30,
+ .raw_payload_len=18,
+ .expected_errno=71,
+ .descr="Invalid frame: Length of < 126 with add. 64 bit len field",
+ .i=0,
+ .simulate_sock_malfunction_at=0,
+ .errno_val=0,
+ .close_sock_at=0
+ }
+};