summaryrefslogtreecommitdiff
path: root/thirdparty/wslay/wslay_frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/wslay/wslay_frame.c')
-rw-r--r--thirdparty/wslay/wslay_frame.c306
1 files changed, 202 insertions, 104 deletions
diff --git a/thirdparty/wslay/wslay_frame.c b/thirdparty/wslay/wslay_frame.c
index 445e750ca5..435044a3f4 100644
--- a/thirdparty/wslay/wslay_frame.c
+++ b/thirdparty/wslay/wslay_frame.c
@@ -34,10 +34,9 @@
int wslay_frame_context_init(wslay_frame_context_ptr *ctx,
const struct wslay_frame_callbacks *callbacks,
- void *user_data)
-{
- *ctx = (wslay_frame_context_ptr)malloc(sizeof(struct wslay_frame_context));
- if(*ctx == NULL) {
+ void *user_data) {
+ *ctx = malloc(sizeof(struct wslay_frame_context));
+ if (*ctx == NULL) {
return -1;
}
memset(*ctx, 0, sizeof(struct wslay_frame_context));
@@ -50,38 +49,35 @@ int wslay_frame_context_init(wslay_frame_context_ptr *ctx,
return 0;
}
-void wslay_frame_context_free(wslay_frame_context_ptr ctx)
-{
- free(ctx);
-}
+void wslay_frame_context_free(wslay_frame_context_ptr ctx) { free(ctx); }
ssize_t wslay_frame_send(wslay_frame_context_ptr ctx,
- struct wslay_frame_iocb *iocb)
-{
- if(iocb->data_length > iocb->payload_length) {
+ struct wslay_frame_iocb *iocb) {
+ if (iocb->data_length > iocb->payload_length) {
return WSLAY_ERR_INVALID_ARGUMENT;
}
- if(ctx->ostate == PREP_HEADER) {
+ if (ctx->ostate == PREP_HEADER) {
uint8_t *hdptr = ctx->oheader;
memset(ctx->oheader, 0, sizeof(ctx->oheader));
- *hdptr |= (iocb->fin << 7) & 0x80u;
- *hdptr |= (iocb->rsv << 4) & 0x70u;
- *hdptr |= iocb->opcode & 0xfu;
+ *hdptr |= (uint8_t)((uint8_t)(iocb->fin << 7) & 0x80u);
+ *hdptr |= (uint8_t)((uint8_t)(iocb->rsv << 4) & 0x70u);
+ /* Suppress stubborn gcc-10 warning */
+ *hdptr |= (uint8_t)((uint8_t)(iocb->opcode << 0) & 0xfu);
++hdptr;
- *hdptr |= (iocb->mask << 7) & 0x80u;
- if(wslay_is_ctrl_frame(iocb->opcode) && iocb->payload_length > 125) {
+ *hdptr |= (uint8_t)((uint8_t)(iocb->mask << 7) & 0x80u);
+ if (wslay_is_ctrl_frame(iocb->opcode) && iocb->payload_length > 125) {
return WSLAY_ERR_INVALID_ARGUMENT;
}
- if(iocb->payload_length < 126) {
- *hdptr |= iocb->payload_length;
+ if (iocb->payload_length < 126) {
+ *hdptr |= (uint8_t)iocb->payload_length;
++hdptr;
- } else if(iocb->payload_length < (1 << 16)) {
- uint16_t len = htons(iocb->payload_length);
+ } else if (iocb->payload_length < (1 << 16)) {
+ uint16_t len = htons((uint16_t)iocb->payload_length);
*hdptr |= 126;
++hdptr;
memcpy(hdptr, &len, 2);
hdptr += 2;
- } else if(iocb->payload_length < (1ull << 63)) {
+ } else if (iocb->payload_length < (1ull << 63)) {
uint64_t len = hton64(iocb->payload_length);
*hdptr |= 127;
++hdptr;
@@ -91,9 +87,9 @@ ssize_t wslay_frame_send(wslay_frame_context_ptr ctx,
/* Too large payload length */
return WSLAY_ERR_INVALID_ARGUMENT;
}
- if(iocb->mask) {
- if(ctx->callbacks.genmask_callback(ctx->omaskkey, 4,
- ctx->user_data) != 0) {
+ if (iocb->mask) {
+ if (ctx->callbacks.genmask_callback(ctx->omaskkey, 4, ctx->user_data) !=
+ 0) {
return WSLAY_ERR_INVALID_CALLBACK;
} else {
ctx->omask = 1;
@@ -107,21 +103,21 @@ ssize_t wslay_frame_send(wslay_frame_context_ptr ctx,
ctx->opayloadlen = iocb->payload_length;
ctx->opayloadoff = 0;
}
- if(ctx->ostate == SEND_HEADER) {
- ptrdiff_t len = ctx->oheaderlimit-ctx->oheadermark;
+ if (ctx->ostate == SEND_HEADER) {
+ ptrdiff_t len = ctx->oheaderlimit - ctx->oheadermark;
ssize_t r;
int flags = 0;
- if(iocb->data_length > 0) {
+ if (iocb->data_length > 0) {
flags |= WSLAY_MSG_MORE;
};
- r = ctx->callbacks.send_callback(ctx->oheadermark, len, flags,
+ r = ctx->callbacks.send_callback(ctx->oheadermark, (size_t)len, flags,
ctx->user_data);
- if(r > 0) {
- if(r > len) {
+ if (r > 0) {
+ if (r > len) {
return WSLAY_ERR_INVALID_CALLBACK;
} else {
ctx->oheadermark += r;
- if(ctx->oheadermark == ctx->oheaderlimit) {
+ if (ctx->oheadermark == ctx->oheaderlimit) {
ctx->ostate = SEND_PAYLOAD;
} else {
return WSLAY_ERR_WANT_WRITE;
@@ -131,34 +127,34 @@ ssize_t wslay_frame_send(wslay_frame_context_ptr ctx,
return WSLAY_ERR_WANT_WRITE;
}
}
- if(ctx->ostate == SEND_PAYLOAD) {
+ if (ctx->ostate == SEND_PAYLOAD) {
size_t totallen = 0;
- if(iocb->data_length > 0) {
- if(ctx->omask) {
+ if (iocb->data_length > 0) {
+ if (ctx->omask) {
uint8_t temp[4096];
const uint8_t *datamark = iocb->data,
- *datalimit = iocb->data+iocb->data_length;
- while(datamark < datalimit) {
- size_t datalen = datalimit - datamark;
- const uint8_t *writelimit = datamark+
- wslay_min(sizeof(temp), datalen);
- size_t writelen = writelimit-datamark;
+ *datalimit = iocb->data + iocb->data_length;
+ while (datamark < datalimit) {
+ size_t datalen = (size_t)(datalimit - datamark);
+ const uint8_t *writelimit =
+ datamark + wslay_min(sizeof(temp), datalen);
+ size_t writelen = (size_t)(writelimit - datamark);
ssize_t r;
size_t i;
- for(i = 0; i < writelen; ++i) {
- temp[i] = datamark[i]^ctx->omaskkey[(ctx->opayloadoff+i)%4];
+ for (i = 0; i < writelen; ++i) {
+ temp[i] = datamark[i] ^ ctx->omaskkey[(ctx->opayloadoff + i) % 4];
}
r = ctx->callbacks.send_callback(temp, writelen, 0, ctx->user_data);
- if(r > 0) {
- if((size_t)r > writelen) {
+ if (r > 0) {
+ if ((size_t)r > writelen) {
return WSLAY_ERR_INVALID_CALLBACK;
} else {
datamark += r;
- ctx->opayloadoff += r;
- totallen += r;
+ ctx->opayloadoff += (uint64_t)r;
+ totallen += (size_t)r;
}
} else {
- if(totallen > 0) {
+ if (totallen > 0) {
break;
} else {
return WSLAY_ERR_WANT_WRITE;
@@ -169,44 +165,148 @@ ssize_t wslay_frame_send(wslay_frame_context_ptr ctx,
ssize_t r;
r = ctx->callbacks.send_callback(iocb->data, iocb->data_length, 0,
ctx->user_data);
- if(r > 0) {
- if((size_t)r > iocb->data_length) {
+ if (r > 0) {
+ if ((size_t)r > iocb->data_length) {
return WSLAY_ERR_INVALID_CALLBACK;
} else {
- ctx->opayloadoff += r;
- totallen = r;
+ ctx->opayloadoff += (uint64_t)r;
+ totallen = (size_t)r;
}
} else {
return WSLAY_ERR_WANT_WRITE;
}
}
}
- if(ctx->opayloadoff == ctx->opayloadlen) {
+ if (ctx->opayloadoff == ctx->opayloadlen) {
ctx->ostate = PREP_HEADER;
}
- return totallen;
+ return (ssize_t)totallen;
}
return WSLAY_ERR_INVALID_ARGUMENT;
}
-static void wslay_shift_ibuf(wslay_frame_context_ptr ctx)
-{
- ptrdiff_t len = ctx->ibuflimit-ctx->ibufmark;
- memmove(ctx->ibuf, ctx->ibufmark, len);
- ctx->ibuflimit = ctx->ibuf+len;
+ssize_t wslay_frame_write(wslay_frame_context_ptr ctx,
+ struct wslay_frame_iocb *iocb, uint8_t *buf,
+ size_t buflen, size_t *pwpayloadlen) {
+ uint8_t *buf_last = buf;
+ size_t i;
+ size_t hdlen;
+
+ *pwpayloadlen = 0;
+
+ if (iocb->data_length > iocb->payload_length) {
+ return WSLAY_ERR_INVALID_ARGUMENT;
+ }
+
+ switch (ctx->ostate) {
+ case PREP_HEADER:
+ case PREP_HEADER_NOBUF:
+ hdlen = 2;
+ if (iocb->payload_length < 126) {
+ /* nothing to do */
+ } else if (iocb->payload_length < (1 << 16)) {
+ hdlen += 2;
+ } else if (iocb->payload_length < (1ull << 63)) {
+ hdlen += 8;
+ }
+ if (iocb->mask) {
+ hdlen += 4;
+ }
+
+ if (buflen < hdlen) {
+ ctx->ostate = PREP_HEADER_NOBUF;
+ return 0;
+ }
+
+ memset(buf_last, 0, hdlen);
+ *buf_last |= (uint8_t)((uint8_t)(iocb->fin << 7) & 0x80u);
+ *buf_last |= (uint8_t)((uint8_t)(iocb->rsv << 4) & 0x70u);
+ /* Suppress stubborn gcc-10 warning */
+ *buf_last |= (uint8_t)((uint8_t)(iocb->opcode << 0) & 0xfu);
+ ++buf_last;
+ *buf_last |= (uint8_t)((uint8_t)(iocb->mask << 7) & 0x80u);
+ if (wslay_is_ctrl_frame(iocb->opcode) && iocb->payload_length > 125) {
+ return WSLAY_ERR_INVALID_ARGUMENT;
+ }
+ if (iocb->payload_length < 126) {
+ *buf_last |= (uint8_t)iocb->payload_length;
+ ++buf_last;
+ } else if (iocb->payload_length < (1 << 16)) {
+ uint16_t len = htons((uint16_t)iocb->payload_length);
+ *buf_last |= 126;
+ ++buf_last;
+ memcpy(buf_last, &len, 2);
+ buf_last += 2;
+ } else if (iocb->payload_length < (1ull << 63)) {
+ uint64_t len = hton64(iocb->payload_length);
+ *buf_last |= 127;
+ ++buf_last;
+ memcpy(buf_last, &len, 8);
+ buf_last += 8;
+ } else {
+ /* Too large payload length */
+ return WSLAY_ERR_INVALID_ARGUMENT;
+ }
+ if (iocb->mask) {
+ if (ctx->callbacks.genmask_callback(ctx->omaskkey, 4, ctx->user_data) !=
+ 0) {
+ return WSLAY_ERR_INVALID_CALLBACK;
+ } else {
+ ctx->omask = 1;
+ memcpy(buf_last, ctx->omaskkey, 4);
+ buf_last += 4;
+ }
+ }
+ ctx->ostate = SEND_PAYLOAD;
+ ctx->opayloadlen = iocb->payload_length;
+ ctx->opayloadoff = 0;
+
+ buflen -= (size_t)(buf_last - buf);
+ /* fall through */
+ case SEND_PAYLOAD:
+ if (iocb->data_length > 0) {
+ size_t writelen = wslay_min(buflen, iocb->data_length);
+
+ if (ctx->omask) {
+ for (i = 0; i < writelen; ++i) {
+ *buf_last++ =
+ iocb->data[i] ^ ctx->omaskkey[(ctx->opayloadoff + i) % 4];
+ }
+ } else {
+ memcpy(buf_last, iocb->data, writelen);
+ buf_last += writelen;
+ }
+
+ ctx->opayloadoff += writelen;
+ *pwpayloadlen = writelen;
+ }
+
+ if (ctx->opayloadoff == ctx->opayloadlen) {
+ ctx->ostate = PREP_HEADER;
+ }
+
+ return buf_last - buf;
+ default:
+ return WSLAY_ERR_INVALID_ARGUMENT;
+ }
+}
+
+static void wslay_shift_ibuf(wslay_frame_context_ptr ctx) {
+ ptrdiff_t len = ctx->ibuflimit - ctx->ibufmark;
+ memmove(ctx->ibuf, ctx->ibufmark, (size_t)len);
+ ctx->ibuflimit = ctx->ibuf + len;
ctx->ibufmark = ctx->ibuf;
}
-static ssize_t wslay_recv(wslay_frame_context_ptr ctx)
-{
+static ssize_t wslay_recv(wslay_frame_context_ptr ctx) {
ssize_t r;
- if(ctx->ibufmark != ctx->ibuf) {
+ if (ctx->ibufmark != ctx->ibuf) {
wslay_shift_ibuf(ctx);
}
- r = ctx->callbacks.recv_callback
- (ctx->ibuflimit, ctx->ibuf+sizeof(ctx->ibuf)-ctx->ibuflimit,
- 0, ctx->user_data);
- if(r > 0) {
+ r = ctx->callbacks.recv_callback(
+ ctx->ibuflimit, (size_t)(ctx->ibuf + sizeof(ctx->ibuf) - ctx->ibuflimit),
+ 0, ctx->user_data);
+ if (r > 0) {
ctx->ibuflimit += r;
} else {
r = WSLAY_ERR_WANT_READ;
@@ -217,17 +317,16 @@ static ssize_t wslay_recv(wslay_frame_context_ptr ctx)
#define WSLAY_AVAIL_IBUF(ctx) ((size_t)(ctx->ibuflimit - ctx->ibufmark))
ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx,
- struct wslay_frame_iocb *iocb)
-{
+ struct wslay_frame_iocb *iocb) {
ssize_t r;
- if(ctx->istate == RECV_HEADER1) {
+ if (ctx->istate == RECV_HEADER1) {
uint8_t fin, opcode, rsv, payloadlen;
- if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
- if((r = wslay_recv(ctx)) <= 0) {
+ if (WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
+ if ((r = wslay_recv(ctx)) <= 0) {
return r;
}
}
- if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
+ if (WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
return WSLAY_ERR_WANT_READ;
}
fin = (ctx->ibufmark[0] >> 7) & 1;
@@ -240,19 +339,19 @@ ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx,
ctx->imask = (ctx->ibufmark[0] >> 7) & 1;
payloadlen = ctx->ibufmark[0] & 0x7fu;
++ctx->ibufmark;
- if(wslay_is_ctrl_frame(opcode) && (payloadlen > 125 || !fin)) {
+ if (wslay_is_ctrl_frame(opcode) && (payloadlen > 125 || !fin)) {
return WSLAY_ERR_PROTO;
}
- if(payloadlen == 126) {
+ if (payloadlen == 126) {
ctx->istate = RECV_EXT_PAYLOADLEN;
ctx->ireqread = 2;
- } else if(payloadlen == 127) {
+ } else if (payloadlen == 127) {
ctx->istate = RECV_EXT_PAYLOADLEN;
ctx->ireqread = 8;
} else {
ctx->ipayloadlen = payloadlen;
ctx->ipayloadoff = 0;
- if(ctx->imask) {
+ if (ctx->imask) {
ctx->istate = RECV_MASKKEY;
ctx->ireqread = 4;
} else {
@@ -260,42 +359,41 @@ ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx,
}
}
}
- if(ctx->istate == RECV_EXT_PAYLOADLEN) {
- if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
- if((r = wslay_recv(ctx)) <= 0) {
+ if (ctx->istate == RECV_EXT_PAYLOADLEN) {
+ if (WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
+ if ((r = wslay_recv(ctx)) <= 0) {
return r;
}
- if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
+ if (WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
return WSLAY_ERR_WANT_READ;
}
}
ctx->ipayloadlen = 0;
ctx->ipayloadoff = 0;
- memcpy((uint8_t*)&ctx->ipayloadlen+(8-ctx->ireqread),
- ctx->ibufmark, ctx->ireqread);
+ memcpy((uint8_t *)&ctx->ipayloadlen + (8 - ctx->ireqread), ctx->ibufmark,
+ ctx->ireqread);
ctx->ipayloadlen = ntoh64(ctx->ipayloadlen);
ctx->ibufmark += ctx->ireqread;
- if(ctx->ireqread == 8) {
- if(ctx->ipayloadlen < (1 << 16) ||
- ctx->ipayloadlen & (1ull << 63)) {
+ if (ctx->ireqread == 8) {
+ if (ctx->ipayloadlen < (1 << 16) || ctx->ipayloadlen & (1ull << 63)) {
return WSLAY_ERR_PROTO;
}
- } else if(ctx->ipayloadlen < 126) {
+ } else if (ctx->ipayloadlen < 126) {
return WSLAY_ERR_PROTO;
}
- if(ctx->imask) {
+ if (ctx->imask) {
ctx->istate = RECV_MASKKEY;
ctx->ireqread = 4;
} else {
ctx->istate = RECV_PAYLOAD;
}
}
- if(ctx->istate == RECV_MASKKEY) {
- if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
- if((r = wslay_recv(ctx)) <= 0) {
+ if (ctx->istate == RECV_MASKKEY) {
+ if (WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
+ if ((r = wslay_recv(ctx)) <= 0) {
return r;
}
- if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
+ if (WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) {
return WSLAY_ERR_WANT_READ;
}
}
@@ -303,25 +401,25 @@ ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx,
ctx->ibufmark += 4;
ctx->istate = RECV_PAYLOAD;
}
- if(ctx->istate == RECV_PAYLOAD) {
+ if (ctx->istate == RECV_PAYLOAD) {
uint8_t *readlimit, *readmark;
- uint64_t rempayloadlen = ctx->ipayloadlen-ctx->ipayloadoff;
- if(WSLAY_AVAIL_IBUF(ctx) == 0 && rempayloadlen > 0) {
- if((r = wslay_recv(ctx)) <= 0) {
+ uint64_t rempayloadlen = ctx->ipayloadlen - ctx->ipayloadoff;
+ if (WSLAY_AVAIL_IBUF(ctx) == 0 && rempayloadlen > 0) {
+ if ((r = wslay_recv(ctx)) <= 0) {
return r;
}
}
readmark = ctx->ibufmark;
- readlimit = WSLAY_AVAIL_IBUF(ctx) < rempayloadlen ?
- ctx->ibuflimit : ctx->ibufmark+rempayloadlen;
- if(ctx->imask) {
- for(; ctx->ibufmark != readlimit;
- ++ctx->ibufmark, ++ctx->ipayloadoff) {
+ readlimit = WSLAY_AVAIL_IBUF(ctx) < rempayloadlen
+ ? ctx->ibuflimit
+ : ctx->ibufmark + rempayloadlen;
+ if (ctx->imask) {
+ for (; ctx->ibufmark != readlimit; ++ctx->ibufmark, ++ctx->ipayloadoff) {
ctx->ibufmark[0] ^= ctx->imaskkey[ctx->ipayloadoff % 4];
}
} else {
ctx->ibufmark = readlimit;
- ctx->ipayloadoff += readlimit-readmark;
+ ctx->ipayloadoff += (uint64_t)(readlimit - readmark);
}
iocb->fin = ctx->iom.fin;
iocb->rsv = ctx->iom.rsv;
@@ -329,12 +427,12 @@ ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx,
iocb->payload_length = ctx->ipayloadlen;
iocb->mask = ctx->imask;
iocb->data = readmark;
- iocb->data_length = ctx->ibufmark-readmark;
- if(ctx->ipayloadlen == ctx->ipayloadoff) {
+ iocb->data_length = (size_t)(ctx->ibufmark - readmark);
+ if (ctx->ipayloadlen == ctx->ipayloadoff) {
ctx->istate = RECV_HEADER1;
ctx->ireqread = 2;
}
- return iocb->data_length;
+ return (ssize_t)iocb->data_length;
}
return WSLAY_ERR_INVALID_ARGUMENT;
}