wsockd: implement reading of small and large frames (but not huge frames)
This commit is contained in:
parent
53c0462146
commit
d3f01ce7bf
1 changed files with 120 additions and 0 deletions
120
wsockd/wsockd.c
120
wsockd/wsockd.c
|
@ -521,6 +521,124 @@ cleanup_bad_message(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
|
||||||
rb_close(ctlb->F[i]);
|
rb_close(ctlb->F[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ws_frame_unmask(char *msg, int length, uint8_t maskval[WEBSOCKET_MASK_LENGTH])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
msg[i] = msg[i] ^ maskval[i % 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
conn_mod_process_frame(conn_t *conn, ws_frame_hdr_t *hdr, int masked)
|
||||||
|
{
|
||||||
|
char msg[WEBSOCKET_MAX_UNEXTENDED_PAYLOAD_DATA_LENGTH];
|
||||||
|
uint8_t maskval[WEBSOCKET_MASK_LENGTH];
|
||||||
|
int dolen;
|
||||||
|
|
||||||
|
/* if we're masked, we get to collect the masking key for this frame */
|
||||||
|
if (masked)
|
||||||
|
{
|
||||||
|
dolen = rb_rawbuf_get(conn->modbuf_in, maskval, sizeof(maskval));
|
||||||
|
if (!dolen)
|
||||||
|
{
|
||||||
|
close_conn(conn, WAIT_PLAIN, "websocket error: fault unpacking unmask key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dolen = rb_rawbuf_get(conn->modbuf_in, msg, hdr->payload_length_mask);
|
||||||
|
if (!dolen)
|
||||||
|
{
|
||||||
|
close_conn(conn, WAIT_PLAIN, "websocket error: fault unpacking message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (masked)
|
||||||
|
ws_frame_unmask(msg, dolen, maskval);
|
||||||
|
|
||||||
|
rb_linebuf_parse(&conn->plainbuf_out, msg, dolen, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
conn_mod_process_large(conn_t *conn, ws_frame_hdr_t *hdr, int masked)
|
||||||
|
{
|
||||||
|
char msg[READBUF_SIZE];
|
||||||
|
uint16_t msglen;
|
||||||
|
uint8_t maskval[WEBSOCKET_MASK_LENGTH];
|
||||||
|
int dolen;
|
||||||
|
|
||||||
|
memset(msg, 0, sizeof msg);
|
||||||
|
|
||||||
|
dolen = rb_rawbuf_get(conn->modbuf_in, &msglen, sizeof(msglen));
|
||||||
|
if (!dolen)
|
||||||
|
{
|
||||||
|
close_conn(conn, WAIT_PLAIN, "websocket error: fault unpacking message size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msglen = ntohs(msglen);
|
||||||
|
|
||||||
|
if (masked)
|
||||||
|
{
|
||||||
|
dolen = rb_rawbuf_get(conn->modbuf_in, maskval, sizeof(maskval));
|
||||||
|
if (!dolen)
|
||||||
|
{
|
||||||
|
close_conn(conn, WAIT_PLAIN, "websocket error: fault unpacking unmask key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dolen = rb_rawbuf_get(conn->modbuf_in, msg, msglen);
|
||||||
|
if (!dolen)
|
||||||
|
{
|
||||||
|
close_conn(conn, WAIT_PLAIN, "websocket error: fault unpacking message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (masked)
|
||||||
|
ws_frame_unmask(msg, dolen, maskval);
|
||||||
|
|
||||||
|
rb_linebuf_parse(&conn->plainbuf_out, msg, dolen, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
conn_mod_process_huge(conn_t *conn, ws_frame_hdr_t *hdr, int masked)
|
||||||
|
{
|
||||||
|
/* XXX implement me */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
conn_mod_process(conn_t *conn)
|
||||||
|
{
|
||||||
|
ws_frame_hdr_t hdr;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int masked;
|
||||||
|
int dolen = rb_rawbuf_get(conn->modbuf_in, &hdr, sizeof(hdr));
|
||||||
|
if (dolen != sizeof(hdr))
|
||||||
|
break;
|
||||||
|
|
||||||
|
masked = (hdr.payload_length_mask >> 7) == 1;
|
||||||
|
|
||||||
|
hdr.payload_length_mask &= 0x7f;
|
||||||
|
switch (hdr.payload_length_mask)
|
||||||
|
{
|
||||||
|
case 126:
|
||||||
|
conn_mod_process_large(conn, &hdr, masked);
|
||||||
|
break;
|
||||||
|
case 127:
|
||||||
|
conn_mod_process_huge(conn, &hdr, masked);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
conn_mod_process_frame(conn, &hdr, masked);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
conn_mod_handshake_process(conn_t *conn)
|
conn_mod_handshake_process(conn_t *conn)
|
||||||
{
|
{
|
||||||
|
@ -625,6 +743,8 @@ conn_mod_read_cb(rb_fde_t *fd, void *data)
|
||||||
rb_rawbuf_append(conn->modbuf_in, inbuf, length);
|
rb_rawbuf_append(conn->modbuf_in, inbuf, length);
|
||||||
if (!IsKeyed(conn))
|
if (!IsKeyed(conn))
|
||||||
conn_mod_handshake_process(conn);
|
conn_mod_handshake_process(conn);
|
||||||
|
else
|
||||||
|
conn_mod_process(conn);
|
||||||
|
|
||||||
if (length < sizeof(inbuf))
|
if (length < sizeof(inbuf))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue