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