1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "private-lib-core.h"
26 
27 static int
lws_get_idlest_tsi(struct lws_context * context)28 lws_get_idlest_tsi(struct lws_context *context)
29 {
30 	unsigned int lowest = ~0u;
31 	int n = 0, hit = -1;
32 
33 	for (; n < context->count_threads; n++) {
34 		lwsl_debug("%s: %d %d\n", __func__, context->pt[n].fds_count,
35 				context->fd_limit_per_thread - 1);
36 		if ((unsigned int)context->pt[n].fds_count !=
37 		    context->fd_limit_per_thread - 1 &&
38 		    (unsigned int)context->pt[n].fds_count < lowest) {
39 			lowest = context->pt[n].fds_count;
40 			hit = n;
41 		}
42 	}
43 
44 	return hit;
45 }
46 
47 struct lws *
lws_create_new_server_wsi(struct lws_vhost * vhost,int fixed_tsi,const char * desc)48 lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi, const char *desc)
49 {
50 	struct lws *new_wsi;
51 	int n = fixed_tsi;
52 
53 	if (n < 0)
54 		n = lws_get_idlest_tsi(vhost->context);
55 
56 	if (n < 0) {
57 		lwsl_err("no space for new conn\n");
58 		return NULL;
59 	}
60 
61 	lws_context_lock(vhost->context, __func__);
62 	new_wsi = __lws_wsi_create_with_role(vhost->context, n, NULL);
63 	lws_context_unlock(vhost->context);
64 	if (new_wsi == NULL) {
65 		lwsl_err("Out of memory for new connection\n");
66 		return NULL;
67 	}
68 
69 	__lws_lc_tag(&vhost->context->lcg[
70 #if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT)
71 	strcmp(desc, "adopted") ? LWSLCG_WSI_MUX :
72 #endif
73 	LWSLCG_WSI_SERVER], &new_wsi->lc, desc);
74 
75 	new_wsi->wsistate |= LWSIFR_SERVER;
76 	new_wsi->tsi = (char)n;
77 	lwsl_debug("%s joining vhost %s, tsi %d\n", new_wsi->lc.gutag,
78 		   vhost->name, new_wsi->tsi);
79 
80 	lws_vhost_bind_wsi(vhost, new_wsi);
81 	new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
82 	new_wsi->retry_policy = vhost->retry_policy;
83 
84 	/* initialize the instance struct */
85 
86 	lwsi_set_state(new_wsi, LRS_UNCONNECTED);
87 	new_wsi->hdr_parsing_completed = 0;
88 
89 #ifdef LWS_WITH_TLS
90 	new_wsi->tls.use_ssl = LWS_SSL_ENABLED(vhost);
91 #endif
92 
93 	/*
94 	 * these can only be set once the protocol is known
95 	 * we set an un-established connection's protocol pointer
96 	 * to the start of the supported list, so it can look
97 	 * for matching ones during the handshake
98 	 */
99 	new_wsi->a.protocol = vhost->protocols;
100 	new_wsi->user_space = NULL;
101 
102 	/*
103 	 * outermost create notification for wsi
104 	 * no user_space because no protocol selection
105 	 */
106 	vhost->protocols[0].callback(new_wsi, LWS_CALLBACK_WSI_CREATE, NULL,
107 				     NULL, 0);
108 
109 	return new_wsi;
110 }
111 
112 
113 /* if not a socket, it's a raw, non-ssl file descriptor
114  * req cx lock, acq pt lock, acq vh lock
115  */
116 
117 static struct lws *
__lws_adopt_descriptor_vhost1(struct lws_vhost * vh,lws_adoption_type type,const char * vh_prot_name,struct lws * parent,void * opaque,const char * fi_wsi_name)118 __lws_adopt_descriptor_vhost1(struct lws_vhost *vh, lws_adoption_type type,
119 			    const char *vh_prot_name, struct lws *parent,
120 			    void *opaque, const char *fi_wsi_name)
121 {
122 	struct lws_context *context = vh->context;
123 	struct lws_context_per_thread *pt;
124 	struct lws *new_wsi;
125 	int n;
126 
127 	/*
128 	 * Notice that in SMP case, the wsi may be being created on an
129 	 * entirely different pt / tsi for load balancing.  In that case as
130 	 * we initialize it, it may become "live" concurrently unexpectedly...
131 	 */
132 
133 	lws_context_assert_lock_held(vh->context);
134 
135 	n = -1;
136 	if (parent)
137 		n = parent->tsi;
138 	new_wsi = lws_create_new_server_wsi(vh, n, "adopted");
139 	if (!new_wsi)
140 		return NULL;
141 
142 	/* bring in specific fault injection rules early */
143 	lws_fi_inherit_copy(&new_wsi->fic, &context->fic, "wsi", fi_wsi_name);
144 
145 	if (lws_fi(&new_wsi->fic, "createfail")) {
146 		lws_fi_destroy(&new_wsi->fic);
147 
148 		return NULL;
149 	}
150 
151 	new_wsi->a.opaque_user_data = opaque;
152 
153 	pt = &context->pt[(int)new_wsi->tsi];
154 	lws_pt_lock(pt, __func__);
155 
156 	if (parent) {
157 		new_wsi->parent = parent;
158 		new_wsi->sibling_list = parent->child_list;
159 		parent->child_list = new_wsi;
160 	}
161 
162 	if (vh_prot_name) {
163 		new_wsi->a.protocol = lws_vhost_name_to_protocol(new_wsi->a.vhost,
164 							       vh_prot_name);
165 		if (!new_wsi->a.protocol) {
166 			lwsl_err("Protocol %s not enabled on vhost %s\n",
167 				 vh_prot_name, new_wsi->a.vhost->name);
168 			goto bail;
169 		}
170 		if (lws_ensure_user_space(new_wsi)) {
171 		       lwsl_notice("OOM trying to get user_space\n");
172 			goto bail;
173 		}
174 	}
175 
176 	if (!LWS_SSL_ENABLED(new_wsi->a.vhost) ||
177 	    !(type & LWS_ADOPT_SOCKET))
178 		type &= (unsigned int)~LWS_ADOPT_ALLOW_SSL;
179 
180 	if (lws_role_call_adoption_bind(new_wsi, (int)type, vh_prot_name)) {
181 		lwsl_err("%s: no role for desc type 0x%x\n", __func__, type);
182 		goto bail;
183 	}
184 
185 #if defined(LWS_WITH_SERVER)
186 	if (new_wsi->role_ops)
187 		lws_metrics_tag_wsi_add(new_wsi, "role", new_wsi->role_ops->name);
188 #endif
189 
190 	lws_pt_unlock(pt);
191 
192 	/*
193 	 * he's an allocated wsi, but he's not on any fds list or child list,
194 	 * join him to the vhost's list of these kinds of incomplete wsi until
195 	 * he gets another identity (he may do async dns now...)
196 	 */
197 	lws_vhost_lock(new_wsi->a.vhost);
198 	lws_dll2_add_head(&new_wsi->vh_awaiting_socket,
199 			  &new_wsi->a.vhost->vh_awaiting_socket_owner);
200 	lws_vhost_unlock(new_wsi->a.vhost);
201 
202 	return new_wsi;
203 
204 bail:
205        lwsl_notice("%s: exiting on bail\n", __func__);
206 	if (parent)
207 		parent->child_list = new_wsi->sibling_list;
208 	if (new_wsi->user_space)
209 		lws_free(new_wsi->user_space);
210 
211 	lws_fi_destroy(&new_wsi->fic);
212 
213 	lws_pt_unlock(pt);
214 	__lws_vhost_unbind_wsi(new_wsi); /* req cx, acq vh lock */
215 
216 	lws_free(new_wsi);
217 
218 	return NULL;
219 }
220 
221 #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
222 
223 /*
224  * If the incoming wsi is bound to a vhost that is a ss server, this creates
225  * an accepted ss bound to the wsi.
226  *
227  * For h1 or raw, we can do the binding here, but for muxed protocols like h2
228  * or mqtt we have to do it not on the nwsi but on the stream.  And for h2 we
229  * start off bound to h1 role, since we don't know if we will upgrade to h2
230  * until we meet the server.
231  *
232  * 1) No tls is assumed to mean no muxed protocol so can do it at adopt.
233  *
234  * 2) After alpn if not muxed we can do it.
235  *
236  * 3) For muxed, do it at the nwsi migration and on new stream
237  */
238 
239 int
lws_adopt_ss_server_accept(struct lws * new_wsi)240 lws_adopt_ss_server_accept(struct lws *new_wsi)
241 {
242 	struct lws_context_per_thread *pt =
243 			&new_wsi->a.context->pt[(int)new_wsi->tsi];
244 	lws_ss_handle_t *h;
245 	void *pv, **ppv;
246 
247 	if (!new_wsi->a.vhost->ss_handle)
248 		return 0;
249 
250 	pv = (char *)&new_wsi->a.vhost->ss_handle[1];
251 
252 	/*
253 	 * Yes... the vhost is pointing to its secure stream representing the
254 	 * server... we want to create an accepted SS and bind it to new_wsi,
255 	 * the info/ssi from the server SS (so the SS callbacks defined there),
256 	 * the opaque_user_data of the server object and the policy of it.
257 	 */
258 
259 	ppv = (void **)((char *)pv +
260 	      new_wsi->a.vhost->ss_handle->info.opaque_user_data_offset);
261 
262 	/*
263 	 * indicate we are an accepted connection referencing the
264 	 * server object
265 	 */
266 
267 	new_wsi->a.vhost->ss_handle->info.flags |= LWSSSINFLAGS_SERVER;
268 
269 	if (lws_ss_create(new_wsi->a.context, new_wsi->tsi,
270 			  &new_wsi->a.vhost->ss_handle->info,
271 			  *ppv, &h, NULL, NULL)) {
272 		lwsl_err("%s: accept ss creation failed\n", __func__);
273 		goto fail1;
274 	}
275 
276 	/*
277 	 * We made a fresh accepted SS conn from the server pieces,
278 	 * now bind the wsi... the problem is, this is the nwsi if it's
279 	 * h2.
280 	 */
281 
282 	h->wsi = new_wsi;
283 	new_wsi->a.opaque_user_data = h;
284 	h->info.flags |= LWSSSINFLAGS_ACCEPTED;
285 	/* indicate wsi should invalidate any ss link to it on close */
286 	new_wsi->for_ss = 1;
287 
288 	// lwsl_notice("%s: opaq %p, role %s\n", __func__,
289 	//		new_wsi->a.opaque_user_data, new_wsi->role_ops->name);
290 
291 	h->policy = new_wsi->a.vhost->ss_handle->policy;
292 
293 	/* apply requested socket options */
294 	if (lws_plat_set_socket_options_ip(new_wsi->desc.sockfd,
295 					   h->policy->priority,
296 		      (LCCSCF_IP_LOW_LATENCY *
297 		       !!(h->policy->flags & LWSSSPOLF_ATTR_LOW_LATENCY)) |
298 		      (LCCSCF_IP_HIGH_THROUGHPUT *
299 		       !!(h->policy->flags & LWSSSPOLF_ATTR_HIGH_THROUGHPUT)) |
300 		      (LCCSCF_IP_HIGH_RELIABILITY *
301 		       !!(h->policy->flags & LWSSSPOLF_ATTR_HIGH_RELIABILITY)) |
302 		      (LCCSCF_IP_LOW_COST *
303 		       !!(h->policy->flags & LWSSSPOLF_ATTR_LOW_COST))))
304 		lwsl_warn("%s: %s: unable to set ip options\n",
305 			  __func__, new_wsi->lc.gutag);
306 
307 	/*
308 	 * add us to the list of clients that came in from the server
309 	 */
310 
311 	lws_pt_lock(pt, __func__);
312 	lws_dll2_add_tail(&h->cli_list, &new_wsi->a.vhost->ss_handle->src_list);
313 	lws_pt_unlock(pt);
314 
315 	/*
316 	 * Let's give it appropriate state notifications
317 	 */
318 
319 	if (lws_ss_event_helper(h, LWSSSCS_CREATING))
320 		goto fail;
321 	if (lws_ss_event_helper(h, LWSSSCS_CONNECTING))
322 		goto fail;
323 
324 	/* defer CONNECTED until we see if he is upgrading */
325 
326 //	if (lws_ss_event_helper(h, LWSSSCS_CONNECTED))
327 //		goto fail;
328 
329 	// lwsl_notice("%s: accepted ss complete, pcol %s\n", __func__,
330 	//		new_wsi->a.protocol->name);
331 
332 	return 0;
333 
334 fail:
335 	lws_ss_destroy(&h);
336 fail1:
337 	return 1;
338 }
339 
340 #endif
341 
342 
343 static struct lws *
lws_adopt_descriptor_vhost2(struct lws * new_wsi,lws_adoption_type type,lws_sock_file_fd_type fd)344 lws_adopt_descriptor_vhost2(struct lws *new_wsi, lws_adoption_type type,
345 			    lws_sock_file_fd_type fd)
346 {
347 	struct lws_context_per_thread *pt =
348 			&new_wsi->a.context->pt[(int)new_wsi->tsi];
349 	int n;
350 
351 	/* enforce that every fd is nonblocking */
352 
353 	if (type & LWS_ADOPT_SOCKET) {
354 		if (lws_plat_set_nonblocking(fd.sockfd)) {
355 			lwsl_err("%s: unable to set sockfd %d nonblocking\n",
356 				 __func__, fd.sockfd);
357 			goto fail;
358 		}
359 	}
360 #if !defined(WIN32)
361 	else
362 		if (lws_plat_set_nonblocking(fd.filefd)) {
363 			lwsl_err("%s: unable to set filefd nonblocking\n",
364 				 __func__);
365 			goto fail;
366 		}
367 #endif
368 
369 	new_wsi->desc = fd;
370 
371 	if (!LWS_SSL_ENABLED(new_wsi->a.vhost) ||
372 	    !(type & LWS_ADOPT_SOCKET))
373 		type &= (unsigned int)~LWS_ADOPT_ALLOW_SSL;
374 
375 	/*
376 	 * A new connection was accepted. Give the user a chance to
377 	 * set properties of the newly created wsi. There's no protocol
378 	 * selected yet so we issue this to the vhosts's default protocol,
379 	 * itself by default protocols[0]
380 	 */
381 	new_wsi->wsistate |= LWSIFR_SERVER;
382 	n = LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED;
383 	if (new_wsi->role_ops->adoption_cb[lwsi_role_server(new_wsi)])
384 		n = new_wsi->role_ops->adoption_cb[lwsi_role_server(new_wsi)];
385 
386 	if (new_wsi->a.context->event_loop_ops->sock_accept)
387 		if (new_wsi->a.context->event_loop_ops->sock_accept(new_wsi))
388 			goto fail;
389 
390 #if LWS_MAX_SMP > 1
391 	/*
392 	 * Caution: after this point the wsi is live on its service thread
393 	 * which may be concurrent to this.  We mark the wsi as still undergoing
394 	 * init in another pt so the assigned pt leaves it alone.
395 	 */
396 	new_wsi->undergoing_init_from_other_pt = 1;
397 #endif
398 
399 	if (!(type & LWS_ADOPT_ALLOW_SSL)) {
400 		lws_pt_lock(pt, __func__);
401 		if (__insert_wsi_socket_into_fds(new_wsi->a.context, new_wsi)) {
402 			lws_pt_unlock(pt);
403 			lwsl_err("%s: fail inserting socket\n", __func__);
404 			goto fail;
405 		}
406 		lws_pt_unlock(pt);
407 	}
408 #if defined(LWS_WITH_SERVER)
409 	 else
410 		if (lws_server_socket_service_ssl(new_wsi, fd.sockfd, 0)) {
411 			lwsl_info("%s: fail ssl negotiation\n", __func__);
412 
413 			goto fail;
414 		}
415 #endif
416 
417 	lws_vhost_lock(new_wsi->a.vhost);
418 	/* he has fds visibility now, remove from vhost orphan list */
419 	lws_dll2_remove(&new_wsi->vh_awaiting_socket);
420 	lws_vhost_unlock(new_wsi->a.vhost);
421 
422 	/*
423 	 *  by deferring callback to this point, after insertion to fds,
424 	 * lws_callback_on_writable() can work from the callback
425 	 */
426 	if ((new_wsi->a.protocol->callback)(new_wsi, (enum lws_callback_reasons)n, new_wsi->user_space,
427 					  NULL, 0))
428 		goto fail;
429 
430 	/* role may need to do something after all adoption completed */
431 
432 	lws_role_call_adoption_bind(new_wsi, (int)type | _LWS_ADOPT_FINISH,
433 				    new_wsi->a.protocol->name);
434 
435 #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
436 	/*
437 	 * Did we come from an accepted client connection to a ss server?
438 	 *
439 	 * !!! For mux protocols, this will cause an additional inactive ss
440 	 * representing the nwsi.  Doing that allows us to support both h1
441 	 * (here) and h2 (at __lws_wsi_server_new())
442 	 */
443 
444 	lwsl_info("%s: %s, vhost %s\n", __func__, new_wsi->lc.gutag,
445 			new_wsi->a.vhost->lc.gutag);
446 
447 	if (lws_adopt_ss_server_accept(new_wsi))
448 		goto fail;
449 #endif
450 
451 #if LWS_MAX_SMP > 1
452 	/* its actual pt can service it now */
453 
454 	new_wsi->undergoing_init_from_other_pt = 0;
455 #endif
456 
457 	lws_cancel_service_pt(new_wsi);
458 
459 	return new_wsi;
460 
461 fail:
462 	if (type & LWS_ADOPT_SOCKET)
463 		lws_close_free_wsi(new_wsi, LWS_CLOSE_STATUS_NOSTATUS,
464 				   "adopt skt fail");
465 
466 	return NULL;
467 }
468 
469 
470 /* if not a socket, it's a raw, non-ssl file descriptor */
471 
472 struct lws *
lws_adopt_descriptor_vhost(struct lws_vhost * vh,lws_adoption_type type,lws_sock_file_fd_type fd,const char * vh_prot_name,struct lws * parent)473 lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
474 			   lws_sock_file_fd_type fd, const char *vh_prot_name,
475 			   struct lws *parent)
476 {
477 	lws_adopt_desc_t info;
478 
479 	memset(&info, 0, sizeof(info));
480 
481 	info.vh = vh;
482 	info.type = type;
483 	info.fd = fd;
484 	info.vh_prot_name = vh_prot_name;
485 	info.parent = parent;
486 
487 	return lws_adopt_descriptor_vhost_via_info(&info);
488 }
489 
490 struct lws *
lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t * info)491 lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info)
492 {
493 	socklen_t slen = sizeof(lws_sockaddr46);
494 	struct lws *new_wsi;
495 
496 #if defined(LWS_WITH_PEER_LIMITS)
497 	struct lws_peer *peer = NULL;
498 
499 	if (info->type & LWS_ADOPT_SOCKET) {
500 		peer = lws_get_or_create_peer(info->vh, info->fd.sockfd);
501 
502 		if (peer && info->vh->context->ip_limit_wsi &&
503 		    peer->count_wsi >= info->vh->context->ip_limit_wsi) {
504 			lwsl_info("Peer reached wsi limit %d\n",
505 					info->vh->context->ip_limit_wsi);
506 			if (info->vh->context->pl_notify_cb)
507 				info->vh->context->pl_notify_cb(
508 							info->vh->context,
509 							info->fd.sockfd,
510 							&peer->sa46);
511 			compatible_close(info->fd.sockfd);
512 			return NULL;
513 		}
514 	}
515 #endif
516 
517 	lws_context_lock(info->vh->context, __func__);
518 
519 	new_wsi = __lws_adopt_descriptor_vhost1(info->vh, info->type,
520 					      info->vh_prot_name, info->parent,
521 					      info->opaque, info->fi_wsi_name);
522 	if (!new_wsi) {
523 		if (info->type & LWS_ADOPT_SOCKET)
524 			compatible_close(info->fd.sockfd);
525 		goto bail;
526 	}
527 
528 	if (info->type & LWS_ADOPT_SOCKET &&
529 	    getpeername(info->fd.sockfd, (struct sockaddr *)&new_wsi->sa46_peer,
530 								    &slen) < 0)
531 		lwsl_info("%s: getpeername failed\n", __func__);
532 
533 #if defined(LWS_WITH_PEER_LIMITS)
534 	if (peer)
535 		lws_peer_add_wsi(info->vh->context, peer, new_wsi);
536 #endif
537 
538 	new_wsi = lws_adopt_descriptor_vhost2(new_wsi, info->type, info->fd);
539 
540 bail:
541 	lws_context_unlock(info->vh->context);
542 
543 	return new_wsi;
544 }
545 
546 struct lws *
lws_adopt_socket_vhost(struct lws_vhost * vh,lws_sockfd_type accept_fd)547 lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd)
548 {
549 	lws_sock_file_fd_type fd;
550 
551 	fd.sockfd = accept_fd;
552 	return lws_adopt_descriptor_vhost(vh, LWS_ADOPT_SOCKET |
553 			LWS_ADOPT_HTTP | LWS_ADOPT_ALLOW_SSL, fd, NULL, NULL);
554 }
555 
556 struct lws *
lws_adopt_socket(struct lws_context * context,lws_sockfd_type accept_fd)557 lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd)
558 {
559 	return lws_adopt_socket_vhost(context->vhost_list, accept_fd);
560 }
561 
562 /* Common read-buffer adoption for lws_adopt_*_readbuf */
563 static struct lws*
adopt_socket_readbuf(struct lws * wsi,const char * readbuf,size_t len)564 adopt_socket_readbuf(struct lws *wsi, const char *readbuf, size_t len)
565 {
566 	struct lws_context_per_thread *pt;
567 	struct lws_pollfd *pfd;
568 	int n;
569 
570 	if (!wsi)
571 		return NULL;
572 
573 	if (!readbuf || len == 0)
574 		return wsi;
575 
576 	if (wsi->position_in_fds_table == LWS_NO_FDS_POS)
577 		return wsi;
578 
579 	pt = &wsi->a.context->pt[(int)wsi->tsi];
580 
581 	n = lws_buflist_append_segment(&wsi->buflist, (const uint8_t *)readbuf,
582 				       len);
583 	if (n < 0)
584 		goto bail;
585 	if (n)
586 		lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner);
587 
588 	/*
589 	 * we can't process the initial read data until we can attach an ah.
590 	 *
591 	 * if one is available, get it and place the data in his ah rxbuf...
592 	 * wsi with ah that have pending rxbuf get auto-POLLIN service.
593 	 *
594 	 * no autoservice because we didn't get a chance to attach the
595 	 * readbuf data to wsi or ah yet, and we will do it next if we get
596 	 * the ah.
597 	 */
598 	if (wsi->http.ah || !lws_header_table_attach(wsi, 0)) {
599 
600 		lwsl_notice("%s: calling service on readbuf ah\n", __func__);
601 
602 		/*
603 		 * unlike a normal connect, we have the headers already
604 		 * (or the first part of them anyway).
605 		 * libuv won't come back and service us without a network
606 		 * event, so we need to do the header service right here.
607 		 */
608 		pfd = &pt->fds[wsi->position_in_fds_table];
609 		pfd->revents |= LWS_POLLIN;
610 		lwsl_err("%s: calling service\n", __func__);
611 		if (lws_service_fd_tsi(wsi->a.context, pfd, wsi->tsi))
612 			/* service closed us */
613 			return NULL;
614 
615 		return wsi;
616 	}
617 	lwsl_err("%s: deferring handling ah\n", __func__);
618 
619 	return wsi;
620 
621 bail:
622 	lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
623 			   "adopt skt readbuf fail");
624 
625 	return NULL;
626 }
627 
628 #if defined(LWS_WITH_UDP)
629 #if defined(LWS_WITH_CLIENT)
630 
631 /*
632  * This is the ASYNC_DNS callback target for udp client, it's analogous to
633  * connect3()
634  */
635 
636 static struct lws *
lws_create_adopt_udp2(struct lws * wsi,const char * ads,const struct addrinfo * r,int n,void * opaque)637 lws_create_adopt_udp2(struct lws *wsi, const char *ads,
638 		      const struct addrinfo *r, int n, void *opaque)
639 {
640 	lws_sock_file_fd_type sock;
641 	int bc = 1, m;
642 
643 	assert(wsi);
644 
645 	if (ads && (n < 0 || !r)) {
646 		/*
647 		 * DNS lookup failed: there are no usable results.  Fail the
648 		 * overall connection request.
649 		 */
650 		lwsl_notice("%s: bad: n %d, r %p\n", __func__, n, r);
651 
652 		goto bail;
653 	}
654 
655 	m = lws_sort_dns(wsi, r);
656 #if defined(LWS_WITH_SYS_ASYNC_DNS)
657 	lws_async_dns_freeaddrinfo(&r);
658 #else
659 	freeaddrinfo((struct addrinfo *)r);
660 #endif
661 	if (m)
662 		goto bail;
663 
664 	while (lws_dll2_get_head(&wsi->dns_sorted_list)) {
665 		lws_dns_sort_t *s = lws_container_of(
666 				lws_dll2_get_head(&wsi->dns_sorted_list),
667 				lws_dns_sort_t, list);
668 
669 		/*
670 		 * Remove it from the head, but don't free it yet... we are
671 		 * taking responsibility to free it
672 		 */
673 		lws_dll2_remove(&s->list);
674 
675 		/*
676 		 * We have done the dns lookup, identify the result we want
677 		 * if any, and then complete the adoption by binding wsi to
678 		 * socket opened on it.
679 		 *
680 		 * Ignore the weak assumptions about protocol driven by port
681 		 * number and force to DGRAM / UDP since that's what this
682 		 * function is for.
683 		 */
684 
685 #if !defined(__linux__)
686 		sock.sockfd = socket(s->dest.sa4.sin_family,
687 				     SOCK_DGRAM, IPPROTO_UDP);
688 #else
689 		/* PF_PACKET is linux-only */
690 		sock.sockfd = socket(wsi->pf_packet ? PF_PACKET :
691 						s->dest.sa4.sin_family,
692 				     SOCK_DGRAM, wsi->pf_packet ?
693 					htons(0x800) : IPPROTO_UDP);
694 #endif
695 		if (sock.sockfd == LWS_SOCK_INVALID)
696 			goto resume;
697 
698 		/* ipv6 udp!!! */
699 
700 		if (s->af == AF_INET)
701 			s->dest.sa4.sin_port = htons(wsi->c_port);
702 #if defined(LWS_WITH_IPV6)
703 		else
704 			s->dest.sa6.sin6_port = htons(wsi->c_port);
705 #endif
706 
707 		if (setsockopt(sock.sockfd, SOL_SOCKET, SO_REUSEADDR,
708 			       (const char *)&bc, sizeof(bc)) < 0)
709 			lwsl_err("%s: failed to set reuse\n", __func__);
710 
711 		if (wsi->do_broadcast &&
712 		    setsockopt(sock.sockfd, SOL_SOCKET, SO_BROADCAST,
713 			       (const char *)&bc, sizeof(bc)) < 0)
714 			lwsl_err("%s: failed to set broadcast\n", __func__);
715 
716 		/* Bind the udp socket to a particular network interface */
717 
718 		if (opaque &&
719 		    lws_plat_BINDTODEVICE(sock.sockfd, (const char *)opaque))
720 			goto resume;
721 
722 		if (wsi->do_bind &&
723 		    bind(sock.sockfd, sa46_sockaddr(&s->dest),
724 #if defined(_WIN32)
725 			 (int)sa46_socklen(&s->dest)
726 #else
727 			 sizeof(struct sockaddr)
728 #endif
729 		) == -1) {
730 			lwsl_err("%s: bind failed\n", __func__);
731 			goto resume;
732 		}
733 
734 		if (!wsi->do_bind && !wsi->pf_packet) {
735 #if !defined(__APPLE__)
736 			if (connect(sock.sockfd, sa46_sockaddr(&s->dest),
737 				    sa46_socklen(&s->dest)) == -1 &&
738 			    errno != EADDRNOTAVAIL /* openbsd */ ) {
739 				lwsl_err("%s: conn fd %d fam %d %s:%u failed "
740 					 "errno %d\n", __func__, sock.sockfd,
741 					 s->dest.sa4.sin_family,
742 					 ads ? ads : "null", wsi->c_port,
743 					 LWS_ERRNO);
744 				compatible_close(sock.sockfd);
745 				goto resume;
746 			}
747 #endif
748 		}
749 
750 		if (wsi->udp)
751 			wsi->udp->sa46 = s->dest;
752 		wsi->sa46_peer = s->dest;
753 
754 		/* we connected: complete the udp socket adoption flow */
755 
756 #if defined(LWS_WITH_SYS_ASYNC_DNS)
757 	if (wsi->a.context->async_dns.wsi == wsi)
758 		wsi->a.context->async_dns.dns_server_connected = 1;
759 #endif
760 
761 		lws_free(s);
762 		lws_addrinfo_clean(wsi);
763 		return lws_adopt_descriptor_vhost2(wsi,
764 						LWS_ADOPT_RAW_SOCKET_UDP, sock);
765 
766 resume:
767 		lws_free(s);
768 	}
769 
770 	lwsl_err("%s: unable to create INET socket %d\n", __func__, LWS_ERRNO);
771 	lws_addrinfo_clean(wsi);
772 
773 #if defined(LWS_WITH_SYS_ASYNC_DNS)
774 	if (wsi->a.context->async_dns.wsi == wsi)
775 		lws_async_dns_drop_server(wsi->a.context);
776 #endif
777 
778 bail:
779 
780 	/* caller must close */
781 
782 	return NULL;
783 }
784 
785 struct lws *
lws_create_adopt_udp(struct lws_vhost * vhost,const char * ads,int port,int flags,const char * protocol_name,const char * ifname,struct lws * parent_wsi,void * opaque,const lws_retry_bo_t * retry_policy,const char * fi_wsi_name)786 lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
787 		     int flags, const char *protocol_name, const char *ifname,
788 		     struct lws *parent_wsi, void *opaque,
789 		     const lws_retry_bo_t *retry_policy, const char *fi_wsi_name)
790 {
791 #if !defined(LWS_PLAT_OPTEE)
792 	struct lws *wsi;
793 	int n;
794 
795 	lwsl_info("%s: %s:%u\n", __func__, ads ? ads : "null", port);
796 
797 	/* create the logical wsi without any valid fd */
798 
799 	lws_context_lock(vhost->context, __func__);
800 
801 	wsi = __lws_adopt_descriptor_vhost1(vhost, LWS_ADOPT_SOCKET |
802 						 LWS_ADOPT_RAW_SOCKET_UDP,
803 					  protocol_name, parent_wsi, opaque,
804 					  fi_wsi_name);
805 
806 	lws_context_unlock(vhost->context);
807 	if (!wsi) {
808 		lwsl_err("%s: udp wsi creation failed\n", __func__);
809 		goto bail;
810 	}
811 
812 	// lwsl_notice("%s: role %s\n", __func__, wsi->role_ops->name);
813 
814 	wsi->do_bind = !!(flags & LWS_CAUDP_BIND);
815 	wsi->do_broadcast = !!(flags & LWS_CAUDP_BROADCAST);
816 	wsi->pf_packet = !!(flags & LWS_CAUDP_PF_PACKET);
817 	wsi->c_port = (uint16_t)(unsigned int)port;
818 	if (retry_policy)
819 		wsi->retry_policy = retry_policy;
820 	else
821 		wsi->retry_policy = vhost->retry_policy;
822 
823 #if !defined(LWS_WITH_SYS_ASYNC_DNS)
824 	{
825 		struct addrinfo *r, h;
826 		char buf[16];
827 
828 		memset(&h, 0, sizeof(h));
829 		h.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
830 		h.ai_socktype = SOCK_DGRAM;
831 		h.ai_protocol = IPPROTO_UDP;
832 #if defined(AI_PASSIVE)
833 		h.ai_flags = AI_PASSIVE;
834 #endif
835 #ifdef AI_ADDRCONFIG
836 		h.ai_flags |= AI_ADDRCONFIG;
837 #endif
838 
839 		/* if the dns lookup is synchronous, do the whole thing now */
840 		lws_snprintf(buf, sizeof(buf), "%u", port);
841 		n = getaddrinfo(ads, buf, &h, &r);
842 		if (n) {
843 #if !defined(LWS_PLAT_FREERTOS)
844 			lwsl_info("%s: getaddrinfo error: %s\n", __func__,
845 				  gai_strerror(n));
846 #else
847 			lwsl_info("%s: getaddrinfo error: %s\n", __func__,
848 					strerror(n));
849 #endif
850 			//freeaddrinfo(r);
851 			goto bail1;
852 		}
853 		/*
854 		 * With synchronous dns, complete it immediately after the
855 		 * blocking dns lookup finished... free r when connect either
856 		 * completed or failed
857 		 */
858 		wsi = lws_create_adopt_udp2(wsi, ads, r, 0, NULL);
859 
860 		return wsi;
861 	}
862 #else
863 	if (ads) {
864 		/*
865 		 * with async dns, use the wsi as the point about which to do
866 		 * the dns lookup and have it call the second part when it's
867 		 * done.
868 		 *
869 		 * Keep a refcount on the results and free it when we connected
870 		 * or definitively failed.
871 		 *
872 		 * Notice wsi has no socket at this point (we don't know what
873 		 * kind to ask for until we get the dns back).  But it is bound
874 		 * to a vhost and can be cleaned up from that at vhost destroy.
875 		 */
876 		n = lws_async_dns_query(vhost->context, 0, ads,
877 					LWS_ADNS_RECORD_A,
878 					lws_create_adopt_udp2, wsi,
879 					(void *)ifname);
880 		// lwsl_notice("%s: dns query returned %d\n", __func__, n);
881 		if (n == LADNS_RET_FAILED) {
882 			lwsl_err("%s: async dns failed\n", __func__);
883 			wsi = NULL;
884 			/*
885 			 * It was already closed by calling callback with error
886 			 * from lws_async_dns_query()
887 			 */
888 			goto bail;
889 		}
890 	} else {
891 		lwsl_debug("%s: udp adopt has no ads\n", __func__);
892 		wsi = lws_create_adopt_udp2(wsi, ads, NULL, 0, (void *)ifname);
893 	}
894 
895 	/* dns lookup is happening asynchronously */
896 
897 	// lwsl_notice("%s: returning wsi %p\n", __func__, wsi);
898 
899 	return wsi;
900 #endif
901 #if !defined(LWS_WITH_SYS_ASYNC_DNS)
902 bail1:
903 	lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "adopt udp2 fail");
904 	wsi = NULL;
905 #endif
906 bail:
907 	return wsi;
908 #else
909 	return NULL;
910 #endif
911 }
912 #endif
913 #endif
914 
915 struct lws *
lws_adopt_socket_readbuf(struct lws_context * context,lws_sockfd_type accept_fd,const char * readbuf,size_t len)916 lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
917 			 const char *readbuf, size_t len)
918 {
919         return adopt_socket_readbuf(lws_adopt_socket(context, accept_fd),
920 				    readbuf, len);
921 }
922 
923 struct lws *
lws_adopt_socket_vhost_readbuf(struct lws_vhost * vhost,lws_sockfd_type accept_fd,const char * readbuf,size_t len)924 lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost,
925 			       lws_sockfd_type accept_fd,
926 			       const char *readbuf, size_t len)
927 {
928         return adopt_socket_readbuf(lws_adopt_socket_vhost(vhost, accept_fd),
929 				    readbuf, len);
930 }
931