http header malloc pool implement pool
[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 sockaddr_in server_addr4;
13         struct sockaddr_in client_addr4;
14         struct lws_pollfd pfd;
15         struct sockaddr *v;
16         int n, plen = 0;
17         const char *ads;
18
19         lwsl_client("%s\n", __func__);
20
21         /* proxy? */
22
23         if (context->http_proxy_port) {
24                 plen = sprintf((char *)context->serv_buf,
25                         "CONNECT %s:%u HTTP/1.0\x0d\x0a"
26                         "User-agent: libwebsockets\x0d\x0a",
27                         lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
28                         wsi->u.hdr.ah->c_port);
29
30                 if (context->proxy_basic_auth_token[0])
31                         plen += sprintf((char *)context->serv_buf + plen,
32                                         "Proxy-authorization: basic %s\x0d\x0a",
33                                         context->proxy_basic_auth_token);
34
35                 plen += sprintf((char *)context->serv_buf + plen,
36                                 "\x0d\x0a");
37
38                 ads = context->http_proxy_address;
39
40 #ifdef LWS_USE_IPV6
41                 if (LWS_IPV6_ENABLED(context)) {
42                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
43                         server_addr6.sin6_port = htons(context->http_proxy_port);
44                 } else
45 #endif
46                         server_addr4.sin_port = htons(context->http_proxy_port);
47
48         } else {
49                 ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
50 #ifdef LWS_USE_IPV6
51                 if (LWS_IPV6_ENABLED(context)) {
52                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
53                         server_addr6.sin6_port = htons(wsi->u.hdr.ah->c_port);
54                 } else
55 #endif
56                         server_addr4.sin_port = htons(wsi->u.hdr.ah->c_port);
57         }
58
59         /*
60          * prepare the actual connection (to the proxy, if any)
61          */
62        lwsl_client("%s: address %s\n", __func__, ads);
63
64 #ifdef LWS_USE_IPV6
65         if (LWS_IPV6_ENABLED(context)) {
66                 memset(&hints, 0, sizeof(struct addrinfo));
67 #if !defined(__ANDROID__)
68                 hints.ai_family = AF_INET6;
69                 hints.ai_flags = AI_V4MAPPED;
70 #endif
71                 n = getaddrinfo(ads, NULL, &hints, &result);
72                 if (n) {
73 #ifdef _WIN32
74                         lwsl_err("getaddrinfo: %ls\n", gai_strerrorW(n));
75 #else
76                         lwsl_err("getaddrinfo: %s\n", gai_strerror(n));
77 #endif
78                         goto oom4;
79                 }
80
81                 server_addr6.sin6_family = AF_INET6;
82                 switch (result->ai_family) {
83 #if defined(__ANDROID__)
84                 case AF_INET:
85                         /* map IPv4 to IPv6 */
86                         bzero((char *)&server_addr6.sin6_addr,
87                                                 sizeof(struct in6_addr));
88                         server_addr6.sin6_addr.s6_addr[10] = 0xff;
89                         server_addr6.sin6_addr.s6_addr[11] = 0xff;
90                         memcpy(&server_addr6.sin6_addr.s6_addr[12],
91                                 &((struct sockaddr_in *)result->ai_addr)->sin_addr,
92                                                         sizeof(struct in_addr));
93                         break;
94 #endif
95                 case AF_INET6:
96                         memcpy(&server_addr6.sin6_addr,
97                           &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
98                                                 sizeof(struct in6_addr));
99                         break;
100                 default:
101                         lwsl_err("Unknown address family\n");
102                         freeaddrinfo(result);
103                         goto oom4;
104                 }
105
106                 freeaddrinfo(result);
107         } else
108 #endif
109         {
110                 struct addrinfo ai, *res, *result;
111                 void *p = NULL;
112
113                 memset (&ai, 0, sizeof ai);
114                 ai.ai_family = PF_UNSPEC;
115                 ai.ai_socktype = SOCK_STREAM;
116                 ai.ai_flags = AI_CANONNAME;
117
118                 if (getaddrinfo(ads, NULL, &ai, &result))
119                         goto oom4;
120
121                 res = result;
122                 while (!p && res) {
123                         switch (res->ai_family) {
124                         case AF_INET:
125                                 p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
126                                 break;
127                         }
128
129                         res = res->ai_next;
130                 }
131
132                 if (!p) {
133                         freeaddrinfo(result);
134                         goto oom4;
135                 }
136
137                 server_addr4.sin_family = AF_INET;
138                 server_addr4.sin_addr = *((struct in_addr *)p);
139                 bzero(&server_addr4.sin_zero, 8);
140                 freeaddrinfo(result);
141         }
142
143         if (!lws_socket_is_valid(wsi->sock)) {
144
145 #ifdef LWS_USE_IPV6
146                 if (LWS_IPV6_ENABLED(context))
147                         wsi->sock = socket(AF_INET6, SOCK_STREAM, 0);
148                 else
149 #endif
150                         wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
151
152                 if (!lws_socket_is_valid(wsi->sock)) {
153                         lwsl_warn("Unable to open socket\n");
154                         goto oom4;
155                 }
156
157                 if (lws_plat_set_socket_options(context, wsi->sock)) {
158                         lwsl_err("Failed to set wsi socket options\n");
159                         compatible_close(wsi->sock);
160                         goto oom4;
161                 }
162
163                 wsi->mode = LWSCM_WSCL_WAITING_CONNECT;
164
165                 lws_libev_accept(wsi, wsi->sock);
166                 if (insert_wsi_socket_into_fds(context, wsi)) {
167                         compatible_close(wsi->sock);
168                         goto oom4;
169                 }
170
171                 /*
172                  * past here, we can't simply free the structs as error
173                  * handling as oom4 does.  We have to run the whole close flow.
174                  */
175
176                 lws_set_timeout(wsi,
177                         PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
178                                                               AWAITING_TIMEOUT);
179 #ifdef LWS_USE_IPV6
180                 if (LWS_IPV6_ENABLED(context)) {
181                         v = (struct sockaddr *)&client_addr6;
182                         n = sizeof(client_addr6);
183                         bzero((char *)v, n);
184                         client_addr6.sin6_family = AF_INET6;
185                 } else
186 #endif
187                 {
188                         v = (struct sockaddr *)&client_addr4;
189                         n = sizeof(client_addr4);
190                         bzero((char *)v, n);
191                         client_addr4.sin_family = AF_INET;
192                 }
193
194                 if (context->iface) {
195                         if (interface_to_sa(context, context->iface,
196                                         (struct sockaddr_in *)v, n) < 0) {
197                                 lwsl_err("Unable to find interface %s\n",
198                                                                 context->iface);
199                                 goto failed;
200                         }
201
202                         if (bind(wsi->sock, v, n) < 0) {
203                                 lwsl_err("Error binding to interface %s",
204                                                                 context->iface);
205                                 goto failed;
206                         }
207                 }
208         }
209
210 #ifdef LWS_USE_IPV6
211         if (LWS_IPV6_ENABLED(context)) {
212                 v = (struct sockaddr *)&server_addr6;
213                 n = sizeof(struct sockaddr_in6);
214         } else
215 #endif
216         {
217                 v = (struct sockaddr *)&server_addr4;
218                 n = sizeof(struct sockaddr);
219         }
220
221         if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
222                 if (LWS_ERRNO == LWS_EALREADY ||
223                     LWS_ERRNO == LWS_EINPROGRESS ||
224                     LWS_ERRNO == LWS_EWOULDBLOCK
225 #ifdef _WIN32
226                         || LWS_ERRNO == WSAEINVAL
227 #endif
228                 ) {
229                         lwsl_client("nonblocking connect retry\n");
230
231                         /*
232                          * must do specifically a POLLOUT poll to hear
233                          * about the connect completion
234                          */
235                         if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
236                                 goto failed;
237                         lws_libev_io(wsi, LWS_EV_START | LWS_EV_WRITE);
238
239                         return wsi;
240                 }
241
242                 if (LWS_ERRNO != LWS_EISCONN) {
243                         lwsl_debug("Connect failed errno=%d\n", LWS_ERRNO);
244                         goto failed;
245                 }
246         }
247
248         lwsl_client("connected\n");
249
250         /* we are connected to server, or proxy */
251
252         if (context->http_proxy_port) {
253
254                 /*
255                  * OK from now on we talk via the proxy, so connect to that
256                  *
257                  * (will overwrite existing pointer,
258                  * leaving old string/frag there but unreferenced)
259                  */
260                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
261                                           context->http_proxy_address))
262                         goto failed;
263                 wsi->u.hdr.ah->c_port = context->http_proxy_port;
264
265                 n = send(wsi->sock, (char *)context->serv_buf, plen,
266                          MSG_NOSIGNAL);
267                 if (n < 0) {
268                         lwsl_debug("ERROR writing to proxy socket\n");
269                         goto failed;
270                 }
271
272                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
273                                 AWAITING_TIMEOUT);
274
275                 wsi->mode = LWSCM_WSCL_WAITING_PROXY_REPLY;
276
277                 return wsi;
278         }
279
280         /*
281          * provoke service to issue the handshake directly
282          * we need to do it this way because in the proxy case, this is the
283          * next state and executed only if and when we get a good proxy
284          * response inside the state machine... but notice in SSL case this
285          * may not have sent anything yet with 0 return, and won't until some
286          * many retries from main loop.  To stop that becoming endless,
287          * cover with a timeout.
288          */
289
290         lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
291                         AWAITING_TIMEOUT);
292
293         wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE;
294         pfd.fd = wsi->sock;
295         pfd.revents = LWS_POLLIN;
296
297         n = lws_service_fd(context, &pfd);
298         if (n < 0)
299                 goto failed;
300         if (n) /* returns 1 on failure after closing wsi */
301                 return NULL;
302
303         return wsi;
304
305 oom4:
306         lws_free_header_table(wsi);
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_connect() - Connect to another websocket server
319  * @context:    Websocket context
320  * @address:    Remote server address, eg, "myserver.com"
321  * @port:       Port to connect to on the remote server, eg, 80
322  * @ssl_connection:     0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
323  *                      signed certs
324  * @path:       Websocket path on server
325  * @host:       Hostname on server
326  * @origin:     Socket origin name
327  * @protocol:   Comma-separated list of protocols being asked for from
328  *              the server, or just one.  The server will pick the one it
329  *              likes best.  If you don't want to specify a protocol, which is
330  *              legal, use NULL here.
331  * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
332  *              protocol supported, or the specific protocol ordinal
333  *
334  *      This function creates a connection to a remote server
335  */
336
337 LWS_VISIBLE struct lws *
338 lws_client_connect(struct lws_context *context, const char *address,
339                    int port, int ssl_connection, const char *path,
340                    const char *host, const char *origin,
341                    const char *protocol, int ietf_version_or_minus_one)
342 {
343         struct lws *wsi;
344
345         wsi = lws_zalloc(sizeof(struct lws));
346         if (wsi == NULL)
347                 goto bail;
348
349         wsi->context = context;
350         wsi->sock = LWS_SOCK_INVALID;
351
352         /* -1 means just use latest supported */
353
354         if (ietf_version_or_minus_one == -1)
355                 ietf_version_or_minus_one = SPEC_LATEST_SUPPORTED;
356
357         wsi->ietf_spec_revision = ietf_version_or_minus_one;
358         wsi->user_space = NULL;
359         wsi->state = LWSS_CLIENT_UNCONNECTED;
360         wsi->protocol = NULL;
361         wsi->pending_timeout = NO_PENDING_TIMEOUT;
362
363 #ifdef LWS_OPENSSL_SUPPORT
364         wsi->use_ssl = ssl_connection;
365 #else
366         if (ssl_connection) {
367                 lwsl_err("libwebsockets not configured for ssl\n");
368                 goto bail;
369         }
370 #endif
371
372         if (lws_allocate_header_table(wsi))
373                 goto bail;
374
375         /*
376          * we're not necessarily in a position to action these right away,
377          * stash them... we only need during connect phase so u.hdr is fine
378          */
379         wsi->u.hdr.ah->c_port = port;
380         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
381                 goto bail1;
382
383         /* these only need u.hdr lifetime as well */
384
385         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path))
386                 goto bail1;
387
388         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
389                 goto bail1;
390
391         if (origin)
392                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN, origin))
393                         goto bail1;
394         /*
395          * this is a list of protocols we tell the server we're okay with
396          * stash it for later when we compare server response with it
397          */
398         if (protocol)
399                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
400                                           protocol))
401                         goto bail1;
402
403         wsi->protocol = &context->protocols[0];
404
405         /*
406          * Check with each extension if it is able to route and proxy this
407          * connection for us.  For example, an extension like x-google-mux
408          * can handle this and then we don't need an actual socket for this
409          * connection.
410          */
411
412         if (lws_ext_cb_all_exts(context, wsi,
413                         LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
414                                                      (void *)address, port) > 0) {
415                 lwsl_client("lws_client_connect: ext handling conn\n");
416
417                 lws_set_timeout(wsi,
418                         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
419                                 AWAITING_TIMEOUT);
420
421                 wsi->mode = LWSCM_WSCL_WAITING_EXTENSION_CONNECT;
422                 return wsi;
423         }
424         lwsl_client("lws_client_connect: direct conn\n");
425
426         return lws_client_connect_2(wsi);
427
428 bail1:
429         lws_free_header_table(wsi);
430 bail:
431         lws_free(wsi);
432
433         return NULL;
434 }
435
436
437 /**
438  * lws_client_connect_extended() - Connect to another websocket server
439  * @context:    Websocket context
440  * @address:    Remote server address, eg, "myserver.com"
441  * @port:       Port to connect to on the remote server, eg, 80
442  * @ssl_connection:     0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
443  *                      signed certs
444  * @path:       Websocket path on server
445  * @host:       Hostname on server
446  * @origin:     Socket origin name
447  * @protocol:   Comma-separated list of protocols being asked for from
448  *              the server, or just one.  The server will pick the one it
449  *              likes best.
450  * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
451  *              protocol supported, or the specific protocol ordinal
452  * @userdata: Pre-allocated user data
453  *
454  *      This function creates a connection to a remote server
455  */
456
457 LWS_VISIBLE struct lws *
458 lws_client_connect_extended(struct lws_context *context, const char *address,
459                             int port, int ssl_connection, const char *path,
460                             const char *host, const char *origin,
461                             const char *protocol, int ietf_version_or_minus_one,
462                             void *userdata)
463 {
464         struct lws *wsi;
465
466         wsi = lws_client_connect(context, address, port, ssl_connection, path,
467                                  host, origin, protocol,
468                                  ietf_version_or_minus_one);
469
470         if (wsi && !wsi->user_space && userdata) {
471                 wsi->user_space_externally_allocated = 1;
472                 wsi->user_space = userdata ;
473         }
474
475         return wsi;
476 }