d1baa0eb26ada26c22016cba4c6185cb6bee1407
[platform/upstream/libwebsockets.git] / lib / client-handshake.c
1 #include "private-libwebsockets.h"
2
3 struct lws *
4 lws_client_connect_2(struct lws *wsi)
5 {
6 #ifdef LWS_USE_IPV6
7         struct sockaddr_in6 server_addr6;
8         struct sockaddr_in6 client_addr6;
9         struct addrinfo hints, *result;
10 #endif
11         struct lws_context *context = wsi->context;
12         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
13         struct sockaddr_in server_addr4;
14         struct sockaddr_in client_addr4;
15         struct lws_pollfd pfd;
16         struct sockaddr *v;
17         int n, plen = 0;
18         const char *ads;
19
20         lwsl_client("%s\n", __func__);
21
22         /* proxy? */
23
24         if (context->http_proxy_port) {
25                 plen = sprintf((char *)pt->serv_buf,
26                         "CONNECT %s:%u HTTP/1.0\x0d\x0a"
27                         "User-agent: libwebsockets\x0d\x0a",
28                         lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
29                         wsi->u.hdr.c_port);
30
31                 if (context->proxy_basic_auth_token[0])
32                         plen += sprintf((char *)pt->serv_buf + plen,
33                                         "Proxy-authorization: basic %s\x0d\x0a",
34                                         context->proxy_basic_auth_token);
35
36                 plen += sprintf((char *)pt->serv_buf + plen, "\x0d\x0a");
37                 ads = context->http_proxy_address;
38
39 #ifdef LWS_USE_IPV6
40                 if (LWS_IPV6_ENABLED(context)) {
41                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
42                         server_addr6.sin6_port = htons(context->http_proxy_port);
43                 } else
44 #endif
45                         server_addr4.sin_port = htons(context->http_proxy_port);
46
47         } else {
48                 ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
49 #ifdef LWS_USE_IPV6
50                 if (LWS_IPV6_ENABLED(context)) {
51                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
52                         server_addr6.sin6_port = htons(wsi->u.hdr.c_port);
53                 } else
54 #endif
55                         server_addr4.sin_port = htons(wsi->u.hdr.c_port);
56         }
57
58         /*
59          * prepare the actual connection (to the proxy, if any)
60          */
61        lwsl_client("%s: address %s\n", __func__, ads);
62
63 #ifdef LWS_USE_IPV6
64         if (LWS_IPV6_ENABLED(context)) {
65                 memset(&hints, 0, sizeof(struct addrinfo));
66 #if !defined(__ANDROID__)
67                 hints.ai_family = AF_INET6;
68                 hints.ai_flags = AI_V4MAPPED;
69 #endif
70                 n = getaddrinfo(ads, NULL, &hints, &result);
71                 if (n) {
72 #ifdef _WIN32
73                         lwsl_err("getaddrinfo: %ls\n", gai_strerrorW(n));
74 #else
75                         lwsl_err("getaddrinfo: %s\n", gai_strerror(n));
76 #endif
77                         goto oom4;
78                 }
79
80                 server_addr6.sin6_family = AF_INET6;
81                 switch (result->ai_family) {
82 #if defined(__ANDROID__)
83                 case AF_INET:
84                         /* map IPv4 to IPv6 */
85                         bzero((char *)&server_addr6.sin6_addr,
86                                                 sizeof(struct in6_addr));
87                         server_addr6.sin6_addr.s6_addr[10] = 0xff;
88                         server_addr6.sin6_addr.s6_addr[11] = 0xff;
89                         memcpy(&server_addr6.sin6_addr.s6_addr[12],
90                                 &((struct sockaddr_in *)result->ai_addr)->sin_addr,
91                                                         sizeof(struct in_addr));
92                         break;
93 #endif
94                 case AF_INET6:
95                         memcpy(&server_addr6.sin6_addr,
96                           &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
97                                                 sizeof(struct in6_addr));
98                         break;
99                 default:
100                         lwsl_err("Unknown address family\n");
101                         freeaddrinfo(result);
102                         goto oom4;
103                 }
104
105                 freeaddrinfo(result);
106         } else
107 #endif
108         {
109                 struct addrinfo ai, *res, *result;
110                 void *p = NULL;
111
112                 memset (&ai, 0, sizeof ai);
113                 ai.ai_family = PF_UNSPEC;
114                 ai.ai_socktype = SOCK_STREAM;
115                 ai.ai_flags = AI_CANONNAME;
116
117                 if (getaddrinfo(ads, NULL, &ai, &result))
118                         goto oom4;
119
120                 res = result;
121                 while (!p && res) {
122                         switch (res->ai_family) {
123                         case AF_INET:
124                                 p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
125                                 break;
126                         }
127
128                         res = res->ai_next;
129                 }
130
131                 if (!p) {
132                         freeaddrinfo(result);
133                         goto oom4;
134                 }
135
136                 server_addr4.sin_family = AF_INET;
137                 server_addr4.sin_addr = *((struct in_addr *)p);
138                 bzero(&server_addr4.sin_zero, 8);
139                 freeaddrinfo(result);
140         }
141
142         if (!lws_socket_is_valid(wsi->sock)) {
143
144 #ifdef LWS_USE_IPV6
145                 if (LWS_IPV6_ENABLED(context))
146                         wsi->sock = socket(AF_INET6, SOCK_STREAM, 0);
147                 else
148 #endif
149                         wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
150
151                 if (!lws_socket_is_valid(wsi->sock)) {
152                         lwsl_warn("Unable to open socket\n");
153                         goto oom4;
154                 }
155
156                 if (lws_plat_set_socket_options(context, wsi->sock)) {
157                         lwsl_err("Failed to set wsi socket options\n");
158                         compatible_close(wsi->sock);
159                         goto oom4;
160                 }
161
162                 wsi->mode = LWSCM_WSCL_WAITING_CONNECT;
163
164                 lws_libev_accept(wsi, wsi->sock);
165                 if (insert_wsi_socket_into_fds(context, wsi)) {
166                         compatible_close(wsi->sock);
167                         goto oom4;
168                 }
169
170                 /*
171                  * past here, we can't simply free the structs as error
172                  * handling as oom4 does.  We have to run the whole close flow.
173                  */
174
175                 lws_set_timeout(wsi,
176                         PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
177                                                               AWAITING_TIMEOUT);
178 #ifdef LWS_USE_IPV6
179                 if (LWS_IPV6_ENABLED(context)) {
180                         v = (struct sockaddr *)&client_addr6;
181                         n = sizeof(client_addr6);
182                         bzero((char *)v, n);
183                         client_addr6.sin6_family = AF_INET6;
184                 } else
185 #endif
186                 {
187                         v = (struct sockaddr *)&client_addr4;
188                         n = sizeof(client_addr4);
189                         bzero((char *)v, n);
190                         client_addr4.sin_family = AF_INET;
191                 }
192
193                 if (context->iface) {
194                         if (interface_to_sa(context, context->iface,
195                                         (struct sockaddr_in *)v, n) < 0) {
196                                 lwsl_err("Unable to find interface %s\n",
197                                                                 context->iface);
198                                 goto failed;
199                         }
200
201                         if (bind(wsi->sock, v, n) < 0) {
202                                 lwsl_err("Error binding to interface %s",
203                                                                 context->iface);
204                                 goto failed;
205                         }
206                 }
207         }
208
209 #ifdef LWS_USE_IPV6
210         if (LWS_IPV6_ENABLED(context)) {
211                 v = (struct sockaddr *)&server_addr6;
212                 n = sizeof(struct sockaddr_in6);
213         } else
214 #endif
215         {
216                 v = (struct sockaddr *)&server_addr4;
217                 n = sizeof(struct sockaddr);
218         }
219
220         if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
221                 if (LWS_ERRNO == LWS_EALREADY ||
222                     LWS_ERRNO == LWS_EINPROGRESS ||
223                     LWS_ERRNO == LWS_EWOULDBLOCK
224 #ifdef _WIN32
225                         || LWS_ERRNO == WSAEINVAL
226 #endif
227                 ) {
228                         lwsl_client("nonblocking connect retry\n");
229
230                         /*
231                          * must do specifically a POLLOUT poll to hear
232                          * about the connect completion
233                          */
234                         if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
235                                 goto failed;
236
237                         return wsi;
238                 }
239
240                 if (LWS_ERRNO != LWS_EISCONN) {
241                         lwsl_debug("Connect failed errno=%d\n", LWS_ERRNO);
242                         goto failed;
243                 }
244         }
245
246         lwsl_client("connected\n");
247
248         /* we are connected to server, or proxy */
249
250         if (context->http_proxy_port) {
251
252                 /*
253                  * OK from now on we talk via the proxy, so connect to that
254                  *
255                  * (will overwrite existing pointer,
256                  * leaving old string/frag there but unreferenced)
257                  */
258                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
259                                           context->http_proxy_address))
260                         goto failed;
261                 wsi->u.hdr.c_port = context->http_proxy_port;
262
263                 n = send(wsi->sock, (char *)pt->serv_buf, plen,
264                          MSG_NOSIGNAL);
265                 if (n < 0) {
266                         lwsl_debug("ERROR writing to proxy socket\n");
267                         goto failed;
268                 }
269
270                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
271                                 AWAITING_TIMEOUT);
272
273                 wsi->mode = LWSCM_WSCL_WAITING_PROXY_REPLY;
274
275                 return wsi;
276         }
277
278         /*
279          * provoke service to issue the handshake directly
280          * we need to do it this way because in the proxy case, this is the
281          * next state and executed only if and when we get a good proxy
282          * response inside the state machine... but notice in SSL case this
283          * may not have sent anything yet with 0 return, and won't until some
284          * many retries from main loop.  To stop that becoming endless,
285          * cover with a timeout.
286          */
287
288         lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
289                         AWAITING_TIMEOUT);
290
291         wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE;
292         pfd.fd = wsi->sock;
293         pfd.revents = LWS_POLLIN;
294
295         n = lws_service_fd(context, &pfd);
296         if (n < 0)
297                 goto failed;
298         if (n) /* returns 1 on failure after closing wsi */
299                 return NULL;
300
301         return wsi;
302
303 oom4:
304         /* we're closing, losing some rx is OK */
305         wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
306         lws_header_table_detach(wsi, 0);
307         lws_free(wsi);
308
309         return NULL;
310
311 failed:
312         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
313
314         return NULL;
315 }
316
317 /**
318  * lws_client_reset() - retarget a connected wsi to start over with a new connection (ie, redirect)
319  *                      this only works if still in HTTP, ie, not upgraded yet
320  * wsi:         connection to reset
321  * address:     network address of the new server
322  * port:        port to connect to
323  * path:        uri path to connect to on the new server
324  * host:        host header to send to the new server
325  */
326 LWS_VISIBLE struct lws *
327 lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const char *path, const char *host)
328 {
329         if (wsi->u.hdr.redirects == 3) {
330                 lwsl_err("%s: Too many redirects\n", __func__);
331                 return NULL;
332         }
333         wsi->u.hdr.redirects++;
334
335 #ifdef LWS_OPENSSL_SUPPORT
336         wsi->use_ssl = ssl;
337 #else
338         if (ssl) {
339                 lwsl_err("%s: not configured for ssl\n", __func__);
340                 return NULL;
341         }
342 #endif
343
344         lwsl_notice("redirect ads='%s', port=%d, path='%s'\n", address, port, path);
345
346         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
347                 return NULL;
348
349         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path))
350                 return NULL;
351
352         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
353                 return NULL;
354
355         compatible_close(wsi->sock);
356         remove_wsi_socket_from_fds(wsi);
357         wsi->sock = LWS_SOCK_INVALID;
358         wsi->state = LWSS_CLIENT_UNCONNECTED;
359         wsi->protocol = NULL;
360         wsi->pending_timeout = NO_PENDING_TIMEOUT;
361         wsi->u.hdr.c_port = port;
362
363         return lws_client_connect_2(wsi);
364 }
365
366 /**
367  * lws_client_connect_via_info() - Connect to another websocket server
368  * @i:pointer to lws_client_connect_info struct
369  *
370  *      This function creates a connection to a remote server
371  */
372
373
374 LWS_VISIBLE struct lws *
375 lws_client_connect_via_info(struct lws_client_connect_info *i)
376 {
377         struct lws *wsi;
378         int v = SPEC_LATEST_SUPPORTED;
379
380         wsi = lws_zalloc(sizeof(struct lws));
381         if (wsi == NULL)
382                 goto bail;
383
384         wsi->context = i->context;
385         /* assert the mode and union status (hdr) clearly */
386         lws_union_transition(wsi, LWSCM_HTTP_CLIENT);
387         wsi->sock = LWS_SOCK_INVALID;
388
389         /* 1) fill up the wsi with stuff from the connect_info as far as it
390          * can go.  It's because not only is our connection async, we might
391          * not even be able to get ahold of an ah at this point.
392          */
393
394         /* -1 means just use latest supported */
395         if (i->ietf_version_or_minus_one != -1 && i->ietf_version_or_minus_one)
396                 v = i->ietf_version_or_minus_one;
397
398         wsi->ietf_spec_revision = v;
399         wsi->user_space = NULL;
400         wsi->state = LWSS_CLIENT_UNCONNECTED;
401         wsi->protocol = NULL;
402         wsi->pending_timeout = NO_PENDING_TIMEOUT;
403         wsi->position_in_fds_table = -1;
404         wsi->u.hdr.c_port = i->port;
405
406         wsi->protocol = &i->context->protocols[0];
407         if (wsi && !wsi->user_space && i->userdata) {
408                 wsi->user_space_externally_allocated = 1;
409                 wsi->user_space = i->userdata;
410         }
411
412 #ifdef LWS_OPENSSL_SUPPORT
413         wsi->use_ssl = i->ssl_connection;
414 #else
415         if (i->ssl_connection) {
416                 lwsl_err("libwebsockets not configured for ssl\n");
417                 goto bail;
418         }
419 #endif
420         wsi->protocol = &i->context->protocols[0];
421         if (wsi && !wsi->user_space && i->userdata) {
422                 wsi->user_space_externally_allocated = 1;
423                 wsi->user_space = i->userdata;
424         }
425
426         /* 2) stash the things from connect_info that we can't process without
427          * an ah.  Because if no ah, we will go on the ah waiting list and
428          * process those things later (after the connect_info and maybe the
429          * things pointed to have gone out of scope.
430          */
431
432         wsi->u.hdr.stash = lws_malloc(sizeof(*wsi->u.hdr.stash));
433         if (!wsi->u.hdr.stash) {
434                 lwsl_err("%s: OOM\n", __func__);
435                 goto bail;
436         }
437
438         wsi->u.hdr.stash->origin[0] = '\0';
439         wsi->u.hdr.stash->protocol[0] = '\0';
440         wsi->u.hdr.stash->method[0] = '\0';
441
442         strncpy(wsi->u.hdr.stash->address, i->address,
443                 sizeof(wsi->u.hdr.stash->address) - 1);
444         strncpy(wsi->u.hdr.stash->path, i->path,
445                 sizeof(wsi->u.hdr.stash->path) - 1);
446         strncpy(wsi->u.hdr.stash->host, i->host,
447                 sizeof(wsi->u.hdr.stash->host) - 1);
448         if (i->origin)
449                 strncpy(wsi->u.hdr.stash->origin, i->origin,
450                         sizeof(wsi->u.hdr.stash->origin) - 1);
451         if (i->protocol)
452                 strncpy(wsi->u.hdr.stash->protocol, i->protocol,
453                         sizeof(wsi->u.hdr.stash->protocol) - 1);
454         if (i->method)
455                 strncpy(wsi->u.hdr.stash->method, i->method,
456                         sizeof(wsi->u.hdr.stash->method) - 1);
457
458         wsi->u.hdr.stash->address[sizeof(wsi->u.hdr.stash->address) - 1] = '\0';
459         wsi->u.hdr.stash->path[sizeof(wsi->u.hdr.stash->path) - 1] = '\0';
460         wsi->u.hdr.stash->host[sizeof(wsi->u.hdr.stash->host) - 1] = '\0';
461         wsi->u.hdr.stash->origin[sizeof(wsi->u.hdr.stash->origin) - 1] = '\0';
462         wsi->u.hdr.stash->protocol[sizeof(wsi->u.hdr.stash->protocol) - 1] = '\0';
463         wsi->u.hdr.stash->method[sizeof(wsi->u.hdr.stash->method) - 1] = '\0';
464
465         /* if we went on the waiting list, no probs just return the wsi
466          * when we get the ah, now or later, he will call
467          * lws_client_connect_via_info2() below
468          */
469         if (lws_header_table_attach(wsi, 0))
470                 lwsl_debug("%s: went on ah wait list\n", __func__);
471
472         return wsi;
473
474 bail:
475         lws_free(wsi);
476
477         return NULL;
478 }
479
480 struct lws *
481 lws_client_connect_via_info2(struct lws *wsi)
482 {
483         struct client_info_stash *stash = wsi->u.hdr.stash;
484
485         if (!stash)
486                 return wsi;
487
488         /*
489          * we're not necessarily in a position to action these right away,
490          * stash them... we only need during connect phase so u.hdr is fine
491          */
492         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
493                                   stash->address))
494                 goto bail1;
495
496         /* these only need u.hdr lifetime as well */
497
498         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash->path))
499                 goto bail1;
500
501         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, stash->host))
502                 goto bail1;
503
504         if (stash->origin[0])
505                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
506                                           stash->origin))
507                         goto bail1;
508         /*
509          * this is a list of protocols we tell the server we're okay with
510          * stash it for later when we compare server response with it
511          */
512         if (stash->protocol[0])
513                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
514                                           stash->protocol))
515                         goto bail1;
516         if (stash->method[0])
517                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
518                                           stash->method))
519                         goto bail1;
520
521         lws_free_set_NULL(wsi->u.hdr.stash);
522
523         /*
524          * Check with each extension if it is able to route and proxy this
525          * connection for us.  For example, an extension like x-google-mux
526          * can handle this and then we don't need an actual socket for this
527          * connection.
528          */
529
530         if (lws_ext_cb_all_exts(wsi->context, wsi,
531                                 LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION,
532                                 (void *)stash->address,
533                                 wsi->u.hdr.c_port) > 0) {
534                 lwsl_client("lws_client_connect: ext handling conn\n");
535
536                 lws_set_timeout(wsi,
537                         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
538                                 AWAITING_TIMEOUT);
539
540                 wsi->mode = LWSCM_WSCL_WAITING_EXTENSION_CONNECT;
541                 return wsi;
542         }
543         lwsl_client("lws_client_connect: direct conn\n");
544         wsi->context->count_wsi_allocated++;
545
546         return lws_client_connect_2(wsi);
547
548 bail1:
549         lws_free_set_NULL(wsi->u.hdr.stash);
550
551         return NULL;
552 }
553
554
555 /**
556  * lws_client_connect_extended() - Connect to another websocket server
557  *                              DEPRECATED use lws_client_connect_via_info
558  * @context:    Websocket context
559  * @address:    Remote server address, eg, "myserver.com"
560  * @port:       Port to connect to on the remote server, eg, 80
561  * @ssl_connection:     0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
562  *                      signed certs
563  * @path:       Websocket path on server
564  * @host:       Hostname on server
565  * @origin:     Socket origin name
566  * @protocol:   Comma-separated list of protocols being asked for from
567  *              the server, or just one.  The server will pick the one it
568  *              likes best.
569  * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
570  *              protocol supported, or the specific protocol ordinal
571  * @userdata: Pre-allocated user data
572  *
573  *      This function creates a connection to a remote server
574  */
575
576 LWS_VISIBLE struct lws *
577 lws_client_connect_extended(struct lws_context *context, const char *address,
578                             int port, int ssl_connection, const char *path,
579                             const char *host, const char *origin,
580                             const char *protocol, int ietf_version_or_minus_one,
581                             void *userdata)
582 {
583         struct lws_client_connect_info i;
584
585         memset(&i, 0, sizeof(i));
586
587         i.context = context;
588         i.address = address;
589         i.port = port;
590         i.ssl_connection = ssl_connection;
591         i.path = path;
592         i.host = host;
593         i.origin = origin;
594         i.protocol = protocol;
595         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
596         i.userdata = userdata;
597
598         return lws_client_connect_via_info(&i);
599 }
600 /**
601  * lws_client_connect_info() - Connect to another websocket server
602  *                              DEPRECATED use lws_client_connect_via_info
603  * @context:    Websocket context
604  * @address:    Remote server address, eg, "myserver.com"
605  * @port:       Port to connect to on the remote server, eg, 80
606  * @ssl_connection:     0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
607  *                      signed certs
608  * @path:       Websocket path on server
609  * @host:       Hostname on server
610  * @origin:     Socket origin name
611  * @protocol:   Comma-separated list of protocols being asked for from
612  *              the server, or just one.  The server will pick the one it
613  *              likes best.  If you don't want to specify a protocol, which is
614  *              legal, use NULL here.
615  * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
616  *              protocol supported, or the specific protocol ordinal
617  *
618  *      This function creates a connection to a remote server
619  */
620
621
622 LWS_VISIBLE struct lws *
623 lws_client_connect(struct lws_context *context, const char *address,
624                             int port, int ssl_connection, const char *path,
625                             const char *host, const char *origin,
626                             const char *protocol, int ietf_version_or_minus_one)
627 {
628         struct lws_client_connect_info i;
629
630         memset(&i, 0, sizeof(i));
631
632         i.context = context;
633         i.address = address;
634         i.port = port;
635         i.ssl_connection = ssl_connection;
636         i.path = path;
637         i.host = host;
638         i.origin = origin;
639         i.protocol = protocol;
640         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
641         i.userdata = NULL;
642
643         return lws_client_connect_via_info(&i);
644 }
645