From: Andy Green Date: Sun, 24 Apr 2011 07:12:38 +0000 (+0100) Subject: handle new masking order and fixups X-Git-Tag: 1.2~96 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc15798f65f747a170aa40e9ed8ed37e0cb52189;p=profile%2Fivi%2Flibwebsockets.git handle new masking order and fixups Signed-off-by: Andy Green --- diff --git a/lib/parsers.c b/lib/parsers.c index fa41dfb..94b02fa 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -302,9 +302,6 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) * 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: @@ -427,7 +424,7 @@ handle_first: if (c & 0x70) { fprintf(stderr, - "Frame has extensions set illegally 1\n"); + "Frame has extensions set illegally 1 %02X\n", c); /* kill the connection */ return -1; } @@ -496,7 +493,7 @@ handle_first: wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; break; default: - wsi->rx_packet_length = c; + wsi->rx_packet_length = c & 0x7f; if (wsi->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; @@ -548,7 +545,7 @@ handle_first: if (wsi->ietf_spec_revision < 7) c = wsi->xor_mask(wsi, c); #if defined __LP64__ - wsi->rx_packet_length |= ((size_t)c)) << 48; + wsi->rx_packet_length |= ((size_t)c) << 48; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; break; @@ -557,7 +554,7 @@ handle_first: if (wsi->ietf_spec_revision < 7) c = wsi->xor_mask(wsi, c); #if defined __LP64__ - wsi->rx_packet_length |= ((size_t)c)) << 40; + wsi->rx_packet_length |= ((size_t)c) << 40; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; break; @@ -671,11 +668,12 @@ issue: wsi->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; + wsi->frame_mask_index = 0; break; case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - if (wsi->all_zero_nonce && wsi->ietf_spec_revision >= 5) + if (wsi->ietf_spec_revision < 4 || (wsi->all_zero_nonce && wsi->ietf_spec_revision >= 5)) wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + (wsi->rx_user_buffer_head++)] = c; else @@ -1070,8 +1068,14 @@ issue: break; case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->rx_user_buffer_head++)] = c; + if ((!wsi->this_frame_masked) || wsi->all_zero_nonce) + wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + + (wsi->rx_user_buffer_head++)] = c; + else + wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + + (wsi->rx_user_buffer_head++)] = + wsi->xor_mask(wsi, c); + if (--wsi->rx_packet_length == 0) { wsi->lws_rx_parse_state = LWS_RXPS_NEW; goto spill; @@ -1280,7 +1284,7 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, int shift = 7; struct lws_tokens eff_buf; int ret; - int masked_7 = wsi->mode == LWS_CONNMODE_WS_CLIENT; + int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT; unsigned char *dropmask = NULL; unsigned char is_masked_bit = 0; @@ -1325,16 +1329,16 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, /* frame type = text, length-free spam mode */ - buf[-1] = 0; - buf[len] = 0xff; /* EOT marker */ pre = 1; + buf[-pre] = 0; + buf[len] = 0xff; /* EOT marker */ post = 1; break; case 7: if (masked7) { - pre -= 4; - dropmask = &buf[pre]; + pre += 4; + dropmask = &buf[0 - pre]; is_masked_bit = 0x80; } /* fallthru */ @@ -1366,7 +1370,6 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, n = LWS_WS_OPCODE_04__CLOSE; else n = LWS_WS_OPCODE_07__CLOSE; - break; /* * v5 mandates the first byte of close packet @@ -1440,47 +1443,40 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, n |= 1 << 7; if (len < 126) { - buf[pre - 2] = n; - buf[pre - 1] = len | is_masked_bit; pre += 2; + buf[-pre] = n; + buf[-pre + 1] = len | is_masked_bit; } else { if (len < 65536) { - buf[pre - 4] = n; - buf[pre - 3] = 126 | is_masked_bit; - buf[pre - 2] = len >> 8; - buf[pre - 1] = len; pre += 4; + buf[-pre] = n; + buf[-pre + 1] = 126 | is_masked_bit; + buf[-pre + 2] = len >> 8; + buf[-pre + 3] = len; } else { - buf[pre - 10] = n; - buf[pre - 9] = 127 | is_masked_bit; + pre += 10; + buf[-pre] = n; + buf[-pre + 1] = 127 | is_masked_bit; #if defined __LP64__ - buf[pre - 8] = (len >> 56) & 0x7f; - buf[pre - 7] = len >> 48; - buf[pre - 6] = len >> 40; - buf[pre - 5] = len >> 32; + buf[-pre + 2] = (len >> 56) & 0x7f; + buf[-pre + 3] = len >> 48; + buf[-pre + 4] = len >> 40; + buf[-pre + 5] = len >> 32; #else - buf[pre - 8] = 0; - buf[pre - 7] = 0; - buf[pre - 6] = 0; - buf[pre - 5] = 0; + buf[-pre + 2] = 0; + buf[-pre + 3] = 0; + buf[-pre + 4] = 0; + buf[-pre + 5] = 0; #endif - buf[pre - 4] = len >> 24; - buf[pre - 3] = len >> 16; - buf[pre - 2] = len >> 8; - buf[pre - 1] = len; - pre += 10; + buf[-pre + 6] = len >> 24; + buf[-pre + 7] = len >> 16; + buf[-pre + 8] = len >> 8; + buf[-pre + 9] = len; } } break; } -#if 0 - for (n = 0; n < (len + pre + post); n++) - fprintf(stderr, "%02X ", buf[n - pre]); - - fprintf(stderr, "\n"); -#endif - /* * Deal with masking if we are in client -> server direction and * the protocol demands it @@ -1502,13 +1498,21 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, return 1; } - /* - * use the XOR masking against everything we send - * past the frame nonce - */ - for (n = 0; n < (len + pre + post); n++) - buf[n - pre] = wsi->xor_mask(wsi, buf[n - pre]); + if (wsi->ietf_spec_revision < 7) + /* + * use the XOR masking against everything we + * send past the frame key + */ + for (n = -pre; n < ((int)len + post); n++) + buf[n] = wsi->xor_mask(wsi, buf[n]); + else + /* + * in v7, just mask the payload + */ + for (n = 0; n < (int)len; n++) + dropmask[n + 4] = wsi->xor_mask(wsi, dropmask[n + 4]); + if (wsi->ietf_spec_revision < 7) { /* make space for the frame nonce in clear */ @@ -1522,19 +1526,35 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, memcpy(dropmask, wsi->frame_masking_nonce_04, 4); } else { - /* make space for the frame nonce in clear */ - pre += 4; + if (wsi->ietf_spec_revision < 7) { + + /* make space for the frame nonce in clear */ + pre += 4; - buf[0 - pre] = 0; - buf[1 - pre] = 0; - buf[2 - pre] = 0; - buf[3 - pre] = 0; + buf[0 - pre] = 0; + buf[1 - pre] = 0; + buf[2 - pre] = 0; + buf[3 - pre] = 0; + } else { + dropmask[0] = 0; + dropmask[1] = 0; + dropmask[2] = 0; + dropmask[3] = 0; + } } } send_raw: +#if 0 + fprintf(stderr, "send %ld: ", len + post); + for (n = -pre; n < ((int)len + post); n++) + fprintf(stderr, "%02X ", buf[n]); + + fprintf(stderr, "\n"); +#endif + if (protocol == LWS_WRITE_HTTP) { if (lws_issue_raw(wsi, (unsigned char *)buf - pre, len + pre + post))