lws_intptr_t
[platform/upstream/libwebsockets.git] / lib / parsers.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2013 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 "private-libwebsockets.h"
23
24 const unsigned char lextable[] = {
25         #include "lextable.h"
26 };
27
28 #define FAIL_CHAR 0x08
29
30 int LWS_WARN_UNUSED_RESULT
31 lextable_decode(int pos, char c)
32 {
33         if (c >= 'A' && c <= 'Z')
34                 c += 'a' - 'A';
35
36         while (1) {
37                 if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */
38                         if ((lextable[pos] & 0x7f) != c)
39                                 return -1;
40                         /* fall thru */
41                         pos++;
42                         if (lextable[pos] == FAIL_CHAR)
43                                 return -1;
44                         return pos;
45                 }
46
47                 if (lextable[pos] == FAIL_CHAR)
48                         return -1;
49
50                 /* b7 = 0, end or 3-byte */
51                 if (lextable[pos] < FAIL_CHAR) /* terminal marker */
52                         return pos;
53
54                 if (lextable[pos] == c) /* goto */
55                         return pos + (lextable[pos + 1]) +
56                                                 (lextable[pos + 2] << 8);
57                 /* fall thru goto */
58                 pos += 3;
59                 /* continue */
60         }
61 }
62
63 void
64 _lws_header_table_reset(struct allocated_headers *ah)
65 {
66         /* init the ah to reflect no headers or data have appeared yet */
67         memset(ah->frag_index, 0, sizeof(ah->frag_index));
68         ah->nfrag = 0;
69         ah->pos = 0;
70         ah->http_response = 0;
71 }
72
73 // doesn't scrub the ah rxbuffer by default, parent must do if needed
74
75 void
76 lws_header_table_reset(struct lws *wsi, int autoservice)
77 {
78         struct allocated_headers *ah = wsi->u.hdr.ah;
79         struct lws_context_per_thread *pt;
80         struct lws_pollfd *pfd;
81
82         /* if we have the idea we're resetting 'our' ah, must be bound to one */
83         assert(ah);
84         /* ah also concurs with ownership */
85         assert(ah->wsi == wsi);
86
87         _lws_header_table_reset(ah);
88
89         wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
90         wsi->u.hdr.lextable_pos = 0;
91
92         /* since we will restart the ah, our new headers are not completed */
93         wsi->hdr_parsing_completed = 0;
94
95         /*
96          * if we inherited pending rx (from socket adoption deferred
97          * processing), apply and free it.
98          */
99         if (wsi->u.hdr.preamble_rx) {
100                 memcpy(ah->rx, wsi->u.hdr.preamble_rx,
101                        wsi->u.hdr.preamble_rx_len);
102                 ah->rxlen = wsi->u.hdr.preamble_rx_len;
103                 lws_free_set_NULL(wsi->u.hdr.preamble_rx);
104
105                 if (autoservice) {
106                         lwsl_notice("%s: calling service on readbuf ah\n", __func__);
107
108                         pt = &wsi->context->pt[(int)wsi->tsi];
109
110                         /* unlike a normal connect, we have the headers already
111                          * (or the first part of them anyway)
112                          */
113                         pfd = &pt->fds[wsi->position_in_fds_table];
114                         pfd->revents |= LWS_POLLIN;
115                         lwsl_err("%s: calling service\n", __func__);
116                         lws_service_fd_tsi(wsi->context, pfd, wsi->tsi);
117                 }
118         }
119 }
120
121 int LWS_WARN_UNUSED_RESULT
122 lws_header_table_attach(struct lws *wsi, int autoservice)
123 {
124         struct lws_context *context = wsi->context;
125         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
126         struct lws_pollargs pa;
127         struct lws **pwsi;
128         int n;
129
130         lwsl_info("%s: wsi %p: ah %p (tsi %d, count = %d) in\n", __func__, (void *)wsi,
131                  (void *)wsi->u.hdr.ah, wsi->tsi, pt->ah_count_in_use);
132
133         /* if we are already bound to one, just clear it down */
134         if (wsi->u.hdr.ah) {
135                 lwsl_info("cleardown\n");
136                 goto reset;
137         }
138
139         lws_pt_lock(pt);
140         pwsi = &pt->ah_wait_list;
141         while (*pwsi) {
142                 if (*pwsi == wsi) {
143                         /* if already waiting on list, if no new ah just ret */
144                         if (pt->ah_count_in_use ==
145                             context->max_http_header_pool) {
146                                 lwsl_notice("%s: no free ah to attach\n", __func__);
147                                 goto bail;
148                         }
149                         /* new ah.... remove ourselves from waiting list */
150                         *pwsi = wsi->u.hdr.ah_wait_list; /* set our prev to our next */
151                         wsi->u.hdr.ah_wait_list = NULL; /* no next any more */
152                         pt->ah_wait_list_length--;
153                         break;
154                 }
155                 pwsi = &(*pwsi)->u.hdr.ah_wait_list;
156         }
157         /*
158          * pool is all busy... add us to waiting list and return that we
159          * weren't able to deliver it right now
160          */
161         if (pt->ah_count_in_use == context->max_http_header_pool) {
162                 lwsl_info("%s: adding %p to ah waiting list\n", __func__, wsi);
163                 wsi->u.hdr.ah_wait_list = pt->ah_wait_list;
164                 pt->ah_wait_list = wsi;
165                 pt->ah_wait_list_length++;
166
167                 /* we cannot accept input then */
168
169                 _lws_change_pollfd(wsi, LWS_POLLIN, 0, &pa);
170                 goto bail;
171         }
172
173         for (n = 0; n < context->max_http_header_pool; n++)
174                 if (!pt->ah_pool[n].in_use)
175                         break;
176
177         /* if the count of in use said something free... */
178         assert(n != context->max_http_header_pool);
179
180         wsi->u.hdr.ah = &pt->ah_pool[n];
181         wsi->u.hdr.ah->in_use = 1;
182         pt->ah_pool[n].wsi = wsi; /* mark our owner */
183         pt->ah_count_in_use++;
184
185         _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
186
187         lwsl_info("%s: did attach wsi %p: ah %p: count %d (on exit)\n", __func__,
188                   (void *)wsi, (void *)wsi->u.hdr.ah, pt->ah_count_in_use);
189
190         lws_pt_unlock(pt);
191
192 reset:
193
194         /* and reset the rx state */
195         wsi->u.hdr.ah->rxpos = 0;
196         wsi->u.hdr.ah->rxlen = 0;
197
198         lws_header_table_reset(wsi, autoservice);
199         time(&wsi->u.hdr.ah->assigned);
200
201 #ifndef LWS_NO_CLIENT
202         if (wsi->state == LWSS_CLIENT_UNCONNECTED)
203                 if (!lws_client_connect_via_info2(wsi))
204                         /* our client connect has failed, the wsi
205                          * has been closed
206                          */
207                         return -1;
208 #endif
209
210         return 0;
211
212 bail:
213         lws_pt_unlock(pt);
214
215         return 1;
216 }
217
218 void
219 lws_header_table_force_to_detachable_state(struct lws *wsi)
220 {
221         if (wsi->u.hdr.ah) {
222                 wsi->u.hdr.ah->rxpos = -1;
223                 wsi->u.hdr.ah->rxlen = -1;
224                 wsi->hdr_parsing_completed = 1;
225         }
226 }
227
228 int
229 lws_header_table_is_in_detachable_state(struct lws *wsi)
230 {
231         struct allocated_headers *ah = wsi->u.hdr.ah;
232
233         return ah && ah->rxpos == ah->rxlen && wsi->hdr_parsing_completed;
234 }
235
236 int lws_header_table_detach(struct lws *wsi, int autoservice)
237 {
238         struct lws_context *context = wsi->context;
239         struct allocated_headers *ah = wsi->u.hdr.ah;
240         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
241         struct lws_pollargs pa;
242         struct lws **pwsi;
243         time_t now;
244
245         if (!ah)
246                 return 0;
247
248         lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__,
249                   (void *)wsi, (void *)ah, wsi->tsi,
250                   pt->ah_count_in_use);
251
252         if (wsi->u.hdr.preamble_rx)
253                 lws_free_set_NULL(wsi->u.hdr.preamble_rx);
254
255         /* may not be detached while he still has unprocessed rx */
256         if (!lws_header_table_is_in_detachable_state(wsi)) {
257                 lwsl_err("%s: %p: CANNOT DETACH rxpos:%d, rxlen:%d, wsi->hdr_parsing_completed = %d\n", __func__, wsi,
258                                 ah->rxpos, ah->rxlen, wsi->hdr_parsing_completed);
259                 return 0;
260         }
261
262         lws_pt_lock(pt);
263
264         pwsi = &pt->ah_wait_list;
265         if (!ah) { /* remove from wait list if none attached */
266                 while (*pwsi) {
267                         if (*pwsi == wsi) {
268                                 lwsl_info("%s: wsi %p, remv wait\n",
269                                           __func__, wsi);
270                                 *pwsi = wsi->u.hdr.ah_wait_list;
271                                 wsi->u.hdr.ah_wait_list = NULL;
272                                 pt->ah_wait_list_length--;
273                                 goto bail;
274                         }
275                         pwsi = &(*pwsi)->u.hdr.ah_wait_list;
276                 }
277                 /* no ah, not on list... no more business here */
278                 goto bail;
279         }
280         /* we did have an ah attached */
281         time(&now);
282         if (ah->assigned && now - ah->assigned > 3) {
283                 /*
284                  * we're detaching the ah, but it was held an
285                  * unreasonably long time
286                  */
287                 lwsl_notice("%s: wsi %p: ah held %ds, "
288                             "ah.rxpos %d, ah.rxlen %d, mode/state %d %d,"
289                             "wsi->more_rx_waiting %d\n", __func__, wsi,
290                             (int)(now - ah->assigned),
291                             ah->rxpos, ah->rxlen, wsi->mode, wsi->state,
292                             wsi->more_rx_waiting);
293         }
294
295         ah->assigned = 0;
296
297         /* if we think we're detaching one, there should be one in use */
298         assert(pt->ah_count_in_use > 0);
299         /* and this specific one should have been in use */
300         assert(ah->in_use);
301         wsi->u.hdr.ah = NULL;
302         ah->wsi = NULL; /* no owner */
303
304         /* oh there is nobody on the waiting list... leave it at that then */
305         if (!*pwsi) {
306                 ah->in_use = 0;
307                 pt->ah_count_in_use--;
308
309                 goto bail;
310         }
311
312         /* somebody else on same tsi is waiting, give it to oldest guy */
313
314         lwsl_info("pt wait list %p\n", *pwsi);
315         while ((*pwsi)->u.hdr.ah_wait_list)
316                 pwsi = &(*pwsi)->u.hdr.ah_wait_list;
317
318         wsi = *pwsi;
319         lwsl_info("last wsi in wait list %p\n", wsi);
320
321         wsi->u.hdr.ah = ah;
322         ah->wsi = wsi; /* new owner */
323         /* and reset the rx state */
324         ah->rxpos = 0;
325         ah->rxlen = 0;
326         lws_header_table_reset(wsi, autoservice);
327         time(&wsi->u.hdr.ah->assigned);
328
329         /* clients acquire the ah and then insert themselves in fds table... */
330         if (wsi->position_in_fds_table != -1) {
331                 lwsl_info("%s: Enabling %p POLLIN\n", __func__, wsi);
332
333                 /* he has been stuck waiting for an ah, but now his wait is over,
334                  * let him progress
335                  */
336                 _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
337         }
338
339         /* point prev guy to next guy in list instead */
340         *pwsi = wsi->u.hdr.ah_wait_list;
341         /* the guy who got one is out of the list */
342         wsi->u.hdr.ah_wait_list = NULL;
343         pt->ah_wait_list_length--;
344
345 #ifndef LWS_NO_CLIENT
346         if (wsi->state == LWSS_CLIENT_UNCONNECTED) {
347                 lws_pt_unlock(pt);
348
349                 if (!lws_client_connect_via_info2(wsi)) {
350                         /* our client connect has failed, the wsi
351                          * has been closed
352                          */
353
354                         return -1;
355                 }
356                 return 0;
357         }
358 #endif
359
360         assert(!!pt->ah_wait_list_length == !!(lws_intptr_t)pt->ah_wait_list);
361 bail:
362         lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__,
363           (void *)wsi, (void *)ah, wsi->tsi,
364           pt->ah_count_in_use);
365         lws_pt_unlock(pt);
366
367         return 0;
368 }
369
370 LWS_VISIBLE int
371 lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx)
372 {
373         int n;
374
375         n = wsi->u.hdr.ah->frag_index[h];
376         if (!n)
377                 return 0;
378         do {
379                 if (!frag_idx)
380                         return wsi->u.hdr.ah->frags[n].len;
381                 n = wsi->u.hdr.ah->frags[n].nfrag;
382         } while (frag_idx-- && n);
383
384         return 0;
385 }
386
387 LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h)
388 {
389         int n;
390         int len = 0;
391
392         n = wsi->u.hdr.ah->frag_index[h];
393         if (!n)
394                 return 0;
395         do {
396                 len += wsi->u.hdr.ah->frags[n].len;
397                 n = wsi->u.hdr.ah->frags[n].nfrag;
398         } while (n);
399
400         return len;
401 }
402
403 LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len,
404                                       enum lws_token_indexes h, int frag_idx)
405 {
406         int n = 0;
407         int f = wsi->u.hdr.ah->frag_index[h];
408
409         if (!f)
410                 return -1;
411
412         while (n < frag_idx) {
413                 f = wsi->u.hdr.ah->frags[f].nfrag;
414                 if (!f)
415                         return -1;
416                 n++;
417         }
418
419         if (wsi->u.hdr.ah->frags[f].len >= len)
420                 return -1;
421
422         memcpy(dst, wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[f].offset,
423                wsi->u.hdr.ah->frags[f].len);
424         dst[wsi->u.hdr.ah->frags[f].len] = '\0';
425
426         return wsi->u.hdr.ah->frags[f].len;
427 }
428
429 LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len,
430                              enum lws_token_indexes h)
431 {
432         int toklen = lws_hdr_total_length(wsi, h);
433         int n;
434
435         if (toklen >= len)
436                 return -1;
437
438         n = wsi->u.hdr.ah->frag_index[h];
439         if (!n)
440                 return 0;
441
442         do {
443                 strcpy(dst, &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]);
444                 dst += wsi->u.hdr.ah->frags[n].len;
445                 n = wsi->u.hdr.ah->frags[n].nfrag;
446         } while (n);
447
448         return toklen;
449 }
450
451 char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h)
452 {
453         int n;
454
455         n = wsi->u.hdr.ah->frag_index[h];
456         if (!n)
457                 return NULL;
458
459         return wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[n].offset;
460 }
461
462 int LWS_WARN_UNUSED_RESULT
463 lws_pos_in_bounds(struct lws *wsi)
464 {
465         if (wsi->u.hdr.ah->pos < (unsigned int)wsi->context->max_http_header_data)
466                 return 0;
467
468         if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
469                 lwsl_err("Ran out of header data space\n");
470                 return 1;
471         }
472
473         /*
474          * with these tests everywhere, it should never be able to exceed
475          * the limit, only meet the limit
476          */
477
478         lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->u.hdr.ah->pos,
479                  wsi->context->max_http_header_data);
480         assert(0);
481
482         return 1;
483 }
484
485 int LWS_WARN_UNUSED_RESULT
486 lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s)
487 {
488         wsi->u.hdr.ah->nfrag++;
489         if (wsi->u.hdr.ah->nfrag == ARRAY_SIZE(wsi->u.hdr.ah->frags)) {
490                 lwsl_warn("More hdr frags than we can deal with, dropping\n");
491                 return -1;
492         }
493
494         wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->nfrag;
495
496         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].offset = wsi->u.hdr.ah->pos;
497         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len = 0;
498         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].nfrag = 0;
499
500         do {
501                 if (lws_pos_in_bounds(wsi))
502                         return -1;
503
504                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s;
505                 if (*s)
506                         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
507         } while (*s++);
508
509         return 0;
510 }
511
512 signed char char_to_hex(const char c)
513 {
514         if (c >= '0' && c <= '9')
515                 return c - '0';
516
517         if (c >= 'a' && c <= 'f')
518                 return c - 'a' + 10;
519
520         if (c >= 'A' && c <= 'F')
521                 return c - 'A' + 10;
522
523         return -1;
524 }
525
526 static int LWS_WARN_UNUSED_RESULT
527 issue_char(struct lws *wsi, unsigned char c)
528 {
529         unsigned short frag_len;
530
531         if (lws_pos_in_bounds(wsi))
532                 return -1;
533
534         frag_len = wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len;
535         /*
536          * If we haven't hit the token limit, just copy the character into
537          * the header
538          */
539         if (frag_len < wsi->u.hdr.current_token_limit) {
540                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
541                 if (c)
542                         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
543                 return 0;
544         }
545
546         /* Insert a null character when we *hit* the limit: */
547         if (frag_len == wsi->u.hdr.current_token_limit) {
548                 if (lws_pos_in_bounds(wsi))
549                         return -1;
550                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
551                 lwsl_warn("header %i exceeds limit %d\n",
552                           wsi->u.hdr.parser_state,
553                           wsi->u.hdr.current_token_limit);
554         }
555
556         return 1;
557 }
558
559 int LWS_WARN_UNUSED_RESULT
560 lws_parse(struct lws *wsi, unsigned char c)
561 {
562         static const unsigned char methods[] = {
563                 WSI_TOKEN_GET_URI,
564                 WSI_TOKEN_POST_URI,
565                 WSI_TOKEN_OPTIONS_URI,
566                 WSI_TOKEN_PUT_URI,
567                 WSI_TOKEN_PATCH_URI,
568                 WSI_TOKEN_DELETE_URI,
569                 WSI_TOKEN_CONNECT,
570         };
571         struct allocated_headers *ah = wsi->u.hdr.ah;
572         struct lws_context *context = wsi->context;
573         unsigned int n, m, enc = 0;
574
575         assert(wsi->u.hdr.ah);
576
577         switch (wsi->u.hdr.parser_state) {
578         default:
579
580                 lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c);
581
582                 /* collect into malloc'd buffers */
583                 /* optional initial space swallow */
584                 if (!ah->frags[ah->frag_index[wsi->u.hdr.parser_state]].len &&
585                     c == ' ')
586                         break;
587
588                 for (m = 0; m < ARRAY_SIZE(methods); m++)
589                         if (wsi->u.hdr.parser_state == methods[m])
590                                 break;
591                 if (m == ARRAY_SIZE(methods))
592                         /* it was not any of the methods */
593                         goto check_eol;
594
595                 /* special URI processing... end at space */
596
597                 if (c == ' ') {
598                         /* enforce starting with / */
599                         if (!ah->frags[ah->nfrag].len)
600                                 if (issue_char(wsi, '/') < 0)
601                                         return -1;
602
603                         if (wsi->u.hdr.ups == URIPS_SEEN_SLASH_DOT_DOT) {
604                                 /*
605                                  * back up one dir level if possible
606                                  * safe against header fragmentation because
607                                  * the method URI can only be in 1 fragment
608                                  */
609                                 if (ah->frags[ah->nfrag].len > 2) {
610                                         ah->pos--;
611                                         ah->frags[ah->nfrag].len--;
612                                         do {
613                                                 ah->pos--;
614                                                 ah->frags[ah->nfrag].len--;
615                                         } while (ah->frags[ah->nfrag].len > 1 &&
616                                                  ah->data[ah->pos] != '/');
617                                 }
618                         }
619
620                         /* begin parsing HTTP version: */
621                         if (issue_char(wsi, '\0') < 0)
622                                 return -1;
623                         wsi->u.hdr.parser_state = WSI_TOKEN_HTTP;
624                         goto start_fragment;
625                 }
626
627                 /*
628                  * PRIORITY 1
629                  * special URI processing... convert %xx
630                  */
631
632                 switch (wsi->u.hdr.ues) {
633                 case URIES_IDLE:
634                         if (c == '%') {
635                                 wsi->u.hdr.ues = URIES_SEEN_PERCENT;
636                                 goto swallow;
637                         }
638                         break;
639                 case URIES_SEEN_PERCENT:
640                         if (char_to_hex(c) < 0)
641                                 /* illegal post-% char */
642                                 goto forbid;
643
644                         wsi->u.hdr.esc_stash = c;
645                         wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1;
646                         goto swallow;
647
648                 case URIES_SEEN_PERCENT_H1:
649                         if (char_to_hex(c) < 0)
650                                 /* illegal post-% char */
651                                 goto forbid;
652
653                         c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) |
654                                         char_to_hex(c);
655                         enc = 1;
656                         wsi->u.hdr.ues = URIES_IDLE;
657                         break;
658                 }
659
660                 /*
661                  * PRIORITY 2
662                  * special URI processing...
663                  *  convert /.. or /... or /../ etc to /
664                  *  convert /./ to /
665                  *  convert // or /// etc to /
666                  *  leave /.dir or whatever alone
667                  */
668
669                 switch (wsi->u.hdr.ups) {
670                 case URIPS_IDLE:
671                         if (!c)
672                                 return -1;
673                         /* genuine delimiter */
674                         if ((c == '&' || c == ';') && !enc) {
675                                 if (issue_char(wsi, c) < 0)
676                                         return -1;
677                                 /* swallow the terminator */
678                                 ah->frags[ah->nfrag].len--;
679                                 /* link to next fragment */
680                                 ah->frags[ah->nfrag].nfrag = ah->nfrag + 1;
681                                 ah->nfrag++;
682                                 if (ah->nfrag >= ARRAY_SIZE(ah->frags))
683                                         goto excessive;
684                                 /* start next fragment after the & */
685                                 wsi->u.hdr.post_literal_equal = 0;
686                                 ah->frags[ah->nfrag].offset = ah->pos;
687                                 ah->frags[ah->nfrag].len = 0;
688                                 ah->frags[ah->nfrag].nfrag = 0;
689                                 goto swallow;
690                         }
691                         /* uriencoded = in the name part, disallow */
692                         if (c == '=' && enc &&
693                             ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] &&
694                             !wsi->u.hdr.post_literal_equal)
695                                 c = '_';
696
697                         /* after the real =, we don't care how many = */
698                         if (c == '=' && !enc)
699                                 wsi->u.hdr.post_literal_equal = 1;
700
701                         /* + to space */
702                         if (c == '+' && !enc)
703                                 c = ' ';
704                         /* issue the first / always */
705                         if (c == '/' && !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS])
706                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
707                         break;
708                 case URIPS_SEEN_SLASH:
709                         /* swallow subsequent slashes */
710                         if (c == '/')
711                                 goto swallow;
712                         /* track and swallow the first . after / */
713                         if (c == '.') {
714                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT;
715                                 goto swallow;
716                         }
717                         wsi->u.hdr.ups = URIPS_IDLE;
718                         break;
719                 case URIPS_SEEN_SLASH_DOT:
720                         /* swallow second . */
721                         if (c == '.') {
722                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
723                                 goto swallow;
724                         }
725                         /* change /./ to / */
726                         if (c == '/') {
727                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
728                                 goto swallow;
729                         }
730                         /* it was like /.dir ... regurgitate the . */
731                         wsi->u.hdr.ups = URIPS_IDLE;
732                         if (issue_char(wsi, '.') < 0)
733                                 return -1;
734                         break;
735
736                 case URIPS_SEEN_SLASH_DOT_DOT:
737
738                         /* /../ or /..[End of URI] --> backup to last / */
739                         if (c == '/' || c == '?') {
740                                 /*
741                                  * back up one dir level if possible
742                                  * safe against header fragmentation because
743                                  * the method URI can only be in 1 fragment
744                                  */
745                                 if (ah->frags[ah->nfrag].len > 2) {
746                                         ah->pos--;
747                                         ah->frags[ah->nfrag].len--;
748                                         do {
749                                                 ah->pos--;
750                                                 ah->frags[ah->nfrag].len--;
751                                         } while (ah->frags[ah->nfrag].len > 1 &&
752                                                  ah->data[ah->pos] != '/');
753                                 }
754                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
755                                 if (ah->frags[ah->nfrag].len > 1)
756                                         break;
757                                 goto swallow;
758                         }
759
760                         /*  /..[^/] ... regurgitate and allow */
761
762                         if (issue_char(wsi, '.') < 0)
763                                 return -1;
764                         if (issue_char(wsi, '.') < 0)
765                                 return -1;
766                         wsi->u.hdr.ups = URIPS_IDLE;
767                         break;
768                 }
769
770                 if (c == '?' && !enc &&
771                     !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI arguments */
772                         if (wsi->u.hdr.ues != URIES_IDLE)
773                                 goto forbid;
774
775                         /* seal off uri header */
776                         if (issue_char(wsi, '\0') < 0)
777                                 return -1;
778
779                         /* move to using WSI_TOKEN_HTTP_URI_ARGS */
780                         ah->nfrag++;
781                         if (ah->nfrag >= ARRAY_SIZE(ah->frags))
782                                 goto excessive;
783                         ah->frags[ah->nfrag].offset = ah->pos;
784                         ah->frags[ah->nfrag].len = 0;
785                         ah->frags[ah->nfrag].nfrag = 0;
786
787                         wsi->u.hdr.post_literal_equal = 0;
788                         ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = ah->nfrag;
789                         wsi->u.hdr.ups = URIPS_IDLE;
790                         goto swallow;
791                 }
792
793 check_eol:
794                 /* bail at EOL */
795                 if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE &&
796                     c == '\x0d') {
797                         if (wsi->u.hdr.ues != URIES_IDLE)
798                                 goto forbid;
799
800                         c = '\0';
801                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
802                         lwsl_parser("*\n");
803                 }
804
805                 n = issue_char(wsi, c);
806                 if ((int)n < 0)
807                         return -1;
808                 if (n > 0)
809                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
810
811 swallow:
812                 /* per-protocol end of headers management */
813
814                 if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
815                         goto set_parsing_complete;
816                 break;
817
818                 /* collecting and checking a name part */
819         case WSI_TOKEN_NAME_PART:
820                 lwsl_parser("WSI_TOKEN_NAME_PART '%c' (mode=%d)\n", c, wsi->mode);
821
822                 wsi->u.hdr.lextable_pos =
823                                 lextable_decode(wsi->u.hdr.lextable_pos, c);
824                 /*
825                  * Server needs to look out for unknown methods...
826                  */
827                 if (wsi->u.hdr.lextable_pos < 0 &&
828                     wsi->mode == LWSCM_HTTP_SERVING) {
829                         /* this is not a header we know about */
830                         for (m = 0; m < ARRAY_SIZE(methods); m++)
831                                 if (ah->frag_index[methods[m]]) {
832                                         /*
833                                          * already had the method, no idea what
834                                          * this crap from the client is, ignore
835                                          */
836                                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
837                                         break;
838                                 }
839                         /*
840                          * hm it's an unknown http method from a client in fact,
841                          * it cannot be valid http
842                          */
843                         if (m == ARRAY_SIZE(methods)) {
844                                 /*
845                                  * are we set up to accept raw in these cases?
846                                  */
847                                 if (lws_check_opt(wsi->vhost->options,
848                                            LWS_SERVER_OPTION_FALLBACK_TO_RAW))
849                                         return 2; /* transition to raw */
850
851                                 lwsl_info("Unknown method - dropping\n");
852                                 goto forbid;
853                         }
854                         break;
855                 }
856                 /*
857                  * ...otherwise for a client, let him ignore unknown headers
858                  * coming from the server
859                  */
860                 if (wsi->u.hdr.lextable_pos < 0) {
861                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
862                         break;
863                 }
864
865                 if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
866                         /* terminal state */
867
868                         n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
869                                         lextable[wsi->u.hdr.lextable_pos + 1];
870
871                         lwsl_parser("known hdr %d\n", n);
872                         for (m = 0; m < ARRAY_SIZE(methods); m++)
873                                 if (n == methods[m] &&
874                                     ah->frag_index[methods[m]]) {
875                                         lwsl_warn("Duplicated method\n");
876                                         return -1;
877                                 }
878
879                         /*
880                          * WSORIGIN is protocol equiv to ORIGIN,
881                          * JWebSocket likes to send it, map to ORIGIN
882                          */
883                         if (n == WSI_TOKEN_SWORIGIN)
884                                 n = WSI_TOKEN_ORIGIN;
885
886                         wsi->u.hdr.parser_state = (enum lws_token_indexes)
887                                                         (WSI_TOKEN_GET_URI + n);
888
889                         if (context->token_limits)
890                                 wsi->u.hdr.current_token_limit =
891                                         context->token_limits->token_limit[
892                                                        wsi->u.hdr.parser_state];
893                         else
894                                 wsi->u.hdr.current_token_limit =
895                                         wsi->context->max_http_header_data;
896
897                         if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
898                                 goto set_parsing_complete;
899
900                         goto start_fragment;
901                 }
902                 break;
903
904 start_fragment:
905                 ah->nfrag++;
906 excessive:
907                 if (ah->nfrag == ARRAY_SIZE(ah->frags)) {
908                         lwsl_warn("More hdr frags than we can deal with\n");
909                         return -1;
910                 }
911
912                 ah->frags[ah->nfrag].offset = ah->pos;
913                 ah->frags[ah->nfrag].len = 0;
914                 ah->frags[ah->nfrag].nfrag = 0;
915
916                 n = ah->frag_index[wsi->u.hdr.parser_state];
917                 if (!n) { /* first fragment */
918                         ah->frag_index[wsi->u.hdr.parser_state] = ah->nfrag;
919                         break;
920                 }
921                 /* continuation */
922                 while (ah->frags[n].nfrag)
923                         n = ah->frags[n].nfrag;
924                 ah->frags[n].nfrag = ah->nfrag;
925
926                 if (issue_char(wsi, ' ') < 0)
927                         return -1;
928                 break;
929
930                 /* skipping arg part of a name we didn't recognize */
931         case WSI_TOKEN_SKIPPING:
932                 lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c);
933
934                 if (c == '\x0d')
935                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
936                 break;
937
938         case WSI_TOKEN_SKIPPING_SAW_CR:
939                 lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
940                 if (wsi->u.hdr.ues != URIES_IDLE)
941                         goto forbid;
942                 if (c == '\x0a') {
943                         wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
944                         wsi->u.hdr.lextable_pos = 0;
945                 } else
946                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
947                 break;
948                 /* we're done, ignore anything else */
949
950         case WSI_PARSING_COMPLETE:
951                 lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c);
952                 break;
953         }
954
955         return 0;
956
957 set_parsing_complete:
958         if (wsi->u.hdr.ues != URIES_IDLE)
959                 goto forbid;
960         if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
961                 if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
962                         wsi->ietf_spec_revision =
963                                atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION));
964
965                 lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision);
966         }
967         wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
968         wsi->hdr_parsing_completed = 1;
969
970         return 0;
971
972 forbid:
973         lwsl_notice(" forbidding on uri sanitation\n");
974         lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
975         return -1;
976 }
977
978 LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi)
979 {
980         return wsi->u.ws.frame_is_binary;
981 }
982
983 void
984 lws_add_wsi_to_draining_ext_list(struct lws *wsi)
985 {
986         struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
987
988         if (wsi->u.ws.rx_draining_ext)
989                 return;
990
991         lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__);
992
993         wsi->u.ws.rx_draining_ext = 1;
994         wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
995         pt->rx_draining_ext_list = wsi;
996 }
997
998 void
999 lws_remove_wsi_from_draining_ext_list(struct lws *wsi)
1000 {
1001         struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
1002         struct lws **w = &pt->rx_draining_ext_list;
1003
1004         if (!wsi->u.ws.rx_draining_ext)
1005                 return;
1006
1007         lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__);
1008
1009         wsi->u.ws.rx_draining_ext = 0;
1010
1011         /* remove us from context draining ext list */
1012         while (*w) {
1013                 if (*w == wsi) {
1014                         /* if us, point it instead to who we were pointing to */
1015                         *w = wsi->u.ws.rx_draining_ext_list;
1016                         break;
1017                 }
1018                 w = &((*w)->u.ws.rx_draining_ext_list);
1019         }
1020         wsi->u.ws.rx_draining_ext_list = NULL;
1021 }
1022
1023 /*
1024  * client-parser.c: lws_client_rx_sm() needs to be roughly kept in
1025  *   sync with changes here, esp related to ext draining
1026  */
1027
1028 int
1029 lws_rx_sm(struct lws *wsi, unsigned char c)
1030 {
1031         int callback_action = LWS_CALLBACK_RECEIVE;
1032         int ret = 0, n, rx_draining_ext = 0;
1033         struct lws_tokens eff_buf;
1034
1035         eff_buf.token = NULL;
1036         eff_buf.token_len = 0;
1037         if (wsi->socket_is_permanently_unusable)
1038                 return -1;
1039
1040         switch (wsi->lws_rx_parse_state) {
1041         case LWS_RXPS_NEW:
1042                 if (wsi->u.ws.rx_draining_ext) {
1043                         eff_buf.token = NULL;
1044                         eff_buf.token_len = 0;
1045                         lws_remove_wsi_from_draining_ext_list(wsi);
1046                         rx_draining_ext = 1;
1047                         lwsl_debug("%s: doing draining flow\n", __func__);
1048
1049                         goto drain_extension;
1050                 }
1051                 switch (wsi->ietf_spec_revision) {
1052                 case 13:
1053                         /*
1054                          * no prepended frame key any more
1055                          */
1056                         wsi->u.ws.all_zero_nonce = 1;
1057                         goto handle_first;
1058
1059                 default:
1060                         lwsl_warn("lws_rx_sm: unknown spec version %d\n",
1061                                                        wsi->ietf_spec_revision);
1062                         break;
1063                 }
1064                 break;
1065         case LWS_RXPS_04_mask_1:
1066                 wsi->u.ws.mask[1] = c;
1067                 if (c)
1068                         wsi->u.ws.all_zero_nonce = 0;
1069                 wsi->lws_rx_parse_state = LWS_RXPS_04_mask_2;
1070                 break;
1071         case LWS_RXPS_04_mask_2:
1072                 wsi->u.ws.mask[2] = c;
1073                 if (c)
1074                         wsi->u.ws.all_zero_nonce = 0;
1075                 wsi->lws_rx_parse_state = LWS_RXPS_04_mask_3;
1076                 break;
1077         case LWS_RXPS_04_mask_3:
1078                 wsi->u.ws.mask[3] = c;
1079                 if (c)
1080                         wsi->u.ws.all_zero_nonce = 0;
1081
1082                 /*
1083                  * start from the zero'th byte in the XOR key buffer since
1084                  * this is the start of a frame with a new key
1085                  */
1086
1087                 wsi->u.ws.mask_idx = 0;
1088
1089                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
1090                 break;
1091
1092         /*
1093          *  04 logical framing from the spec (all this is masked when incoming
1094          *  and has to be unmasked)
1095          *
1096          * We ignore the possibility of extension data because we don't
1097          * negotiate any extensions at the moment.
1098          *
1099          *    0                   1                   2                   3
1100          *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1101          *   +-+-+-+-+-------+-+-------------+-------------------------------+
1102          *   |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
1103          *   |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
1104          *   |N|V|V|V|       |V|             |   (if payload len==126/127)   |
1105          *   | |1|2|3|       |4|             |                               |
1106          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
1107          *   |     Extended payload length continued, if payload len == 127  |
1108          *   + - - - - - - - - - - - - - - - +-------------------------------+
1109          *   |                               |         Extension data        |
1110          *   +-------------------------------+ - - - - - - - - - - - - - - - +
1111          *   :                                                               :
1112          *   +---------------------------------------------------------------+
1113          *   :                       Application data                        :
1114          *   +---------------------------------------------------------------+
1115          *
1116          *  We pass payload through to userland as soon as we get it, ignoring
1117          *  FIN.  It's up to userland to buffer it up if it wants to see a
1118          *  whole unfragmented block of the original size (which may be up to
1119          *  2^63 long!)
1120          */
1121
1122         case LWS_RXPS_04_FRAME_HDR_1:
1123 handle_first:
1124
1125                 wsi->u.ws.opcode = c & 0xf;
1126                 wsi->u.ws.rsv = c & 0x70;
1127                 wsi->u.ws.final = !!((c >> 7) & 1);
1128
1129                 switch (wsi->u.ws.opcode) {
1130                 case LWSWSOPC_TEXT_FRAME:
1131                 case LWSWSOPC_BINARY_FRAME:
1132                         wsi->u.ws.rsv_first_msg = (c & 0x70);
1133                         wsi->u.ws.frame_is_binary =
1134                              wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME;
1135                         break;
1136                 case 3:
1137                 case 4:
1138                 case 5:
1139                 case 6:
1140                 case 7:
1141                 case 0xb:
1142                 case 0xc:
1143                 case 0xd:
1144                 case 0xe:
1145                 case 0xf:
1146                         lwsl_info("illegal opcode\n");
1147                         return -1;
1148                 }
1149                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
1150                 break;
1151
1152         case LWS_RXPS_04_FRAME_HDR_LEN:
1153
1154                 wsi->u.ws.this_frame_masked = !!(c & 0x80);
1155
1156                 switch (c & 0x7f) {
1157                 case 126:
1158                         /* control frames are not allowed to have big lengths */
1159                         if (wsi->u.ws.opcode & 8)
1160                                 goto illegal_ctl_length;
1161
1162                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
1163                         break;
1164                 case 127:
1165                         /* control frames are not allowed to have big lengths */
1166                         if (wsi->u.ws.opcode & 8)
1167                                 goto illegal_ctl_length;
1168
1169                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
1170                         break;
1171                 default:
1172                         wsi->u.ws.rx_packet_length = c & 0x7f;
1173                         if (wsi->u.ws.this_frame_masked)
1174                                 wsi->lws_rx_parse_state =
1175                                                 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1176                         else
1177                                 if (wsi->u.ws.rx_packet_length)
1178                                         wsi->lws_rx_parse_state =
1179                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1180                                 else {
1181                                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1182                                         goto spill;
1183                                 }
1184                         break;
1185                 }
1186                 break;
1187
1188         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
1189                 wsi->u.ws.rx_packet_length = c << 8;
1190                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
1191                 break;
1192
1193         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
1194                 wsi->u.ws.rx_packet_length |= c;
1195                 if (wsi->u.ws.this_frame_masked)
1196                         wsi->lws_rx_parse_state =
1197                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1198                 else
1199                         wsi->lws_rx_parse_state =
1200                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1201                 break;
1202
1203         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
1204                 if (c & 0x80) {
1205                         lwsl_warn("b63 of length must be zero\n");
1206                         /* kill the connection */
1207                         return -1;
1208                 }
1209 #if defined __LP64__
1210                 wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
1211 #else
1212                 wsi->u.ws.rx_packet_length = 0;
1213 #endif
1214                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
1215                 break;
1216
1217         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
1218 #if defined __LP64__
1219                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
1220 #endif
1221                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
1222                 break;
1223
1224         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
1225 #if defined __LP64__
1226                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
1227 #endif
1228                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
1229                 break;
1230
1231         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
1232 #if defined __LP64__
1233                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
1234 #endif
1235                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
1236                 break;
1237
1238         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
1239                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
1240                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
1241                 break;
1242
1243         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
1244                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
1245                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
1246                 break;
1247
1248         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
1249                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
1250                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
1251                 break;
1252
1253         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
1254                 wsi->u.ws.rx_packet_length |= ((size_t)c);
1255                 if (wsi->u.ws.this_frame_masked)
1256                         wsi->lws_rx_parse_state =
1257                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1258                 else
1259                         wsi->lws_rx_parse_state =
1260                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1261                 break;
1262
1263         case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
1264                 wsi->u.ws.mask[0] = c;
1265                 if (c)
1266                         wsi->u.ws.all_zero_nonce = 0;
1267                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
1268                 break;
1269
1270         case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
1271                 wsi->u.ws.mask[1] = c;
1272                 if (c)
1273                         wsi->u.ws.all_zero_nonce = 0;
1274                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
1275                 break;
1276
1277         case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
1278                 wsi->u.ws.mask[2] = c;
1279                 if (c)
1280                         wsi->u.ws.all_zero_nonce = 0;
1281                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
1282                 break;
1283
1284         case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
1285                 wsi->u.ws.mask[3] = c;
1286                 if (c)
1287                         wsi->u.ws.all_zero_nonce = 0;
1288                 wsi->lws_rx_parse_state =
1289                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1290                 wsi->u.ws.mask_idx = 0;
1291                 if (wsi->u.ws.rx_packet_length == 0) {
1292                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1293                         goto spill;
1294                 }
1295                 break;
1296
1297
1298         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
1299                 assert(wsi->u.ws.rx_ubuf);
1300
1301                 if (wsi->u.ws.rx_draining_ext)
1302                         goto drain_extension;
1303
1304                 if (wsi->u.ws.rx_ubuf_head + LWS_PRE >=
1305                     wsi->u.ws.rx_ubuf_alloc) {
1306                         lwsl_err("Attempted overflow \n");
1307                         return -1;
1308                 }
1309                 if (wsi->u.ws.all_zero_nonce)
1310                         wsi->u.ws.rx_ubuf[LWS_PRE +
1311                                          (wsi->u.ws.rx_ubuf_head++)] = c;
1312                 else
1313                         wsi->u.ws.rx_ubuf[LWS_PRE +
1314                                (wsi->u.ws.rx_ubuf_head++)] =
1315                                    c ^ wsi->u.ws.mask[
1316                                             (wsi->u.ws.mask_idx++) & 3];
1317
1318                 if (--wsi->u.ws.rx_packet_length == 0) {
1319                         /* spill because we have the whole frame */
1320                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1321                         goto spill;
1322                 }
1323
1324                 /*
1325                  * if there's no protocol max frame size given, we are
1326                  * supposed to default to context->pt_serv_buf_size
1327                  */
1328
1329                 if (!wsi->protocol->rx_buffer_size &&
1330                     wsi->u.ws.rx_ubuf_head != wsi->context->pt_serv_buf_size)
1331                         break;
1332                 else
1333                         if (wsi->protocol->rx_buffer_size &&
1334                                         wsi->u.ws.rx_ubuf_head !=
1335                                                   wsi->protocol->rx_buffer_size)
1336                         break;
1337
1338                 /* spill because we filled our rx buffer */
1339 spill:
1340                 /*
1341                  * is this frame a control packet we should take care of at this
1342                  * layer?  If so service it and hide it from the user callback
1343                  */
1344
1345                 lwsl_parser("spill on %s\n", wsi->protocol->name);
1346
1347                 switch (wsi->u.ws.opcode) {
1348                 case LWSWSOPC_CLOSE:
1349
1350                         /* is this an acknowledgement of our close? */
1351                         if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
1352                                 /*
1353                                  * fine he has told us he is closing too, let's
1354                                  * finish our close
1355                                  */
1356                                 lwsl_parser("seen client close ack\n");
1357                                 return -1;
1358                         }
1359                         if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY)
1360                                 /* if he sends us 2 CLOSE, kill him */
1361                                 return -1;
1362
1363                         if (lws_partial_buffered(wsi)) {
1364                                 /*
1365                                  * if we're in the middle of something,
1366                                  * we can't do a normal close response and
1367                                  * have to just close our end.
1368                                  */
1369                                 wsi->socket_is_permanently_unusable = 1;
1370                                 lwsl_parser("Closing on peer close due to Pending tx\n");
1371                                 return -1;
1372                         }
1373
1374                         if (user_callback_handle_rxflow(
1375                                         wsi->protocol->callback, wsi,
1376                                         LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
1377                                         wsi->user_space,
1378                                         &wsi->u.ws.rx_ubuf[LWS_PRE],
1379                                         wsi->u.ws.rx_ubuf_head))
1380                                 return -1;
1381
1382                         lwsl_parser("server sees client close packet\n");
1383                         wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
1384                         /* deal with the close packet contents as a PONG */
1385                         wsi->u.ws.payload_is_close = 1;
1386                         goto process_as_ping;
1387
1388                 case LWSWSOPC_PING:
1389                         lwsl_info("received %d byte ping, sending pong\n",
1390                                                  wsi->u.ws.rx_ubuf_head);
1391
1392                         if (wsi->u.ws.ping_pending_flag) {
1393                                 /*
1394                                  * there is already a pending ping payload
1395                                  * we should just log and drop
1396                                  */
1397                                 lwsl_parser("DROP PING since one pending\n");
1398                                 goto ping_drop;
1399                         }
1400 process_as_ping:
1401                         /* control packets can only be < 128 bytes long */
1402                         if (wsi->u.ws.rx_ubuf_head > 128 - 3) {
1403                                 lwsl_parser("DROP PING payload too large\n");
1404                                 goto ping_drop;
1405                         }
1406
1407                         /* stash the pong payload */
1408                         memcpy(wsi->u.ws.ping_payload_buf + LWS_PRE,
1409                                &wsi->u.ws.rx_ubuf[LWS_PRE],
1410                                 wsi->u.ws.rx_ubuf_head);
1411
1412                         wsi->u.ws.ping_payload_len = wsi->u.ws.rx_ubuf_head;
1413                         wsi->u.ws.ping_pending_flag = 1;
1414
1415                         /* get it sent as soon as possible */
1416                         lws_callback_on_writable(wsi);
1417 ping_drop:
1418                         wsi->u.ws.rx_ubuf_head = 0;
1419                         return 0;
1420
1421                 case LWSWSOPC_PONG:
1422                         lwsl_info("received pong\n");
1423                         lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE],
1424                                      wsi->u.ws.rx_ubuf_head);
1425
1426                         if (wsi->pending_timeout == PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) {
1427                                 lwsl_info("received expected PONG on wsi %p\n", wsi);
1428                                 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
1429                         }
1430
1431                         /* issue it */
1432                         callback_action = LWS_CALLBACK_RECEIVE_PONG;
1433                         break;
1434
1435                 case LWSWSOPC_TEXT_FRAME:
1436                 case LWSWSOPC_BINARY_FRAME:
1437                 case LWSWSOPC_CONTINUATION:
1438                         break;
1439
1440                 default:
1441                         lwsl_parser("passing opc %x up to exts\n",
1442                                     wsi->u.ws.opcode);
1443                         /*
1444                          * It's something special we can't understand here.
1445                          * Pass the payload up to the extension's parsing
1446                          * state machine.
1447                          */
1448
1449                         eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
1450                         eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
1451
1452                         if (lws_ext_cb_active(wsi, LWS_EXT_CB_EXTENDED_PAYLOAD_RX,
1453                                               &eff_buf, 0) <= 0)
1454                                 /* not handle or fail */
1455                                 lwsl_ext("ext opc opcode 0x%x unknown\n",
1456                                          wsi->u.ws.opcode);
1457
1458                         wsi->u.ws.rx_ubuf_head = 0;
1459                         return 0;
1460                 }
1461
1462                 /*
1463                  * No it's real payload, pass it up to the user callback.
1464                  * It's nicely buffered with the pre-padding taken care of
1465                  * so it can be sent straight out again using lws_write
1466                  */
1467
1468                 eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
1469                 eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
1470
1471 drain_extension:
1472                 lwsl_ext("%s: passing %d to ext\n", __func__, eff_buf.token_len);
1473
1474                 if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
1475                     wsi->state == LWSS_AWAITING_CLOSE_ACK)
1476                         goto already_done;
1477
1478                 n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
1479                 /* eff_buf may be pointing somewhere completely different now,
1480                  * it's the output
1481                  */
1482                 if (n < 0) {
1483                         /*
1484                          * we may rely on this to get RX, just drop connection
1485                          */
1486                         wsi->socket_is_permanently_unusable = 1;
1487                         return -1;
1488                 }
1489
1490                 if (rx_draining_ext && eff_buf.token_len == 0)
1491                         goto already_done;
1492
1493                 if (n && eff_buf.token_len) {
1494                         /* extension had more... main loop will come back */
1495                         lws_add_wsi_to_draining_ext_list(wsi);
1496                 } else
1497                         lws_remove_wsi_from_draining_ext_list(wsi);
1498
1499                 if (eff_buf.token_len > 0 ||
1500                     callback_action == LWS_CALLBACK_RECEIVE_PONG) {
1501                         eff_buf.token[eff_buf.token_len] = '\0';
1502
1503                         if (wsi->protocol->callback) {
1504
1505                                 if (callback_action == LWS_CALLBACK_RECEIVE_PONG)
1506                                         lwsl_info("Doing pong callback\n");
1507
1508                                 ret = user_callback_handle_rxflow(
1509                                                 wsi->protocol->callback,
1510                                                 wsi,
1511                                                 (enum lws_callback_reasons)callback_action,
1512                                                 wsi->user_space,
1513                                                 eff_buf.token,
1514                                                 eff_buf.token_len);
1515                         }
1516                         else
1517                                 lwsl_err("No callback on payload spill!\n");
1518                 }
1519
1520 already_done:
1521                 wsi->u.ws.rx_ubuf_head = 0;
1522                 break;
1523         }
1524
1525         return ret;
1526
1527 illegal_ctl_length:
1528
1529         lwsl_warn("Control frame with xtended length is illegal\n");
1530         /* kill the connection */
1531         return -1;
1532 }
1533
1534 LWS_VISIBLE size_t
1535 lws_remaining_packet_payload(struct lws *wsi)
1536 {
1537         return wsi->u.ws.rx_packet_length;
1538 }
1539
1540 /* Once we reach LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED, we know how much
1541  * to expect in that state and can deal with it in bulk more efficiently.
1542  */
1543
1544 int
1545 lws_payload_until_length_exhausted(struct lws *wsi, unsigned char **buf,
1546                                    size_t *len)
1547 {
1548         unsigned char *buffer = *buf, mask[4];
1549         int buffer_size, n;
1550         unsigned int avail;
1551         char *rx_ubuf;
1552
1553         if (wsi->protocol->rx_buffer_size)
1554                 buffer_size = wsi->protocol->rx_buffer_size;
1555         else
1556                 buffer_size = wsi->context->pt_serv_buf_size;
1557         avail = buffer_size - wsi->u.ws.rx_ubuf_head;
1558
1559         /* do not consume more than we should */
1560         if (avail > wsi->u.ws.rx_packet_length)
1561                 avail = wsi->u.ws.rx_packet_length;
1562
1563         /* do not consume more than what is in the buffer */
1564         if (avail > *len)
1565                 avail = *len;
1566
1567         /* we want to leave 1 byte for the parser to handle properly */
1568         if (avail <= 1)
1569                 return 0;
1570
1571         avail--;
1572         rx_ubuf = wsi->u.ws.rx_ubuf + LWS_PRE + wsi->u.ws.rx_ubuf_head;
1573         if (wsi->u.ws.all_zero_nonce)
1574                 memcpy(rx_ubuf, buffer, avail);
1575         else {
1576
1577                 for (n = 0; n < 4; n++)
1578                         mask[n] = wsi->u.ws.mask[(wsi->u.ws.mask_idx + n) & 3];
1579
1580                 /* deal with 4-byte chunks using unwrapped loop */
1581                 n = avail >> 2;
1582                 while (n--) {
1583                         *(rx_ubuf++) = *(buffer++) ^ mask[0];
1584                         *(rx_ubuf++) = *(buffer++) ^ mask[1];
1585                         *(rx_ubuf++) = *(buffer++) ^ mask[2];
1586                         *(rx_ubuf++) = *(buffer++) ^ mask[3];
1587                 }
1588                 /* and the remaining bytes bytewise */
1589                 for (n = 0; n < (int)(avail & 3); n++)
1590                         *(rx_ubuf++) = *(buffer++) ^ mask[n];
1591
1592                 wsi->u.ws.mask_idx = (wsi->u.ws.mask_idx + avail) & 3;
1593         }
1594
1595         (*buf) += avail;
1596         wsi->u.ws.rx_ubuf_head += avail;
1597         wsi->u.ws.rx_packet_length -= avail;
1598         *len -= avail;
1599
1600         return avail;
1601 }