• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_log_cx_t			*log_cx;
199 } lws_lifecycle_t;
200 
201 void
202 __lws_lc_tag(struct lws_context *cx, lws_lifecycle_group_t *grp,
203 	     lws_lifecycle_t *lc, const char *format, ...);
204 
205 void
206 __lws_lc_tag_append(lws_lifecycle_t *lc, const char *app);
207 
208 void
209 __lws_lc_untag(struct lws_context *cx, lws_lifecycle_t *lc);
210 
211 const char *
212 lws_lc_tag(lws_lifecycle_t *lc);
213 
214 extern lws_log_cx_t log_cx;
215 
216 /*
217  * Generic bidi tx credit management
218  */
219 
220 struct lws_tx_credit {
221 	int32_t			tx_cr;		/* our credit to write peer */
222 	int32_t			peer_tx_cr_est; /* peer's credit to write us */
223 
224 	int32_t			manual_initial_tx_credit;
225 
226 	uint8_t			skint; /* unable to write anything */
227 	uint8_t			manual;
228 };
229 
230 #ifdef LWS_WITH_IPV6
231 #if defined(WIN32) || defined(_WIN32)
232 #include <iphlpapi.h>
233 #else
234 #include <net/if.h>
235 #endif
236 #endif
237 
238 #undef X509_NAME
239 
240 /*
241  * All lws_tls...() functions must return this type, converting the
242  * native backend result and doing the extra work to determine which one
243  * as needed.
244  *
245  * Native TLS backend return codes are NOT ALLOWED outside the backend.
246  *
247  * Non-SSL mode also uses these types.
248  */
249 enum lws_ssl_capable_status {
250 	LWS_SSL_CAPABLE_ERROR			= -1, /* it failed */
251 	LWS_SSL_CAPABLE_DONE			= 0,  /* it succeeded */
252 	LWS_SSL_CAPABLE_MORE_SERVICE_READ	= -2, /* retry WANT_READ */
253 	LWS_SSL_CAPABLE_MORE_SERVICE_WRITE	= -3, /* retry WANT_WRITE */
254 	LWS_SSL_CAPABLE_MORE_SERVICE		= -4, /* general retry */
255 };
256 
257 enum lws_context_destroy {
258 	LWSCD_NO_DESTROY,		/* running */
259 	LWSCD_PT_WAS_DEFERRED,		/* destroy from inside service */
260 	LWSCD_PT_WAIT_ALL_DESTROYED,	/* libuv ends up here later */
261 	LWSCD_FINALIZATION		/* the final destruction of context */
262 };
263 
264 #if defined(LWS_WITH_TLS)
265 #include "private-lib-tls.h"
266 #endif
267 
268 #if defined(WIN32) || defined(_WIN32)
269 	 // Visual studio older than 2015 and WIN_CE has only _stricmp
270 	#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE)
271 	#define strcasecmp _stricmp
272 	#define strncasecmp _strnicmp
273 	#elif !defined(__MINGW32__)
274 	#define strcasecmp stricmp
275 	#define strncasecmp strnicmp
276 	#endif
277 	#define getdtablesize() 30000
278 #endif
279 
280 #ifndef LWS_ARRAY_SIZE
281 #define LWS_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
282 #endif
283 
284 #ifdef __cplusplus
285 extern "C" {
286 #endif
287 
288 #define lws_safe_modulo(_a, _b) ((_b) ? ((_a) % (_b)) : 0)
289 
290 #if defined(__clang__)
291 #define lws_memory_barrier() __sync_synchronize()
292 #elif defined(__GNUC__)
293 #define lws_memory_barrier() __sync_synchronize()
294 #else
295 #define lws_memory_barrier()
296 #endif
297 
298 
299 struct lws_ring {
300 	void *buf;
301 	void (*destroy_element)(void *element);
302 	uint32_t buflen;
303 	uint32_t element_len;
304 	uint32_t head;
305 	uint32_t oldest_tail;
306 };
307 
308 struct lws_protocols;
309 struct lws;
310 
311 #if defined(LWS_WITH_NETWORK) /* network */
312 #include "private-lib-event-libs.h"
313 
314 #if defined(LWS_WITH_SECURE_STREAMS)
315 #include "private-lib-secure-streams.h"
316 #endif
317 
318 #if defined(LWS_WITH_SYS_SMD)
319 #include "private-lib-system-smd.h"
320 #endif
321 
322 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
323 #include "private-lib-system-fault-injection.h"
324 #endif
325 
326 #include "private-lib-system-metrics.h"
327 
328 
329 struct lws_foreign_thread_pollfd {
330 	struct lws_foreign_thread_pollfd *next;
331 	int fd_index;
332 	int _and;
333 	int _or;
334 };
335 #endif /* network */
336 
337 #if defined(LWS_WITH_NETWORK)
338 #include "private-lib-core-net.h"
339 #endif
340 
341 struct lws_system_blob {
342 	union {
343 		struct lws_buflist *bl;
344 		struct {
345 			const uint8_t *ptr;
346 			size_t len;
347 		} direct;
348 	} u;
349 	char	is_direct;
350 };
351 
352 
353 typedef struct lws_attach_item {
354 	lws_dll2_t			list;
355 	lws_attach_cb_t			cb;
356 	void				*opaque;
357 	lws_system_states_t		state;
358 } lws_attach_item_t;
359 
360 /*
361  * These are the context's lifecycle group indexes that exist in this build
362  * configuration.  If you add some, make sure to also add the tag_prefix in
363  * context.c context creation with matching preprocessor conditionals.
364  */
365 
366 enum {
367 	LWSLCG_WSI,			/* generic wsi, eg, pipe, listen */
368 	LWSLCG_VHOST,
369 
370 	LWSLCG_WSI_SERVER,		/* server wsi */
371 
372 #if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT)
373 	LWSLCG_WSI_MUX,			/* a mux child wsi */
374 #endif
375 
376 #if defined(LWS_WITH_CLIENT)
377 	LWSLCG_WSI_CLIENT,		/* client wsi */
378 #endif
379 
380 #if defined(LWS_WITH_SECURE_STREAMS)
381 #if defined(LWS_WITH_CLIENT)
382 	LWSLCG_SS_CLIENT,		/* secstream client handle */
383 #endif
384 #if defined(LWS_WITH_SERVER)
385 	LWSLCG_SS_SERVER,		/* secstream server handle */
386 #endif
387 #if defined(LWS_WITH_CLIENT)
388 	LWSLCG_WSI_SS_CLIENT,		/* wsi bound to ss client handle */
389 #endif
390 #if defined(LWS_WITH_SERVER)
391 	LWSLCG_WSI_SS_SERVER,		/* wsi bound to ss server handle */
392 #endif
393 #endif
394 
395 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
396 #if defined(LWS_WITH_CLIENT)
397 	LWSLCG_SSP_CLIENT,		/* SSPC handle client connection to proxy */
398 #endif
399 #if defined(LWS_WITH_SERVER)
400 	LWSLCG_SSP_ONWARD,		/* SS handle at proxy for onward conn */
401 #endif
402 #if defined(LWS_WITH_CLIENT)
403 	LWSLCG_WSI_SSP_CLIENT,		/* wsi bound to SSPC cli conn to proxy */
404 #endif
405 #if defined(LWS_WITH_SERVER)
406 	LWSLCG_WSI_SSP_ONWARD,		/* wsi bound to Proxy onward connection */
407 #endif
408 #endif
409 
410 	/* always last */
411 	LWSLCG_COUNT
412 };
413 
414 /*
415  * the rest is managed per-context, that includes
416  *
417  *  - processwide single fd -> wsi lookup
418  *  - contextwide headers pool
419  */
420 
421 struct lws_context {
422  #if defined(LWS_WITH_SERVER)
423 	char canonical_hostname[96];
424  #endif
425 
426 #if defined(LWS_WITH_FILE_OPS)
427 	struct lws_plat_file_ops fops_platform;
428 #endif
429 
430 #if defined(LWS_WITH_ZIP_FOPS)
431 	struct lws_plat_file_ops fops_zip;
432 #endif
433 
434 	lws_system_blob_t system_blobs[LWS_SYSBLOB_TYPE_COUNT];
435 
436 #if defined(LWS_WITH_SYS_SMD)
437 	lws_smd_t				smd;
438 #endif
439 #if defined(LWS_WITH_SECURE_STREAMS)
440 	struct lws_ss_handle			*ss_cpd;
441 #endif
442 	lws_sorted_usec_list_t			sul_cpd_defer;
443 
444 #if defined(LWS_WITH_NETWORK)
445 	struct lws_context_per_thread		pt[LWS_MAX_SMP];
446 	lws_retry_bo_t				default_retry;
447 	lws_sorted_usec_list_t			sul_system_state;
448 
449 	lws_lifecycle_group_t			lcg[LWSLCG_COUNT];
450 
451 	const struct lws_protocols		*protocols_copy;
452 
453 #if defined(LWS_WITH_NETLINK)
454 	lws_sorted_usec_list_t			sul_nl_coldplug;
455 	/* process can only have one netlink socket, have to do it in ctx */
456 	lws_dll2_owner_t			routing_table;
457 	struct lws				*netlink;
458 #endif
459 
460 #if defined(LWS_PLAT_FREERTOS)
461 	struct sockaddr_in			frt_pipe_si;
462 #endif
463 
464 #if defined(LWS_WITH_HTTP2)
465 	struct http2_settings			set;
466 #endif
467 
468 #if LWS_MAX_SMP > 1
469 	struct lws_mutex_refcount		mr;
470 #endif
471 
472 #if defined(LWS_WITH_SYS_METRICS)
473 	lws_dll2_owner_t			owner_mtr_dynpol;
474 	/**< owner for lws_metric_policy_dyn_t (dynamic part of metric pols) */
475 	lws_dll2_owner_t			owner_mtr_no_pol;
476 	/**< owner for lws_metric_pub_t with no policy to bind to */
477 #endif
478 
479 #if defined(LWS_WITH_NETWORK)
480 /*
481  * LWS_WITH_NETWORK =====>
482  */
483 
484 	lws_dll2_owner_t		owner_vh_being_destroyed;
485 
486 	lws_metric_t			*mt_service; /* doing service */
487 	const lws_metric_policy_t	*metrics_policies;
488 	const char			*metrics_prefix;
489 
490 #if defined(LWS_WITH_SYS_METRICS) && defined(LWS_WITH_CLIENT)
491 	lws_metric_t			*mt_conn_tcp; /* client tcp conns */
492 	lws_metric_t			*mt_conn_tls; /* client tcp conns */
493 	lws_metric_t			*mt_conn_dns; /* client dns external lookups */
494 	lws_metric_t			*mth_conn_failures; /* histogram of conn failure reasons */
495 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
496 	lws_metric_t			*mt_http_txn; /* client http transaction */
497 #endif
498 #if defined(LWS_WITH_SYS_ASYNC_DNS)
499 	lws_metric_t			*mt_adns_cache; /* async dns lookup lat */
500 #endif
501 #if defined(LWS_WITH_SECURE_STREAMS)
502 	lws_metric_t			*mth_ss_conn; /* SS connection outcomes */
503 #endif
504 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
505 	lws_metric_t			*mt_ss_cliprox_conn; /* SS cli->prox conn */
506 	lws_metric_t			*mt_ss_cliprox_paylat; /* cli->prox payload latency */
507 	lws_metric_t			*mt_ss_proxcli_paylat; /* prox->cli payload latency */
508 #endif
509 #endif /* client */
510 
511 #if defined(LWS_WITH_SERVER)
512 	lws_metric_t			*mth_srv;
513 #endif
514 
515 #if defined(LWS_WITH_EVENT_LIBS)
516 	struct lws_plugin		*evlib_plugin_list;
517 	void				*evlib_ctx; /* overallocated */
518 #endif
519 
520 #if defined(LWS_WITH_TLS)
521 	struct lws_context_tls		tls;
522 #if defined (LWS_WITH_TLS_JIT_TRUST)
523 	lws_dll2_owner_t		jit_inflight;
524 	/* ongoing sync or async jit trust lookups */
525 	struct lws_cache_ttl_lru	*trust_cache;
526 	/* caches host -> truncated trust SKID mappings */
527 #endif
528 #endif
529 #if defined(LWS_WITH_DRIVERS)
530 	lws_netdevs_t			netdevs;
531 #endif
532 
533 #if defined(LWS_WITH_SYS_ASYNC_DNS)
534 	lws_async_dns_t			async_dns;
535 #endif
536 
537 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
538 	lws_fi_ctx_t			fic;
539 	/**< Toplevel Fault Injection ctx */
540 #endif
541 
542 #if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT)
543 	struct lws_cache_ttl_lru *l1, *nsc;
544 #endif
545 
546 #if defined(LWS_WITH_SYS_NTPCLIENT)
547 	void				*ntpclient_priv;
548 #endif
549 
550 #if defined(LWS_WITH_SECURE_STREAMS)
551 	struct lws_ss_handle		*hss_fetch_policy;
552 #if defined(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM)
553 	struct lws_ss_handle		*hss_auth;
554 	lws_sorted_usec_list_t		sul_api_amazon_com;
555 	lws_sorted_usec_list_t		sul_api_amazon_com_kick;
556 #endif
557 #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
558 	struct lws_ss_x509		*server_der_list;
559 #endif
560 #endif
561 
562 #if defined(LWS_WITH_SYS_STATE)
563 	lws_state_manager_t		mgr_system;
564 	lws_state_notify_link_t		protocols_notify;
565 #endif
566 #if defined (LWS_WITH_SYS_DHCP_CLIENT)
567 	lws_dll2_owner_t		dhcpc_owner;
568 					/**< list of ifaces with dhcpc */
569 #endif
570 
571 	/* pointers */
572 
573 	struct lws_vhost		*vhost_list;
574 	struct lws_vhost		*no_listener_vhost_list;
575 	struct lws_vhost		*vhost_pending_destruction_list;
576 	struct lws_vhost		*vhost_system;
577 
578 #if defined(LWS_WITH_SERVER)
579 	const char			*server_string;
580 #endif
581 
582 	const struct lws_event_loop_ops	*event_loop_ops;
583 #endif
584 
585 #if defined(LWS_WITH_TLS)
586 	const struct lws_tls_ops	*tls_ops;
587 #endif
588 
589 #if defined(LWS_WITH_PLUGINS)
590 	struct lws_plugin		*plugin_list;
591 #endif
592 #ifdef _WIN32
593 /* different implementation between unix and windows */
594 	struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
595 #else
596 	struct lws **lws_lookup;
597 
598 #endif
599 
600 /*
601  * <====== LWS_WITH_NETWORK end
602  */
603 
604 #endif /* NETWORK */
605 
606 	lws_log_cx_t			*log_cx;
607 	const char			*name;
608 
609 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
610 	const char	*ss_proxy_bind;
611 	const char	*ss_proxy_address;
612 #endif
613 
614 #if defined(LWS_WITH_FILE_OPS)
615 	const struct lws_plat_file_ops *fops;
616 #endif
617 
618 	struct lws_context **pcontext_finalize;
619 #if !defined(LWS_PLAT_FREERTOS)
620 	const char *username, *groupname;
621 #endif
622 
623 #if defined(LWS_WITH_MBEDTLS)
624 	mbedtls_entropy_context mec;
625 	mbedtls_ctr_drbg_context mcdc;
626 #endif
627 
628 #if defined(LWS_WITH_THREADPOOL)
629 	struct lws_threadpool *tp_list_head;
630 #endif
631 
632 #if defined(LWS_WITH_PEER_LIMITS)
633 	struct lws_peer			**pl_hash_table;
634 	struct lws_peer			*peer_wait_list;
635 	lws_peer_limits_notify_t	pl_notify_cb;
636 	time_t				next_cull;
637 #endif
638 
639 	const lws_system_ops_t		*system_ops;
640 
641 #if defined(LWS_WITH_SECURE_STREAMS)
642 #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
643 	const char			*pss_policies_json;
644 	struct lwsac			*ac_policy;
645 	void				*pol_args;
646 #endif
647 	const lws_ss_policy_t		*pss_policies;
648 	const lws_ss_auth_t		*pss_auths;
649 #if defined(LWS_WITH_SSPLUGINS)
650 	const lws_ss_plugin_t		**pss_plugins;
651 #endif
652 #endif
653 
654 	void *external_baggage_free_on_destroy;
655 	const struct lws_token_limits *token_limits;
656 	void *user_space;
657 #if defined(LWS_WITH_SERVER)
658 	const struct lws_protocol_vhost_options *reject_service_keywords;
659 	lws_reload_func deprecation_cb;
660 #endif
661 #if !defined(LWS_PLAT_FREERTOS)
662 	void (*eventlib_signal_cb)(void *event_lib_handle, int signum);
663 #endif
664 
665 #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
666 	cap_value_t caps[4];
667 	char count_caps;
668 #endif
669 
670 	lws_usec_t time_up; /* monotonic */
671 #if defined(LWS_WITH_SYS_SMD)
672 	lws_usec_t smd_ttl_us;
673 #endif
674 	uint64_t options;
675 
676 	time_t last_ws_ping_pong_check_s;
677 #if defined(LWS_WITH_SECURE_STREAMS)
678 	time_t					last_policy;
679 #endif
680 
681 #if defined(LWS_PLAT_FREERTOS)
682 	unsigned long time_last_state_dump;
683 	uint32_t last_free_heap;
684 #endif
685 
686 	unsigned int max_fds;
687 #if !defined(LWS_NO_DAEMONIZE)
688 	pid_t started_with_parent;
689 #endif
690 
691 #if !defined(LWS_PLAT_FREERTOS)
692 	uid_t uid;
693 	gid_t gid;
694 	int fd_random;
695 	int count_cgi_spawned;
696 #endif
697 
698 	unsigned int fd_limit_per_thread;
699 	unsigned int timeout_secs;
700 	unsigned int pt_serv_buf_size;
701 	unsigned int max_http_header_data;
702 	unsigned int max_http_header_pool;
703 	int simultaneous_ssl_restriction;
704 	int simultaneous_ssl;
705 	int simultaneous_ssl_handshake_restriction;
706 	int simultaneous_ssl_handshake;
707 #if defined(LWS_WITH_TLS_JIT_TRUST)
708 	int		vh_idle_grace_ms;
709 #endif
710 #if defined(LWS_WITH_PEER_LIMITS)
711 	uint32_t pl_hash_elements;	/* protected by context->lock */
712 	uint32_t count_peers;		/* protected by context->lock */
713 	unsigned short ip_limit_ah;
714 	unsigned short ip_limit_wsi;
715 #endif
716 
717 #if defined(LWS_WITH_SYS_SMD)
718 	uint16_t smd_queue_depth;
719 #endif
720 
721 #if defined(LWS_WITH_NETLINK)
722 	lws_route_uidx_t			route_uidx;
723 #endif
724 
725 	char		tls_gate_accepts;
726 
727 	unsigned int deprecated:1;
728 	unsigned int inside_context_destroy:1;
729 	unsigned int being_destroyed:1;
730 	unsigned int service_no_longer_possible:1;
731 	unsigned int being_destroyed2:1;
732 	unsigned int requested_stop_internal_loops:1;
733 	unsigned int protocol_init_done:1;
734 	unsigned int doing_protocol_init:1;
735 	unsigned int done_protocol_destroy_cb:1;
736 	unsigned int evlib_finalize_destroy_after_int_loops_stop:1;
737 	unsigned int max_fds_unrelated_to_ulimit:1;
738 	unsigned int policy_updated:1;
739 #if defined(LWS_WITH_NETLINK)
740 	unsigned int nl_initial_done:1;
741 #endif
742 
743 	unsigned short count_threads;
744 	unsigned short undestroyed_threads;
745 	short plugin_protocol_count;
746 	short plugin_extension_count;
747 	short server_string_len;
748 	unsigned short deprecation_pending_listen_close_count;
749 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
750 	uint16_t	ss_proxy_port;
751 #endif
752 	/* 0 if not known, else us resolution of the poll wait */
753 	uint16_t us_wait_resolution;
754 
755 	uint8_t max_fi;
756 	uint8_t captive_portal_detect;
757 	uint8_t captive_portal_detect_type;
758 
759 	uint8_t		destroy_state; /* enum lws_context_destroy */
760 };
761 
762 #define lws_get_context_protocol(ctx, x) ctx->vhost_list->protocols[x]
763 #define lws_get_vh_protocol(vh, x) vh->protocols[x]
764 
765 int
766 lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);
767 
768 void
769 lws_vhost_destroy1(struct lws_vhost *vh);
770 
771 #if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT)
772 int
773 lws_parse_set_cookie(struct lws *wsi);
774 
775 int
776 lws_cookie_send_cookies(struct lws *wsi, char **pp, char *end);
777 #endif
778 
779 #if defined(LWS_PLAT_FREERTOS)
780 int
781 lws_find_string_in_file(const char *filename, const char *str, int stringlen);
782 #endif
783 
784 signed char char_to_hex(const char c);
785 
786 #if defined(LWS_WITH_NETWORK)
787 int
788 lws_system_do_attach(struct lws_context_per_thread *pt);
789 #endif
790 
791 struct lws_buflist {
792 	struct lws_buflist *next;
793 	size_t len;
794 	size_t pos;
795 };
796 
797 char *
798 lws_strdup(const char *s);
799 
800 int
801 lws_b64_selftest(void);
802 
803 
804 #ifndef LWS_NO_DAEMONIZE
805  pid_t get_daemonize_pid();
806 #else
807  #define get_daemonize_pid() (0)
808 #endif
809 
810 void lwsl_emit_stderr(int level, const char *line);
811 
812 #if !defined(LWS_WITH_TLS)
813  #define LWS_SSL_ENABLED(context) (0)
814  #define lws_context_init_server_ssl(_a, _b) (0)
815  #define lws_ssl_destroy(_a)
816  #define lws_context_init_alpn(_a)
817  #define lws_ssl_capable_read lws_ssl_capable_read_no_ssl
818  #define lws_ssl_capable_write lws_ssl_capable_write_no_ssl
819  #define lws_ssl_pending lws_ssl_pending_no_ssl
820  #define lws_server_socket_service_ssl(_b, _c, _d) (0)
821  #define lws_ssl_close(_a) (0)
822  #define lws_ssl_context_destroy(_a)
823  #define lws_ssl_SSL_CTX_destroy(_a)
824  #define lws_ssl_remove_wsi_from_buffered_list(_a)
825  #define __lws_ssl_remove_wsi_from_buffered_list(_a)
826  #define lws_context_init_ssl_library(_a, _b)
827  #define lws_context_deinit_ssl_library(_a)
828  #define lws_tls_check_all_cert_lifetimes(_a)
829  #define lws_tls_acme_sni_cert_destroy(_a)
830 #endif
831 
832 
833 
834 #if LWS_MAX_SMP > 1
835 #define lws_context_lock(c, reason) lws_mutex_refcount_lock(&c->mr, reason)
836 #define lws_context_unlock(c) lws_mutex_refcount_unlock(&c->mr)
837 #define lws_context_assert_lock_held(c) lws_mutex_refcount_assert_held(&c->mr)
838 #define lws_vhost_assert_lock_held(v) lws_mutex_refcount_assert_held(&v->mr)
839 /* enforce context lock held */
840 #define lws_vhost_lock(v) lws_mutex_refcount_lock(&v->mr, __func__)
841 #define lws_vhost_unlock(v) lws_mutex_refcount_unlock(&v->mr)
842 
843 
844 #else
845 #define lws_pt_mutex_init(_a) (void)(_a)
846 #define lws_pt_mutex_destroy(_a) (void)(_a)
847 #define lws_pt_lock(_a, b) (void)(_a)
848 #define lws_pt_assert_lock_held(_a) (void)(_a)
849 #define lws_pt_unlock(_a) (void)(_a)
850 #define lws_context_lock(_a, _b) (void)(_a)
851 #define lws_context_unlock(_a) (void)(_a)
852 #define lws_context_assert_lock_held(_a) (void)(_a)
853 #define lws_vhost_assert_lock_held(_a) (void)(_a)
854 #define lws_vhost_lock(_a) (void)(_a)
855 #define lws_vhost_unlock(_a) (void)(_a)
856 #define lws_pt_stats_lock(_a) (void)(_a)
857 #define lws_pt_stats_unlock(_a) (void)(_a)
858 #endif
859 
860 int LWS_WARN_UNUSED_RESULT
861 lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, size_t len);
862 
863 int LWS_WARN_UNUSED_RESULT
864 lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, size_t len);
865 
866 int LWS_WARN_UNUSED_RESULT
867 lws_ssl_pending_no_ssl(struct lws *wsi);
868 
869 int
870 lws_tls_check_cert_lifetime(struct lws_vhost *vhost);
871 
872 int lws_jws_selftest(void);
873 int lws_jwe_selftest(void);
874 
875 int
876 lws_protocol_init(struct lws_context *context);
877 
878 int
879 lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p,
880 		  const char *reason);
881 
882 const struct lws_protocol_vhost_options *
883 lws_vhost_protocol_options(struct lws_vhost *vh, const char *name);
884 
885 const struct lws_http_mount *
886 lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len);
887 
888 #ifdef LWS_WITH_HTTP2
889 int lws_wsi_is_h2(struct lws *wsi);
890 #endif
891 /*
892  * custom allocator
893  */
894 void *
895 lws_realloc(void *ptr, size_t size, const char *reason);
896 
897 void * LWS_WARN_UNUSED_RESULT
898 lws_zalloc(size_t size, const char *reason);
899 
900 #ifdef LWS_PLAT_OPTEE
901 void *lws_malloc(size_t size, const char *reason);
902 void lws_free(void *p);
903 #define lws_free_set_NULL(P)    do { lws_free(P); (P) = NULL; } while(0)
904 #else
905 #define lws_malloc(S, R)	lws_realloc(NULL, S, R)
906 #define lws_free(P)	lws_realloc(P, 0, "lws_free")
907 #define lws_free_set_NULL(P)	do { lws_realloc(P, 0, "free"); (P) = NULL; } while(0)
908 #endif
909 
910 int
911 __lws_create_event_pipes(struct lws_context *context);
912 
913 int
914 lws_plat_apply_FD_CLOEXEC(int n);
915 
916 const struct lws_plat_file_ops *
917 lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,
918 		    const char **vpath);
919 
920 /* lws_plat_ */
921 
922 int
923 lws_plat_context_early_init(void);
924 void
925 lws_plat_context_early_destroy(struct lws_context *context);
926 void
927 lws_plat_context_late_destroy(struct lws_context *context);
928 
929 int
930 lws_plat_init(struct lws_context *context,
931 	      const struct lws_context_creation_info *info);
932 int
933 lws_plat_drop_app_privileges(struct lws_context *context, int actually_drop);
934 
935 #if defined(LWS_WITH_UNIX_SOCK) && !defined(WIN32)
936 int
937 lws_plat_user_colon_group_to_ids(const char *u_colon_g, uid_t *puid, gid_t *pgid);
938 #endif
939 
940 int
941 lws_plat_ntpclient_config(struct lws_context *context);
942 
943 int
944 lws_plat_ifname_to_hwaddr(int fd, const char *ifname, uint8_t *hwaddr, int len);
945 
946 int
947 lws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost);
948 
949 int
950 lws_check_byte_utf8(unsigned char state, unsigned char c);
951 int LWS_WARN_UNUSED_RESULT
952 lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);
953 int alloc_file(struct lws_context *context, const char *filename,
954 			  uint8_t **buf, lws_filepos_t *amount);
955 
956 int
957 lws_lec_scratch(lws_lec_pctx_t *ctx);
958 void
959 lws_lec_signed(lws_lec_pctx_t *ctx, int64_t num);
960 
961 int
962 lws_cose_key_checks(const lws_cose_key_t *key, int64_t kty, int64_t alg,
963 		    int key_op, const char *crv);
964 
965 void lws_msleep(unsigned int);
966 
967 void
968 lws_context_destroy2(struct lws_context *context);
969 
970 #if !defined(PRIu64)
971 #define PRIu64 "llu"
972 #endif
973 
974 #if defined(LWS_WITH_ABSTRACT)
975 #include "private-lib-abstract.h"
976 #endif
977 
978 #ifdef __cplusplus
979 };
980 #endif
981 
982 #endif
983