client check cb return during establish
[platform/upstream/libwebsockets.git] / lib / client.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2014 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 int lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len)
25 {
26         unsigned int n;
27
28         switch (wsi->mode) {
29         case LWSCM_WSCL_WAITING_PROXY_REPLY:
30         case LWSCM_WSCL_ISSUE_HANDSHAKE:
31         case LWSCM_WSCL_WAITING_SERVER_REPLY:
32         case LWSCM_WSCL_WAITING_EXTENSION_CONNECT:
33         case LWSCM_WS_CLIENT:
34                 for (n = 0; n < len; n++)
35                         if (lws_client_rx_sm(wsi, *(*buf)++)) {
36                                 lwsl_debug("client_rx_sm failed\n");
37                                 return 1;
38                         }
39                 return 0;
40         default:
41                 break;
42         }
43         return 0;
44 }
45
46 int lws_client_socket_service(struct lws_context *context,
47                               struct lws *wsi, struct lws_pollfd *pollfd)
48 {
49         char *p = (char *)&context->serv_buf[0];
50         unsigned char c;
51         int n, len;
52
53         switch (wsi->mode) {
54
55         case LWSCM_WSCL_WAITING_CONNECT:
56
57                 /*
58                  * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
59                  * timeout protection set in client-handshake.c
60                  */
61
62                if (lws_client_connect_2(wsi) == NULL) {
63                         /* closed */
64                         lwsl_client("closed\n");
65                         return -1;
66                 }
67
68                 /* either still pending connection, or changed mode */
69                 return 0;
70
71         case LWSCM_WSCL_WAITING_PROXY_REPLY:
72
73                 /* handle proxy hung up on us */
74
75                 if (pollfd->revents & LWS_POLLHUP) {
76
77                         lwsl_warn("Proxy connection %p (fd=%d) dead\n",
78                                   (void *)wsi, pollfd->fd);
79
80                         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
81                         return 0;
82                 }
83
84                 n = recv(wsi->sock, (char *)context->serv_buf,
85                                         sizeof(context->serv_buf), 0);
86                 if (n < 0) {
87
88                         if (LWS_ERRNO == LWS_EAGAIN) {
89                                 lwsl_debug("Proxy read returned EAGAIN... retrying\n");
90                                 return 0;
91                         }
92
93                         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
94                         lwsl_err("ERROR reading from proxy socket\n");
95                         return 0;
96                 }
97
98                 context->serv_buf[13] = '\0';
99                 if (strcmp((char *)context->serv_buf, "HTTP/1.0 200 ") &&
100                     strcmp((char *)context->serv_buf, "HTTP/1.1 200 ")
101                 ) {
102                         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
103                         lwsl_err("ERROR proxy: %s\n", context->serv_buf);
104                         return 0;
105                 }
106
107                 /* clear his proxy connection timeout */
108
109                 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
110
111                 /* fallthru */
112
113         case LWSCM_WSCL_ISSUE_HANDSHAKE:
114
115                 /*
116                  * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
117                  * timeout protection set in client-handshake.c
118                  */
119
120                 /*
121                  * take care of our lws_callback_on_writable
122                  * happening at a time when there's no real connection yet
123                  */
124                 if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
125                         return -1;
126                 lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_WRITE);
127
128 #ifdef LWS_OPENSSL_SUPPORT
129                 /* we can retry this... just cook the SSL BIO the first time */
130
131                 if (wsi->use_ssl && !wsi->ssl) {
132 #if defined(CYASSL_SNI_HOST_NAME) || defined(WOLFSSL_SNI_HOST_NAME) || defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
133                         const char *hostname = lws_hdr_simple_ptr(wsi,
134                                                 _WSI_TOKEN_CLIENT_HOST);
135 #endif
136
137                         wsi->ssl = SSL_new(context->ssl_client_ctx);
138 #ifndef USE_WOLFSSL
139                         SSL_set_mode(wsi->ssl,
140                                         SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
141 #endif
142                         /*
143                          * use server name indication (SNI), if supported,
144                          * when establishing connection
145                          */
146 #ifdef USE_WOLFSSL
147 #ifdef USE_OLD_CYASSL
148 #ifdef CYASSL_SNI_HOST_NAME
149                         CyaSSL_UseSNI(wsi->ssl, CYASSL_SNI_HOST_NAME,
150                                 hostname, strlen(hostname));
151 #endif
152 #else
153 #ifdef WOLFSSL_SNI_HOST_NAME
154                         wolfSSL_UseSNI(wsi->ssl, WOLFSSL_SNI_HOST_NAME,
155                                 hostname, strlen(hostname));
156 #endif
157 #endif
158 #else
159 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
160                         SSL_set_tlsext_host_name(wsi->ssl, hostname);
161 #endif
162 #endif
163
164 #ifdef USE_WOLFSSL
165                         /*
166                          * wolfSSL/CyaSSL does certificate verification differently
167                          * from OpenSSL.
168                          * If we should ignore the certificate, we need to set
169                          * this before SSL_new and SSL_connect is called.
170                          * Otherwise the connect will simply fail with error
171                          * code -155
172                          */
173 #ifdef USE_OLD_CYASSL
174                         if (wsi->use_ssl == 2)
175                                 CyaSSL_set_verify(wsi->ssl,
176                                                         SSL_VERIFY_NONE, NULL);
177 #else
178                         if (wsi->use_ssl == 2)
179                                 wolfSSL_set_verify(wsi->ssl,
180                                                         SSL_VERIFY_NONE, NULL);
181 #endif
182 #endif /* USE_WOLFSSL */
183
184                         wsi->client_bio =
185                                 BIO_new_socket(wsi->sock, BIO_NOCLOSE);
186                         SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
187
188 #ifdef USE_WOLFSSL
189 #ifdef USE_OLD_CYASSL
190                         CyaSSL_set_using_nonblock(wsi->ssl, 1);
191 #else
192                         wolfSSL_set_using_nonblock(wsi->ssl, 1);
193 #endif
194 #else
195                         BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */
196 #endif
197
198                         SSL_set_ex_data(wsi->ssl,
199                                         openssl_websocket_private_data_index,
200                                                                        context);
201                 }
202
203                 if (wsi->use_ssl) {
204                         lws_latency_pre(context, wsi);
205                         n = SSL_connect(wsi->ssl);
206                         lws_latency(context, wsi,
207                           "SSL_connect LWSCM_WSCL_ISSUE_HANDSHAKE",
208                                                                       n, n > 0);
209
210                         if (n < 0) {
211                                 n = SSL_get_error(wsi->ssl, n);
212
213                                 if (n == SSL_ERROR_WANT_READ)
214                                         goto some_wait;
215
216                                 if (n == SSL_ERROR_WANT_WRITE) {
217                                         /*
218                                          * wants us to retry connect due to
219                                          * state of the underlying ssl layer...
220                                          * but since it may be stalled on
221                                          * blocked write, no incoming data may
222                                          * arrive to trigger the retry.
223                                          * Force (possibly many times if the SSL
224                                          * state persists in returning the
225                                          * condition code, but other sockets
226                                          * are getting serviced inbetweentimes)
227                                          * us to get called back when writable.
228                                          */
229
230                                         lwsl_info(
231                                              "SSL_connect WANT_WRITE... retrying\n");
232                                         lws_callback_on_writable(wsi);
233 some_wait:
234                                         wsi->mode = LWSCM_WSCL_WAITING_SSL;
235
236                                         return 0; /* no error */
237                                 }
238                                 n = -1;
239                         }
240
241                         if (n <= 0) {
242                                 /*
243                                  * retry if new data comes until we
244                                  * run into the connection timeout or win
245                                  */
246
247                                 n = ERR_get_error();
248                                 if (n != SSL_ERROR_NONE) {
249                                         lwsl_err("SSL connect error %lu: %s\n",
250                                                 n,
251                                                 ERR_error_string(n,
252                                                           (char *)context->serv_buf));
253                                         return 0;
254                                 }
255                         }
256                 } else
257                         wsi->ssl = NULL;
258
259                 /* fallthru */
260
261         case LWSCM_WSCL_WAITING_SSL:
262
263                 if (wsi->use_ssl) {
264
265                         if (wsi->mode == LWSCM_WSCL_WAITING_SSL) {
266                                 lws_latency_pre(context, wsi);
267                                 n = SSL_connect(wsi->ssl);
268                                 lws_latency(context, wsi,
269                                             "SSL_connect LWSCM_WSCL_WAITING_SSL",
270                                             n, n > 0);
271
272                                 if (n < 0) {
273                                         n = SSL_get_error(wsi->ssl, n);
274
275                                         if (n == SSL_ERROR_WANT_READ)
276                                                 goto some_wait;
277
278                                         if (n == SSL_ERROR_WANT_WRITE) {
279                                                 /*
280                                                  * wants us to retry connect due to
281                                                  * state of the underlying ssl layer...
282                                                  * but since it may be stalled on
283                                                  * blocked write, no incoming data may
284                                                  * arrive to trigger the retry.
285                                                  * Force (possibly many times if the SSL
286                                                  * state persists in returning the
287                                                  * condition code, but other sockets
288                                                  * are getting serviced inbetweentimes)
289                                                  * us to get called back when writable.
290                                                  */
291
292                                                 lwsl_info("SSL_connect WANT_WRITE... retrying\n");
293                                                 lws_callback_on_writable(wsi);
294
295                                                 goto some_wait;
296                                         }
297                                         n = -1;
298                                 }
299
300                                 if (n <= 0) {
301                                         /*
302                                          * retry if new data comes until we
303                                          * run into the connection timeout or win
304                                          */
305                                         n = ERR_get_error();
306                                         if (n != SSL_ERROR_NONE) {
307                                                 lwsl_err("SSL connect error %lu: %s\n",
308                                                          n, ERR_error_string(n,
309                                                          (char *)context->serv_buf));
310                                                 return 0;
311                                         }
312                                 }
313                         }
314
315                         #ifndef USE_WOLFSSL
316                         /*
317                          * See comment above about wolfSSL certificate
318                          * verification
319                          */
320                         lws_latency_pre(context, wsi);
321                         n = SSL_get_verify_result(wsi->ssl);
322                         lws_latency(context, wsi,
323                                 "SSL_get_verify_result LWS_CONNMODE..HANDSHAKE",
324                                                                       n, n > 0);
325
326                         if (n != X509_V_OK) {
327                                 if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
328                                      n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) && wsi->use_ssl == 2) {
329                                         lwsl_notice("accepting self-signed certificate\n");
330                                 } else {
331                                         lwsl_err("server's cert didn't look good, X509_V_ERR = %d: %s\n",
332                                                  n, ERR_error_string(n, (char *)context->serv_buf));
333                                         lws_close_free_wsi(wsi,
334                                                 LWS_CLOSE_STATUS_NOSTATUS);
335                                         return 0;
336                                 }
337                         }
338 #endif /* USE_WOLFSSL */
339                 } else
340                         wsi->ssl = NULL;
341 #endif
342
343                 wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE2;
344                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
345                                 AWAITING_TIMEOUT);
346
347                 /* fallthru */
348
349         case LWSCM_WSCL_ISSUE_HANDSHAKE2:
350                 p = lws_generate_client_handshake(wsi, p);
351                 if (p == NULL) {
352                         lwsl_err("Failed to generate handshake for client\n");
353                         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
354                         return 0;
355                 }
356
357                 /* send our request to the server */
358
359                 lws_latency_pre(context, wsi);
360
361                 n = lws_ssl_capable_write(wsi, context->serv_buf,
362                                           p - (char *)context->serv_buf);
363                 lws_latency(context, wsi, "send lws_issue_raw", n,
364                             n == p - (char *)context->serv_buf);
365                 switch (n) {
366                 case LWS_SSL_CAPABLE_ERROR:
367                         lwsl_debug("ERROR writing to client socket\n");
368                         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
369                         return 0;
370                 case LWS_SSL_CAPABLE_MORE_SERVICE:
371                         lws_callback_on_writable(wsi);
372                         break;
373                 }
374
375                 wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
376                 wsi->u.hdr.lextable_pos = 0;
377                 wsi->mode = LWSCM_WSCL_WAITING_SERVER_REPLY;
378                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
379                                 AWAITING_TIMEOUT);
380                 break;
381
382         case LWSCM_WSCL_WAITING_SERVER_REPLY:
383
384                 /* handle server hung up on us */
385
386                 if (pollfd->revents & LWS_POLLHUP) {
387
388                         lwsl_debug("Server connection %p (fd=%d) dead\n",
389                                 (void *)wsi, pollfd->fd);
390
391                         goto bail3;
392                 }
393
394                 if (!(pollfd->revents & LWS_POLLIN))
395                         break;
396
397                 /* interpret the server response */
398
399                 /*
400                  *  HTTP/1.1 101 Switching Protocols
401                  *  Upgrade: websocket
402                  *  Connection: Upgrade
403                  *  Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
404                  *  Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
405                  *  Sec-WebSocket-Protocol: chat
406                  */
407
408                 /*
409                  * we have to take some care here to only take from the
410                  * socket bytewise.  The browser may (and has been seen to
411                  * in the case that onopen() performs websocket traffic)
412                  * coalesce both handshake response and websocket traffic
413                  * in one packet, since at that point the connection is
414                  * definitively ready from browser pov.
415                  */
416                 len = 1;
417                 while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE &&
418                        len > 0) {
419                         n = lws_ssl_capable_read(wsi, &c, 1);
420                         lws_latency(context, wsi, "send lws_issue_raw", n,
421                                     n == 1);
422                         switch (n) {
423                         case LWS_SSL_CAPABLE_ERROR:
424                                 goto bail3;
425                         case LWS_SSL_CAPABLE_MORE_SERVICE:
426                                 return 0;
427                         }
428
429                         if (lws_parse(wsi, c)) {
430                                 lwsl_warn("problems parsing header\n");
431                                 goto bail3;
432                         }
433                 }
434
435                 /*
436                  * hs may also be coming in multiple packets, there is a 5-sec
437                  * libwebsocket timeout still active here too, so if parsing did
438                  * not complete just wait for next packet coming in this state
439                  */
440
441                 if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
442                         break;
443
444                 /*
445                  * otherwise deal with the handshake.  If there's any
446                  * packet traffic already arrived we'll trigger poll() again
447                  * right away and deal with it that way
448                  */
449
450                 return lws_client_interpret_server_handshake(wsi);
451
452 bail3:
453                 lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n");
454                 lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
455                 return -1;
456
457         case LWSCM_WSCL_WAITING_EXTENSION_CONNECT:
458                 lwsl_ext("LWSCM_WSCL_WAITING_EXTENSION_CONNECT\n");
459                 break;
460
461         case LWSCM_WSCL_PENDING_CANDIDATE_CHILD:
462                 lwsl_ext("LWSCM_WSCL_PENDING_CANDIDATE_CHILD\n");
463                 break;
464         default:
465                 break;
466         }
467
468         return 0;
469 }
470
471
472 /*
473  * In-place str to lower case
474  */
475
476 static void
477 strtolower(char *s)
478 {
479         while (*s) {
480                 *s = tolower((int)*s);
481                 s++;
482         }
483 }
484
485 int
486 lws_client_interpret_server_handshake(struct lws *wsi)
487 {
488         struct lws_context *context = wsi->context;
489         int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR;
490         int n, len, okay = 0, isErrorCodeReceived = 0;
491         const char *pc;
492         char *p;
493 #ifndef LWS_NO_EXTENSIONS
494         const struct lws_extension *ext;
495         char ext_name[128];
496         const char *c;
497         int more = 1;
498         void *v;
499 #endif
500
501         /*
502          * well, what the server sent looked reasonable for syntax.
503          * Now let's confirm it sent all the necessary headers
504          */
505
506         if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) {
507                 lwsl_info("no ACCEPT\n");
508                 p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
509                 isErrorCodeReceived = 1;
510                 goto bail3;
511         }
512
513         p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
514         if (!p) {
515                 lwsl_info("no URI\n");
516                 goto bail3;
517         }
518         if (p && strncmp(p, "101", 3)) {
519                 lwsl_warn(
520                        "lws_client_handshake: got bad HTTP response '%s'\n", p);
521                 goto bail3;
522         }
523
524         p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE);
525         if (!p) {
526                 lwsl_info("no UPGRADE\n");
527                 goto bail3;
528         }
529         strtolower(p);
530         if (strcmp(p, "websocket")) {
531                 lwsl_warn(
532                       "lws_client_handshake: got bad Upgrade header '%s'\n", p);
533                 goto bail3;
534         }
535
536         p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_CONNECTION);
537         if (!p) {
538                 lwsl_info("no Connection hdr\n");
539                 goto bail3;
540         }
541         strtolower(p);
542         if (strcmp(p, "upgrade")) {
543                 lwsl_warn("lws_client_int_s_hs: bad header %s\n", p);
544                 goto bail3;
545         }
546
547         pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
548         if (!pc) {
549                 lwsl_parser("lws_client_int_s_hs: no protocol list\n");
550         } else
551                 lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc);
552
553         /*
554          * confirm the protocol the server wants to talk was in the list
555          * of protocols we offered
556          */
557
558         len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL);
559         if (!len) {
560
561                 lwsl_info("lws_client_int_s_hs: WSI_TOKEN_PROTOCOL is null\n");
562                 /*
563                  * no protocol name to work from,
564                  * default to first protocol
565                  */
566                 wsi->protocol = &context->protocols[0];
567                 goto check_extensions;
568         }
569
570         p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL);
571         len = strlen(p);
572
573         while (pc && *pc && !okay) {
574                 if (!strncmp(pc, p, len) &&
575                     (pc[len] == ',' || pc[len] == '\0')) {
576                         okay = 1;
577                         continue;
578                 }
579                 while (*pc && *pc++ != ',')
580                         ;
581                 while (*pc && *pc == ' ')
582                         pc++;
583         }
584
585         if (!okay) {
586                 lwsl_err("lws_client_int_s_hs: got bad protocol %s\n", p);
587                 goto bail2;
588         }
589
590         /*
591          * identify the selected protocol struct and set it
592          */
593         n = 0;
594         wsi->protocol = NULL;
595         while (context->protocols[n].callback && !wsi->protocol) {
596                 if (strcmp(p, context->protocols[n].name) == 0) {
597                         wsi->protocol = &context->protocols[n];
598                         break;
599                 }
600                 n++;
601         }
602
603         if (wsi->protocol == NULL) {
604                 lwsl_err("lws_client_int_s_hs: fail protocol %s\n", p);
605                 goto bail2;
606         }
607
608
609 check_extensions:
610 #ifndef LWS_NO_EXTENSIONS
611         /* instantiate the accepted extensions */
612
613         if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) {
614                 lwsl_ext("no client extenstions allowed by server\n");
615                 goto check_accept;
616         }
617
618         /*
619          * break down the list of server accepted extensions
620          * and go through matching them or identifying bogons
621          */
622
623         if (lws_hdr_copy(wsi, (char *)context->serv_buf,
624                    sizeof(context->serv_buf), WSI_TOKEN_EXTENSIONS) < 0) {
625                 lwsl_warn("ext list from server failed to copy\n");
626                 goto bail2;
627         }
628
629         c = (char *)context->serv_buf;
630         n = 0;
631         while (more) {
632
633                 if (*c && (*c != ',' && *c != ' ' && *c != '\t')) {
634                         ext_name[n] = *c++;
635                         if (n < sizeof(ext_name) - 1)
636                                 n++;
637                         continue;
638                 }
639                 ext_name[n] = '\0';
640                 if (!*c)
641                         more = 0;
642                 else {
643                         c++;
644                         if (!n)
645                                 continue;
646                 }
647
648                 /* check we actually support it */
649
650                 lwsl_ext("checking client ext %s\n", ext_name);
651
652                 n = 0;
653                 ext = lws_get_context(wsi)->extensions;
654                 while (ext && ext->callback) {
655                         if (strcmp(ext_name, ext->name)) {
656                                 ext++;
657                                 continue;
658                         }
659
660                         n = 1;
661                         lwsl_ext("instantiating client ext %s\n", ext_name);
662
663                         /* instantiate the extension on this conn */
664
665                         wsi->active_extensions_user[
666                                 wsi->count_active_extensions] =
667                                          lws_zalloc(ext->per_session_data_size);
668                         if (wsi->active_extensions_user[
669                                 wsi->count_active_extensions] == NULL) {
670                                 lwsl_err("Out of mem\n");
671                                 goto bail2;
672                         }
673                         wsi->active_extensions[
674                                   wsi->count_active_extensions] = ext;
675
676                         /* allow him to construct his context */
677
678                         ext->callback(lws_get_context(wsi), ext, wsi,
679                                       LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
680                                       wsi->active_extensions_user[
681                                          wsi->count_active_extensions],
682                                       NULL, 0);
683
684                         wsi->count_active_extensions++;
685
686                         ext++;
687                 }
688
689                 if (n == 0) {
690                         lwsl_warn("Unknown ext '%s'!\n", ext_name);
691                         goto bail2;
692                 }
693
694                 n = 0;
695         }
696
697 check_accept:
698 #endif
699
700         /*
701          * Confirm his accept token is the one we precomputed
702          */
703
704         p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT);
705         if (strcmp(p, wsi->u.hdr.ah->initial_handshake_hash_base64)) {
706                 lwsl_warn("lws_client_int_s_hs: accept %s wrong vs %s\n", p,
707                                   wsi->u.hdr.ah->initial_handshake_hash_base64);
708                 goto bail2;
709         }
710
711         /* allocate the per-connection user memory (if any) */
712         if (lws_ensure_user_space(wsi)) {
713                 lwsl_err("Problem allocating wsi user mem\n");
714                 goto bail2;
715         }
716
717         /*
718          * we seem to be good to go, give client last chance to check
719          * headers and OK it
720          */
721         if (wsi->protocol->callback(wsi,
722                                     LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
723                                     wsi->user_space, NULL, 0))
724                 goto bail2;
725
726         /* clear his proxy connection timeout */
727
728         lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
729
730         /* free up his parsing allocations */
731
732         lws_free(wsi->u.hdr.ah);
733
734         lws_union_transition(wsi, LWSCM_WS_CLIENT);
735         wsi->state = LWSS_ESTABLISHED;
736
737         wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
738
739         /*
740          * create the frame buffer for this connection according to the
741          * size mentioned in the protocol definition.  If 0 there, then
742          * use a big default for compatibility
743          */
744
745         n = wsi->protocol->rx_buffer_size;
746         if (!n)
747                 n = LWS_MAX_SOCKET_IO_BUF;
748         n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING;
749         wsi->u.ws.rx_user_buffer = lws_malloc(n);
750         if (!wsi->u.ws.rx_user_buffer) {
751                 lwsl_err("Out of Mem allocating rx buffer %d\n", n);
752                 goto bail2;
753         }
754         lwsl_info("Allocating client RX buffer %d\n", n);
755
756         if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n,
757                        sizeof n)) {
758                 lwsl_warn("Failed to set SNDBUF to %d", n);
759                 goto bail3;
760         }
761
762         lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name);
763
764         /* call him back to inform him he is up */
765
766         if (wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_ESTABLISHED,
767                                     wsi->user_space, NULL, 0))
768                 goto bail3;
769 #ifndef LWS_NO_EXTENSIONS
770         /*
771          * inform all extensions, not just active ones since they
772          * already know
773          */
774
775         ext = context->extensions;
776
777         while (ext && ext->callback) {
778                 v = NULL;
779                 for (n = 0; n < wsi->count_active_extensions; n++)
780                         if (wsi->active_extensions[n] == ext)
781                                 v = wsi->active_extensions_user[n];
782
783                 ext->callback(context, ext, wsi,
784                           LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, v, NULL, 0);
785                 ext++;
786         }
787 #endif
788
789         return 0;
790
791 bail3:
792         lws_free_set_NULL(wsi->u.ws.rx_user_buffer);
793         close_reason = LWS_CLOSE_STATUS_NOSTATUS;
794
795 bail2:
796         if (wsi->protocol) {
797                 if (isErrorCodeReceived && p) {
798                         wsi->protocol->callback(wsi,
799                                 LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
800                                                 wsi->user_space, p,
801                                                 (unsigned int)strlen(p));
802                 } else {
803                         wsi->protocol->callback(wsi,
804                                 LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
805                                                 wsi->user_space, NULL, 0);
806                 }
807         }
808
809         lwsl_info("closing connection due to bail2 connection error\n");
810
811         /* free up his parsing allocations */
812         lws_free_set_NULL(wsi->u.hdr.ah);
813         lws_close_free_wsi(wsi, close_reason);
814
815         return 1;
816 }
817
818
819 char *
820 lws_generate_client_handshake(struct lws *wsi, char *pkt)
821 {
822         char buf[128], hash[20], key_b64[40], *p = pkt;
823         struct lws_context *context = wsi->context;
824         int n;
825 #ifndef LWS_NO_EXTENSIONS
826         const struct lws_extension *ext;
827         int ext_count = 0;
828 #endif
829
830         /*
831          * create the random key
832          */
833         n = lws_get_random(context, hash, 16);
834         if (n != 16) {
835                 lwsl_err("Unable to read from random dev %s\n",
836                          SYSTEM_RANDOM_FILEPATH);
837                 lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
838                 return NULL;
839         }
840
841         lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64));
842
843         /*
844          * 00 example client handshake
845          *
846          * GET /socket.io/websocket HTTP/1.1
847          * Upgrade: WebSocket
848          * Connection: Upgrade
849          * Host: 127.0.0.1:9999
850          * Origin: http://127.0.0.1
851          * Sec-WebSocket-Key1: 1 0 2#0W 9 89 7  92 ^
852          * Sec-WebSocket-Key2: 7 7Y 4328 B2v[8(z1
853          * Cookie: socketio=websocket
854          *
855          * (Á®Ä0¶†≥
856          *
857          * 04 example client handshake
858          *
859          * GET /chat HTTP/1.1
860          * Host: server.example.com
861          * Upgrade: websocket
862          * Connection: Upgrade
863          * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
864          * Sec-WebSocket-Origin: http://example.com
865          * Sec-WebSocket-Protocol: chat, superchat
866          * Sec-WebSocket-Version: 4
867          */
868
869         p += sprintf(p, "GET %s HTTP/1.1\x0d\x0a",
870                      lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI));
871
872         p += sprintf(p, "Pragma: no-cache\x0d\x0a"
873                         "Cache-Control: no-cache\x0d\x0a");
874
875         p += sprintf(p, "Host: %s\x0d\x0a",
876                      lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST));
877         p += sprintf(p, "Upgrade: websocket\x0d\x0a"
878                         "Connection: Upgrade\x0d\x0a"
879                         "Sec-WebSocket-Key: ");
880         strcpy(p, key_b64);
881         p += strlen(key_b64);
882         p += sprintf(p, "\x0d\x0a");
883         if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN))
884                 p += sprintf(p, "Origin: http://%s\x0d\x0a",
885                              lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
886
887         if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS))
888                 p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a",
889                      lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS));
890
891         /* tell the server what extensions we could support */
892
893         p += sprintf(p, "Sec-WebSocket-Extensions: ");
894 #ifndef LWS_NO_EXTENSIONS
895         ext = context->extensions;
896         while (ext && ext->callback) {
897
898                 n = lws_ext_cb_all_exts(context, wsi,
899                            LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION,
900                            (char *)ext->name, 0);
901                 if (n) { /* an extension vetos us */
902                         lwsl_ext("ext %s vetoed\n", (char *)ext->name);
903                         ext++;
904                         continue;
905                 }
906
907                 n = context->protocols[0].callback(wsi,
908                         LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
909                                 wsi->user_space, (char *)ext->name, 0);
910
911                 /*
912                  * zero return from callback means
913                  * go ahead and allow the extension,
914                  * it's what we get if the callback is
915                  * unhandled
916                  */
917
918                 if (n) {
919                         ext++;
920                         continue;
921                 }
922
923                 /* apply it */
924
925                 if (ext_count)
926                         *p++ = ',';
927                 p += sprintf(p, "%s", ext->name);
928                 ext_count++;
929
930                 ext++;
931         }
932 #endif
933         p += sprintf(p, "\x0d\x0a");
934
935         if (wsi->ietf_spec_revision)
936                 p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a",
937                              wsi->ietf_spec_revision);
938
939         /* give userland a chance to append, eg, cookies */
940
941         context->protocols[0].callback(wsi,
942                                        LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
943                                        NULL, &p,
944                                        (pkt + sizeof(context->serv_buf)) - p - 12);
945
946         p += sprintf(p, "\x0d\x0a");
947
948         /* prepare the expected server accept response */
949
950         key_b64[39] = '\0'; /* enforce composed length below buf sizeof */
951         n = sprintf(buf, "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key_b64);
952
953         lws_SHA1((unsigned char *)buf, n, (unsigned char *)hash);
954
955         lws_b64_encode_string(hash, 20,
956                               wsi->u.hdr.ah->initial_handshake_hash_base64,
957                               sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64));
958
959         return p;
960 }
961