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