mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
add 07 support
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
5fd55cd3a9
commit
283d0a2046
2 changed files with 157 additions and 23 deletions
170
lib/parsers.c
170
lib/parsers.c
|
@ -297,6 +297,16 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_1;
|
||||
break;
|
||||
case 7:
|
||||
/*
|
||||
* no prepended frame key any more
|
||||
*/
|
||||
wsi->all_zero_nonce = 1;
|
||||
wsi->frame_masking_nonce_04[0] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
goto handle_first;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "libwebsocket_rx_sm doesn't know "
|
||||
"about spec version %d\n", wsi->ietf_spec_revision);
|
||||
|
@ -393,6 +403,8 @@ post_mask:
|
|||
*/
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_1:
|
||||
handle_first:
|
||||
|
||||
/*
|
||||
* 04 spec defines the opcode like this: (1, 2, and 3 are
|
||||
* "control frame" opcodes which may not be fragmented or
|
||||
|
@ -410,7 +422,8 @@ post_mask:
|
|||
* FIN (b7)
|
||||
*/
|
||||
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
|
||||
if (c & 0x70) {
|
||||
fprintf(stderr,
|
||||
|
@ -426,15 +439,19 @@ post_mask:
|
|||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN:
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
|
||||
if (c & 0x80) {
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
|
||||
if ((c & 0x80) && wsi->ietf_spec_revision < 7) {
|
||||
fprintf(stderr, "Frame has extensions "
|
||||
"set illegally 2\n");
|
||||
/* kill the connection */
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsi->this_frame_masked = !!(c & 0x80);
|
||||
|
||||
switch (c) {
|
||||
case 126:
|
||||
/* control frames are not allowed to have big lengths */
|
||||
|
@ -468,29 +485,40 @@ post_mask:
|
|||
break;
|
||||
default:
|
||||
wsi->rx_packet_length = c;
|
||||
wsi->lws_rx_parse_state =
|
||||
if (wsi->this_frame_masked)
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
|
||||
else
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN16_2:
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
|
||||
wsi->rx_packet_length = c << 8;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN16_1:
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
|
||||
wsi->rx_packet_length |= c;
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
if (wsi->this_frame_masked)
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
|
||||
else
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_8:
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
if (c & 0x80) {
|
||||
fprintf(stderr, "b63 of length must be zero\n");
|
||||
/* kill the connection */
|
||||
|
@ -505,45 +533,63 @@ post_mask:
|
|||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_7:
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
#if defined __LP64__
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c)) << 48;
|
||||
wsi->rx_packet_length |= ((size_t)c)) << 48;
|
||||
#endif
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_6:
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
#if defined __LP64__
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c)) << 40;
|
||||
wsi->rx_packet_length |= ((size_t)c)) << 40;
|
||||
#endif
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_5:
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
#if defined __LP64__
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c)) << 32;
|
||||
wsi->rx_packet_length |= ((size_t)c) << 32;
|
||||
#endif
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_4:
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c)) << 24;
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
wsi->rx_packet_length |= ((size_t)c) << 24;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_3:
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c)) << 16;
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
wsi->rx_packet_length |= ((size_t)c) << 16;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_2:
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c)) << 8;
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
wsi->rx_packet_length |= ((size_t)c) << 8;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_1:
|
||||
wsi->rx_packet_length |= ((size_t)wsi->xor_mask(wsi, c));
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
if (wsi->ietf_spec_revision < 7)
|
||||
c = wsi->xor_mask(wsi, c);
|
||||
wsi->rx_packet_length |= ((size_t)c);
|
||||
if (wsi->this_frame_masked)
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
|
||||
else
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_EAT_UNTIL_76_FF:
|
||||
|
@ -585,6 +631,37 @@ issue:
|
|||
case LWS_RXPS_PULLING_76_LENGTH:
|
||||
break;
|
||||
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
|
||||
wsi->frame_masking_nonce_04[0] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
|
||||
wsi->frame_masking_nonce_04[1] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
|
||||
wsi->frame_masking_nonce_04[2] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
|
||||
wsi->frame_masking_nonce_04[3] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
|
||||
|
||||
case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
|
||||
if (wsi->all_zero_nonce && wsi->ietf_spec_revision >= 5)
|
||||
wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
|
||||
|
@ -692,6 +769,7 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
/*
|
||||
* 04 logical framing from the spec (all this is masked when
|
||||
* incoming and has to be unmasked)
|
||||
|
@ -720,6 +798,10 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
* FIN. It's up to userland to buffer it up if it wants to see a
|
||||
* whole unfragmented block of the original size (which may be up to
|
||||
* 2^63 long!)
|
||||
*
|
||||
* Notice in v7 RSV4 is set to indicate 32-bit frame key is coming in
|
||||
* after length, unlike extension data which is now deprecated, this
|
||||
* does not impact the payload length calculation.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -751,6 +833,7 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "client_rx_sm doesn't know how "
|
||||
"to handle spec version %02d\n",
|
||||
|
@ -762,13 +845,15 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN:
|
||||
|
||||
if (c & 0x80) {
|
||||
if ((c & 0x80) && wsi->ietf_spec_revision < 7) {
|
||||
fprintf(stderr,
|
||||
"Frame has extensions set illegally 4\n");
|
||||
/* kill the connection */
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsi->this_frame_masked = !!(c & 0x80);
|
||||
|
||||
switch (c) {
|
||||
case 126:
|
||||
/* control frames are not allowed to have big lengths */
|
||||
|
@ -802,7 +887,11 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
break;
|
||||
default:
|
||||
wsi->rx_packet_length = c;
|
||||
wsi->lws_rx_parse_state =
|
||||
if (wsi->this_frame_masked)
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
|
||||
else
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
}
|
||||
|
@ -815,8 +904,12 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN16_1:
|
||||
wsi->rx_packet_length |= c;
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
if (wsi->this_frame_masked)
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
|
||||
else
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_8:
|
||||
|
@ -871,6 +964,39 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
|
||||
case LWS_RXPS_04_FRAME_HDR_LEN64_1:
|
||||
wsi->rx_packet_length |= (size_t)c;
|
||||
if (wsi->this_frame_masked)
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
|
||||
else
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
|
||||
wsi->frame_masking_nonce_04[0] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
|
||||
wsi->frame_masking_nonce_04[1] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
|
||||
wsi->frame_masking_nonce_04[2] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
|
||||
break;
|
||||
|
||||
case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
|
||||
wsi->frame_masking_nonce_04[3] = c;
|
||||
if (c)
|
||||
wsi->all_zero_nonce = 0;
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
break;
|
||||
|
|
|
@ -109,7 +109,7 @@ static inline void debug(const char *format, ...)
|
|||
#define MAX_BROADCAST_PAYLOAD 2048
|
||||
#define LWS_MAX_PROTOCOLS 10
|
||||
#define LWS_MAX_EXTENSIONS_ACTIVE 10
|
||||
#define SPEC_LATEST_SUPPORTED 6
|
||||
#define SPEC_LATEST_SUPPORTED 7
|
||||
|
||||
#define MAX_WEBSOCKET_04_KEY_LEN 128
|
||||
#define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
|
||||
|
@ -166,6 +166,11 @@ enum lws_rx_parse_state {
|
|||
LWS_RXPS_04_FRAME_HDR_LEN64_2,
|
||||
LWS_RXPS_04_FRAME_HDR_LEN64_1,
|
||||
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_1,
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_2,
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_3,
|
||||
LWS_RXPS_07_COLLECT_FRAME_KEY_4,
|
||||
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED
|
||||
};
|
||||
|
||||
|
@ -279,6 +284,9 @@ struct libwebsocket {
|
|||
|
||||
enum lws_close_status close_reason;
|
||||
|
||||
/* 07 specific */
|
||||
char this_frame_masked;
|
||||
|
||||
/* client support */
|
||||
char initial_handshake_hash_base64[30];
|
||||
enum connection_mode mode;
|
||||
|
|
Loading…
Add table
Reference in a new issue