2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #include "private-lib-core.h"
25 * parsers.c: lws_ws_rx_sm() needs to be roughly kept in
26 * sync with changes here, esp related to ext draining
29 int lws_ws_client_rx_sm(struct lws *wsi, unsigned char c)
31 struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
32 int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
33 struct lws_ext_pm_deflate_rx_ebufs pmdrx;
34 unsigned short close_code;
37 #if !defined(LWS_WITHOUT_EXTENSIONS)
38 int rx_draining_ext = 0;
41 pmdrx.eb_in.token = NULL;
43 pmdrx.eb_out.token = NULL;
46 #if !defined(LWS_WITHOUT_EXTENSIONS)
47 if (wsi->ws->rx_draining_ext) {
50 lws_remove_wsi_from_draining_ext_list(wsi);
52 lwsl_debug("%s: doing draining flow\n", __func__);
58 if (wsi->socket_is_permanently_unusable)
61 switch (wsi->lws_rx_parse_state) {
63 /* control frames (PING) may interrupt checkable sequences */
64 wsi->ws->defeat_check_utf8 = 0;
66 switch (wsi->ws->ietf_spec_revision) {
68 wsi->ws->opcode = c & 0xf;
69 /* revisit if an extension wants them... */
70 switch (wsi->ws->opcode) {
71 case LWSWSOPC_TEXT_FRAME:
72 wsi->ws->rsv_first_msg = (c & 0x70);
73 #if !defined(LWS_WITHOUT_EXTENSIONS)
75 * set the expectation that we will have to
76 * fake up the zlib trailer to the inflator for
79 wsi->ws->pmd_trailer_application = !!(c & 0x40);
81 wsi->ws->continuation_possible = 1;
82 wsi->ws->check_utf8 = lws_check_opt(
83 wsi->context->options,
84 LWS_SERVER_OPTION_VALIDATE_UTF8);
86 wsi->ws->first_fragment = 1;
88 case LWSWSOPC_BINARY_FRAME:
89 wsi->ws->rsv_first_msg = (c & 0x70);
90 #if !defined(LWS_WITHOUT_EXTENSIONS)
92 * set the expectation that we will have to
93 * fake up the zlib trailer to the inflator for
96 wsi->ws->pmd_trailer_application = !!(c & 0x40);
98 wsi->ws->check_utf8 = 0;
99 wsi->ws->continuation_possible = 1;
100 wsi->ws->first_fragment = 1;
102 case LWSWSOPC_CONTINUATION:
103 if (!wsi->ws->continuation_possible) {
104 lwsl_info("disordered continuation\n");
107 wsi->ws->first_fragment = 0;
110 wsi->ws->check_utf8 = 0;
123 lwsl_info("illegal opcode\n");
126 wsi->ws->defeat_check_utf8 = 1;
129 wsi->ws->rsv = (c & 0x70);
130 /* revisit if an extension wants them... */
132 #if !defined(LWS_WITHOUT_EXTENSIONS)
133 !wsi->ws->count_act_ext &&
136 lwsl_info("illegal rsv bits set\n");
139 wsi->ws->final = !!((c >> 7) & 1);
140 lwsl_ext("%s: This RX frame Final %d\n", __func__,
143 if (wsi->ws->owed_a_fin &&
144 (wsi->ws->opcode == LWSWSOPC_TEXT_FRAME ||
145 wsi->ws->opcode == LWSWSOPC_BINARY_FRAME)) {
146 lwsl_info("hey you owed us a FIN\n");
149 if ((!(wsi->ws->opcode & 8)) && wsi->ws->final) {
150 wsi->ws->continuation_possible = 0;
151 wsi->ws->owed_a_fin = 0;
154 if ((wsi->ws->opcode & 8) && !wsi->ws->final) {
155 lwsl_info("control msg can't be fragmented\n");
159 wsi->ws->owed_a_fin = 1;
161 switch (wsi->ws->opcode) {
162 case LWSWSOPC_TEXT_FRAME:
163 case LWSWSOPC_BINARY_FRAME:
164 wsi->ws->frame_is_binary = wsi->ws->opcode ==
165 LWSWSOPC_BINARY_FRAME;
168 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
172 lwsl_err("unknown spec version %02d\n",
173 wsi->ws->ietf_spec_revision);
178 case LWS_RXPS_04_FRAME_HDR_LEN:
180 wsi->ws->this_frame_masked = !!(c & 0x80);
184 /* control frames are not allowed to have big lengths */
185 if (wsi->ws->opcode & 8)
186 goto illegal_ctl_length;
187 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
190 /* control frames are not allowed to have big lengths */
191 if (wsi->ws->opcode & 8)
192 goto illegal_ctl_length;
193 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
196 wsi->ws->rx_packet_length = c & 0x7f;
197 if (wsi->ws->this_frame_masked)
198 wsi->lws_rx_parse_state =
199 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
201 if (wsi->ws->rx_packet_length) {
202 wsi->lws_rx_parse_state =
203 LWS_RXPS_WS_FRAME_PAYLOAD;
205 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
213 case LWS_RXPS_04_FRAME_HDR_LEN16_2:
214 wsi->ws->rx_packet_length = c << 8;
215 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
218 case LWS_RXPS_04_FRAME_HDR_LEN16_1:
219 wsi->ws->rx_packet_length |= c;
220 if (wsi->ws->this_frame_masked)
221 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1;
223 if (wsi->ws->rx_packet_length)
224 wsi->lws_rx_parse_state =
225 LWS_RXPS_WS_FRAME_PAYLOAD;
227 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
233 case LWS_RXPS_04_FRAME_HDR_LEN64_8:
235 lwsl_warn("b63 of length must be zero\n");
236 /* kill the connection */
240 wsi->ws->rx_packet_length = ((size_t)c) << 56;
242 wsi->ws->rx_packet_length = 0;
244 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
247 case LWS_RXPS_04_FRAME_HDR_LEN64_7:
249 wsi->ws->rx_packet_length |= ((size_t)c) << 48;
251 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
254 case LWS_RXPS_04_FRAME_HDR_LEN64_6:
256 wsi->ws->rx_packet_length |= ((size_t)c) << 40;
258 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
261 case LWS_RXPS_04_FRAME_HDR_LEN64_5:
263 wsi->ws->rx_packet_length |= ((size_t)c) << 32;
265 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
268 case LWS_RXPS_04_FRAME_HDR_LEN64_4:
269 wsi->ws->rx_packet_length |= ((size_t)c) << 24;
270 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
273 case LWS_RXPS_04_FRAME_HDR_LEN64_3:
274 wsi->ws->rx_packet_length |= ((size_t)c) << 16;
275 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
278 case LWS_RXPS_04_FRAME_HDR_LEN64_2:
279 wsi->ws->rx_packet_length |= ((size_t)c) << 8;
280 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
283 case LWS_RXPS_04_FRAME_HDR_LEN64_1:
284 wsi->ws->rx_packet_length |= (size_t)c;
285 if (wsi->ws->this_frame_masked)
286 wsi->lws_rx_parse_state =
287 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
289 if (wsi->ws->rx_packet_length)
290 wsi->lws_rx_parse_state =
291 LWS_RXPS_WS_FRAME_PAYLOAD;
293 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
299 case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
300 wsi->ws->mask[0] = c;
302 wsi->ws->all_zero_nonce = 0;
303 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
306 case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
307 wsi->ws->mask[1] = c;
309 wsi->ws->all_zero_nonce = 0;
310 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
313 case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
314 wsi->ws->mask[2] = c;
316 wsi->ws->all_zero_nonce = 0;
317 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
320 case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
321 wsi->ws->mask[3] = c;
323 wsi->ws->all_zero_nonce = 0;
325 if (wsi->ws->rx_packet_length)
326 wsi->lws_rx_parse_state =
327 LWS_RXPS_WS_FRAME_PAYLOAD;
329 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
334 case LWS_RXPS_WS_FRAME_PAYLOAD:
336 assert(wsi->ws->rx_ubuf);
337 #if !defined(LWS_WITHOUT_EXTENSIONS)
338 if (wsi->ws->rx_draining_ext)
339 goto drain_extension;
341 if (wsi->ws->this_frame_masked && !wsi->ws->all_zero_nonce)
342 c ^= wsi->ws->mask[(wsi->ws->mask_idx++) & 3];
345 * unmask and collect the payload body in
346 * rx_ubuf_head + LWS_PRE
349 wsi->ws->rx_ubuf[LWS_PRE + (wsi->ws->rx_ubuf_head++)] = c;
351 if (--wsi->ws->rx_packet_length == 0) {
352 /* spill because we have the whole frame */
353 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
354 lwsl_debug("%s: spilling as we have the whole frame\n",
360 * if there's no protocol max frame size given, we are
361 * supposed to default to context->pt_serv_buf_size
363 if (!wsi->protocol->rx_buffer_size &&
364 wsi->ws->rx_ubuf_head != wsi->context->pt_serv_buf_size)
367 if (wsi->protocol->rx_buffer_size &&
368 wsi->ws->rx_ubuf_head != wsi->protocol->rx_buffer_size)
371 /* spill because we filled our rx buffer */
373 lwsl_debug("%s: spilling as we filled our rx buffer\n",
380 * is this frame a control packet we should take care of at this
381 * layer? If so service it and hide it from the user callback
384 switch (wsi->ws->opcode) {
386 pp = &wsi->ws->rx_ubuf[LWS_PRE];
387 if (lws_check_opt(wsi->context->options,
388 LWS_SERVER_OPTION_VALIDATE_UTF8) &&
389 wsi->ws->rx_ubuf_head > 2 &&
390 lws_check_utf8(&wsi->ws->utf8, pp + 2,
391 wsi->ws->rx_ubuf_head - 2))
394 /* is this an acknowledgment of our close? */
395 if (lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK) {
397 * fine he has told us he is closing too, let's
400 lwsl_parser("seen server's close ack\n");
404 lwsl_parser("client sees server close len = %d\n",
405 wsi->ws->rx_ubuf_head);
406 if (wsi->ws->rx_ubuf_head >= 2) {
407 close_code = (pp[0] << 8) | pp[1];
408 if (close_code < 1000 ||
409 close_code == 1004 ||
410 close_code == 1005 ||
411 close_code == 1006 ||
412 close_code == 1012 ||
413 close_code == 1013 ||
414 close_code == 1014 ||
415 close_code == 1015 ||
416 (close_code >= 1016 && close_code < 3000)
418 pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff;
419 pp[1] = LWS_CLOSE_STATUS_PROTOCOL_ERR & 0xff;
422 if (user_callback_handle_rxflow(
423 wsi->protocol->callback, wsi,
424 LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
426 wsi->ws->rx_ubuf_head))
429 memcpy(wsi->ws->ping_payload_buf + LWS_PRE, pp,
430 wsi->ws->rx_ubuf_head);
431 wsi->ws->close_in_ping_buffer_len =
432 wsi->ws->rx_ubuf_head;
434 lwsl_info("%s: scheduling return close as ack\n",
436 __lws_change_pollfd(wsi, LWS_POLLIN, 0);
437 lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_SEND, 3);
438 wsi->waiting_to_send_close_frame = 1;
439 wsi->close_needs_ack = 0;
440 lwsi_set_state(wsi, LRS_WAITING_TO_SEND_CLOSE);
441 lws_callback_on_writable(wsi);
446 lwsl_info("received %d byte ping, sending pong\n",
447 wsi->ws->rx_ubuf_head);
449 /* he set a close reason on this guy, ignore PING */
450 if (wsi->ws->close_in_ping_buffer_len)
453 if (wsi->ws->ping_pending_flag) {
455 * there is already a pending ping payload
456 * we should just log and drop
458 lwsl_parser("DROP PING since one pending\n");
462 /* control packets can only be < 128 bytes long */
463 if (wsi->ws->rx_ubuf_head > 128 - 3) {
464 lwsl_parser("DROP PING payload too large\n");
468 /* stash the pong payload */
469 memcpy(wsi->ws->ping_payload_buf + LWS_PRE,
470 &wsi->ws->rx_ubuf[LWS_PRE],
471 wsi->ws->rx_ubuf_head);
473 wsi->ws->ping_payload_len = wsi->ws->rx_ubuf_head;
474 wsi->ws->ping_pending_flag = 1;
476 /* get it sent as soon as possible */
477 lws_callback_on_writable(wsi);
479 wsi->ws->rx_ubuf_head = 0;
484 lwsl_info("%s: client %p received pong\n", __func__, wsi);
485 lwsl_hexdump(&wsi->ws->rx_ubuf[LWS_PRE],
486 wsi->ws->rx_ubuf_head);
488 if (wsi->ws->await_pong) {
489 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
490 wsi->ws->await_pong = 0;
493 * prepare to send the ping again if nothing
494 * sent to countermand it
497 __lws_sul_insert(&pt->pt_sul_owner,
499 (lws_usec_t)wsi->context->ws_ping_pong_interval *
503 callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
506 case LWSWSOPC_CONTINUATION:
507 case LWSWSOPC_TEXT_FRAME:
508 case LWSWSOPC_BINARY_FRAME:
512 /* not handled or failed */
513 lwsl_ext("Unhandled ext opc 0x%x\n", wsi->ws->opcode);
514 wsi->ws->rx_ubuf_head = 0;
520 * No it's real payload, pass it up to the user callback.
522 * We have been statefully collecting it in the
523 * LWS_RXPS_WS_FRAME_PAYLOAD clause above.
525 * It's nicely buffered with the pre-padding taken care of
526 * so it can be sent straight out again using lws_write.
528 * However, now we have a chunk of it, we want to deal with it
529 * all here. Since this may be input to permessage-deflate and
530 * there are block limits on that for input and output, we may
536 pmdrx.eb_in.token = &wsi->ws->rx_ubuf[LWS_PRE];
537 pmdrx.eb_in.len = wsi->ws->rx_ubuf_head;
539 /* for the non-pm-deflate case */
541 pmdrx.eb_out = pmdrx.eb_in;
543 lwsl_debug("%s: starting disbursal of %d deframed rx\n",
544 __func__, wsi->ws->rx_ubuf_head);
546 #if !defined(LWS_WITHOUT_EXTENSIONS)
551 // lwsl_notice("%s: pmdrx.eb_in.len: %d\n", __func__,
552 // (int)pmdrx.eb_in.len);
554 n = PMDR_DID_NOTHING;
556 #if !defined(LWS_WITHOUT_EXTENSIONS)
557 lwsl_ext("%s: +++ passing %d %p to ext\n", __func__,
558 pmdrx.eb_in.len, pmdrx.eb_in.token);
560 n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX,
562 lwsl_ext("Ext RX returned %d\n", n);
564 wsi->socket_is_permanently_unusable = 1;
567 if (n == PMDR_DID_NOTHING)
570 lwsl_ext("%s: post inflate ebuf in len %d / out len %d\n",
571 __func__, pmdrx.eb_in.len, pmdrx.eb_out.len);
573 #if !defined(LWS_WITHOUT_EXTENSIONS)
574 if (rx_draining_ext && !pmdrx.eb_out.len) {
575 lwsl_debug(" --- ending drain on 0 read result\n");
579 if (n == PMDR_HAS_PENDING) { /* 1 means stuff to drain */
580 /* extension had more... main loop will come back */
581 lwsl_ext("%s: adding to draining ext list\n",
583 lws_add_wsi_to_draining_ext_list(wsi);
585 lwsl_ext("%s: removing from draining ext list\n",
587 lws_remove_wsi_from_draining_ext_list(wsi);
589 rx_draining_ext = wsi->ws->rx_draining_ext;
592 if (wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) {
594 if (lws_check_utf8(&wsi->ws->utf8,
597 lws_close_reason(wsi,
598 LWS_CLOSE_STATUS_INVALID_PAYLOAD,
599 (uint8_t *)"bad utf8", 8);
603 /* we are ending partway through utf-8 character? */
604 if (!wsi->ws->rx_packet_length &&
605 wsi->ws->final && wsi->ws->utf8
606 #if !defined(LWS_WITHOUT_EXTENSIONS)
607 /* if ext not negotiated, going to be UNKNOWN */
608 && (n == PMDR_EMPTY_FINAL || n == PMDR_UNKNOWN)
611 lwsl_info("FINAL utf8 error\n");
612 lws_close_reason(wsi,
613 LWS_CLOSE_STATUS_INVALID_PAYLOAD,
614 (uint8_t *)"partial utf8", 12);
616 lwsl_info("utf8 error\n");
617 lwsl_hexdump_info(pmdrx.eb_out.token,
624 if (pmdrx.eb_out.len < 0 &&
625 callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG)
628 if (!pmdrx.eb_out.token)
631 pmdrx.eb_out.token[pmdrx.eb_out.len] = '\0';
633 if (!wsi->protocol->callback)
636 if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
637 lwsl_info("Client doing pong callback\n");
639 #if !defined(LWS_WITHOUT_EXTENSIONS)
640 if (n == PMDR_HAS_PENDING)
641 /* extension had more... main loop will come back
642 * we want callback to be done with this set, if so,
643 * because lws_is_final() hides it was final until the
646 lws_add_wsi_to_draining_ext_list(wsi);
648 lws_remove_wsi_from_draining_ext_list(wsi);
651 if (lwsi_state(wsi) == LRS_RETURNED_CLOSE ||
652 lwsi_state(wsi) == LRS_WAITING_TO_SEND_CLOSE ||
653 lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK)
656 /* if pmd not enabled, in == out */
658 if (n == PMDR_DID_NOTHING
659 #if !defined(LWS_WITHOUT_EXTENSIONS)
663 pmdrx.eb_in.len -= pmdrx.eb_out.len;
665 m = wsi->protocol->callback(wsi,
666 (enum lws_callback_reasons)callback_action,
667 wsi->user_space, pmdrx.eb_out.token,
670 wsi->ws->first_fragment = 0;
672 lwsl_debug("%s: bulk ws rx: inp used %d, output %d\n",
673 __func__, wsi->ws->rx_ubuf_head,
676 /* if user code wants to close, let caller know */
680 } while (pmdrx.eb_in.len
681 #if !defined(LWS_WITHOUT_EXTENSIONS)
687 wsi->ws->rx_ubuf_head = 0;
690 lwsl_err("client rx illegal state\n");
697 lwsl_warn("Control frame asking for extended length is illegal\n");
699 /* kill the connection */