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