a9f866508cc248a5b1b669a5235b6c4e06f089be
[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 addrinfo hints, *result;
9 #endif
10         struct lws_context *context = wsi->context;
11         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
12         struct sockaddr_in server_addr4;
13         struct lws_pollfd pfd;
14         struct sockaddr *v;
15         const char *cce = "";
16         int n, plen = 0;
17         const char *ads;
18
19         lwsl_client("%s\n", __func__);
20
21         if (!wsi->u.hdr.ah) {
22                 cce = "ah was NULL at cc2";
23                 lwsl_err("%s\n", cce);
24                 goto oom4;
25         }
26
27         /* proxy? */
28
29         /* http proxy */
30         if (wsi->vhost->http_proxy_port) {
31                 plen = sprintf((char *)pt->serv_buf,
32                         "CONNECT %s:%u HTTP/1.0\x0d\x0a"
33                         "User-agent: libwebsockets\x0d\x0a",
34                         lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
35                         wsi->c_port);
36
37                 if (wsi->vhost->proxy_basic_auth_token[0])
38                         plen += sprintf((char *)pt->serv_buf + plen,
39                                         "Proxy-authorization: basic %s\x0d\x0a",
40                                         wsi->vhost->proxy_basic_auth_token);
41
42                 plen += sprintf((char *)pt->serv_buf + plen, "\x0d\x0a");
43                 ads = wsi->vhost->http_proxy_address;
44
45 #ifdef LWS_USE_IPV6
46                 if (LWS_IPV6_ENABLED(wsi->vhost)) {
47                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
48                         server_addr6.sin6_port = htons(wsi->vhost->http_proxy_port);
49                 } else
50 #endif
51                         server_addr4.sin_port = htons(wsi->vhost->http_proxy_port);
52
53         }
54 #if defined(LWS_WITH_SOCKS5)
55         /* socks proxy */
56         else if (wsi->vhost->socks_proxy_port) {
57                 socks_generate_msg(wsi, SOCKS_MSG_GREETING, (size_t *)&plen);
58                 lwsl_client("%s\n", "Sending SOCKS Greeting.");
59
60                 ads = wsi->vhost->socks_proxy_address;
61
62 #ifdef LWS_USE_IPV6
63                 if (LWS_IPV6_ENABLED(wsi->vhost)) {
64                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
65                         server_addr6.sin6_port = htons(wsi->vhost->socks_proxy_port);
66                 } else
67 #endif
68                         server_addr4.sin_port = htons(wsi->vhost->socks_proxy_port);
69
70         }
71 #endif
72         else {
73                 ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
74 #ifdef LWS_USE_IPV6
75                 if (LWS_IPV6_ENABLED(wsi->vhost)) {
76                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
77                         server_addr6.sin6_port = htons(wsi->c_port);
78                 } else
79 #endif
80                         server_addr4.sin_port = htons(wsi->c_port);
81         }
82
83         /*
84          * prepare the actual connection (to the proxy, if any)
85          */
86        lwsl_notice("%s: %p: address %s\n", __func__, wsi, ads);
87
88 #ifdef LWS_USE_IPV6
89         if (LWS_IPV6_ENABLED(wsi->vhost)) {
90                 memset(&hints, 0, sizeof(struct addrinfo));
91 #if !defined(__ANDROID__)
92                 hints.ai_family = AF_INET6;
93                 hints.ai_flags = AI_V4MAPPED;
94 #endif
95                 n = getaddrinfo(ads, NULL, &hints, &result);
96                 if (n) {
97 #ifdef _WIN32
98                         lwsl_err("getaddrinfo: %ls\n", gai_strerrorW(n));
99 #else
100                         lwsl_err("getaddrinfo: %s\n", gai_strerror(n));
101 #endif
102                         cce = "getaddrinfo (ipv6) failed";
103                         goto oom4;
104                 }
105
106                 server_addr6.sin6_family = AF_INET6;
107                 switch (result->ai_family) {
108 #if defined(__ANDROID__)
109                 case AF_INET:
110                         /* map IPv4 to IPv6 */
111                         bzero((char *)&server_addr6.sin6_addr,
112                                                 sizeof(struct in6_addr));
113                         server_addr6.sin6_addr.s6_addr[10] = 0xff;
114                         server_addr6.sin6_addr.s6_addr[11] = 0xff;
115                         memcpy(&server_addr6.sin6_addr.s6_addr[12],
116                                 &((struct sockaddr_in *)result->ai_addr)->sin_addr,
117                                                         sizeof(struct in_addr));
118                         break;
119 #endif
120                 case AF_INET6:
121                         memcpy(&server_addr6.sin6_addr,
122                           &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
123                                                 sizeof(struct in6_addr));
124                         break;
125                 default:
126                         lwsl_err("Unknown address family\n");
127                         freeaddrinfo(result);
128                         cce = "unknown address family";
129                         goto oom4;
130                 }
131
132                 freeaddrinfo(result);
133         } else
134 #endif
135         {
136                 struct addrinfo ai, *res, *result = NULL;
137                 void *p = NULL;
138                 int addr_rv;
139
140                 memset (&ai, 0, sizeof ai);
141                 ai.ai_family = PF_UNSPEC;
142                 ai.ai_socktype = SOCK_STREAM;
143                 ai.ai_flags = AI_CANONNAME;
144
145                 addr_rv = getaddrinfo(ads, NULL, &ai, &result);
146                 if (!addr_rv) {
147                         res = result;
148                         while (!p && res) {
149                                 switch (res->ai_family) {
150                                 case AF_INET:
151                                         p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
152                                         break;
153                                 }
154
155                                 res = res->ai_next;
156                         }
157 #if defined(LWS_FALLBACK_GETHOSTBYNAME)
158                 } else if (addr_rv == EAI_SYSTEM) {
159                         struct hostent *host;
160
161                         lwsl_info("getaddrinfo (ipv4) failed, trying gethostbyname\n");
162                         host = gethostbyname(ads);
163                         if (host) {
164                                 p = host->h_addr;
165                         } else {
166                                 lwsl_err("gethostbyname failed\n");
167                                 cce = "gethostbyname (ipv4) failed";
168                                 goto oom4;
169                         }
170 #endif
171                 } else {
172                         lwsl_err("getaddrinfo failed\n");
173                         cce = "getaddrinfo (ipv4) failed";
174                         goto oom4;
175                 }
176
177                 if (!p) {
178                         if (result)
179                                 freeaddrinfo(result);
180                         lwsl_err("Couldn't identify address\n");
181                         cce = "unable to lookup address";
182                         goto oom4;
183                 }
184
185                 server_addr4.sin_family = AF_INET;
186                 server_addr4.sin_addr = *((struct in_addr *)p);
187                 bzero(&server_addr4.sin_zero, 8);
188                 if (result)
189                         freeaddrinfo(result);
190         }
191
192         if (!lws_socket_is_valid(wsi->desc.sockfd)) {
193
194 #ifdef LWS_USE_IPV6
195                 if (LWS_IPV6_ENABLED(wsi->vhost))
196                         wsi->desc.sockfd = socket(AF_INET6, SOCK_STREAM, 0);
197                 else
198 #endif
199                         wsi->desc.sockfd = socket(AF_INET, SOCK_STREAM, 0);
200
201                 if (!lws_socket_is_valid(wsi->desc.sockfd)) {
202                         lwsl_warn("Unable to open socket\n");
203                         cce = "unable to open socket";
204                         goto oom4;
205                 }
206
207                 if (lws_plat_set_socket_options(wsi->vhost, wsi->desc.sockfd)) {
208                         lwsl_err("Failed to set wsi socket options\n");
209                         compatible_close(wsi->desc.sockfd);
210                         cce = "set socket opts failed";
211                         goto oom4;
212                 }
213
214                 wsi->mode = LWSCM_WSCL_WAITING_CONNECT;
215
216                 lws_libev_accept(wsi, wsi->desc);
217                 lws_libuv_accept(wsi, wsi->desc);
218                 lws_libevent_accept(wsi, wsi->desc);
219                 if (insert_wsi_socket_into_fds(context, wsi)) {
220                         compatible_close(wsi->desc.sockfd);
221                         cce = "insert wsi failed";
222                         goto oom4;
223                 }
224
225                 lws_change_pollfd(wsi, 0, LWS_POLLIN);
226
227                 /*
228                  * past here, we can't simply free the structs as error
229                  * handling as oom4 does.  We have to run the whole close flow.
230                  */
231
232                 if (!wsi->protocol)
233                         wsi->protocol = &wsi->vhost->protocols[0];
234
235                 wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_CREATE,
236                                         wsi->user_space, NULL, 0);
237
238                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
239                                 AWAITING_TIMEOUT);
240
241                 n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, wsi->vhost->iface);
242                 if (n < 0) {
243                         cce = "unable to bind socket";
244                         goto failed;
245                 }
246         }
247
248 #ifdef LWS_USE_IPV6
249         if (LWS_IPV6_ENABLED(wsi->vhost)) {
250                 v = (struct sockaddr *)&server_addr6;
251                 n = sizeof(struct sockaddr_in6);
252         } else
253 #endif
254         {
255                 v = (struct sockaddr *)&server_addr4;
256                 n = sizeof(struct sockaddr);
257         }
258
259         if (connect(wsi->desc.sockfd, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
260                 if (LWS_ERRNO == LWS_EALREADY ||
261                     LWS_ERRNO == LWS_EINPROGRESS ||
262                     LWS_ERRNO == LWS_EWOULDBLOCK
263 #ifdef _WIN32
264                         || LWS_ERRNO == WSAEINVAL
265 #endif
266                 ) {
267                         lwsl_client("nonblocking connect retry (errno = %d)\n",
268                                     LWS_ERRNO);
269
270                         if (lws_plat_check_connection_error(wsi)) {
271                                 cce = "socket connect failed";
272                                 goto failed;
273                         }
274
275                         /*
276                          * must do specifically a POLLOUT poll to hear
277                          * about the connect completion
278                          */
279                         if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
280                                 cce = "POLLOUT set failed";
281                                 goto failed;
282                         }
283
284                         return wsi;
285                 }
286
287                 if (LWS_ERRNO != LWS_EISCONN) {
288                         lwsl_notice("Connect failed errno=%d\n", LWS_ERRNO);
289                         cce = "connect failed";
290                         goto failed;
291                 }
292         }
293
294         lwsl_client("connected\n");
295
296         /* we are connected to server, or proxy */
297
298         /* http proxy */
299         if (wsi->vhost->http_proxy_port) {
300
301                 /*
302                  * OK from now on we talk via the proxy, so connect to that
303                  *
304                  * (will overwrite existing pointer,
305                  * leaving old string/frag there but unreferenced)
306                  */
307                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
308                                           wsi->vhost->http_proxy_address))
309                         goto failed;
310                 wsi->c_port = wsi->vhost->http_proxy_port;
311
312                 n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
313                          MSG_NOSIGNAL);
314                 if (n < 0) {
315                         lwsl_debug("ERROR writing to proxy socket\n");
316                         cce = "proxy write failed";
317                         goto failed;
318                 }
319
320                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
321                                 AWAITING_TIMEOUT);
322
323                 wsi->mode = LWSCM_WSCL_WAITING_PROXY_REPLY;
324
325                 return wsi;
326         }
327 #if defined(LWS_WITH_SOCKS5)
328         /* socks proxy */
329         else if (wsi->vhost->socks_proxy_port) {
330                 n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
331                          MSG_NOSIGNAL);
332                 if (n < 0) {
333                         lwsl_debug("ERROR writing greeting to socks proxy"
334                                 "socket.\n");
335                         cce = "socks write failed";
336                         goto failed;
337                 }
338
339                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY,
340                                 AWAITING_TIMEOUT);
341
342                 wsi->mode = LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY;
343
344                 return wsi;
345         }
346 #endif
347
348         /*
349          * provoke service to issue the handshake directly
350          * we need to do it this way because in the proxy case, this is the
351          * next state and executed only if and when we get a good proxy
352          * response inside the state machine... but notice in SSL case this
353          * may not have sent anything yet with 0 return, and won't until some
354          * many retries from main loop.  To stop that becoming endless,
355          * cover with a timeout.
356          */
357
358         lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
359                         AWAITING_TIMEOUT);
360
361         wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE;
362         pfd.fd = wsi->desc.sockfd;
363         pfd.events = LWS_POLLIN;
364         pfd.revents = LWS_POLLIN;
365
366         n = lws_service_fd(context, &pfd);
367         if (n < 0) {
368                 cce = "first service failed";
369                 goto failed;
370         }
371         if (n) /* returns 1 on failure after closing wsi */
372                 return NULL;
373
374         return wsi;
375
376 oom4:
377         /* we're closing, losing some rx is OK */
378         if (wsi->u.hdr.ah)
379                 wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
380         if (wsi->mode == LWSCM_HTTP_CLIENT ||
381             wsi->mode == LWSCM_HTTP_CLIENT_ACCEPTED ||
382             wsi->mode == LWSCM_WSCL_WAITING_CONNECT) {
383                 wsi->vhost->protocols[0].callback(wsi,
384                         LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
385                         wsi->user_space, (void *)cce, strlen(cce));
386                 wsi->already_did_cce = 1;
387         }
388         /* take care that we might be inserted in fds already */
389         if (wsi->position_in_fds_table != -1)
390                 goto failed1;
391         lws_remove_from_timeout_list(wsi);
392         lws_header_table_detach(wsi, 0);
393         lws_free(wsi);
394
395         return NULL;
396
397 failed:
398         wsi->vhost->protocols[0].callback(wsi,
399                 LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
400                 wsi->user_space, (void *)cce, strlen(cce));
401         wsi->already_did_cce = 1;
402 failed1:
403         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
404
405         return NULL;
406 }
407
408 /**
409  * lws_client_reset() - retarget a connected wsi to start over with a new connection (ie, redirect)
410  *                      this only works if still in HTTP, ie, not upgraded yet
411  * wsi:         connection to reset
412  * address:     network address of the new server
413  * port:        port to connect to
414  * path:        uri path to connect to on the new server
415  * host:        host header to send to the new server
416  */
417 LWS_VISIBLE struct lws *
418 lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
419                  const char *path, const char *host)
420 {
421         char origin[300] = "", protocol[300] = "", method[32] = "", *p;
422         struct lws *wsi = *pwsi;
423
424         if (wsi->redirects == 3) {
425                 lwsl_err("%s: Too many redirects\n", __func__);
426                 return NULL;
427         }
428         wsi->redirects++;
429
430 #ifdef LWS_OPENSSL_SUPPORT
431         wsi->use_ssl = ssl;
432 #else
433         if (ssl) {
434                 lwsl_err("%s: not configured for ssl\n", __func__);
435                 return NULL;
436         }
437 #endif
438
439         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
440         if (p)
441                 strncpy(origin, p, sizeof(origin) - 1);
442
443         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
444         if (p)
445                 strncpy(protocol, p, sizeof(protocol) - 1);
446
447         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
448         if (p)
449                 strncpy(method, p, sizeof(method) - 1);
450
451         lwsl_debug("redirect ads='%s', port=%d, path='%s', ssl = %d\n",
452                    address, port, path, ssl);
453
454         /* close the connection by hand */
455
456         compatible_close(wsi->desc.sockfd);
457         remove_wsi_socket_from_fds(wsi);
458
459         wsi->desc.sockfd = LWS_SOCK_INVALID;
460         wsi->state = LWSS_CLIENT_UNCONNECTED;
461         wsi->protocol = NULL;
462         wsi->pending_timeout = NO_PENDING_TIMEOUT;
463         wsi->c_port = port;
464         wsi->hdr_parsing_completed = 0;
465         _lws_header_table_reset(wsi->u.hdr.ah);
466
467         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
468                 return NULL;
469
470         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
471                 return NULL;
472
473         if (origin[0])
474                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
475                                           origin))
476                         return NULL;
477         if (protocol[0])
478                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
479                                           protocol))
480                         return NULL;
481         if (method[0])
482                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
483                                           method))
484                         return NULL;
485
486         origin[0] = '/';
487         strncpy(&origin[1], path, sizeof(origin) - 2);
488         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, origin))
489                 return NULL;
490
491         *pwsi = lws_client_connect_2(wsi);
492
493         return *pwsi;
494 }
495
496 #ifdef LWS_WITH_HTTP_PROXY
497 static hubbub_error
498 html_parser_cb(const hubbub_token *token, void *pw)
499 {
500         struct lws_rewrite *r = (struct lws_rewrite *)pw;
501         char buf[1024], *start = buf + LWS_PRE, *p = start,
502              *end = &buf[sizeof(buf) - 1];
503         size_t i;
504
505         switch (token->type) {
506         case HUBBUB_TOKEN_DOCTYPE:
507
508                 p += lws_snprintf(p, end - p, "<!DOCTYPE %.*s %s ",
509                                 (int) token->data.doctype.name.len,
510                                 token->data.doctype.name.ptr,
511                                 token->data.doctype.force_quirks ?
512                                                 "(force-quirks) " : "");
513
514                 if (token->data.doctype.public_missing)
515                         printf("\tpublic: missing\n");
516                 else
517                         p += lws_snprintf(p, end - p, "PUBLIC \"%.*s\"\n",
518                                 (int) token->data.doctype.public_id.len,
519                                 token->data.doctype.public_id.ptr);
520
521                 if (token->data.doctype.system_missing)
522                         printf("\tsystem: missing\n");
523                 else
524                         p += lws_snprintf(p, end - p, " \"%.*s\">\n",
525                                 (int) token->data.doctype.system_id.len,
526                                 token->data.doctype.system_id.ptr);
527
528                 break;
529         case HUBBUB_TOKEN_START_TAG:
530                 p += lws_snprintf(p, end - p, "<%.*s", (int)token->data.tag.name.len,
531                                 token->data.tag.name.ptr);
532
533 /*                              (token->data.tag.self_closing) ?
534                                                 "(self-closing) " : "",
535                                 (token->data.tag.n_attributes > 0) ?
536                                                 "attributes:" : "");
537 */
538                 for (i = 0; i < token->data.tag.n_attributes; i++) {
539                         if (!hstrcmp(&token->data.tag.attributes[i].name, "href", 4) ||
540                             !hstrcmp(&token->data.tag.attributes[i].name, "action", 6) ||
541                             !hstrcmp(&token->data.tag.attributes[i].name, "src", 3)) {
542                                 const char *pp = (const char *)token->data.tag.attributes[i].value.ptr;
543                                 int plen = (int) token->data.tag.attributes[i].value.len;
544
545                                 if (!hstrcmp(&token->data.tag.attributes[i].value,
546                                              r->from, r->from_len)) {
547                                         pp += r->from_len;
548                                         plen -= r->from_len;
549                                 }
550                                 p += lws_snprintf(p, end - p, " %.*s=\"%s/%.*s\"",
551                                        (int) token->data.tag.attributes[i].name.len,
552                                        token->data.tag.attributes[i].name.ptr,
553                                        r->to, plen, pp);
554
555                         } else
556
557                                 p += lws_snprintf(p, end - p, " %.*s=\"%.*s\"",
558                                         (int) token->data.tag.attributes[i].name.len,
559                                         token->data.tag.attributes[i].name.ptr,
560                                         (int) token->data.tag.attributes[i].value.len,
561                                         token->data.tag.attributes[i].value.ptr);
562                 }
563                 p += lws_snprintf(p, end - p, ">\n");
564                 break;
565         case HUBBUB_TOKEN_END_TAG:
566                 p += lws_snprintf(p, end - p, "</%.*s", (int) token->data.tag.name.len,
567                                 token->data.tag.name.ptr);
568 /*
569                                 (token->data.tag.self_closing) ?
570                                                 "(self-closing) " : "",
571                                 (token->data.tag.n_attributes > 0) ?
572                                                 "attributes:" : "");
573 */
574                 for (i = 0; i < token->data.tag.n_attributes; i++) {
575                         p += lws_snprintf(p, end - p, " %.*s='%.*s'\n",
576                                 (int) token->data.tag.attributes[i].name.len,
577                                 token->data.tag.attributes[i].name.ptr,
578                                 (int) token->data.tag.attributes[i].value.len,
579                                 token->data.tag.attributes[i].value.ptr);
580                 }
581                 p += lws_snprintf(p, end - p, ">\n");
582                 break;
583         case HUBBUB_TOKEN_COMMENT:
584                 p += lws_snprintf(p, end - p, "<!-- %.*s -->\n",
585                                 (int) token->data.comment.len,
586                                 token->data.comment.ptr);
587                 break;
588         case HUBBUB_TOKEN_CHARACTER:
589                 p += lws_snprintf(p, end - p, "%.*s", (int) token->data.character.len,
590                                 token->data.character.ptr);
591                 break;
592         case HUBBUB_TOKEN_EOF:
593                 p += lws_snprintf(p, end - p, "\n");
594                 break;
595         }
596
597         if (user_callback_handle_rxflow(r->wsi->protocol->callback,
598                         r->wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ,
599                         r->wsi->user_space, start, p - start))
600                 return -1;
601
602         return HUBBUB_OK;
603 }
604 #endif
605
606 LWS_VISIBLE struct lws *
607 lws_client_connect_via_info(struct lws_client_connect_info *i)
608 {
609         struct lws *wsi;
610         int v = SPEC_LATEST_SUPPORTED;
611         const struct lws_protocols *p;
612
613         if (i->context->requested_kill)
614                 return NULL;
615
616         if (!i->context->protocol_init_done)
617                 lws_protocol_init(i->context);
618
619         wsi = lws_zalloc(sizeof(struct lws));
620         if (wsi == NULL)
621                 goto bail;
622
623         wsi->context = i->context;
624         /* assert the mode and union status (hdr) clearly */
625         lws_union_transition(wsi, LWSCM_HTTP_CLIENT);
626         wsi->desc.sockfd = LWS_SOCK_INVALID;
627
628         /* 1) fill up the wsi with stuff from the connect_info as far as it
629          * can go.  It's because not only is our connection async, we might
630          * not even be able to get ahold of an ah at this point.
631          */
632
633         /* -1 means just use latest supported */
634         if (i->ietf_version_or_minus_one != -1 && i->ietf_version_or_minus_one)
635                 v = i->ietf_version_or_minus_one;
636
637         wsi->ietf_spec_revision = v;
638         wsi->user_space = NULL;
639         wsi->state = LWSS_CLIENT_UNCONNECTED;
640         wsi->pending_timeout = NO_PENDING_TIMEOUT;
641         wsi->position_in_fds_table = -1;
642         wsi->c_port = i->port;
643         wsi->vhost = i->vhost;
644         if (!wsi->vhost)
645                 wsi->vhost = i->context->vhost_list;
646
647         wsi->protocol = &wsi->vhost->protocols[0];
648
649         /* for http[s] connection, allow protocol selection by name */
650
651         if (i->method && i->vhost && i->protocol) {
652                 p = lws_vhost_name_to_protocol(i->vhost, i->protocol);
653                 if (p)
654                         wsi->protocol = p;
655         }
656
657         if (wsi && !wsi->user_space && i->userdata) {
658                 wsi->user_space_externally_allocated = 1;
659                 wsi->user_space = i->userdata;
660         } else
661                 /* if we stay in http, we can assign the user space now,
662                  * otherwise do it after the protocol negotiated
663                  */
664                 if (i->method)
665                         if (lws_ensure_user_space(wsi))
666                                 goto bail;
667
668 #ifdef LWS_OPENSSL_SUPPORT
669         wsi->use_ssl = i->ssl_connection;
670 #else
671         if (i->ssl_connection) {
672                 lwsl_err("libwebsockets not configured for ssl\n");
673                 goto bail;
674         }
675 #endif
676
677         /* 2) stash the things from connect_info that we can't process without
678          * an ah.  Because if no ah, we will go on the ah waiting list and
679          * process those things later (after the connect_info and maybe the
680          * things pointed to have gone out of scope.
681          */
682
683         wsi->u.hdr.stash = lws_malloc(sizeof(*wsi->u.hdr.stash));
684         if (!wsi->u.hdr.stash) {
685                 lwsl_err("%s: OOM\n", __func__);
686                 goto bail;
687         }
688
689         wsi->u.hdr.stash->origin[0] = '\0';
690         wsi->u.hdr.stash->protocol[0] = '\0';
691         wsi->u.hdr.stash->method[0] = '\0';
692
693         strncpy(wsi->u.hdr.stash->address, i->address,
694                 sizeof(wsi->u.hdr.stash->address) - 1);
695         strncpy(wsi->u.hdr.stash->path, i->path,
696                 sizeof(wsi->u.hdr.stash->path) - 1);
697         strncpy(wsi->u.hdr.stash->host, i->host,
698                 sizeof(wsi->u.hdr.stash->host) - 1);
699         if (i->origin)
700                 strncpy(wsi->u.hdr.stash->origin, i->origin,
701                         sizeof(wsi->u.hdr.stash->origin) - 1);
702         if (i->protocol)
703                 strncpy(wsi->u.hdr.stash->protocol, i->protocol,
704                         sizeof(wsi->u.hdr.stash->protocol) - 1);
705         if (i->method)
706                 strncpy(wsi->u.hdr.stash->method, i->method,
707                         sizeof(wsi->u.hdr.stash->method) - 1);
708
709         wsi->u.hdr.stash->address[sizeof(wsi->u.hdr.stash->address) - 1] = '\0';
710         wsi->u.hdr.stash->path[sizeof(wsi->u.hdr.stash->path) - 1] = '\0';
711         wsi->u.hdr.stash->host[sizeof(wsi->u.hdr.stash->host) - 1] = '\0';
712         wsi->u.hdr.stash->origin[sizeof(wsi->u.hdr.stash->origin) - 1] = '\0';
713         wsi->u.hdr.stash->protocol[sizeof(wsi->u.hdr.stash->protocol) - 1] = '\0';
714         wsi->u.hdr.stash->method[sizeof(wsi->u.hdr.stash->method) - 1] = '\0';
715
716         if (i->pwsi)
717                 *i->pwsi = wsi;
718
719         /* if we went on the waiting list, no probs just return the wsi
720          * when we get the ah, now or later, he will call
721          * lws_client_connect_via_info2() below.
722          */
723         if (lws_header_table_attach(wsi, 0) < 0) {
724                 /*
725                  * if we failed here, the connection is already closed
726                  * and freed.
727                  */
728                 goto bail1;
729         }
730
731         if (i->parent_wsi) {
732                 lwsl_info("%s: created child %p of parent %p\n", __func__,
733                                 wsi, i->parent_wsi);
734                 wsi->parent = i->parent_wsi;
735                 wsi->sibling_list = i->parent_wsi->child_list;
736                 i->parent_wsi->child_list = wsi;
737         }
738 #ifdef LWS_WITH_HTTP_PROXY
739         if (i->uri_replace_to)
740                 wsi->rw = lws_rewrite_create(wsi, html_parser_cb,
741                                              i->uri_replace_from,
742                                              i->uri_replace_to);
743 #endif
744
745         return wsi;
746
747 bail:
748         lws_free(wsi);
749
750 bail1:
751         if (i->pwsi)
752                 *i->pwsi = NULL;
753
754         return NULL;
755 }
756
757 struct lws *
758 lws_client_connect_via_info2(struct lws *wsi)
759 {
760         struct client_info_stash *stash = wsi->u.hdr.stash;
761
762         if (!stash)
763                 return wsi;
764
765         /*
766          * we're not necessarily in a position to action these right away,
767          * stash them... we only need during connect phase so u.hdr is fine
768          */
769         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
770                                   stash->address))
771                 goto bail1;
772
773         /* these only need u.hdr lifetime as well */
774
775         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash->path))
776                 goto bail1;
777
778         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, stash->host))
779                 goto bail1;
780
781         if (stash->origin[0])
782                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
783                                           stash->origin))
784                         goto bail1;
785         /*
786          * this is a list of protocols we tell the server we're okay with
787          * stash it for later when we compare server response with it
788          */
789         if (stash->protocol[0])
790                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
791                                           stash->protocol))
792                         goto bail1;
793         if (stash->method[0])
794                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
795                                           stash->method))
796                         goto bail1;
797
798 #if defined(LWS_WITH_SOCKS5)
799         if (!wsi->vhost->socks_proxy_port)
800                 lws_free_set_NULL(wsi->u.hdr.stash);
801 #endif
802
803         /*
804          * Check with each extension if it is able to route and proxy this
805          * connection for us.  For example, an extension like x-google-mux
806          * can handle this and then we don't need an actual socket for this
807          * connection.
808          */
809
810         if (lws_ext_cb_all_exts(wsi->context, wsi,
811                                 LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION,
812                                 (void *)stash->address,
813                                 wsi->c_port) > 0) {
814                 lwsl_client("lws_client_connect: ext handling conn\n");
815
816                 lws_set_timeout(wsi,
817                         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
818                                 AWAITING_TIMEOUT);
819
820                 wsi->mode = LWSCM_WSCL_WAITING_EXTENSION_CONNECT;
821                 return wsi;
822         }
823         lwsl_client("lws_client_connect: direct conn\n");
824         wsi->context->count_wsi_allocated++;
825
826         return lws_client_connect_2(wsi);
827
828 bail1:
829 #if defined(LWS_WITH_SOCKS5)
830         if (!wsi->vhost->socks_proxy_port)
831                 lws_free_set_NULL(wsi->u.hdr.stash);
832 #endif
833
834         return NULL;
835 }
836
837 LWS_VISIBLE struct lws *
838 lws_client_connect_extended(struct lws_context *context, const char *address,
839                             int port, int ssl_connection, const char *path,
840                             const char *host, const char *origin,
841                             const char *protocol, int ietf_version_or_minus_one,
842                             void *userdata)
843 {
844         struct lws_client_connect_info i;
845
846         memset(&i, 0, sizeof(i));
847
848         i.context = context;
849         i.address = address;
850         i.port = port;
851         i.ssl_connection = ssl_connection;
852         i.path = path;
853         i.host = host;
854         i.origin = origin;
855         i.protocol = protocol;
856         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
857         i.userdata = userdata;
858
859         return lws_client_connect_via_info(&i);
860 }
861
862 LWS_VISIBLE struct lws *
863 lws_client_connect(struct lws_context *context, const char *address,
864                             int port, int ssl_connection, const char *path,
865                             const char *host, const char *origin,
866                             const char *protocol, int ietf_version_or_minus_one)
867 {
868         struct lws_client_connect_info i;
869
870         memset(&i, 0, sizeof(i));
871
872         i.context = context;
873         i.address = address;
874         i.port = port;
875         i.ssl_connection = ssl_connection;
876         i.path = path;
877         i.host = host;
878         i.origin = origin;
879         i.protocol = protocol;
880         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
881         i.userdata = NULL;
882
883         return lws_client_connect_via_info(&i);
884 }
885
886 #if defined(LWS_WITH_SOCKS5)
887 void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
888                         size_t *msg_len)
889 {
890         struct lws_context *context = wsi->context;
891         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
892         size_t len = 0;
893
894         if (type == SOCKS_MSG_GREETING) {
895                 /* socks version, version 5 only */
896                 pt->serv_buf[len++] = SOCKS_VERSION_5;
897                 /* number of methods */
898                 pt->serv_buf[len++] = 2;
899                 /* username password method */
900                 pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD;
901                 /* no authentication method */
902                 pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH;
903         }
904         else if (type == SOCKS_MSG_USERNAME_PASSWORD) {
905                 size_t user_len = 0;
906                 size_t passwd_len = 0;
907
908                 user_len = strlen(wsi->vhost->socks_user);
909                 passwd_len = strlen(wsi->vhost->socks_password);
910
911                 /* the subnegotiation version */
912                 pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1;
913                 /* length of the user name */
914                 pt->serv_buf[len++] = user_len;
915                 /* user name */
916                 strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user,
917                         context->pt_serv_buf_size - len);
918                 len += user_len;
919                 /* length of the password */
920                 pt->serv_buf[len++] = passwd_len;
921                 /* password */
922                 strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password,
923                         context->pt_serv_buf_size - len);
924                 len += passwd_len;
925         }
926         else if (type == SOCKS_MSG_CONNECT) {
927                 size_t len_index = 0;
928                 short net_num = 0;
929                 char *net_buf = (char*)&net_num;
930
931                 /* socks version */
932                 pt->serv_buf[len++] = SOCKS_VERSION_5;
933                 /* socks command */
934                 pt->serv_buf[len++] = SOCKS_COMMAND_CONNECT;
935                 /* reserved */
936                 pt->serv_buf[len++] = 0;
937                 /* address type */
938                 pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME;
939                 len_index = len;
940                 len++;
941                 /* the address we tell SOCKS proxy to connect to */
942                 strncpy((char *)&(pt->serv_buf[len]), wsi->u.hdr.stash->address,
943                         context->pt_serv_buf_size - len);
944                 len += strlen(wsi->u.hdr.stash->address);
945                 net_num = htons((short)wsi->c_port);
946                 /* the port we tell SOCKS proxy to connect to */
947                 pt->serv_buf[len++] = net_buf[0];
948                 pt->serv_buf[len++] = net_buf[1];
949                 /* the length of the address, excluding port */
950                 pt->serv_buf[len_index] = strlen(wsi->u.hdr.stash->address);
951         }
952
953         *msg_len = len;
954 }
955 #endif