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