adopt readbuf do service
[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.ah->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.ah->c_port);
53                 } else
54 #endif
55                         server_addr4.sin_port = htons(wsi->u.hdr.ah->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.ah->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.ah->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         wsi->sock = LWS_SOCK_INVALID;
386
387         /* -1 means just use latest supported */
388
389         if (i->ietf_version_or_minus_one != -1 && i->ietf_version_or_minus_one)
390                 v = i->ietf_version_or_minus_one;
391
392         wsi->ietf_spec_revision = v;
393         wsi->user_space = NULL;
394         wsi->state = LWSS_CLIENT_UNCONNECTED;
395         wsi->protocol = NULL;
396         wsi->pending_timeout = NO_PENDING_TIMEOUT;
397         wsi->position_in_fds_table = -1;
398
399 #ifdef LWS_OPENSSL_SUPPORT
400         wsi->use_ssl = i->ssl_connection;
401 #else
402         if (i->ssl_connection) {
403                 lwsl_err("libwebsockets not configured for ssl\n");
404                 goto bail;
405         }
406 #endif
407
408         if (lws_header_table_attach(wsi, 0))
409                 goto bail;
410
411         /*
412          * we're not necessarily in a position to action these right away,
413          * stash them... we only need during connect phase so u.hdr is fine
414          */
415         wsi->u.hdr.ah->c_port = i->port;
416         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, i->address))
417                 goto bail1;
418
419         /* these only need u.hdr lifetime as well */
420
421         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, i->path))
422                 goto bail1;
423
424         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, i->host))
425                 goto bail1;
426
427         if (i->origin)
428                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN, i->origin))
429                         goto bail1;
430         /*
431          * this is a list of protocols we tell the server we're okay with
432          * stash it for later when we compare server response with it
433          */
434         if (i->protocol)
435                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
436                                           i->protocol))
437                         goto bail1;
438
439         wsi->protocol = &i->context->protocols[0];
440         if (wsi && !wsi->user_space && i->userdata) {
441                 wsi->user_space_externally_allocated = 1;
442                 wsi->user_space = i->userdata;
443         }
444
445         /*
446          * Check with each extension if it is able to route and proxy this
447          * connection for us.  For example, an extension like x-google-mux
448          * can handle this and then we don't need an actual socket for this
449          * connection.
450          */
451
452         if (lws_ext_cb_all_exts(i->context, wsi,
453                         LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION,
454                                                      (void *)i->address, i->port) > 0) {
455                 lwsl_client("lws_client_connect: ext handling conn\n");
456
457                 lws_set_timeout(wsi,
458                         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
459                                 AWAITING_TIMEOUT);
460
461                 wsi->mode = LWSCM_WSCL_WAITING_EXTENSION_CONNECT;
462                 return wsi;
463         }
464         lwsl_client("lws_client_connect: direct conn\n");
465
466         wsi->context->count_wsi_allocated++;
467
468         return lws_client_connect_2(wsi);
469
470 bail1:
471         /* we're closing, losing some rx is OK */
472         wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
473         lws_header_table_detach(wsi, 0);
474 bail:
475         lws_free(wsi);
476
477         return NULL;
478 }
479
480
481 /**
482  * lws_client_connect_extended() - Connect to another websocket server
483  *                              DEPRECATED use lws_client_connect_via_info
484  * @context:    Websocket context
485  * @address:    Remote server address, eg, "myserver.com"
486  * @port:       Port to connect to on the remote server, eg, 80
487  * @ssl_connection:     0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
488  *                      signed certs
489  * @path:       Websocket path on server
490  * @host:       Hostname on server
491  * @origin:     Socket origin name
492  * @protocol:   Comma-separated list of protocols being asked for from
493  *              the server, or just one.  The server will pick the one it
494  *              likes best.
495  * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
496  *              protocol supported, or the specific protocol ordinal
497  * @userdata: Pre-allocated user data
498  *
499  *      This function creates a connection to a remote server
500  */
501
502 LWS_VISIBLE struct lws *
503 lws_client_connect_extended(struct lws_context *context, const char *address,
504                             int port, int ssl_connection, const char *path,
505                             const char *host, const char *origin,
506                             const char *protocol, int ietf_version_or_minus_one,
507                             void *userdata)
508 {
509         struct lws_client_connect_info i;
510
511         memset(&i, 0, sizeof(i));
512
513         i.context = context;
514         i.address = address;
515         i.port = port;
516         i.ssl_connection = ssl_connection;
517         i.path = path;
518         i.host = host;
519         i.origin = origin;
520         i.protocol = protocol;
521         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
522         i.userdata = userdata;
523
524         return lws_client_connect_via_info(&i);
525 }
526 /**
527  * lws_client_connect_info() - Connect to another websocket server
528  *                              DEPRECATED use lws_client_connect_via_info
529  * @context:    Websocket context
530  * @address:    Remote server address, eg, "myserver.com"
531  * @port:       Port to connect to on the remote server, eg, 80
532  * @ssl_connection:     0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
533  *                      signed certs
534  * @path:       Websocket path on server
535  * @host:       Hostname on server
536  * @origin:     Socket origin name
537  * @protocol:   Comma-separated list of protocols being asked for from
538  *              the server, or just one.  The server will pick the one it
539  *              likes best.  If you don't want to specify a protocol, which is
540  *              legal, use NULL here.
541  * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
542  *              protocol supported, or the specific protocol ordinal
543  *
544  *      This function creates a connection to a remote server
545  */
546
547
548 LWS_VISIBLE struct lws *
549 lws_client_connect(struct lws_context *context, const char *address,
550                             int port, int ssl_connection, const char *path,
551                             const char *host, const char *origin,
552                             const char *protocol, int ietf_version_or_minus_one)
553 {
554         struct lws_client_connect_info i;
555
556         memset(&i, 0, sizeof(i));
557
558         i.context = context;
559         i.address = address;
560         i.port = port;
561         i.ssl_connection = ssl_connection;
562         i.path = path;
563         i.host = host;
564         i.origin = origin;
565         i.protocol = protocol;
566         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
567         i.userdata = NULL;
568
569         return lws_client_connect_via_info(&i);
570 }
571