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#if !defined(__LWS_CORE_NET_PRIVATE_H__)
26#define __LWS_CORE_NET_PRIVATE_H__
27
28#if !defined(_POSIX_C_SOURCE)
29#define _POSIX_C_SOURCE 200112L
30#endif
31
32/*
33 * Generic pieces needed to manage muxable stream protocols like h2
34 */
35
36struct lws_muxable {
37	struct lws	*parent_wsi;
38	struct lws	*child_list;
39	struct lws	*sibling_list;
40
41	unsigned int	my_sid;
42	unsigned int	child_count;
43
44	uint32_t	highest_sid;
45
46	uint8_t		requested_POLLOUT;
47};
48
49#include "private-lib-roles.h"
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55#define __lws_sul_insert_us(owner, sul, _us) \
56		(sul)->us = lws_now_usecs() + (lws_usec_t)(_us); \
57		__lws_sul_insert(owner, sul)
58
59
60/*
61 *
62 *  ------ roles ------
63 *
64 */
65
66/* null-terminated array of pointers to roles lws built with */
67extern const struct lws_role_ops *available_roles[];
68
69#define LWS_FOR_EVERY_AVAILABLE_ROLE_START(xx) { \
70		const struct lws_role_ops **ppxx = available_roles; \
71		while (*ppxx) { \
72			const struct lws_role_ops *xx = *ppxx++;
73
74#define LWS_FOR_EVERY_AVAILABLE_ROLE_END }}
75
76/*
77 *
78 *  ------ event_loop ops ------
79 *
80 */
81
82/* enums of socks version */
83enum socks_version {
84	SOCKS_VERSION_4 = 4,
85	SOCKS_VERSION_5 = 5
86};
87
88/* enums of subnegotiation version */
89enum socks_subnegotiation_version {
90	SOCKS_SUBNEGOTIATION_VERSION_1 = 1,
91};
92
93/* enums of socks commands */
94enum socks_command {
95	SOCKS_COMMAND_CONNECT = 1,
96	SOCKS_COMMAND_BIND = 2,
97	SOCKS_COMMAND_UDP_ASSOCIATE = 3
98};
99
100/* enums of socks address type */
101enum socks_atyp {
102	SOCKS_ATYP_IPV4 = 1,
103	SOCKS_ATYP_DOMAINNAME = 3,
104	SOCKS_ATYP_IPV6 = 4
105};
106
107/* enums of socks authentication methods */
108enum socks_auth_method {
109	SOCKS_AUTH_NO_AUTH = 0,
110	SOCKS_AUTH_GSSAPI = 1,
111	SOCKS_AUTH_USERNAME_PASSWORD = 2
112};
113
114/* enums of subnegotiation status */
115enum socks_subnegotiation_status {
116	SOCKS_SUBNEGOTIATION_STATUS_SUCCESS = 0,
117};
118
119/* enums of socks request reply */
120enum socks_request_reply {
121	SOCKS_REQUEST_REPLY_SUCCESS = 0,
122	SOCKS_REQUEST_REPLY_FAILURE_GENERAL = 1,
123	SOCKS_REQUEST_REPLY_CONNECTION_NOT_ALLOWED = 2,
124	SOCKS_REQUEST_REPLY_NETWORK_UNREACHABLE = 3,
125	SOCKS_REQUEST_REPLY_HOST_UNREACHABLE = 4,
126	SOCKS_REQUEST_REPLY_CONNECTION_REFUSED = 5,
127	SOCKS_REQUEST_REPLY_TTL_EXPIRED = 6,
128	SOCKS_REQUEST_REPLY_COMMAND_NOT_SUPPORTED = 7,
129	SOCKS_REQUEST_REPLY_ATYP_NOT_SUPPORTED = 8
130};
131
132/* enums used to generate socks messages */
133enum socks_msg_type {
134	/* greeting */
135	SOCKS_MSG_GREETING,
136	/* credential, user name and password */
137	SOCKS_MSG_USERNAME_PASSWORD,
138	/* connect command */
139	SOCKS_MSG_CONNECT
140};
141
142enum {
143	LWS_RXFLOW_ALLOW = (1 << 0),
144	LWS_RXFLOW_PENDING_CHANGE = (1 << 1),
145};
146
147typedef enum lws_parser_return {
148	LPR_FORBIDDEN	= -2,
149	LPR_FAIL	= -1,
150	LPR_OK		= 0,
151	LPR_DO_FALLBACK = 2,
152} lws_parser_return_t;
153
154enum pmd_return {
155	PMDR_UNKNOWN,
156	PMDR_DID_NOTHING,
157	PMDR_HAS_PENDING,
158	PMDR_EMPTY_NONFINAL,
159	PMDR_EMPTY_FINAL,
160	PMDR_NOTHING_WE_SHOULD_DO,
161
162	PMDR_FAILED = -1
163};
164
165#if defined(LWS_WITH_PEER_LIMITS)
166struct lws_peer {
167	struct lws_peer *next;
168	struct lws_peer *peer_wait_list;
169
170	lws_sockaddr46	sa46;
171
172	time_t time_created;
173	time_t time_closed_all;
174
175	uint32_t hash;
176	uint32_t count_wsi;
177	uint32_t total_wsi;
178
179#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
180	struct lws_peer_role_http http;
181#endif
182};
183#endif
184
185#ifdef LWS_WITH_IPV6
186#define LWS_IPV6_ENABLED(vh) \
187	(!lws_check_opt(vh->context->options, LWS_SERVER_OPTION_DISABLE_IPV6) && \
188	 !lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_IPV6))
189#else
190#define LWS_IPV6_ENABLED(context) (0)
191#endif
192
193#ifdef LWS_WITH_UNIX_SOCK
194#define LWS_UNIX_SOCK_ENABLED(vhost) \
195	(vhost->options & LWS_SERVER_OPTION_UNIX_SOCK)
196#else
197#define LWS_UNIX_SOCK_ENABLED(vhost) (0)
198#endif
199
200enum uri_path_states {
201	URIPS_IDLE,
202	URIPS_SEEN_SLASH,
203	URIPS_SEEN_SLASH_DOT,
204	URIPS_SEEN_SLASH_DOT_DOT,
205};
206
207enum uri_esc_states {
208	URIES_IDLE,
209	URIES_SEEN_PERCENT,
210	URIES_SEEN_PERCENT_H1,
211};
212
213#if defined(LWS_WITH_CLIENT)
214
215enum {
216	CIS_ADDRESS,
217	CIS_PATH,
218	CIS_HOST,
219	CIS_ORIGIN,
220	CIS_PROTOCOL,
221	CIS_METHOD,
222	CIS_IFACE,
223	CIS_ALPN,
224
225
226	CIS_COUNT
227};
228
229struct client_info_stash {
230	char *cis[CIS_COUNT];
231	void *opaque_user_data; /* not allocated or freed by lws */
232};
233#endif
234
235#if defined(LWS_WITH_UDP)
236#define lws_wsi_is_udp(___wsi) (!!___wsi->udp)
237#endif
238
239#define LWS_H2_FRAME_HEADER_LENGTH 9
240
241lws_usec_t
242__lws_sul_service_ripe(lws_dll2_owner_t *own, int num_own, lws_usec_t usnow);
243
244/*
245 * lws_async_dns
246 */
247
248typedef struct lws_async_dns {
249	lws_sockaddr46 		sa46; /* nameserver */
250	lws_dll2_owner_t	waiting;
251	lws_dll2_owner_t	cached;
252	struct lws		*wsi;
253	time_t			time_set_server;
254	uint8_t			dns_server_set:1;
255	uint8_t			dns_server_connected:1;
256} lws_async_dns_t;
257
258typedef enum {
259	LADNS_CONF_SERVER_UNKNOWN				= -1,
260	LADNS_CONF_SERVER_SAME,
261	LADNS_CONF_SERVER_CHANGED
262} lws_async_dns_server_check_t;
263
264#if defined(LWS_WITH_SYS_ASYNC_DNS)
265void
266lws_aysnc_dns_completed(struct lws *wsi, void *sa, size_t salen,
267			lws_async_dns_retcode_t ret);
268#endif
269void
270lws_async_dns_cancel(struct lws *wsi);
271
272void
273lws_async_dns_drop_server(struct lws_context *context);
274
275/*
276 * so we can have n connections being serviced simultaneously,
277 * these things need to be isolated per-thread.
278 */
279
280struct lws_context_per_thread {
281#if LWS_MAX_SMP > 1
282	pthread_mutex_t lock_stats;
283	struct lws_mutex_refcount mr;
284	pthread_t self;
285#endif
286	struct lws_dll2_owner dll_buflist_owner;  /* guys with pending rxflow */
287	struct lws_dll2_owner seq_owner;	   /* list of lws_sequencer-s */
288	lws_dll2_owner_t      attach_owner;	/* pending lws_attach */
289
290#if defined(LWS_WITH_SECURE_STREAMS)
291	lws_dll2_owner_t ss_owner;
292#endif
293#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) || \
294    defined(LWS_WITH_SECURE_STREAMS_THREAD_API)
295	lws_dll2_owner_t ss_dsh_owner;
296	lws_dll2_owner_t ss_client_owner;
297#endif
298
299	struct lws_dll2_owner pt_sul_owner[LWS_COUNT_PT_SUL_OWNERS];
300
301#if defined (LWS_WITH_SEQUENCER)
302	lws_sorted_usec_list_t sul_seq_heartbeat;
303#endif
304#if (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) && defined(LWS_WITH_SERVER)
305	lws_sorted_usec_list_t sul_ah_lifecheck;
306#endif
307#if defined(LWS_WITH_TLS) && defined(LWS_WITH_SERVER)
308	lws_sorted_usec_list_t sul_tls;
309#endif
310#if defined(LWS_PLAT_UNIX)
311	lws_sorted_usec_list_t sul_plat;
312#endif
313#if defined(LWS_ROLE_CGI)
314	lws_sorted_usec_list_t sul_cgi;
315#endif
316#if defined(LWS_WITH_PEER_LIMITS)
317	lws_sorted_usec_list_t sul_peer_limits;
318#endif
319
320#if !defined(LWS_PLAT_FREERTOS)
321	struct lws *fake_wsi;   /* used for callbacks where there's no wsi */
322#endif
323
324#if defined(WIN32)
325	struct sockaddr_in frt_pipe_si;
326#endif
327
328#if defined(LWS_WITH_TLS)
329	struct lws_pt_tls tls;
330#endif
331	struct lws_context *context;
332
333	/*
334	 * usable by anything in the service code, but only if the scope
335	 * does not last longer than the service action (since next service
336	 * of any socket can likewise use it and overwrite)
337	 */
338	unsigned char *serv_buf;
339
340	struct lws_pollfd *fds;
341	volatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list;
342
343	lws_sockfd_type dummy_pipe_fds[2];
344	struct lws *pipe_wsi;
345
346	/* --- role based members --- */
347
348#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
349	struct lws_pt_role_ws ws;
350#endif
351#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
352	struct lws_pt_role_http http;
353#endif
354#if defined(LWS_ROLE_DBUS)
355	struct lws_pt_role_dbus dbus;
356#endif
357	/* --- event library based members --- */
358
359	void		*evlib_pt; /* overallocated */
360
361	/* --- */
362
363	unsigned long count_conns;
364	unsigned int fds_count;
365
366	/*
367	 * set to the Thread ID that's doing the service loop just before entry
368	 * to poll indicates service thread likely idling in poll()
369	 * volatile because other threads may check it as part of processing
370	 * for pollfd event change.
371	 */
372	volatile int service_tid;
373	int service_tid_detected;
374#if !defined(LWS_PLAT_FREERTOS)
375	int count_event_loop_static_asset_handles;
376#endif
377
378	volatile unsigned char inside_poll;
379	volatile unsigned char foreign_spinlock;
380
381	unsigned char tid;
382
383	unsigned char inside_service:1;
384	unsigned char inside_lws_service:1;
385	unsigned char event_loop_foreign:1;
386	unsigned char event_loop_destroy_processing_done:1;
387	unsigned char event_loop_pt_unused:1;
388	unsigned char destroy_self:1;
389	unsigned char is_destroyed:1;
390};
391
392/*
393 * virtual host -related context information
394 *   vhostwide SSL context
395 *   vhostwide proxy
396 *
397 * hierarchy:
398 *
399 * context -> vhost -> wsi
400 *
401 * incoming connection non-SSL vhost binding:
402 *
403 *    listen socket -> wsi -> select vhost after first headers
404 *
405 * incoming connection SSL vhost binding:
406 *
407 *    SSL SNI -> wsi -> bind after SSL negotiation
408 */
409
410struct lws_vhost {
411#if defined(LWS_WITH_CLIENT) && defined(LWS_CLIENT_HTTP_PROXYING)
412	char proxy_basic_auth_token[128];
413#endif
414#if LWS_MAX_SMP > 1
415	struct lws_mutex_refcount		mr;
416	char					close_flow_vs_tsi[LWS_MAX_SMP];
417#endif
418
419#if defined(LWS_ROLE_H2)
420	struct lws_vhost_role_h2 h2;
421#endif
422#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
423	struct lws_vhost_role_http http;
424#endif
425#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
426	struct lws_vhost_role_ws ws;
427#endif
428
429	lws_lifecycle_t		lc;
430	lws_dll2_t		vh_being_destroyed_list;
431
432#if defined(LWS_WITH_SOCKS5)
433	char socks_proxy_address[128];
434	char socks_user[96];
435	char socks_password[96];
436#endif
437
438#if defined(LWS_WITH_TLS_SESSIONS)
439	lws_dll2_owner_t	tls_sessions; /* vh lock */
440#endif
441
442#if defined(LWS_WITH_EVENT_LIBS)
443	void		*evlib_vh; /* overallocated */
444#endif
445#if defined(LWS_WITH_SYS_METRICS)
446	lws_metric_t	*mt_traffic_rx;
447	lws_metric_t	*mt_traffic_tx;
448#endif
449
450#if defined(LWS_WITH_SYS_FAULT_INJECTION)
451	lws_fi_ctx_t				fic;
452	/**< Fault Injection ctx for the vhost, hierarchy vhost->context */
453#endif
454
455	uint64_t options;
456
457	struct lws_context *context;
458	struct lws_vhost *vhost_next;
459
460	const lws_retry_bo_t *retry_policy;
461
462#if defined(LWS_WITH_TLS_JIT_TRUST)
463	lws_sorted_usec_list_t		sul_unref; /* grace period after idle */
464#endif
465
466#if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
467	lws_ss_handle_t		*ss_handle; /* ss handle for the server obj */
468#endif
469
470	lws_dll2_owner_t	listen_wsi;
471
472	const char *name;
473	const char *iface;
474	const char *listen_accept_role;
475	const char *listen_accept_protocol;
476	const char *unix_socket_perms;
477
478	void (*finalize)(struct lws_vhost *vh, void *arg);
479	void *finalize_arg;
480
481	const struct lws_protocols *protocols;
482	void **protocol_vh_privs;
483	const struct lws_protocol_vhost_options *pvo;
484	const struct lws_protocol_vhost_options *headers;
485	struct lws_dll2_owner *same_vh_protocol_owner;
486	struct lws_vhost *no_listener_vhost_list;
487	struct lws_dll2_owner abstract_instances_owner;		/* vh lock */
488
489#if defined(LWS_WITH_CLIENT)
490	struct lws_dll2_owner dll_cli_active_conns_owner;
491#endif
492	struct lws_dll2_owner vh_awaiting_socket_owner;
493
494#if defined(LWS_WITH_TLS)
495	struct lws_vhost_tls tls;
496#endif
497
498	void *user;
499
500	int listen_port;
501#if !defined(LWS_PLAT_FREERTOS) && !defined(OPTEE_TA) && !defined(WIN32)
502	int bind_iface;
503#endif
504
505#if defined(LWS_WITH_SOCKS5)
506	unsigned int socks_proxy_port;
507#endif
508	int count_protocols;
509	int ka_time;
510	int ka_probes;
511	int ka_interval;
512	int keepalive_timeout;
513	int timeout_secs_ah_idle;
514	int connect_timeout_secs;
515	int fo_listen_queue;
516
517	int count_bound_wsi;
518
519#ifdef LWS_WITH_ACCESS_LOG
520	int log_fd;
521#endif
522
523#if defined(LWS_WITH_TLS_SESSIONS)
524	uint32_t		tls_session_cache_max;
525#endif
526
527#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) || defined(LWS_WITH_SECURE_STREAMS_CPP)
528	int8_t			ss_refcount;
529	/**< refcount of number of ss connections with streamtypes using this
530	 * trust store */
531#endif
532
533	uint8_t allocated_vhost_protocols:1;
534	uint8_t created_vhost_protocols:1;
535	uint8_t being_destroyed:1;
536	uint8_t from_ss_policy:1;
537#if defined(LWS_WITH_TLS_JIT_TRUST)
538	uint8_t 		grace_after_unref:1;
539	/* grace time / autodelete aoplies to us */
540#endif
541
542	unsigned char default_protocol_index;
543	unsigned char raw_protocol_index;
544};
545
546void
547__lws_vhost_destroy2(struct lws_vhost *vh);
548
549#define mux_to_wsi(_m) lws_container_of(_m, struct lws, mux)
550
551void
552lws_wsi_mux_insert(struct lws *wsi, struct lws *parent_wsi, unsigned int sid);
553int
554lws_wsi_mux_mark_parents_needing_writeable(struct lws *wsi);
555struct lws *
556lws_wsi_mux_move_child_to_tail(struct lws **wsi2);
557int
558lws_wsi_mux_action_pending_writeable_reqs(struct lws *wsi);
559
560void
561lws_wsi_mux_dump_children(struct lws *wsi);
562
563void
564lws_wsi_mux_close_children(struct lws *wsi, int reason);
565
566void
567lws_wsi_mux_sibling_disconnect(struct lws *wsi);
568
569void
570lws_wsi_mux_dump_waiting_children(struct lws *wsi);
571
572int
573lws_wsi_mux_apply_queue(struct lws *wsi);
574
575/*
576 * struct lws
577 */
578
579/*
580 * These pieces are very commonly used (via accessors) in user protocol handlers
581 * and have to be valid, even in the case no real wsi is available for the cb.
582 *
583 * We put all this category of pointers in there and compose it at the top of
584 * struct lws, so a dummy wsi providing these only needs to be this big, while
585 * still being castable for being a struct wsi *
586 */
587
588struct lws_a {
589	struct lws_context		*context;
590	struct lws_vhost		*vhost;
591	const struct lws_protocols	*protocol;
592	void				*opaque_user_data;
593};
594
595/*
596 * For RTOS-class platforms, their code is relatively new, post-minimal examples
597 * and tend to not have legacy user protocol handler baggage touching unexpected
598 * things in fakewsi unconditionally... we can use an lws_a on the stack and
599 * don't need to define the rest of the wsi content, just cast it, this saves
600 * a wsi footprint in heap (typ 800 bytes nowadays even on RTOS).
601 *
602 * For other platforms that have been around for years and have thousands of
603 * different user protocol handler implementations, it's likely some of them
604 * will be touching the struct lws content unconditionally in the handler even
605 * when we are calling back with a non wsi-specific reason, and may react badly
606 * to it being garbage.  So continue to implement those as a full, zero-ed down
607 * prepared fakewsi on heap at context creation time.
608 */
609
610#if defined(LWS_PLAT_FREERTOS)
611#define lws_fakewsi_def_plwsa(pt) struct lws_a lwsa, *plwsa = &lwsa
612#else
613#define lws_fakewsi_def_plwsa(pt) struct lws_a *plwsa = &(pt)->fake_wsi->a
614#endif
615/* since we reuse the pt version, also correct to zero down the lws_a part */
616#define lws_fakewsi_prep_plwsa_ctx(_c) \
617		memset(plwsa, 0, sizeof(*plwsa)); plwsa->context = _c
618
619struct lws {
620
621	struct lws_a			a;
622
623	/* structs */
624
625#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
626	struct _lws_http_mode_related	http;
627#endif
628#if defined(LWS_ROLE_H2)
629	struct _lws_h2_related		h2;
630#endif
631#if defined(LWS_ROLE_WS)
632	struct _lws_websocket_related	*ws; /* allocated if we upgrade to ws */
633#endif
634#if defined(LWS_ROLE_DBUS)
635	struct _lws_dbus_mode_related	dbus;
636#endif
637#if defined(LWS_ROLE_MQTT)
638	struct _lws_mqtt_related	*mqtt;
639#endif
640
641#if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT)
642	struct lws_muxable		mux;
643	struct lws_tx_credit		txc;
644#endif
645
646	lws_lifecycle_t			lc;
647
648	/* lifetime members */
649
650#if defined(LWS_WITH_EVENT_LIBS)
651	void				*evlib_wsi; /* overallocated */
652#endif
653
654	lws_sorted_usec_list_t		sul_timeout;
655	lws_sorted_usec_list_t		sul_hrtimer;
656	lws_sorted_usec_list_t		sul_validity;
657	lws_sorted_usec_list_t		sul_connect_timeout;
658
659	struct lws_dll2			dll_buflist; /* guys with pending rxflow */
660	struct lws_dll2			same_vh_protocol;
661	struct lws_dll2			vh_awaiting_socket;
662#if defined(LWS_WITH_SYS_ASYNC_DNS)
663	struct lws_dll2			adns; /* on adns list of guys to tell result */
664	lws_async_dns_cb_t		adns_cb; /* callback with result */
665#endif
666#if defined(LWS_WITH_SERVER)
667	struct lws_dll2			listen_list;
668#endif
669#if defined(LWS_WITH_CLIENT)
670	struct lws_dll2			dll_cli_active_conns;
671	struct lws_dll2			dll2_cli_txn_queue;
672	struct lws_dll2_owner		dll2_cli_txn_queue_owner;
673
674	/**< caliper is reused for tcp, tls and txn conn phases */
675
676	lws_dll2_t			speculative_list;
677	lws_dll2_owner_t		speculative_connect_owner;
678	/* wsis: additional connection candidates */
679	lws_dll2_owner_t		dns_sorted_list;
680	/* lws_dns_sort_t: dns results wrapped and sorted in a linked-list...
681	 * deleted as they are tried, list empty == everything tried */
682#endif
683
684#if defined(LWS_WITH_SYS_FAULT_INJECTION)
685	lws_fi_ctx_t			fic;
686	/**< Fault Injection ctx for the wsi, hierarchy wsi->vhost->context */
687	lws_sorted_usec_list_t		sul_fault_timedclose;
688	/**< used to inject a fault that closes the wsi after a random time */
689#endif
690
691#if defined(LWS_WITH_SYS_METRICS)
692	lws_metrics_caliper_compose(cal_conn)
693#endif
694
695	lws_sockaddr46			sa46_local;
696	lws_sockaddr46			sa46_peer;
697
698	/* pointers */
699
700	struct lws			*parent; /* points to parent, if any */
701	struct lws			*child_list; /* points to first child */
702	struct lws			*sibling_list; /* subsequent children at same level */
703	const struct lws_role_ops	*role_ops;
704	struct lws_sequencer		*seq;	/* associated sequencer if any */
705	const lws_retry_bo_t		*retry_policy;
706
707	lws_log_cx_t			*log_cx;
708
709#if defined(LWS_WITH_THREADPOOL) && defined(LWS_HAVE_PTHREAD_H)
710	lws_dll2_owner_t		tp_task_owner; /* struct lws_threadpool_task */
711#endif
712
713#if defined(LWS_WITH_PEER_LIMITS)
714	struct lws_peer			*peer;
715#endif
716
717#if defined(LWS_WITH_UDP)
718	struct lws_udp			*udp;
719#endif
720#if defined(LWS_WITH_CLIENT)
721	struct client_info_stash	*stash;
722	char				*cli_hostname_copy;
723
724#if defined(LWS_WITH_CONMON)
725	struct lws_conmon		conmon;
726	lws_usec_t			conmon_datum;
727#endif
728#endif /* WITH_CLIENT */
729	void				*user_space;
730	void				*opaque_parent_data;
731
732	struct lws_buflist		*buflist; /* input-side buflist */
733	struct lws_buflist		*buflist_out; /* output-side buflist */
734
735#if defined(LWS_WITH_TLS)
736	struct lws_lws_tls		tls;
737	char				alpn[24];
738#endif
739
740	lws_sock_file_fd_type		desc; /* .filefd / .sockfd */
741
742	lws_wsi_state_t			wsistate;
743	lws_wsi_state_t			wsistate_pre_close;
744
745	/* ints */
746#define LWS_NO_FDS_POS (-1)
747	int				position_in_fds_table;
748
749#if defined(LWS_WITH_CLIENT)
750	int				chunk_remaining;
751	int				flags;
752#endif
753	unsigned int			cache_secs;
754
755	short				bugcatcher;
756
757	unsigned int			hdr_parsing_completed:1;
758	unsigned int			mux_substream:1;
759	unsigned int			upgraded_to_http2:1;
760	unsigned int			mux_stream_immortal:1;
761	unsigned int			h2_stream_carries_ws:1; /* immortal set as well */
762	unsigned int			h2_stream_carries_sse:1; /* immortal set as well */
763	unsigned int			h2_acked_settings:1;
764	unsigned int			seen_nonpseudoheader:1;
765	unsigned int			listener:1;
766	unsigned int			pf_packet:1;
767	unsigned int			do_broadcast:1;
768	unsigned int			user_space_externally_allocated:1;
769	unsigned int			socket_is_permanently_unusable:1;
770	unsigned int			rxflow_change_to:2;
771	unsigned int			conn_stat_done:1;
772	unsigned int			cache_reuse:1;
773	unsigned int			cache_revalidate:1;
774	unsigned int			cache_intermediaries:1;
775	unsigned int			favoured_pollin:1;
776	unsigned int			sending_chunked:1;
777	unsigned int			interpreting:1;
778	unsigned int			already_did_cce:1;
779	unsigned int			told_user_closed:1;
780	unsigned int			told_event_loop_closed:1;
781	unsigned int			waiting_to_send_close_frame:1;
782	unsigned int			close_needs_ack:1;
783	unsigned int			ipv6:1;
784	unsigned int			parent_pending_cb_on_writable:1;
785	unsigned int			cgi_stdout_zero_length:1;
786	unsigned int			seen_zero_length_recv:1;
787	unsigned int			rxflow_will_be_applied:1;
788	unsigned int			event_pipe:1;
789	unsigned int			handling_404:1;
790	unsigned int			protocol_bind_balance:1;
791	unsigned int			unix_skt:1;
792	unsigned int			close_when_buffered_out_drained:1;
793	unsigned int			h1_ws_proxied:1;
794	unsigned int			proxied_ws_parent:1;
795	unsigned int			do_bind:1;
796	unsigned int			validity_hup:1;
797	unsigned int			skip_fallback:1;
798	unsigned int			file_desc:1;
799	unsigned int			conn_validity_wakesuspend:1;
800	unsigned int			dns_reachability:1;
801
802	unsigned int			could_have_pending:1; /* detect back-to-back writes */
803	unsigned int			outer_will_close:1;
804	unsigned int			shadow:1; /* we do not control fd lifecycle at all */
805#if defined(LWS_WITH_SECURE_STREAMS)
806	unsigned int			for_ss:1;
807	unsigned int			bound_ss_proxy_conn:1;
808	unsigned int			client_bound_sspc:1;
809	unsigned int			client_proxy_onward:1;
810#endif
811	unsigned int                    tls_borrowed:1;
812	unsigned int                    tls_borrowed_hs:1;
813	unsigned int                    tls_read_wanted_write:1;
814
815#ifdef LWS_WITH_ACCESS_LOG
816	unsigned int			access_log_pending:1;
817#endif
818#if defined(LWS_WITH_CLIENT)
819	unsigned int			do_ws:1; /* whether we are doing http or ws flow */
820	unsigned int			chunked:1; /* if the clientside connection is chunked */
821	unsigned int			client_rx_avail:1;
822	unsigned int			client_http_body_pending:1;
823	unsigned int			transaction_from_pipeline_queue:1;
824	unsigned int			keepalive_active:1;
825	unsigned int			keepalive_rejected:1;
826	unsigned int			redirected_to_get:1;
827	unsigned int			client_pipeline:1;
828	unsigned int			client_h2_alpn:1;
829	unsigned int			client_mux_substream:1;
830	unsigned int			client_mux_migrated:1;
831	unsigned int			client_subsequent_mime_part:1;
832	unsigned int                    client_no_follow_redirect:1;
833	unsigned int                    client_suppress_CONNECTION_ERROR:1;
834	/**< because the client connection creation api is still the parent of
835	 * this activity, and will report the failure */
836	unsigned int			tls_session_reused:1;
837	unsigned int			perf_done:1;
838	unsigned int			close_is_redirect:1;
839	unsigned int			client_mux_substream_was:1;
840#endif
841
842#ifdef _WIN32
843	unsigned int sock_send_blocking:1;
844#endif
845
846	uint16_t			ocport, c_port, conn_port;
847	uint16_t			retry;
848#if defined(LWS_WITH_CLIENT)
849	uint16_t			keep_warm_secs;
850#endif
851
852	/* chars */
853
854	char lws_rx_parse_state; /* enum lws_rx_parse_state */
855	char rx_frame_type; /* enum lws_write_protocol */
856	char pending_timeout; /* enum pending_timeout */
857	char tsi; /* thread service index we belong to */
858	char protocol_interpret_idx;
859	char redirects;
860	uint8_t rxflow_bitmap;
861	uint8_t bound_vhost_index;
862	uint8_t lsp_channel; /* which of stdin/out/err */
863#ifdef LWS_WITH_CGI
864	char hdr_state;
865#endif
866#if defined(LWS_WITH_CLIENT)
867	char chunk_parser; /* enum lws_chunk_parser */
868	uint8_t addrinfo_idx;
869	uint8_t sys_tls_client_cert;
870	uint8_t c_pri;
871#endif
872	uint8_t		af;
873#if defined(LWS_WITH_CGI) || defined(LWS_WITH_CLIENT)
874	char reason_bf; /* internal writeable callback reason bitfield */
875#endif
876#if defined(LWS_WITH_NETLINK)
877	lws_route_uidx_t		peer_route_uidx;
878	/**< unique index of the route the connection is estimated to take */
879#endif
880	uint8_t immortal_substream_count;
881	/* volatile to make sure code is aware other thread can change */
882	volatile char handling_pollout;
883	volatile char leave_pollout_active;
884#if LWS_MAX_SMP > 1
885	volatile char undergoing_init_from_other_pt;
886#endif
887
888};
889
890#define lws_is_flowcontrolled(w) (!!(wsi->rxflow_bitmap))
891
892#if defined(LWS_WITH_SPAWN)
893
894#if defined(WIN32) || defined(_WIN32)
895#else
896#include <sys/wait.h>
897#include <sys/times.h>
898#endif
899
900struct lws_spawn_piped {
901
902	struct lws_spawn_piped_info	info;
903
904	struct lws_dll2			dll;
905	lws_sorted_usec_list_t		sul;
906	lws_sorted_usec_list_t		sul_reap;
907
908	struct lws_context		*context;
909	struct lws			*stdwsi[3];
910	lws_filefd_type			pipe_fds[3][2];
911	int				count_log_lines;
912
913	lws_usec_t			created; /* set by lws_spawn_piped() */
914	lws_usec_t			reaped;
915
916	lws_usec_t			accounting[4];
917
918#if defined(WIN32)
919	HANDLE				child_pid;
920	lws_sorted_usec_list_t		sul_poll;
921#else
922	pid_t				child_pid;
923
924	siginfo_t			si;
925#endif
926	int				reap_retry_budget;
927
928	uint8_t				pipes_alive:2;
929	uint8_t				we_killed_him_timeout:1;
930	uint8_t				we_killed_him_spew:1;
931	uint8_t				ungraceful:1;
932};
933
934void
935lws_spawn_piped_destroy(struct lws_spawn_piped **lsp);
936
937int
938lws_spawn_reap(struct lws_spawn_piped *lsp);
939
940#endif
941
942void
943lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
944
945const struct lws_role_ops *
946lws_role_by_name(const char *name);
947
948int
949lws_socket_bind(struct lws_vhost *vhost, struct lws *wsi,
950		lws_sockfd_type sockfd, int port, const char *iface,
951		int ipv6_allowed);
952
953#if defined(LWS_WITH_SYS_FAULT_INJECTION)
954void
955lws_wsi_fault_timedclose(struct lws *wsi);
956#else
957#define lws_wsi_fault_timedclose(_w)
958#endif
959
960#if defined(LWS_WITH_IPV6)
961unsigned long
962lws_get_addr_scope(struct lws *wsi, const char *ipaddr);
963#endif
964
965void
966lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);
967void
968__lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);
969
970void
971__lws_free_wsi(struct lws *wsi);
972
973void
974lws_conmon_addrinfo_destroy(struct addrinfo *ai);
975
976int
977lws_conmon_append_copy_new_dns_results(struct lws *wsi,
978				       const struct addrinfo *cai);
979
980#if LWS_MAX_SMP > 1
981
982static LWS_INLINE void
983lws_pt_mutex_init(struct lws_context_per_thread *pt)
984{
985	lws_mutex_refcount_init(&pt->mr);
986	pthread_mutex_init(&pt->lock_stats, NULL);
987}
988
989static LWS_INLINE void
990lws_pt_mutex_destroy(struct lws_context_per_thread *pt)
991{
992	pthread_mutex_destroy(&pt->lock_stats);
993	lws_mutex_refcount_destroy(&pt->mr);
994}
995
996#define lws_pt_lock(pt, reason) lws_mutex_refcount_lock(&pt->mr, reason)
997#define lws_pt_unlock(pt) lws_mutex_refcount_unlock(&pt->mr)
998#define lws_pt_assert_lock_held(pt) lws_mutex_refcount_assert_held(&pt->mr)
999
1000static LWS_INLINE void
1001lws_pt_stats_lock(struct lws_context_per_thread *pt)
1002{
1003	pthread_mutex_lock(&pt->lock_stats);
1004}
1005
1006static LWS_INLINE void
1007lws_pt_stats_unlock(struct lws_context_per_thread *pt)
1008{
1009	pthread_mutex_unlock(&pt->lock_stats);
1010}
1011#endif
1012
1013/*
1014 * EXTENSIONS
1015 */
1016
1017#if defined(LWS_WITHOUT_EXTENSIONS)
1018#define lws_any_extension_handled(_a, _b, _c, _d) (0)
1019#define lws_ext_cb_active(_a, _b, _c, _d) (0)
1020#define lws_ext_cb_all_exts(_a, _b, _c, _d, _e) (0)
1021#define lws_issue_raw_ext_access lws_issue_raw
1022#define lws_context_init_extensions(_a, _b)
1023#endif
1024
1025int LWS_WARN_UNUSED_RESULT
1026lws_client_interpret_server_handshake(struct lws *wsi);
1027
1028int LWS_WARN_UNUSED_RESULT
1029lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c);
1030
1031int LWS_WARN_UNUSED_RESULT
1032lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len);
1033
1034void
1035lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state,
1036		    const struct lws_role_ops *ops);
1037
1038int
1039lws_http_to_fallback(struct lws *wsi, unsigned char *buf, size_t len);
1040
1041int LWS_WARN_UNUSED_RESULT
1042user_callback_handle_rxflow(lws_callback_function, struct lws *wsi,
1043			    enum lws_callback_reasons reason, void *user,
1044			    void *in, size_t len);
1045
1046int
1047lws_plat_set_nonblocking(lws_sockfd_type fd);
1048
1049int
1050lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd,
1051			    int unix_skt);
1052
1053int
1054lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags);
1055
1056int
1057lws_plat_check_connection_error(struct lws *wsi);
1058
1059int LWS_WARN_UNUSED_RESULT
1060lws_header_table_attach(struct lws *wsi, int autoservice);
1061
1062int
1063lws_header_table_detach(struct lws *wsi, int autoservice);
1064int
1065__lws_header_table_detach(struct lws *wsi, int autoservice);
1066
1067void
1068lws_header_table_reset(struct lws *wsi, int autoservice);
1069
1070void
1071__lws_header_table_reset(struct lws *wsi, int autoservice);
1072
1073char * LWS_WARN_UNUSED_RESULT
1074lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);
1075
1076int LWS_WARN_UNUSED_RESULT
1077lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s);
1078
1079int LWS_WARN_UNUSED_RESULT
1080lws_ensure_user_space(struct lws *wsi);
1081
1082int LWS_WARN_UNUSED_RESULT
1083lws_change_pollfd(struct lws *wsi, int _and, int _or);
1084
1085#if defined(LWS_WITH_SERVER)
1086 int _lws_vhost_init_server(const struct lws_context_creation_info *info,
1087			      struct lws_vhost *vhost);
1088struct lws_vhost *
1089 lws_select_vhost(struct lws_context *context, int port, const char *servername);
1090int LWS_WARN_UNUSED_RESULT
1091 lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len);
1092void
1093 lws_server_get_canonical_hostname(struct lws_context *context,
1094				   const struct lws_context_creation_info *info);
1095#else
1096 #define _lws_vhost_init_server(_a, _b) (0)
1097 #define lws_parse_ws(_a, _b, _c) (0)
1098 #define lws_server_get_canonical_hostname(_a, _b)
1099#endif
1100
1101int
1102__remove_wsi_socket_from_fds(struct lws *wsi);
1103
1104enum {
1105	LWSRXFC_ERROR = -1,
1106	LWSRXFC_CACHED = 0,
1107	LWSRXFC_ADDITIONAL = 1,
1108	LWSRXFC_TRIMMED = 2,
1109};
1110
1111
1112int
1113_lws_plat_service_forced_tsi(struct lws_context *context, int tsi);
1114
1115int
1116lws_rxflow_cache(struct lws *wsi, unsigned char *buf, size_t n, size_t len);
1117
1118int
1119lws_service_flag_pending(struct lws_context *context, int tsi);
1120
1121int
1122lws_has_buffered_out(struct lws *wsi);
1123
1124int LWS_WARN_UNUSED_RESULT
1125lws_ws_client_rx_sm(struct lws *wsi, unsigned char c);
1126
1127lws_parser_return_t LWS_WARN_UNUSED_RESULT
1128lws_parse(struct lws *wsi, unsigned char *buf, int *len);
1129
1130int LWS_WARN_UNUSED_RESULT
1131lws_parse_urldecode(struct lws *wsi, uint8_t *_c);
1132
1133void
1134lws_sa46_copy_address(lws_sockaddr46 *sa46a, const void *in, int af);
1135
1136int LWS_WARN_UNUSED_RESULT
1137lws_http_action(struct lws *wsi);
1138
1139void
1140__lws_close_free_wsi_final(struct lws *wsi);
1141void
1142lws_libuv_closehandle(struct lws *wsi);
1143int
1144lws_libuv_check_watcher_active(struct lws *wsi);
1145
1146#if defined(LWS_WITH_EVLIB_PLUGINS) || defined(LWS_WITH_PLUGINS)
1147const lws_plugin_header_t *
1148lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
1149		const char *sofilename, const char *_class,
1150		each_plugin_cb_t each, void *each_user);
1151
1152int
1153lws_plat_destroy_dl(struct lws_plugin *p);
1154#endif
1155
1156struct lws *
1157lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
1158
1159void
1160lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi);
1161void
1162__lws_vhost_unbind_wsi(struct lws *wsi); /* req cx + vh lock */
1163
1164void
1165__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs);
1166int
1167__lws_change_pollfd(struct lws *wsi, int _and, int _or);
1168
1169
1170int
1171lws_callback_as_writeable(struct lws *wsi);
1172
1173int
1174lws_role_call_client_bind(struct lws *wsi,
1175			  const struct lws_client_connect_info *i);
1176void
1177lws_remove_child_from_any_parent(struct lws *wsi);
1178
1179char *
1180lws_generate_client_ws_handshake(struct lws *wsi, char *p, const char *conn1);
1181int
1182lws_client_ws_upgrade(struct lws *wsi, const char **cce);
1183int
1184lws_create_client_ws_object(const struct lws_client_connect_info *i,
1185			    struct lws *wsi);
1186int
1187lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len);
1188int
1189lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn);
1190int
1191lws_tls_server_conn_alpn(struct lws *wsi);
1192
1193int
1194lws_ws_client_rx_sm_block(struct lws *wsi, unsigned char **buf, size_t len);
1195void
1196lws_destroy_event_pipe(struct lws *wsi);
1197
1198/* socks */
1199int
1200lws_socks5c_generate_msg(struct lws *wsi, enum socks_msg_type type, ssize_t *msg_len);
1201
1202int LWS_WARN_UNUSED_RESULT
1203__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi);
1204
1205int LWS_WARN_UNUSED_RESULT
1206lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);
1207
1208lws_usec_t
1209__lws_seq_timeout_check(struct lws_context_per_thread *pt, lws_usec_t usnow);
1210
1211lws_usec_t
1212__lws_ss_timeout_check(struct lws_context_per_thread *pt, lws_usec_t usnow);
1213
1214struct lws * LWS_WARN_UNUSED_RESULT
1215lws_client_connect_2_dnsreq(struct lws *wsi);
1216
1217LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT
1218lws_client_reset(struct lws **wsi, int ssl, const char *address, int port,
1219		 const char *path, const char *host, char weak);
1220
1221struct lws * LWS_WARN_UNUSED_RESULT
1222lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi, const char *desc);
1223
1224char * LWS_WARN_UNUSED_RESULT
1225lws_generate_client_handshake(struct lws *wsi, char *pkt);
1226
1227int
1228lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd);
1229
1230struct lws *
1231lws_http_client_connect_via_info2(struct lws *wsi);
1232
1233
1234struct lws *
1235__lws_wsi_create_with_role(struct lws_context *context, int tsi,
1236			 const struct lws_role_ops *ops,
1237			 lws_log_cx_t *log_cx_template);
1238int
1239lws_wsi_inject_to_loop(struct lws_context_per_thread *pt, struct lws *wsi);
1240
1241int
1242lws_wsi_extract_from_loop(struct lws *wsi);
1243
1244
1245#if defined(LWS_WITH_CLIENT)
1246int
1247lws_http_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd);
1248
1249int LWS_WARN_UNUSED_RESULT
1250lws_http_transaction_completed_client(struct lws *wsi);
1251#if !defined(LWS_WITH_TLS)
1252	#define lws_context_init_client_ssl(_a, _b) (0)
1253#endif
1254void
1255lws_decode_ssl_error(void);
1256#else
1257#define lws_context_init_client_ssl(_a, _b) (0)
1258#endif
1259
1260int
1261__lws_rx_flow_control(struct lws *wsi);
1262
1263int
1264_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa);
1265
1266#if defined(LWS_WITH_SERVER)
1267int
1268lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len);
1269#else
1270#define lws_server_socket_service(_b, _c) (0)
1271#define lws_handshake_server(_a, _b, _c) (0)
1272#endif
1273
1274#ifdef LWS_WITH_ACCESS_LOG
1275int
1276lws_access_log(struct lws *wsi);
1277void
1278lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int len, int meth);
1279#else
1280#define lws_access_log(_a)
1281#endif
1282
1283#if defined(_DEBUG)
1284void
1285lws_wsi_txc_describe(struct lws_tx_credit *txc, const char *at, uint32_t sid);
1286#else
1287#define lws_wsi_txc_describe(x, y, z) { (void)x; }
1288#endif
1289
1290int
1291lws_wsi_txc_check_skint(struct lws_tx_credit *txc, int32_t tx_cr);
1292
1293int
1294lws_wsi_txc_report_manual_txcr_in(struct lws *wsi, int32_t bump);
1295
1296void
1297lws_mux_mark_immortal(struct lws *wsi);
1298void
1299lws_http_close_immortal(struct lws *wsi);
1300
1301int
1302lws_cgi_kill_terminated(struct lws_context_per_thread *pt);
1303
1304void
1305lws_cgi_remove_and_kill(struct lws *wsi);
1306
1307void
1308lws_plat_delete_socket_from_fds(struct lws_context *context,
1309				struct lws *wsi, int m);
1310void
1311lws_plat_insert_socket_into_fds(struct lws_context *context,
1312				struct lws *wsi);
1313
1314int
1315lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,
1316		       struct lws_pollfd *pfd);
1317
1318#if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
1319int
1320lws_adopt_ss_server_accept(struct lws *new_wsi);
1321#endif
1322
1323int
1324lws_plat_pipe_create(struct lws *wsi);
1325int
1326lws_plat_pipe_signal(struct lws_context *ctx, int tsi);
1327void
1328lws_plat_pipe_close(struct lws *wsi);
1329
1330void
1331lws_addrinfo_clean(struct lws *wsi);
1332
1333void
1334lws_add_wsi_to_draining_ext_list(struct lws *wsi);
1335void
1336lws_remove_wsi_from_draining_ext_list(struct lws *wsi);
1337int
1338lws_poll_listen_fd(struct lws_pollfd *fd);
1339int
1340lws_plat_service(struct lws_context *context, int timeout_ms);
1341LWS_VISIBLE int
1342_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
1343
1344int
1345lws_pthread_self_to_tsi(struct lws_context *context);
1346const char * LWS_WARN_UNUSED_RESULT
1347lws_plat_inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
1348int LWS_WARN_UNUSED_RESULT
1349lws_plat_inet_pton(int af, const char *src, void *dst);
1350
1351void
1352lws_same_vh_protocol_remove(struct lws *wsi);
1353void
1354__lws_same_vh_protocol_remove(struct lws *wsi);
1355void
1356lws_same_vh_protocol_insert(struct lws *wsi, int n);
1357
1358int
1359lws_client_stash_create(struct lws *wsi, const char **cisin);
1360
1361void
1362lws_seq_destroy_all_on_pt(struct lws_context_per_thread *pt);
1363
1364void
1365lws_addrinfo_clean(struct lws *wsi);
1366
1367int
1368_lws_route_pt_close_unroutable(struct lws_context_per_thread *pt);
1369
1370void
1371_lws_routing_entry_dump(struct lws_context *cx, lws_route_t *rou);
1372
1373void
1374_lws_routing_table_dump(struct lws_context *cx);
1375
1376#define LRR_IGNORE_PRI			(1 << 0)
1377#define LRR_MATCH_SRC			(1 << 1)
1378#define LRR_MATCH_DST			(1 << 2)
1379
1380lws_route_t *
1381_lws_route_remove(struct lws_context_per_thread *pt, lws_route_t *robj, int flags);
1382
1383void
1384_lws_route_table_empty(struct lws_context_per_thread *pt);
1385
1386void
1387_lws_route_table_ifdown(struct lws_context_per_thread *pt, int idx);
1388
1389lws_route_uidx_t
1390_lws_route_get_uidx(struct lws_context *cx);
1391
1392int
1393_lws_route_pt_close_route_users(struct lws_context_per_thread *pt,
1394			        lws_route_uidx_t uidx);
1395
1396lws_route_t *
1397_lws_route_est_outgoing(struct lws_context_per_thread *pt,
1398		        const lws_sockaddr46 *dest);
1399
1400int
1401lws_sort_dns(struct lws *wsi, const struct addrinfo *result);
1402
1403int
1404lws_broadcast(struct lws_context_per_thread *pt, int reason, void *in, size_t len);
1405
1406
1407#if defined(LWS_WITH_PEER_LIMITS)
1408void
1409lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer);
1410int
1411lws_peer_confirm_ah_attach_ok(struct lws_context *context,
1412			      struct lws_peer *peer);
1413void
1414lws_peer_track_ah_detach(struct lws_context *context, struct lws_peer *peer);
1415void
1416lws_peer_cull_peer_wait_list(struct lws_context *context);
1417struct lws_peer *
1418lws_get_or_create_peer(struct lws_vhost *vhost, lws_sockfd_type sockfd);
1419void
1420lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer,
1421		 struct lws *wsi);
1422void
1423lws_peer_dump_from_wsi(struct lws *wsi);
1424#endif
1425
1426#ifdef LWS_WITH_HUBBUB
1427hubbub_error
1428html_parser_cb(const hubbub_token *token, void *pw);
1429#endif
1430
1431#if defined(_DEBUG)
1432void
1433lws_service_assert_loop_thread(struct lws_context *cx, int tsi);
1434#else
1435#define lws_service_assert_loop_thread(_cx, _tsi)
1436#endif
1437
1438int
1439lws_threadpool_tsi_context(struct lws_context *context, int tsi);
1440
1441void
1442lws_threadpool_wsi_closing(struct lws *wsi);
1443
1444void
1445__lws_wsi_remove_from_sul(struct lws *wsi);
1446
1447void
1448lws_validity_confirmed(struct lws *wsi);
1449void
1450_lws_validity_confirmed_role(struct lws *wsi);
1451
1452int
1453lws_seq_pt_init(struct lws_context_per_thread *pt);
1454
1455int
1456lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi,
1457		       struct lws_tokens *ebuf, char fr, const char *hint);
1458int
1459lws_buflist_aware_finished_consuming(struct lws *wsi, struct lws_tokens *ebuf,
1460				     int used, int buffered, const char *hint);
1461
1462extern const struct lws_protocols protocol_abs_client_raw_skt,
1463				  protocol_abs_client_unit_test;
1464
1465void
1466__lws_reset_wsi(struct lws *wsi);
1467
1468void
1469lws_metrics_dump(struct lws_context *ctx);
1470
1471void
1472lws_inform_client_conn_fail(struct lws *wsi, void *arg, size_t len);
1473
1474#if defined(LWS_WITH_SYS_ASYNC_DNS)
1475lws_async_dns_server_check_t
1476lws_plat_asyncdns_init(struct lws_context *context, lws_sockaddr46 *sa);
1477int
1478lws_async_dns_init(struct lws_context *context);
1479void
1480lws_async_dns_deinit(lws_async_dns_t *dns);
1481#endif
1482
1483int
1484lws_protocol_init_vhost(struct lws_vhost *vh, int *any);
1485int
1486_lws_generic_transaction_completed_active_conn(struct lws **wsi, char take_vh_lock);
1487
1488#define ACTIVE_CONNS_SOLO 0
1489#define ACTIVE_CONNS_MUXED 1
1490#define ACTIVE_CONNS_QUEUED 2
1491#define ACTIVE_CONNS_FAILED 3
1492
1493#if defined(_DEBUG) && !defined(LWS_PLAT_FREERTOS) && !defined(WIN32) && !defined(LWS_PLAT_OPTEE)
1494
1495int
1496sanity_assert_no_wsi_traces(const struct lws_context *context, struct lws *wsi);
1497int
1498sanity_assert_no_sockfd_traces(const struct lws_context *context,
1499			       lws_sockfd_type sfd);
1500#else
1501static inline int sanity_assert_no_wsi_traces(const struct lws_context *context, struct lws *wsi) { (void)context; (void)wsi; return 0; }
1502static inline int sanity_assert_no_sockfd_traces(const struct lws_context *context, lws_sockfd_type sfd) { (void)context; (void)sfd; return 0; }
1503#endif
1504
1505
1506void
1507delete_from_fdwsi(const struct lws_context *context, struct lws *wsi);
1508
1509int
1510lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi, const char *adsin);
1511
1512const char *
1513lws_wsi_client_stash_item(struct lws *wsi, int stash_idx, int hdr_idx);
1514
1515int
1516lws_plat_BINDTODEVICE(lws_sockfd_type fd, const char *ifname);
1517
1518int
1519lws_socks5c_ads_server(struct lws_vhost *vh,
1520		       const struct lws_context_creation_info *info);
1521
1522int
1523lws_socks5c_handle_state(struct lws *wsi, struct lws_pollfd *pollfd,
1524			 const char **pcce);
1525
1526int
1527lws_socks5c_greet(struct lws *wsi, const char **pcce);
1528
1529int
1530lws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len);
1531
1532int
1533lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len);
1534
1535lws_usec_t
1536lws_sul_nonmonotonic_adjust(struct lws_context *ctx, int64_t step_us);
1537
1538void
1539__lws_vhost_destroy_pt_wsi_dieback_start(struct lws_vhost *vh);
1540
1541int
1542lws_vhost_compare_listen(struct lws_vhost *v1, struct lws_vhost *v2);
1543
1544void
1545lws_netdev_instance_remove_destroy(struct lws_netdev_instance *ni);
1546
1547int
1548lws_score_dns_results(struct lws_context *ctx,
1549			     const struct addrinfo **result);
1550
1551#if defined(LWS_WITH_SYS_SMD)
1552int
1553lws_netdev_smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp,
1554		  void *buf, size_t len);
1555#endif
1556
1557void
1558lws_netdev_instance_create(lws_netdev_instance_t *ni, struct lws_context *ctx,
1559			   const lws_netdev_ops_t *ops, const char *name,
1560			   void *platinfo);
1561
1562int
1563lws_netdev_wifi_rssi_sort_compare(const lws_dll2_t *d, const lws_dll2_t *i);
1564void
1565lws_netdev_wifi_scan_empty(lws_netdev_instance_wifi_t *wnd);
1566
1567lws_wifi_sta_t *
1568lws_netdev_wifi_scan_find(lws_netdev_instance_wifi_t *wnd, const char *ssid,
1569			  const uint8_t *bssid);
1570
1571int
1572lws_netdev_wifi_scan_select(lws_netdev_instance_wifi_t *wnd);
1573
1574lws_wifi_creds_t *
1575lws_netdev_credentials_find(lws_netdevs_t *netdevs, const char *ssid,
1576			    const uint8_t *bssid);
1577
1578int
1579lws_netdev_wifi_redo_last(lws_netdev_instance_wifi_t *wnd);
1580
1581void
1582lws_ntpc_trigger(struct lws_context *ctx);
1583
1584void
1585lws_netdev_wifi_scan(lws_sorted_usec_list_t *sul);
1586
1587#define lws_netdevs_from_ndi(ni) \
1588		lws_container_of((ni)->list.owner, lws_netdevs_t, owner)
1589
1590#define lws_context_from_netdevs(nd) \
1591		lws_container_of(nd, struct lws_context, netdevs)
1592
1593/* get the owner of the ni, then compute the context the owner is embedded in */
1594#define netdev_instance_to_ctx(ni) \
1595		lws_container_of(lws_netdevs_from_ndi(ni), \
1596				 struct lws_context, netdevs)
1597
1598enum {
1599	LW5CHS_RET_RET0,
1600	LW5CHS_RET_BAIL3,
1601	LW5CHS_RET_STARTHS,
1602	LW5CHS_RET_NOTHING
1603};
1604
1605void
1606lws_4to6(uint8_t *v6addr, const uint8_t *v4addr);
1607void
1608lws_sa46_4to6(lws_sockaddr46 *sa46, const uint8_t *v4addr, uint16_t port);
1609
1610#ifdef __cplusplus
1611};
1612#endif
1613
1614#endif
1615