Imported Upstream version 3.2.0
[platform/upstream/libwebsockets.git] / lib / roles / ws / server-ws.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com>
5  *
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.
10  *
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.
15  *
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,
19  *  MA  02110-1301  USA
20  */
21
22 #include <core/private.h>
23
24 #define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
25
26 #if !defined(LWS_WITHOUT_EXTENSIONS)
27 static int
28 lws_extension_server_handshake(struct lws *wsi, char **p, int budget)
29 {
30         struct lws_context *context = wsi->context;
31         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
32         char ext_name[64], *args, *end = (*p) + budget - 1;
33         const struct lws_ext_options *opts, *po;
34         const struct lws_extension *ext;
35         struct lws_ext_option_arg oa;
36         int n, m, more = 1;
37         int ext_count = 0;
38         char ignore;
39         char *c;
40
41         /*
42          * Figure out which extensions the client has that we want to
43          * enable on this connection, and give him back the list
44          */
45         if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS))
46                 return 0;
47
48         /*
49          * break down the list of client extensions
50          * and go through them
51          */
52
53         if (lws_hdr_copy(wsi, (char *)pt->serv_buf, context->pt_serv_buf_size,
54                          WSI_TOKEN_EXTENSIONS) < 0)
55                 return 1;
56
57         c = (char *)pt->serv_buf;
58         lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c);
59         wsi->ws->count_act_ext = 0;
60         ignore = 0;
61         n = 0;
62         args = NULL;
63
64         /*
65          * We may get a simple request
66          *
67          * Sec-WebSocket-Extensions: permessage-deflate
68          *
69          * or an elaborated one with requested options
70          *
71          * Sec-WebSocket-Extensions: permessage-deflate; \
72          *                           server_no_context_takeover; \
73          *                           client_no_context_takeover
74          */
75
76         while (more) {
77
78                 if (c >= (char *)pt->serv_buf + 255)
79                         return -1;
80
81                 if (*c && (*c != ',' && *c != '\t')) {
82                         if (*c == ';') {
83                                 ignore = 1;
84                                 if (!args)
85                                         args = c + 1;
86                         }
87                         if (ignore || *c == ' ') {
88                                 c++;
89                                 continue;
90                         }
91                         ext_name[n] = *c++;
92                         if (n < (int)sizeof(ext_name) - 1)
93                                 n++;
94                         continue;
95                 }
96                 ext_name[n] = '\0';
97
98                 ignore = 0;
99                 if (!*c)
100                         more = 0;
101                 else {
102                         c++;
103                         if (!n)
104                                 continue;
105                 }
106
107                 while (args && *args == ' ')
108                         args++;
109
110                 /* check a client's extension against our support */
111
112                 ext = wsi->vhost->ws.extensions;
113
114                 while (ext && ext->callback) {
115
116                         if (strcmp(ext_name, ext->name)) {
117                                 ext++;
118                                 continue;
119                         }
120
121                         /*
122                          * oh, we do support this one he asked for... but let's
123                          * confirm he only gave it once
124                          */
125                         for (m = 0; m < wsi->ws->count_act_ext; m++)
126                                 if (wsi->ws->active_extensions[m] == ext) {
127                                         lwsl_info("ext mentioned twice\n");
128                                         return 1; /* shenanigans */
129                                 }
130
131                         /*
132                          * ask user code if it's OK to apply it on this
133                          * particular connection + protocol
134                          */
135                         m = (wsi->protocol->callback)(wsi,
136                                 LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
137                                 wsi->user_space, ext_name, 0);
138
139                         /*
140                          * zero return from callback means go ahead and allow
141                          * the extension, it's what we get if the callback is
142                          * unhandled
143                          */
144                         if (m) {
145                                 ext++;
146                                 continue;
147                         }
148
149                         /* apply it */
150
151                         ext_count++;
152
153                         /* instantiate the extension on this conn */
154
155                         wsi->ws->active_extensions[wsi->ws->count_act_ext] = ext;
156
157                         /* allow him to construct his context */
158
159                         if (ext->callback(lws_get_context(wsi), ext, wsi,
160                                           LWS_EXT_CB_CONSTRUCT,
161                                           (void *)&wsi->ws->act_ext_user[
162                                                         wsi->ws->count_act_ext],
163                                           (void *)&opts, 0)) {
164                                 lwsl_info("ext %s failed construction\n",
165                                             ext_name);
166                                 ext_count--;
167                                 ext++;
168
169                                 continue;
170                         }
171
172                         if (ext_count > 1)
173                                 *(*p)++ = ',';
174                         else
175                                 LWS_CPYAPP(*p,
176                                           "\x0d\x0aSec-WebSocket-Extensions: ");
177                         *p += lws_snprintf(*p, (end - *p), "%s", ext_name);
178
179                         /*
180                          * The client may send a bunch of different option
181                          * sets for the same extension, we are supposed to
182                          * pick one we like the look of.  The option sets are
183                          * separated by comma.
184                          *
185                          * Actually we just either accept the first one or
186                          * nothing.
187                          *
188                          * Go through the options trying to apply the
189                          * recognized ones
190                          */
191
192                         lwsl_info("ext args %s\n", args);
193
194                         while (args && *args && *args != ',') {
195                                 while (*args == ' ')
196                                         args++;
197                                 po = opts;
198                                 while (po->name) {
199                                         /* only support arg-less options... */
200                                         if (po->type != EXTARG_NONE ||
201                                             strncmp(args, po->name,
202                                                     strlen(po->name))) {
203                                                 po++;
204                                                 continue;
205                                         }
206                                         oa.option_name = NULL;
207                                         oa.option_index = (int)(po - opts);
208                                         oa.start = NULL;
209                                         oa.len = 0;
210                                         lwsl_info("setting '%s'\n", po->name);
211                                         if (!ext->callback(lws_get_context(wsi),
212                                                            ext, wsi,
213                                                 LWS_EXT_CB_OPTION_SET,
214                                                 wsi->ws->act_ext_user[
215                                                         wsi->ws->count_act_ext],
216                                                           &oa, (end - *p))) {
217
218                                                 *p += lws_snprintf(*p,
219                                                                    (end - *p),
220                                                               "; %s", po->name);
221                                                 lwsl_debug("adding option %s\n",
222                                                            po->name);
223                                         }
224                                         po++;
225                                 }
226                                 while (*args && *args != ',' && *args != ';')
227                                         args++;
228
229                                 if (*args == ';')
230                                         args++;
231                         }
232
233                         wsi->ws->count_act_ext++;
234                         lwsl_parser("cnt_act_ext <- %d\n",
235                                     wsi->ws->count_act_ext);
236
237                         if (args && *args == ',')
238                                 more = 0;
239
240                         ext++;
241                 }
242
243                 n = 0;
244                 args = NULL;
245         }
246
247         return 0;
248 }
249 #endif
250
251 int
252 lws_process_ws_upgrade2(struct lws *wsi)
253 {
254         struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
255         const struct lws_protocol_vhost_options *pvos = NULL;
256         const char *ws_prot_basic_auth = NULL;
257
258         /*
259          * Allow basic auth a look-in now we bound the wsi to the protocol.
260          *
261          * For vhost ws basic auth, it is "basic-auth": "path" as usual but
262          * applied to the protocol's entry in the vhost's "ws-protocols":
263          * section, as a pvo.
264          */
265
266         pvos = lws_vhost_protocol_options(wsi->vhost, wsi->protocol->name);
267         if (pvos && pvos->options &&
268             !lws_pvo_get_str((void *)pvos->options, "basic-auth",
269                              &ws_prot_basic_auth)) {
270                 lwsl_info("%s: ws upgrade requires basic auth\n", __func__);
271                 switch(lws_check_basic_auth(wsi, ws_prot_basic_auth)) {
272                 case LCBA_CONTINUE:
273                         break;
274                 case LCBA_FAILED_AUTH:
275                         return lws_unauthorised_basic_auth(wsi);
276                 case LCBA_END_TRANSACTION:
277                         lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
278                         return lws_http_transaction_completed(wsi);
279                 }
280         }
281
282         /*
283          * We are upgrading to ws, so http/1.1 + h2 and keepalive + pipelined
284          * header considerations about keeping the ah around no longer apply.
285          *
286          * However it's common for the first ws protocol data to have been
287          * coalesced with the browser upgrade request and to already be in the
288          * ah rx buffer.
289          */
290
291         lws_pt_lock(pt, __func__);
292
293         if (!wsi->h2_stream_carries_ws)
294                 lws_role_transition(wsi, LWSIFR_SERVER, LRS_ESTABLISHED,
295                                     &role_ops_ws);
296
297         lws_pt_unlock(pt);
298
299         /* allocate the ws struct for the wsi */
300
301         wsi->ws = lws_zalloc(sizeof(*wsi->ws), "ws struct");
302         if (!wsi->ws) {
303                 lwsl_notice("OOM\n");
304                 return 1;
305         }
306
307         if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
308                 wsi->ws->ietf_spec_revision =
309                                atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION));
310
311         /* allocate wsi->user storage */
312         if (lws_ensure_user_space(wsi)) {
313                 lwsl_notice("problem with user space\n");
314                 return 1;
315         }
316
317         /*
318          * Give the user code a chance to study the request and
319          * have the opportunity to deny it
320          */
321         if ((wsi->protocol->callback)(wsi,
322                         LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
323                         wsi->user_space,
324                       lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) {
325                 lwsl_warn("User code denied connection\n");
326                 return 1;
327         }
328
329         /*
330          * Perform the handshake according to the protocol version the
331          * client announced
332          */
333
334         switch (wsi->ws->ietf_spec_revision) {
335         default:
336                 lwsl_notice("Unknown client spec version %d\n",
337                           wsi->ws->ietf_spec_revision);
338                 wsi->ws->ietf_spec_revision = 13;
339                 //return 1;
340                 /* fallthru */
341         case 13:
342 #if defined(LWS_WITH_HTTP2)
343                 if (wsi->h2_stream_carries_ws) {
344                         if (lws_h2_ws_handshake(wsi)) {
345                                 lwsl_notice("h2 ws handshake failed\n");
346                                 return 1;
347                         }
348                         lws_role_transition(wsi,
349                                             LWSIFR_SERVER | LWSIFR_P_ENCAP_H2,
350                                             LRS_ESTABLISHED, &role_ops_ws);
351                 } else
352 #endif
353                 {
354                         lwsl_parser("lws_parse calling handshake_04\n");
355                         if (handshake_0405(wsi->context, wsi)) {
356                                 lwsl_notice("hs0405 has failed the connection\n");
357                                 return 1;
358                         }
359                 }
360                 break;
361         }
362
363         lws_server_init_wsi_for_ws(wsi);
364         lwsl_parser("accepted v%02d connection\n", wsi->ws->ietf_spec_revision);
365
366 #if defined(LWS_WITH_ACCESS_LOG)
367         {
368                 char *uptr = NULL, combo[128];
369                 int l, meth = lws_http_get_uri_and_method(wsi, &uptr, &l);
370
371                 if (wsi->h2_stream_carries_ws)
372                         wsi->http.request_version = HTTP_VERSION_2;
373
374                 wsi->http.access_log.response = 101;
375
376                 l = lws_snprintf(combo, sizeof(combo), "%.*s (%s)", l, uptr,
377                                  wsi->protocol->name);
378
379                 lws_prepare_access_log_info(wsi, combo, l, meth);
380                 lws_access_log(wsi);
381         }
382 #endif
383
384         lwsl_info("%s: %p: dropping ah on ws upgrade\n", __func__, wsi);
385         lws_header_table_detach(wsi, 1);
386
387         return 0;
388 }
389
390 int
391 lws_process_ws_upgrade(struct lws *wsi)
392 {
393         const struct lws_protocols *pcol = NULL;
394         char buf[128], name[64];
395         struct lws_tokenize ts;
396         lws_tokenize_elem e;
397
398         if (!wsi->protocol)
399                 lwsl_err("NULL protocol at lws_read\n");
400
401         /*
402          * It's either websocket or h2->websocket
403          *
404          * If we are on h1, confirm we got the required "connection: upgrade"
405          * header.  h2 / ws-over-h2 does not have this.
406          */
407
408 #if defined(LWS_WITH_HTTP2)
409         if (!wsi->http2_substream) {
410 #endif
411
412                 lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST |
413                                             LWS_TOKENIZE_F_DOT_NONTERM |
414                                             LWS_TOKENIZE_F_RFC7230_DELIMS |
415                                             LWS_TOKENIZE_F_MINUS_NONTERM);
416                 ts.len = lws_hdr_copy(wsi, buf, sizeof(buf) - 1,
417                                       WSI_TOKEN_CONNECTION);
418                 if (ts.len <= 0)
419                         goto bad_conn_format;
420
421                 do {
422                         e = lws_tokenize(&ts);
423                         switch (e) {
424                         case LWS_TOKZE_TOKEN:
425                                 if (!strncasecmp(ts.token, "upgrade", ts.token_len))
426                                         e = LWS_TOKZE_ENDED;
427                                 break;
428
429                         case LWS_TOKZE_DELIMITER:
430                                 break;
431
432                         default: /* includes ENDED */
433         bad_conn_format:
434                                 lwsl_err("%s: malformed or absent conn hdr\n",
435                                          __func__);
436
437                                 return 1;
438                         }
439                 } while (e > 0);
440
441 #if defined(LWS_WITH_HTTP2)
442         }
443 #endif
444
445 #if defined(LWS_WITH_HTTP_PROXY)
446         {
447                 const struct lws_http_mount *hit;
448                 int uri_len = 0, meth;
449                 char *uri_ptr;
450
451                 meth = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len);
452                 hit = lws_find_mount(wsi, uri_ptr, uri_len);
453
454                 if (hit && (meth == 0 || meth == 8) &&
455                     (hit->origin_protocol == LWSMPRO_HTTPS ||
456                      hit->origin_protocol == LWSMPRO_HTTP))
457                         /*
458                          * We are an h1 ws upgrade on a urlpath that corresponds
459                          * to a proxying mount.  Don't try to deal with it
460                          * locally, eg, we won't even have the right protocol
461                          * handler since we're not the guy handling it, just a
462                          * conduit.
463                          *
464                          * Instead open the related ongoing h1 connection
465                          * according to the mount configuration and proxy
466                          * whatever that has to say from now on.
467                          */
468                         return lws_http_proxy_start(wsi, hit, uri_ptr, 1);
469         }
470 #endif
471
472         /*
473          * Select the first protocol we support from the list
474          * the client sent us.
475          */
476
477         lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST |
478                                     LWS_TOKENIZE_F_MINUS_NONTERM |
479                                     LWS_TOKENIZE_F_DOT_NONTERM |
480                                     LWS_TOKENIZE_F_RFC7230_DELIMS);
481         ts.len = lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_PROTOCOL);
482         if (ts.len < 0) {
483                 lwsl_err("%s: protocol list too long\n", __func__);
484                 return 1;
485         }
486         if (!ts.len) {
487                 int n = wsi->vhost->default_protocol_index;
488                 /*
489                  * Some clients only have one protocol and do not send the
490                  * protocol list header... allow it and match to the vhost's
491                  * default protocol (which itself defaults to zero).
492                  *
493                  * Setting the vhost default protocol index to -1 or anything
494                  * more than the actual number of protocols on the vhost causes
495                  * these "no protocol" ws connections to be rejected.
496                  */
497
498                 if (n >= wsi->vhost->count_protocols) {
499                         lwsl_notice("%s: rejecting ws upg with no protocol\n",
500                                     __func__);
501
502                         return 1;
503                 }
504
505                 lwsl_info("%s: defaulting to prot handler %d\n", __func__, n);
506
507                 lws_bind_protocol(wsi, &wsi->vhost->protocols[n],
508                                   "ws upgrade default pcol");
509
510                 goto alloc_ws;
511         }
512
513         /* otherwise go through the user-provided protocol list */
514
515         do {
516                 e = lws_tokenize(&ts);
517                 switch (e) {
518                 case LWS_TOKZE_TOKEN:
519
520                         if (lws_tokenize_cstr(&ts, name, sizeof(name))) {
521                                 lwsl_err("%s: pcol name too long\n", __func__);
522
523                                 return 1;
524                         }
525                         lwsl_debug("checking %s\n", name);
526                         pcol = lws_vhost_name_to_protocol(wsi->vhost, name);
527                         if (pcol) {
528                                 /* if we know it, bind to it and stop looking */
529                                 lws_bind_protocol(wsi, pcol, "ws upg pcol");
530                                 e = LWS_TOKZE_ENDED;
531                         }
532                         break;
533
534                 case LWS_TOKZE_DELIMITER:
535                 case LWS_TOKZE_ENDED:
536                         break;
537
538                 default:
539                         lwsl_err("%s: malformatted protocol list", __func__);
540
541                         return 1;
542                 }
543         } while (e > 0);
544
545         /* we didn't find a protocol he wanted? */
546
547         if (!pcol) {
548                 lwsl_notice("No supported protocol \"%s\"\n", buf);
549
550                 return 1;
551         }
552
553 alloc_ws:
554
555         return lws_process_ws_upgrade2(wsi);
556 }
557
558 int
559 handshake_0405(struct lws_context *context, struct lws *wsi)
560 {
561         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
562         struct lws_process_html_args args;
563         unsigned char hash[20];
564         int n, accept_len;
565         char *response;
566         char *p;
567
568         if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST) ||
569             !lws_hdr_total_length(wsi, WSI_TOKEN_KEY)) {
570                 lwsl_info("handshake_04 missing pieces\n");
571                 /* completed header processing, but missing some bits */
572                 goto bail;
573         }
574
575         if (lws_hdr_total_length(wsi, WSI_TOKEN_KEY) >=
576             MAX_WEBSOCKET_04_KEY_LEN) {
577                 lwsl_warn("Client key too long %d\n", MAX_WEBSOCKET_04_KEY_LEN);
578                 goto bail;
579         }
580
581         /*
582          * since key length is restricted above (currently 128), cannot
583          * overflow
584          */
585         n = sprintf((char *)pt->serv_buf,
586                     "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
587                     lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY));
588
589         lws_SHA1(pt->serv_buf, n, hash);
590
591         accept_len = lws_b64_encode_string((char *)hash, 20,
592                         (char *)pt->serv_buf, context->pt_serv_buf_size);
593         if (accept_len < 0) {
594                 lwsl_warn("Base64 encoded hash too long\n");
595                 goto bail;
596         }
597
598         /* allocate the per-connection user memory (if any) */
599         if (lws_ensure_user_space(wsi))
600                 goto bail;
601
602         /* create the response packet */
603
604         /* make a buffer big enough for everything */
605
606         response = (char *)pt->serv_buf + MAX_WEBSOCKET_04_KEY_LEN +
607                    256 + LWS_PRE;
608         p = response;
609         LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a"
610                       "Upgrade: WebSocket\x0d\x0a"
611                       "Connection: Upgrade\x0d\x0a"
612                       "Sec-WebSocket-Accept: ");
613         strcpy(p, (char *)pt->serv_buf);
614         p += accept_len;
615
616         /* we can only return the protocol header if:
617          *  - one came in, and ... */
618         if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL) &&
619             /*  - it is not an empty string */
620             wsi->protocol->name &&
621             wsi->protocol->name[0]) {
622                 const char *prot = wsi->protocol->name;
623
624 #if defined(LWS_WITH_HTTP_PROXY)
625                 if (wsi->proxied_ws_parent && wsi->child_list)
626                         prot = wsi->child_list->ws->actual_protocol;
627 #endif
628
629                 LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
630                 p += lws_snprintf(p, 128, "%s", prot);
631         }
632
633 #if !defined(LWS_WITHOUT_EXTENSIONS)
634         /*
635          * Figure out which extensions the client has that we want to
636          * enable on this connection, and give him back the list.
637          *
638          * Give him a limited write bugdet
639          */
640         if (lws_extension_server_handshake(wsi, &p, 192))
641                 goto bail;
642 #endif
643         LWS_CPYAPP(p, "\x0d\x0a");
644
645         args.p = p;
646         args.max_len = lws_ptr_diff((char *)pt->serv_buf +
647                                     context->pt_serv_buf_size, p);
648         if (user_callback_handle_rxflow(wsi->protocol->callback, wsi,
649                                         LWS_CALLBACK_ADD_HEADERS,
650                                         wsi->user_space, &args, 0))
651                 goto bail;
652
653         p = args.p;
654
655         /* end of response packet */
656
657         LWS_CPYAPP(p, "\x0d\x0a");
658
659         /* okay send the handshake response accepting the connection */
660
661         lwsl_parser("issuing resp pkt %d len\n",
662                     lws_ptr_diff(p, response));
663 #if defined(DEBUG)
664         fwrite(response, 1,  p - response, stderr);
665 #endif
666         n = lws_write(wsi, (unsigned char *)response, p - response,
667                       LWS_WRITE_HTTP_HEADERS);
668         if (n != (p - response)) {
669                 lwsl_info("%s: ERROR writing to socket %d\n", __func__, n);
670                 goto bail;
671         }
672
673         /* alright clean up and set ourselves into established state */
674
675         lwsi_set_state(wsi, LRS_ESTABLISHED);
676         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
677
678         {
679                 const char * uri_ptr =
680                         lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI);
681                 int uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
682                 const struct lws_http_mount *hit =
683                         lws_find_mount(wsi, uri_ptr, uri_len);
684                 if (hit && hit->cgienv &&
685                     wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_PMO,
686                         wsi->user_space, (void *)hit->cgienv, 0))
687                         return 1;
688         }
689
690         return 0;
691
692 bail:
693         /* caller will free up his parsing allocations */
694         return -1;
695 }
696
697
698
699 /*
700  * Once we reach LWS_RXPS_WS_FRAME_PAYLOAD, we know how much
701  * to expect in that state and can deal with it in bulk more efficiently.
702  */
703
704 static int
705 lws_ws_frame_rest_is_payload(struct lws *wsi, uint8_t **buf, size_t len)
706 {
707         struct lws_ext_pm_deflate_rx_ebufs pmdrx;
708         unsigned int avail = (unsigned int)len;
709         uint8_t *buffer = *buf, mask[4];
710 #if !defined(LWS_WITHOUT_EXTENSIONS)
711         unsigned int old_packet_length = (int)wsi->ws->rx_packet_length;
712 #endif
713         int n = 0;
714
715         /*
716          * With zlib, we can give it as much input as we like.  The pmd
717          * extension will draw it down in chunks (default 1024).
718          *
719          * If we try to restrict how much we give it, because we must go
720          * back to the event loop each time, we will drop the remainder...
721          */
722
723 #if !defined(LWS_WITHOUT_EXTENSIONS)
724         if (!wsi->ws->count_act_ext)
725 #endif
726         {
727                 if (wsi->protocol->rx_buffer_size)
728                         avail = (int)wsi->protocol->rx_buffer_size;
729                 else
730                         avail = wsi->context->pt_serv_buf_size;
731         }
732
733         /* do not consume more than we should */
734         if (avail > wsi->ws->rx_packet_length)
735                 avail = (unsigned int)wsi->ws->rx_packet_length;
736
737         /* do not consume more than what is in the buffer */
738         if (avail > len)
739                 avail = (unsigned int)len;
740
741         if (!avail)
742                 return 0;
743
744         pmdrx.eb_in.token = buffer;
745         pmdrx.eb_in.len = avail;
746         pmdrx.eb_out.token = buffer;
747         pmdrx.eb_out.len = avail;
748
749         if (!wsi->ws->all_zero_nonce) {
750
751                 for (n = 0; n < 4; n++)
752                         mask[n] = wsi->ws->mask[(wsi->ws->mask_idx + n) & 3];
753
754                 /* deal with 4-byte chunks using unwrapped loop */
755                 n = avail >> 2;
756                 while (n--) {
757                         *(buffer) = *(buffer) ^ mask[0];
758                         buffer++;
759                         *(buffer) = *(buffer) ^ mask[1];
760                         buffer++;
761                         *(buffer) = *(buffer) ^ mask[2];
762                         buffer++;
763                         *(buffer) = *(buffer) ^ mask[3];
764                         buffer++;
765                 }
766                 /* and the remaining bytes bytewise */
767                 for (n = 0; n < (int)(avail & 3); n++) {
768                         *(buffer) = *(buffer) ^ mask[n];
769                         buffer++;
770                 }
771
772                 wsi->ws->mask_idx = (wsi->ws->mask_idx + avail) & 3;
773         }
774
775         lwsl_info("%s: using %d of raw input (total %d on offer)\n", __func__,
776                     avail, (int)len);
777
778         (*buf) += avail;
779         len -= avail;
780         wsi->ws->rx_packet_length -= avail;
781
782 #if !defined(LWS_WITHOUT_EXTENSIONS)
783         n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &pmdrx, 0);
784         lwsl_info("%s: ext says %d / ebuf_out.len %d\n", __func__,  n,
785                         pmdrx.eb_out.len);
786
787         /*
788          * ebuf may be pointing somewhere completely different now,
789          * it's the output
790          */
791
792         if (n < 0) {
793                 /*
794                  * we may rely on this to get RX, just drop connection
795                  */
796                 lwsl_notice("%s: LWS_EXT_CB_PAYLOAD_RX blew out\n", __func__);
797                 wsi->socket_is_permanently_unusable = 1;
798
799                 return -1;
800         }
801
802         /*
803          * if we had an rx fragment right at the last compressed byte of the
804          * message, we can get a zero length inflated output, where no prior
805          * rx inflated output marked themselves with FIN, since there was
806          * raw ws payload still to drain at that time.
807          *
808          * Then we need to generate a zero length ws rx that can be understood
809          * as the message completion.
810          */
811
812         if (!pmdrx.eb_out.len &&              /* zero-length inflation output */
813             n == PMDR_EMPTY_FINAL &&    /* nothing to drain from the inflator */
814             old_packet_length &&            /* we gave the inflator new input */
815             !wsi->ws->rx_packet_length &&   /* raw ws packet payload all gone */
816             wsi->ws->final &&               /* the raw ws packet is a FIN guy */
817             wsi->protocol->callback &&
818             !wsi->wsistate_pre_close) {
819
820                 lwsl_ext("%s: issuing zero length FIN pkt\n", __func__);
821
822                 if (user_callback_handle_rxflow(wsi->protocol->callback, wsi,
823                                                 LWS_CALLBACK_RECEIVE,
824                                                 wsi->user_space, NULL, 0))
825                         return -1;
826
827                 return avail;
828         }
829
830         /*
831          * If doing permessage-deflate, above was the only way to get a zero
832          * length receive.  Otherwise we're more willing.
833          */
834         if (wsi->ws->count_act_ext && !pmdrx.eb_out.len)
835                 return avail;
836
837         if (n == PMDR_HAS_PENDING)
838                 /* extension had more... main loop will come back */
839                 lws_add_wsi_to_draining_ext_list(wsi);
840         else
841                 lws_remove_wsi_from_draining_ext_list(wsi);
842 #endif
843
844         if (pmdrx.eb_out.len &&
845             wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) {
846                 if (lws_check_utf8(&wsi->ws->utf8,
847                                    pmdrx.eb_out.token,
848                                    pmdrx.eb_out.len)) {
849                         lws_close_reason(wsi, LWS_CLOSE_STATUS_INVALID_PAYLOAD,
850                                          (uint8_t *)"bad utf8", 8);
851                         goto utf8_fail;
852                 }
853
854                 /* we are ending partway through utf-8 character? */
855                 if (!wsi->ws->rx_packet_length && wsi->ws->final &&
856                     wsi->ws->utf8 && !n) {
857                         lwsl_info("FINAL utf8 error\n");
858                         lws_close_reason(wsi, LWS_CLOSE_STATUS_INVALID_PAYLOAD,
859                                          (uint8_t *)"partial utf8", 12);
860
861 utf8_fail:
862                         lwsl_info("utf8 error\n");
863                         lwsl_hexdump_info(pmdrx.eb_out.token, pmdrx.eb_out.len);
864
865                         return -1;
866                 }
867         }
868
869         if (wsi->protocol->callback && !wsi->wsistate_pre_close)
870                 if (user_callback_handle_rxflow(wsi->protocol->callback, wsi,
871                                                 LWS_CALLBACK_RECEIVE,
872                                                 wsi->user_space,
873                                                 pmdrx.eb_out.token,
874                                                 pmdrx.eb_out.len))
875                         return -1;
876
877         wsi->ws->first_fragment = 0;
878
879 #if !defined(LWS_WITHOUT_EXTENSIONS)
880         lwsl_info("%s: input used %d, output %d, rem len %d, rx_draining_ext %d\n",
881                   __func__, avail, pmdrx.eb_out.len, (int)len,
882                   wsi->ws->rx_draining_ext);
883 #endif
884
885         return avail; /* how much we used from the input */
886 }
887
888
889 int
890 lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len)
891 {
892         unsigned char *bufin = *buf;
893         int m, bulk = 0;
894
895         lwsl_debug("%s: received %d byte packet\n", __func__, (int)len);
896
897         //lwsl_hexdump_notice(*buf, len);
898
899         /* let the rx protocol state machine have as much as it needs */
900
901         while (len) {
902                 /*
903                  * we were accepting input but now we stopped doing so
904                  */
905                 if (wsi->rxflow_bitmap) {
906                         lwsl_info("%s: doing rxflow, caching %d\n", __func__,
907                                 (int)len);
908                         /*
909                          * Since we cached the remaining available input, we
910                          * can say we "consumed" it.
911                          *
912                          * But what about the case where the available input
913                          * came out of the rxflow cache already?  If we are
914                          * effectively "putting it back in the cache", we have
915                          * leave it where it is, already pointed to by the head.
916                          */
917                         if (lws_rxflow_cache(wsi, *buf, 0, (int)len) ==
918                                                         LWSRXFC_TRIMMED) {
919                                 /*
920                                  * We dealt with it by trimming the existing
921                                  * rxflow cache HEAD to account for what we used.
922                                  *
923                                  * indicate we didn't use anything to the caller
924                                  * so he doesn't do any consumed processing
925                                  */
926                                 lwsl_info("%s: trimming inside rxflow cache\n",
927                                           __func__);
928                                 *buf = bufin;
929                         } else
930                                 *buf += len;
931
932                         return 1;
933                 }
934 #if !defined(LWS_WITHOUT_EXTENSIONS)
935                 if (wsi->ws->rx_draining_ext) {
936                         lwsl_debug("%s: draining rx ext\n", __func__);
937                         m = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR, 0);
938                         if (m < 0)
939                                 return -1;
940                         continue;
941                 }
942 #endif
943
944                 /* consume payload bytes efficiently */
945                 while (wsi->lws_rx_parse_state == LWS_RXPS_WS_FRAME_PAYLOAD &&
946                                 (wsi->ws->opcode == LWSWSOPC_TEXT_FRAME ||
947                                  wsi->ws->opcode == LWSWSOPC_BINARY_FRAME ||
948                                  wsi->ws->opcode == LWSWSOPC_CONTINUATION) &&
949                        len) {
950                         uint8_t *bin = *buf;
951
952                         bulk = 1;
953                         m = lws_ws_frame_rest_is_payload(wsi, buf, len);
954                         assert((int)lws_ptr_diff(*buf, bin) <= (int)len);
955                         len -= lws_ptr_diff(*buf, bin);
956
957                         if (!m) {
958
959                                 break;
960                         }
961                         if (m < 0) {
962                                 lwsl_info("%s: rest_is_payload bailed\n",
963                                           __func__);
964                                 return -1;
965                         }
966                 }
967
968                 if (!bulk) {
969                         /* process the byte */
970                         m = lws_ws_rx_sm(wsi, 0, *(*buf)++);
971                         len--;
972                 } else {
973                         /*
974                          * We already handled this byte in bulk, just deal
975                          * with the ramifications
976                          */
977 #if !defined(LWS_WITHOUT_EXTENSIONS)
978                         lwsl_debug("%s: coming out of bulk with len %d, "
979                                    "wsi->ws->rx_draining_ext %d\n",
980                                    __func__, (int)len,
981                                    wsi->ws->rx_draining_ext);
982 #endif
983                         m = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR |
984                                               ALREADY_PROCESSED_NO_CB, 0);
985                 }
986
987                 if (m < 0) {
988                         lwsl_info("%s: lws_ws_rx_sm bailed %d\n", __func__,
989                                   bulk);
990
991                         return -1;
992                 }
993
994                 bulk = 0;
995         }
996
997         lwsl_debug("%s: exit with %d unused\n", __func__, (int)len);
998
999         return 0;
1000 }