From: Andy Green Date: Sat, 25 Mar 2017 00:42:35 +0000 (+0800) Subject: pmd: align client rx sm with server one X-Git-Tag: accepted/tizen/4.0/unified/20171012.191640~159 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7aadd143985a4293da363bebe4c432456e46b7a7;p=platform%2Fupstream%2Flibwebsockets.git pmd: align client rx sm with server one --- diff --git a/lib/client-parser.c b/lib/client-parser.c index ba1921b..9cb7403 100644 --- a/lib/client-parser.c +++ b/lib/client-parser.c @@ -21,6 +21,11 @@ #include "private-libwebsockets.h" +/* + * parsers.c: lws_rx_sm() needs to be roughly kept in + * sync with changes here, esp related to ext draining + */ + int lws_client_rx_sm(struct lws *wsi, unsigned char c) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; @@ -31,26 +36,19 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) unsigned char *pp; if (wsi->u.ws.rx_draining_ext) { - struct lws **w = &pt->rx_draining_ext_list; - lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__); assert(!c); eff_buf.token = NULL; eff_buf.token_len = 0; - wsi->u.ws.rx_draining_ext = 0; - /* remove us from context draining ext list */ - while (*w) { - if (*w == wsi) { - *w = wsi->u.ws.rx_draining_ext_list; - break; - } - w = &((*w)->u.ws.rx_draining_ext_list); - } - wsi->u.ws.rx_draining_ext_list = NULL; + lws_remove_wsi_from_draining_ext_list(wsi); rx_draining_ext = 1; + lwsl_debug("%s: doing draining flow\n", __func__); goto drain_extension; } + if (wsi->socket_is_permanently_unusable) + return -1; + switch (wsi->lws_rx_parse_state) { case LWS_RXPS_NEW: /* control frames (PING) may interrupt checkable sequences */ @@ -308,6 +306,9 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) assert(wsi->u.ws.rx_ubuf); + if (wsi->u.ws.rx_draining_ext) + goto drain_extension; + if (wsi->u.ws.this_frame_masked && !wsi->u.ws.all_zero_nonce) c ^= wsi->u.ws.mask[(wsi->u.ws.mask_idx++) & 3]; @@ -365,10 +366,14 @@ spill: wsi->u.ws.rx_ubuf_head); if (wsi->u.ws.rx_ubuf_head >= 2) { close_code = (pp[0] << 8) | pp[1]; - if (close_code < 1000 || close_code == 1004 || - close_code == 1005 || close_code == 1006 || - close_code == 1012 || close_code == 1013 || - close_code == 1014 || close_code == 1015 || + if (close_code < 1000 || + close_code == 1004 || + close_code == 1005 || + close_code == 1006 || + close_code == 1012 || + close_code == 1013 || + close_code == 1014 || + close_code == 1015 || (close_code >= 1016 && close_code < 3000) ) { pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff; @@ -381,6 +386,7 @@ spill: wsi->user_space, pp, wsi->u.ws.rx_ubuf_head)) return -1; + if (lws_partial_buffered(wsi)) /* * if we're in the middle of something, @@ -496,10 +502,14 @@ ping_drop: eff_buf.token_len = wsi->u.ws.rx_ubuf_head; drain_extension: + lwsl_ext("%s: passing %d to ext\n", __func__, eff_buf.token_len); + n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0); lwsl_ext("Ext RX returned %d\n", n); - if (n < 0) /* fail */ + if (n < 0) { + wsi->socket_is_permanently_unusable = 1; return -1; + } lwsl_ext("post inflate eff_buf len %d\n", eff_buf.token_len); @@ -515,7 +525,8 @@ drain_extension: goto utf8_fail; /* we are ending partway through utf-8 character? */ - if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final && wsi->u.ws.utf8 && !n) { + if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final && + wsi->u.ws.utf8 && !n) { lwsl_info("FINAL utf8 error\n"); utf8_fail: lwsl_info("utf8 error\n"); return -1; @@ -547,7 +558,9 @@ utf8_fail: lwsl_info("utf8 error\n"); wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list; pt->rx_draining_ext_list = wsi; lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__); - } + } else + lws_remove_wsi_from_draining_ext_list(wsi); + if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY || wsi->state == LWSS_AWAITING_CLOSE_ACK) goto already_done; diff --git a/lib/parsers.c b/lib/parsers.c index a38c3af..51b9218 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -954,7 +954,7 @@ LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi) { return wsi->u.ws.frame_is_binary; } -static void +void lws_remove_wsi_from_draining_ext_list(struct lws *wsi) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; @@ -972,6 +972,10 @@ lws_remove_wsi_from_draining_ext_list(struct lws *wsi) wsi->u.ws.rx_draining_ext_list = NULL; } +/* + * client-parser.c: lws_client_rx_sm() needs to be roughly kept in + * sync with changes here, esp related to ext draining + */ int lws_rx_sm(struct lws *wsi, unsigned char c) @@ -993,7 +997,7 @@ lws_rx_sm(struct lws *wsi, unsigned char c) eff_buf.token_len = 0; lws_remove_wsi_from_draining_ext_list(wsi); rx_draining_ext = 1; - lwsl_err("%s: doing draining flow\n", __func__); + lwsl_debug("%s: doing draining flow\n", __func__); goto drain_extension; } @@ -1445,9 +1449,8 @@ drain_extension: wsi->u.ws.rx_draining_ext = 1; wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list; pt->rx_draining_ext_list = wsi; - } else { + } else lws_remove_wsi_from_draining_ext_list(wsi); - } if (eff_buf.token_len > 0 || callback_action == LWS_CALLBACK_RECEIVE_PONG) { diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 3b4d7ff..8b66d60 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -2032,6 +2032,8 @@ lws_plat_service_periodic(struct lws_context *context); LWS_EXTERN int lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi, struct lws_pollfd *pfd); +LWS_EXTERN void +lws_remove_wsi_from_draining_ext_list(struct lws *wsi); LWS_EXTERN int lws_plat_context_early_init(void); LWS_EXTERN void