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