pmd: align client rx sm with server one
authorAndy Green <andy@warmcat.com>
Sat, 25 Mar 2017 00:42:35 +0000 (08:42 +0800)
committerAndy Green <andy@warmcat.com>
Sat, 25 Mar 2017 00:48:23 +0000 (08:48 +0800)
lib/client-parser.c
lib/parsers.c
lib/private-libwebsockets.h

index ba1921b..9cb7403 100644 (file)
 
 #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;
index a38c3af..51b9218 100644 (file)
@@ -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) {
index 3b4d7ff..8b66d60 100644 (file)
@@ -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