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_PRIVATE_LIB_CORE_H__)
26 #define __LWS_PRIVATE_LIB_CORE_H__
27 
28 #include "lws_config.h"
29 #include "lws_config_private.h"
30 
31 
32 #if defined(LWS_WITH_CGI) && defined(LWS_HAVE_VFORK) && \
33     !defined(NO_GNU_SOURCE_THIS_TIME) && !defined(_GNU_SOURCE)
34  #define  _GNU_SOURCE
35 #endif
36 
37 /*
38 #if !defined(_POSIX_C_SOURCE)
39 #define _POSIX_C_SOURCE 200112L
40 #endif
41 */
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <time.h>
47 #include <ctype.h>
48 #include <limits.h>
49 #include <stdarg.h>
50 #include <errno.h>
51 
52 #ifdef LWS_HAVE_INTTYPES_H
53 #include <inttypes.h>
54 #endif
55 
56 #include <assert.h>
57 
58 #ifdef LWS_HAVE_SYS_TYPES_H
59  #include <sys/types.h>
60 #endif
61 #if defined(LWS_HAVE_SYS_STAT_H) && !defined(LWS_PLAT_OPTEE)
62  #include <sys/stat.h>
63 #endif
64 
65 #if LWS_MAX_SMP > 1 || defined(LWS_WITH_SYS_SMD)
66  /* https://stackoverflow.com/questions/33557506/timespec-redefinition-error */
67  #define HAVE_STRUCT_TIMESPEC
68  #include <pthread.h>
69 #else
70  #if !defined(pid_t) && defined(WIN32)
71  #define pid_t int
72  #endif
73 #endif
74 
75 #ifndef LWS_DEF_HEADER_LEN
76 #define LWS_DEF_HEADER_LEN 4096
77 #endif
78 #ifndef LWS_DEF_HEADER_POOL
79 #define LWS_DEF_HEADER_POOL 4
80 #endif
81 #ifndef LWS_MAX_PROTOCOLS
82 #define LWS_MAX_PROTOCOLS 5
83 #endif
84 #ifndef LWS_MAX_EXTENSIONS_ACTIVE
85 #define LWS_MAX_EXTENSIONS_ACTIVE 1
86 #endif
87 #ifndef LWS_MAX_EXT_OFFERS
88 #define LWS_MAX_EXT_OFFERS 8
89 #endif
90 #ifndef SPEC_LATEST_SUPPORTED
91 #define SPEC_LATEST_SUPPORTED 13
92 #endif
93 #ifndef CIPHERS_LIST_STRING
94 #define CIPHERS_LIST_STRING "DEFAULT"
95 #endif
96 #ifndef LWS_SOMAXCONN
97 #define LWS_SOMAXCONN SOMAXCONN
98 #endif
99 
100 #define MAX_WEBSOCKET_04_KEY_LEN 128
101 
102 #ifndef SYSTEM_RANDOM_FILEPATH
103 #define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
104 #endif
105 
106 #define LWS_H2_RX_SCRATCH_SIZE 512
107 
108 #define lws_socket_is_valid(x) (x != LWS_SOCK_INVALID)
109 
110 #ifndef LWS_HAVE_STRERROR
111  #define strerror(x) ""
112 #endif
113 
114  /*
115   *
116   *  ------ private platform defines ------
117   *
118   */
119 
120 #if defined(LWS_PLAT_FREERTOS)
121  #include "private-lib-plat-freertos.h"
122 #else
123  #if defined(WIN32) || defined(_WIN32)
124   #include "private-lib-plat-windows.h"
125  #else
126   #if defined(LWS_PLAT_OPTEE)
127    #include "private-lib-plat.h"
128   #else
129    #include "private-lib-plat-unix.h"
130   #endif
131  #endif
132 #endif
133 
134  /*
135   *
136   *  ------ public api ------
137   *
138   */
139 
140 #include "libwebsockets.h"
141 
142 /*
143  * lws_dsh
144 */
145 
146 typedef struct lws_dsh_obj_head {
147 	lws_dll2_owner_t		owner;
148 	size_t				total_size; /* for this kind in dsh */
149 	int				kind;
150 } lws_dsh_obj_head_t;
151 
152 typedef struct lws_dsh_obj {
153 	lws_dll2_t			list;	/* must be first */
154 	struct lws_dsh	  		*dsh;	/* invalid when on free list */
155 	size_t				size;	/* invalid when on free list */
156 	size_t				asize;
157 	int				kind; /* so we can account at free */
158 } lws_dsh_obj_t;
159 
160 typedef struct lws_dsh {
161 	lws_dll2_t			list;
162 	uint8_t				*buf;
163 	lws_dsh_obj_head_t		*oha;	/* array of object heads/kind */
164 	size_t				buffer_size;
165 	size_t				locally_in_use;
166 	size_t				locally_free;
167 	int				count_kinds;
168 	uint8_t				being_destroyed;
169 	/*
170 	 * Overallocations at create:
171 	 *
172 	 *  - the buffer itself
173 	 *  - the object heads array
174 	 */
175 } lws_dsh_t;
176 
177  /*
178   *
179   *  ------ lifecycle defines ------
180   *
181   */
182 
183 typedef struct lws_lifecycle_group {
184 	lws_dll2_owner_t		owner; /* active count / list */
185 	uint64_t			ordinal; /* monotonic uid count */
186 	const char			*tag_prefix; /* eg, "wsi" */
187 } lws_lifecycle_group_t;
188 
189 typedef struct lws_lifecycle {
190 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
191 	/* we append parent streams on the tag */
192 	char				gutag[96]; /* object unique tag + relationship info */
193 #else
194 	char				gutag[64];
195 #endif
196 	lws_dll2_t			list; /* group list membership */
197 	uint64_t			us_creation; /* creation timestamp */
198 } lws_lifecycle_t;
199 
200 void
201 __lws_lc_tag(lws_lifecycle_group_t *grp, lws_lifecycle_t *lc,
202 		    const char *format, ...);
203 
204 void
205 __lws_lc_tag_append(lws_lifecycle_t *lc, const char *app);
206 
207 void
208 __lws_lc_untag(lws_lifecycle_t *lc);
209 
210 const char *
211 lws_lc_tag(lws_lifecycle_t *lc);
212 
213 /*
214  * Generic bidi tx credit management
215  */
216 
217 struct lws_tx_credit {
218 	int32_t			tx_cr;		/* our credit to write peer */
219 	int32_t			peer_tx_cr_est; /* peer's credit to write us */
220 
221 	int32_t			manual_initial_tx_credit;
222 
223 	uint8_t			skint; /* unable to write anything */
224 	uint8_t			manual;
225 };
226 
227 #ifdef LWS_WITH_IPV6
228 #if defined(WIN32) || defined(_WIN32)
229 #include <iphlpapi.h>
230 #else
231 #include <net/if.h>
232 #endif
233 #endif
234 
235 #undef X509_NAME
236 
237 /*
238  * All lws_tls...() functions must return this type, converting the
239  * native backend result and doing the extra work to determine which one
240  * as needed.
241  *
242  * Native TLS backend return codes are NOT ALLOWED outside the backend.
243  *
244  * Non-SSL mode also uses these types.
245  */
246 enum lws_ssl_capable_status {
247 	LWS_SSL_CAPABLE_ERROR			= -1, /* it failed */
248 	LWS_SSL_CAPABLE_DONE			= 0,  /* it succeeded */
249 	LWS_SSL_CAPABLE_MORE_SERVICE_READ	= -2, /* retry WANT_READ */
250 	LWS_SSL_CAPABLE_MORE_SERVICE_WRITE	= -3, /* retry WANT_WRITE */
251 	LWS_SSL_CAPABLE_MORE_SERVICE		= -4, /* general retry */
252 };
253 
254 enum lws_context_destroy {
255 	LWSCD_NO_DESTROY,		/* running */
256 	LWSCD_PT_WAS_DEFERRED,		/* destroy from inside service */
257 	LWSCD_PT_WAIT_ALL_DESTROYED,	/* libuv ends up here later */
258 	LWSCD_FINALIZATION		/* the final destruction of context */
259 };
260 
261 #if defined(LWS_WITH_TLS)
262 #include "private-lib-tls.h"
263 #endif
264 
265 #if defined(WIN32) || defined(_WIN32)
266 	 // Visual studio older than 2015 and WIN_CE has only _stricmp
267 	#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE)
268 	#define strcasecmp _stricmp
269 	#define strncasecmp _strnicmp
270 	#elif !defined(__MINGW32__)
271 	#define strcasecmp stricmp
272 	#define strncasecmp strnicmp
273 	#endif
274 	#define getdtablesize() 30000
275 #endif
276 
277 #ifndef LWS_ARRAY_SIZE
278 #define LWS_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
279 #endif
280 
281 #ifdef __cplusplus
282 extern "C" {
283 #endif
284 
285 #define lws_safe_modulo(_a, _b) ((_b) ? ((_a) % (_b)) : 0)
286 
287 #if defined(__clang__)
288 #define lws_memory_barrier() __sync_synchronize()
289 #elif defined(__GNUC__)
290 #define lws_memory_barrier() __sync_synchronize()
291 #else
292 #define lws_memory_barrier()
293 #endif
294 
295 
296 struct lws_ring {
297 	void *buf;
298 	void (*destroy_element)(void *element);
299 	uint32_t buflen;
300 	uint32_t element_len;
301 	uint32_t head;
302 	uint32_t oldest_tail;
303 };
304 
305 struct lws_protocols;
306 struct lws;
307 
308 #if defined(LWS_WITH_NETWORK) /* network */
309 #include "private-lib-event-libs.h"
310 
311 #if defined(LWS_WITH_SECURE_STREAMS)
312 #include "private-lib-secure-streams.h"
313 #endif
314 
315 #if defined(LWS_WITH_SYS_SMD)
316 #include "private-lib-system-smd.h"
317 #endif
318 
319 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
320 #include "private-lib-system-fault-injection.h"
321 #endif
322 
323 #include "private-lib-system-metrics.h"
324 
325 
326 struct lws_foreign_thread_pollfd {
327 	struct lws_foreign_thread_pollfd *next;
328 	int fd_index;
329 	int _and;
330 	int _or;
331 };
332 #endif /* network */
333 
334 #if defined(LWS_WITH_NETWORK)
335 #include "private-lib-core-net.h"
336 #endif
337 
338 struct lws_system_blob {
339 	union {
340 		struct lws_buflist *bl;
341 		struct {
342 			const uint8_t *ptr;
343 			size_t len;
344 		} direct;
345 	} u;
346 	char	is_direct;
347 };
348 
349 
350 typedef struct lws_attach_item {
351 	lws_dll2_t			list;
352 	lws_attach_cb_t			cb;
353 	void				*opaque;
354 	lws_system_states_t		state;
355 } lws_attach_item_t;
356 
357 /*
358  * These are the context's lifecycle group indexes that exist in this build
359  * configuration.  If you add some, make sure to also add the tag_prefix in
360  * context.c context creation with matching preprocessor conditionals.
361  */
362 
363 enum {
364 	LWSLCG_WSI,			/* generic wsi, eg, pipe, listen */
365 	LWSLCG_VHOST,
366 
367 	LWSLCG_WSI_SERVER,		/* server wsi */
368 
369 #if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT)
370 	LWSLCG_WSI_MUX,			/* a mux child wsi */
371 #endif
372 
373 #if defined(LWS_WITH_CLIENT)
374 	LWSLCG_WSI_CLIENT,		/* client wsi */
375 #endif
376 
377 #if defined(LWS_WITH_SECURE_STREAMS)
378 #if defined(LWS_WITH_CLIENT)
379 	LWSLCG_SS_CLIENT,		/* secstream client handle */
380 #endif
381 #if defined(LWS_WITH_SERVER)
382 	LWSLCG_SS_SERVER,		/* secstream server handle */
383 #endif
384 #if defined(LWS_WITH_CLIENT)
385 	LWSLCG_WSI_SS_CLIENT,		/* wsi bound to ss client handle */
386 #endif
387 #if defined(LWS_WITH_SERVER)
388 	LWSLCG_WSI_SS_SERVER,		/* wsi bound to ss server handle */
389 #endif
390 #endif
391 
392 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
393 #if defined(LWS_WITH_CLIENT)
394 	LWSLCG_SSP_CLIENT,		/* SSPC handle client connection to proxy */
395 #endif
396 #if defined(LWS_WITH_SERVER)
397 	LWSLCG_SSP_ONWARD,		/* SS handle at proxy for onward conn */
398 #endif
399 #if defined(LWS_WITH_CLIENT)
400 	LWSLCG_WSI_SSP_CLIENT,		/* wsi bound to SSPC cli conn to proxy */
401 #endif
402 #if defined(LWS_WITH_SERVER)
403 	LWSLCG_WSI_SSP_ONWARD,		/* wsi bound to Proxy onward connection */
404 #endif
405 #endif
406 
407 	/* always last */
408 	LWSLCG_COUNT
409 };
410 
411 /*
412  * the rest is managed per-context, that includes
413  *
414  *  - processwide single fd -> wsi lookup
415  *  - contextwide headers pool
416  */
417 
418 struct lws_context {
419  #if defined(LWS_WITH_SERVER)
420 	char canonical_hostname[96];
421  #endif
422 
423 #if defined(LWS_WITH_FILE_OPS)
424 	struct lws_plat_file_ops fops_platform;
425 #endif
426 
427 #if defined(LWS_WITH_ZIP_FOPS)
428 	struct lws_plat_file_ops fops_zip;
429 #endif
430 
431 	lws_system_blob_t system_blobs[LWS_SYSBLOB_TYPE_COUNT];
432 
433 #if defined(LWS_WITH_SYS_SMD)
434 	lws_smd_t				smd;
435 #endif
436 #if defined(LWS_WITH_SECURE_STREAMS)
437 	struct lws_ss_handle			*ss_cpd;
438 #endif
439 	lws_sorted_usec_list_t			sul_cpd_defer;
440 
441 #if defined(LWS_WITH_NETWORK)
442 	struct lws_context_per_thread		pt[LWS_MAX_SMP];
443 	lws_retry_bo_t				default_retry;
444 	lws_sorted_usec_list_t			sul_system_state;
445 
446 	lws_lifecycle_group_t			lcg[LWSLCG_COUNT];
447 
448 #if defined(LWS_WITH_NETLINK)
449 	lws_sorted_usec_list_t			sul_nl_coldplug;
450 	/* process can only have one netlink socket, have to do it in ctx */
451 	lws_dll2_owner_t			routing_table;
452 	struct lws				*netlink;
453 #endif
454 
455 #if defined(LWS_PLAT_FREERTOS)
456 	struct sockaddr_in			frt_pipe_si;
457 #endif
458 
459 #if defined(LWS_WITH_HTTP2)
460 	struct http2_settings			set;
461 #endif
462 
463 #if LWS_MAX_SMP > 1
464 	struct lws_mutex_refcount		mr;
465 #endif
466 
467 #if defined(LWS_WITH_SYS_METRICS)
468 	lws_dll2_owner_t			owner_mtr_dynpol;
469 	/**< owner for lws_metric_policy_dyn_t (dynamic part of metric pols) */
470 	lws_dll2_owner_t			owner_mtr_no_pol;
471 	/**< owner for lws_metric_pub_t with no policy to bind to */
472 #endif
473 
474 #if defined(LWS_WITH_NETWORK)
475 /*
476  * LWS_WITH_NETWORK =====>
477  */
478 
479 	lws_dll2_owner_t		owner_vh_being_destroyed;
480 
481 	lws_metric_t			*mt_service; /* doing service */
482 	const lws_metric_policy_t	*metrics_policies;
483 	const char			*metrics_prefix;
484 
485 #if defined(LWS_WITH_SYS_METRICS) && defined(LWS_WITH_CLIENT)
486 	lws_metric_t			*mt_conn_tcp; /* client tcp conns */
487 	lws_metric_t			*mt_conn_tls; /* client tcp conns */
488 	lws_metric_t			*mt_conn_dns; /* client dns external lookups */
489 	lws_metric_t			*mth_conn_failures; /* histogram of conn failure reasons */
490 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
491 	lws_metric_t			*mt_http_txn; /* client http transaction */
492 #endif
493 #if defined(LWS_WITH_SYS_ASYNC_DNS)
494 	lws_metric_t			*mt_adns_cache; /* async dns lookup lat */
495 #endif
496 #if defined(LWS_WITH_SECURE_STREAMS)
497 	lws_metric_t			*mth_ss_conn; /* SS connection outcomes */
498 #endif
499 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
500 	lws_metric_t			*mt_ss_cliprox_conn; /* SS cli->prox conn */
501 	lws_metric_t			*mt_ss_cliprox_paylat; /* cli->prox payload latency */
502 	lws_metric_t			*mt_ss_proxcli_paylat; /* prox->cli payload latency */
503 #endif
504 #endif /* client */
505 
506 #if defined(LWS_WITH_SERVER)
507 	lws_metric_t			*mth_srv;
508 #endif
509 
510 #if defined(LWS_WITH_EVENT_LIBS)
511 	struct lws_plugin		*evlib_plugin_list;
512 	void				*evlib_ctx; /* overallocated */
513 #endif
514 
515 #if defined(LWS_WITH_TLS)
516 	struct lws_context_tls		tls;
517 #endif
518 #if defined(LWS_WITH_DRIVERS)
519 	lws_netdevs_t			netdevs;
520 #endif
521 
522 #if defined(LWS_WITH_SYS_ASYNC_DNS)
523 	lws_async_dns_t			async_dns;
524 #endif
525 
526 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
527 	lws_fi_ctx_t			fic;
528 	/**< Toplevel Fault Injection ctx */
529 #endif
530 
531 
532 #if defined(LWS_WITH_SYS_NTPCLIENT)
533 	void				*ntpclient_priv;
534 #endif
535 
536 #if defined(LWS_WITH_SECURE_STREAMS)
537 	struct lws_ss_handle		*hss_fetch_policy;
538 #if defined(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM)
539 	struct lws_ss_handle		*hss_auth;
540 	lws_sorted_usec_list_t		sul_api_amazon_com;
541 	lws_sorted_usec_list_t		sul_api_amazon_com_kick;
542 #endif
543 #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
544 	struct lws_ss_x509		*server_der_list;
545 #endif
546 #endif
547 
548 #if defined(LWS_WITH_SYS_STATE)
549 	lws_state_manager_t		mgr_system;
550 	lws_state_notify_link_t		protocols_notify;
551 #endif
552 #if defined (LWS_WITH_SYS_DHCP_CLIENT)
553 	lws_dll2_owner_t		dhcpc_owner;
554 					/**< list of ifaces with dhcpc */
555 #endif
556 
557 	/* pointers */
558 
559 	struct lws_vhost		*vhost_list;
560 	struct lws_vhost		*no_listener_vhost_list;
561 	struct lws_vhost		*vhost_pending_destruction_list;
562 	struct lws_vhost		*vhost_system;
563 
564 #if defined(LWS_WITH_SERVER)
565 	const char			*server_string;
566 #endif
567 
568 	const struct lws_event_loop_ops	*event_loop_ops;
569 #endif
570 
571 #if defined(LWS_WITH_TLS)
572 	const struct lws_tls_ops	*tls_ops;
573 #endif
574 
575 #if defined(LWS_WITH_PLUGINS)
576 	struct lws_plugin		*plugin_list;
577 #endif
578 #ifdef _WIN32
579 /* different implementation between unix and windows */
580 	struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
581 #else
582 	struct lws **lws_lookup;
583 
584 #endif
585 
586 /*
587  * <====== LWS_WITH_NETWORK end
588  */
589 
590 #endif /* NETWORK */
591 
592 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
593 	const char	*ss_proxy_bind;
594 	const char	*ss_proxy_address;
595 #endif
596 
597 #if defined(LWS_WITH_FILE_OPS)
598 	const struct lws_plat_file_ops *fops;
599 #endif
600 
601 	struct lws_context **pcontext_finalize;
602 #if !defined(LWS_PLAT_FREERTOS)
603 	const char *username, *groupname;
604 #endif
605 
606 #if defined(LWS_AMAZON_RTOS) && defined(LWS_WITH_MBEDTLS)
607 	mbedtls_entropy_context mec;
608 	mbedtls_ctr_drbg_context mcdc;
609 #endif
610 
611 #if defined(LWS_WITH_THREADPOOL)
612 	struct lws_threadpool *tp_list_head;
613 #endif
614 
615 #if defined(LWS_WITH_PEER_LIMITS)
616 	struct lws_peer			**pl_hash_table;
617 	struct lws_peer			*peer_wait_list;
618 	lws_peer_limits_notify_t	pl_notify_cb;
619 	time_t				next_cull;
620 #endif
621 
622 	const lws_system_ops_t		*system_ops;
623 
624 #if defined(LWS_WITH_SECURE_STREAMS)
625 #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
626 	const char			*pss_policies_json;
627 	struct lwsac			*ac_policy;
628 	void				*pol_args;
629 #endif
630 	const lws_ss_policy_t		*pss_policies;
631 	const lws_ss_auth_t		*pss_auths;
632 #if defined(LWS_WITH_SSPLUGINS)
633 	const lws_ss_plugin_t		**pss_plugins;
634 #endif
635 #endif
636 
637 	void *external_baggage_free_on_destroy;
638 	const struct lws_token_limits *token_limits;
639 	void *user_space;
640 #if defined(LWS_WITH_SERVER)
641 	const struct lws_protocol_vhost_options *reject_service_keywords;
642 	lws_reload_func deprecation_cb;
643 #endif
644 #if !defined(LWS_PLAT_FREERTOS)
645 	void (*eventlib_signal_cb)(void *event_lib_handle, int signum);
646 #endif
647 
648 #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
649 	cap_value_t caps[4];
650 	char count_caps;
651 #endif
652 
653 	lws_usec_t time_up; /* monotonic */
654 #if defined(LWS_WITH_SYS_SMD)
655 	lws_usec_t smd_ttl_us;
656 #endif
657 	uint64_t options;
658 
659 	time_t last_ws_ping_pong_check_s;
660 #if defined(LWS_WITH_SECURE_STREAMS)
661 	time_t					last_policy;
662 #endif
663 
664 #if defined(LWS_PLAT_FREERTOS)
665 	unsigned long time_last_state_dump;
666 	uint32_t last_free_heap;
667 #endif
668 
669 	unsigned int max_fds;
670 #if !defined(LWS_NO_DAEMONIZE)
671 	pid_t started_with_parent;
672 #endif
673 
674 #if !defined(LWS_PLAT_FREERTOS)
675 	uid_t uid;
676 	gid_t gid;
677 	int fd_random;
678 	int count_cgi_spawned;
679 #endif
680 
681 	unsigned int fd_limit_per_thread;
682 	unsigned int timeout_secs;
683 	unsigned int pt_serv_buf_size;
684 	unsigned int max_http_header_data;
685 	unsigned int max_http_header_pool;
686 	int simultaneous_ssl_restriction;
687 	int simultaneous_ssl;
688 	int ssl_handshake_serialize;
689 #if defined(LWS_WITH_PEER_LIMITS)
690 	uint32_t pl_hash_elements;	/* protected by context->lock */
691 	uint32_t count_peers;		/* protected by context->lock */
692 	unsigned short ip_limit_ah;
693 	unsigned short ip_limit_wsi;
694 #endif
695 
696 #if defined(LWS_WITH_SYS_SMD)
697 	uint16_t smd_queue_depth;
698 #endif
699 
700 #if defined(LWS_WITH_NETLINK)
701 	lws_route_uidx_t			route_uidx;
702 #endif
703 
704 	unsigned int deprecated:1;
705 	unsigned int inside_context_destroy:1;
706 	unsigned int being_destroyed:1;
707 	unsigned int service_no_longer_possible:1;
708 	unsigned int being_destroyed2:1;
709 	unsigned int requested_stop_internal_loops:1;
710 	unsigned int protocol_init_done:1;
711 	unsigned int doing_protocol_init:1;
712 	unsigned int done_protocol_destroy_cb:1;
713 	unsigned int evlib_finalize_destroy_after_int_loops_stop:1;
714 	unsigned int max_fds_unrelated_to_ulimit:1;
715 	unsigned int policy_updated:1;
716 #if defined(LWS_WITH_NETLINK)
717 	unsigned int nl_initial_done:1;
718 #endif
719 
720 	unsigned short count_threads;
721 	unsigned short undestroyed_threads;
722 	short plugin_protocol_count;
723 	short plugin_extension_count;
724 	short server_string_len;
725 	unsigned short deprecation_pending_listen_close_count;
726 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
727 	uint16_t	ss_proxy_port;
728 #endif
729 	/* 0 if not known, else us resolution of the poll wait */
730 	uint16_t us_wait_resolution;
731 
732 	uint8_t max_fi;
733 	uint8_t captive_portal_detect;
734 	uint8_t captive_portal_detect_type;
735 
736 	uint8_t		destroy_state; /* enum lws_context_destroy */
737 };
738 
739 #define lws_get_context_protocol(ctx, x) ctx->vhost_list->protocols[x]
740 #define lws_get_vh_protocol(vh, x) vh->protocols[x]
741 
742 int
743 lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);
744 
745 void
746 lws_vhost_destroy1(struct lws_vhost *vh);
747 
748 
749 #if defined(LWS_PLAT_FREERTOS)
750 int
751 lws_find_string_in_file(const char *filename, const char *str, int stringlen);
752 #endif
753 
754 signed char char_to_hex(const char c);
755 
756 #if defined(LWS_WITH_NETWORK)
757 int
758 lws_system_do_attach(struct lws_context_per_thread *pt);
759 #endif
760 
761 struct lws_buflist {
762 	struct lws_buflist *next;
763 	size_t len;
764 	size_t pos;
765 };
766 
767 char *
768 lws_strdup(const char *s);
769 
770 extern int log_level;
771 
772 int
773 lws_b64_selftest(void);
774 
775 
776 #ifndef LWS_NO_DAEMONIZE
777  pid_t get_daemonize_pid();
778 #else
779  #define get_daemonize_pid() (0)
780 #endif
781 
782 void lwsl_emit_stderr(int level, const char *line);
783 
784 #if !defined(LWS_WITH_TLS)
785  #define LWS_SSL_ENABLED(context) (0)
786  #define lws_context_init_server_ssl(_a, _b) (0)
787  #define lws_ssl_destroy(_a)
788  #define lws_context_init_alpn(_a)
789  #define lws_ssl_capable_read lws_ssl_capable_read_no_ssl
790  #define lws_ssl_capable_write lws_ssl_capable_write_no_ssl
791  #define lws_ssl_pending lws_ssl_pending_no_ssl
792  #define lws_server_socket_service_ssl(_b, _c, _d) (0)
793  #define lws_ssl_close(_a) (0)
794  #define lws_ssl_context_destroy(_a)
795  #define lws_ssl_SSL_CTX_destroy(_a)
796  #define lws_ssl_remove_wsi_from_buffered_list(_a)
797  #define __lws_ssl_remove_wsi_from_buffered_list(_a)
798  #define lws_context_init_ssl_library(_a)
799  #define lws_context_deinit_ssl_library(_a)
800  #define lws_tls_check_all_cert_lifetimes(_a)
801  #define lws_tls_acme_sni_cert_destroy(_a)
802 #endif
803 
804 
805 
806 #if LWS_MAX_SMP > 1
807 #define lws_context_lock(c, reason) lws_mutex_refcount_lock(&c->mr, reason)
808 #define lws_context_unlock(c) lws_mutex_refcount_unlock(&c->mr)
809 #define lws_context_assert_lock_held(c) lws_mutex_refcount_assert_held(&c->mr)
810 #define lws_vhost_assert_lock_held(v) lws_mutex_refcount_assert_held(&v->mr)
811 /* enforce context lock held */
812 #define lws_vhost_lock(v) lws_mutex_refcount_lock(&v->mr, __func__)
813 #define lws_vhost_unlock(v) lws_mutex_refcount_unlock(&v->mr)
814 
815 
816 #else
817 #define lws_pt_mutex_init(_a) (void)(_a)
818 #define lws_pt_mutex_destroy(_a) (void)(_a)
819 #define lws_pt_lock(_a, b) (void)(_a)
820 #define lws_pt_assert_lock_held(_a) (void)(_a)
821 #define lws_pt_unlock(_a) (void)(_a)
822 #define lws_context_lock(_a, _b) (void)(_a)
823 #define lws_context_unlock(_a) (void)(_a)
824 #define lws_context_assert_lock_held(_a) (void)(_a)
825 #define lws_vhost_assert_lock_held(_a) (void)(_a)
826 #define lws_vhost_lock(_a) (void)(_a)
827 #define lws_vhost_unlock(_a) (void)(_a)
828 #define lws_pt_stats_lock(_a) (void)(_a)
829 #define lws_pt_stats_unlock(_a) (void)(_a)
830 #endif
831 
832 int LWS_WARN_UNUSED_RESULT
833 lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, size_t len);
834 
835 int LWS_WARN_UNUSED_RESULT
836 lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, size_t len);
837 
838 int LWS_WARN_UNUSED_RESULT
839 lws_ssl_pending_no_ssl(struct lws *wsi);
840 
841 int
842 lws_tls_check_cert_lifetime(struct lws_vhost *vhost);
843 
844 int lws_jws_selftest(void);
845 int lws_jwe_selftest(void);
846 
847 int
848 lws_protocol_init(struct lws_context *context);
849 
850 int
851 lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p,
852 		  const char *reason);
853 
854 const struct lws_protocol_vhost_options *
855 lws_vhost_protocol_options(struct lws_vhost *vh, const char *name);
856 
857 const struct lws_http_mount *
858 lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len);
859 
860 /*
861  * custom allocator
862  */
863 void *
864 lws_realloc(void *ptr, size_t size, const char *reason);
865 
866 void * LWS_WARN_UNUSED_RESULT
867 lws_zalloc(size_t size, const char *reason);
868 
869 #ifdef LWS_PLAT_OPTEE
870 void *lws_malloc(size_t size, const char *reason);
871 void lws_free(void *p);
872 #define lws_free_set_NULL(P)    do { lws_free(P); (P) = NULL; } while(0)
873 #else
874 #define lws_malloc(S, R)	lws_realloc(NULL, S, R)
875 #define lws_free(P)	lws_realloc(P, 0, "lws_free")
876 #define lws_free_set_NULL(P)	do { lws_realloc(P, 0, "free"); (P) = NULL; } while(0)
877 #endif
878 
879 int
880 __lws_create_event_pipes(struct lws_context *context);
881 
882 int
883 lws_plat_apply_FD_CLOEXEC(int n);
884 
885 const struct lws_plat_file_ops *
886 lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,
887 		    const char **vpath);
888 
889 /* lws_plat_ */
890 
891 int
892 lws_plat_context_early_init(void);
893 void
894 lws_plat_context_early_destroy(struct lws_context *context);
895 void
896 lws_plat_context_late_destroy(struct lws_context *context);
897 
898 int
899 lws_plat_init(struct lws_context *context,
900 	      const struct lws_context_creation_info *info);
901 int
902 lws_plat_drop_app_privileges(struct lws_context *context, int actually_drop);
903 
904 #if defined(LWS_WITH_UNIX_SOCK) && !defined(WIN32)
905 int
906 lws_plat_user_colon_group_to_ids(const char *u_colon_g, uid_t *puid, gid_t *pgid);
907 #endif
908 
909 int
910 lws_plat_ntpclient_config(struct lws_context *context);
911 
912 int
913 lws_plat_ifname_to_hwaddr(int fd, const char *ifname, uint8_t *hwaddr, int len);
914 
915 int
916 lws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost);
917 
918 int
919 lws_check_byte_utf8(unsigned char state, unsigned char c);
920 int LWS_WARN_UNUSED_RESULT
921 lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);
922 int alloc_file(struct lws_context *context, const char *filename,
923 			  uint8_t **buf, lws_filepos_t *amount);
924 
925 void lws_msleep(unsigned int);
926 
927 void
928 lws_context_destroy2(struct lws_context *context);
929 
930 #if !defined(PRIu64)
931 #define PRIu64 "llu"
932 #endif
933 
934 #if defined(LWS_WITH_ABSTRACT)
935 #include "private-lib-abstract.h"
936 #endif
937 
938 #ifdef __cplusplus
939 };
940 #endif
941 
942 #endif
943