1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci#include "private-lib-core.h" 26d4afb5ceSopenharmony_ci 27d4afb5ceSopenharmony_ci#ifndef LWS_BUILD_HASH 28d4afb5ceSopenharmony_ci#define LWS_BUILD_HASH "unknown-build-hash" 29d4afb5ceSopenharmony_ci#endif 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_cistatic const char *library_version = LWS_LIBRARY_VERSION; 32d4afb5ceSopenharmony_ci 33d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 34d4afb5ceSopenharmony_ciextern const char *mbedtls_client_preload_filepath; 35d4afb5ceSopenharmony_ci#endif 36d4afb5ceSopenharmony_ci 37d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_SYS_RESOURCE_H) 38d4afb5ceSopenharmony_ci/* for setrlimit */ 39d4afb5ceSopenharmony_ci#include <sys/resource.h> 40d4afb5ceSopenharmony_ci#endif 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 43d4afb5ceSopenharmony_ci/* in ms */ 44d4afb5ceSopenharmony_cistatic uint32_t default_backoff_table[] = { 1000, 3000, 9000, 17000 }; 45d4afb5ceSopenharmony_ci#endif 46d4afb5ceSopenharmony_ci 47d4afb5ceSopenharmony_ci/** 48d4afb5ceSopenharmony_ci * lws_get_library_version: get version and git hash library built from 49d4afb5ceSopenharmony_ci * 50d4afb5ceSopenharmony_ci * returns a const char * to a string like "1.1 178d78c" 51d4afb5ceSopenharmony_ci * representing the library version followed by the git head hash it 52d4afb5ceSopenharmony_ci * was built from 53d4afb5ceSopenharmony_ci */ 54d4afb5ceSopenharmony_ciconst char * 55d4afb5ceSopenharmony_cilws_get_library_version(void) 56d4afb5ceSopenharmony_ci{ 57d4afb5ceSopenharmony_ci return library_version; 58d4afb5ceSopenharmony_ci} 59d4afb5ceSopenharmony_ci 60d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 61d4afb5ceSopenharmony_ci 62d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 63d4afb5ceSopenharmony_ci 64d4afb5ceSopenharmony_cistatic const char * system_state_names[] = { 65d4afb5ceSopenharmony_ci "undef", 66d4afb5ceSopenharmony_ci "CONTEXT_CREATED", 67d4afb5ceSopenharmony_ci "INITIALIZED", 68d4afb5ceSopenharmony_ci "IFACE_COLDPLUG", 69d4afb5ceSopenharmony_ci "DHCP", 70d4afb5ceSopenharmony_ci "CPD_PRE_TIME", 71d4afb5ceSopenharmony_ci "TIME_VALID", 72d4afb5ceSopenharmony_ci "CPD_POST_TIME", 73d4afb5ceSopenharmony_ci "POLICY_VALID", 74d4afb5ceSopenharmony_ci "REGISTERED", 75d4afb5ceSopenharmony_ci "AUTH1", 76d4afb5ceSopenharmony_ci "AUTH2", 77d4afb5ceSopenharmony_ci "OPERATIONAL", 78d4afb5ceSopenharmony_ci "POLICY_INVALID", 79d4afb5ceSopenharmony_ci "DESTROYING" 80d4afb5ceSopenharmony_ci}; 81d4afb5ceSopenharmony_ci 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ci/* 84d4afb5ceSopenharmony_ci * Handle provoking protocol init when we pass through the right system state 85d4afb5ceSopenharmony_ci */ 86d4afb5ceSopenharmony_ci 87d4afb5ceSopenharmony_cistatic int 88d4afb5ceSopenharmony_cilws_state_notify_protocol_init(struct lws_state_manager *mgr, 89d4afb5ceSopenharmony_ci struct lws_state_notify_link *link, int current, 90d4afb5ceSopenharmony_ci int target) 91d4afb5ceSopenharmony_ci{ 92d4afb5ceSopenharmony_ci struct lws_context *context = lws_container_of(mgr, struct lws_context, 93d4afb5ceSopenharmony_ci mgr_system); 94d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) && \ 95d4afb5ceSopenharmony_ci defined(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM) 96d4afb5ceSopenharmony_ci lws_system_blob_t *ab0, *ab1; 97d4afb5ceSopenharmony_ci#endif 98d4afb5ceSopenharmony_ci int n; 99d4afb5ceSopenharmony_ci 100d4afb5ceSopenharmony_ci /* 101d4afb5ceSopenharmony_ci * Deal with any attachments that were waiting for the right state 102d4afb5ceSopenharmony_ci * to come along 103d4afb5ceSopenharmony_ci */ 104d4afb5ceSopenharmony_ci 105d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) 106d4afb5ceSopenharmony_ci lws_system_do_attach(&context->pt[n]); 107d4afb5ceSopenharmony_ci 108d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) 109d4afb5ceSopenharmony_ci if (target == LWS_SYSTATE_DHCP) { 110d4afb5ceSopenharmony_ci /* 111d4afb5ceSopenharmony_ci * Don't let it past here until at least one iface has been 112d4afb5ceSopenharmony_ci * configured for operation with DHCP 113d4afb5ceSopenharmony_ci */ 114d4afb5ceSopenharmony_ci 115d4afb5ceSopenharmony_ci if (!lws_dhcpc_status(context, NULL)) 116d4afb5ceSopenharmony_ci return 1; 117d4afb5ceSopenharmony_ci } 118d4afb5ceSopenharmony_ci#endif 119d4afb5ceSopenharmony_ci 120d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_NTPCLIENT) 121d4afb5ceSopenharmony_ci if (target == LWS_SYSTATE_TIME_VALID && 122d4afb5ceSopenharmony_ci lws_now_secs() < 1594017754) /* 06:42 Mon Jul 6 2020 UTC */ { 123d4afb5ceSopenharmony_ci lws_ntpc_trigger(context); 124d4afb5ceSopenharmony_ci 125d4afb5ceSopenharmony_ci return 1; 126d4afb5ceSopenharmony_ci } 127d4afb5ceSopenharmony_ci#endif 128d4afb5ceSopenharmony_ci 129d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETLINK) 130d4afb5ceSopenharmony_ci /* 131d4afb5ceSopenharmony_ci * If we're going to use netlink routing data for DNS, we have to 132d4afb5ceSopenharmony_ci * wait to collect it asynchronously from the platform first. Netlink 133d4afb5ceSopenharmony_ci * role init starts a ctx sul for 350ms (reset to 100ms each time some 134d4afb5ceSopenharmony_ci * new netlink data comes) that sets nl_initial_done and tries to move 135d4afb5ceSopenharmony_ci * us to OPERATIONAL 136d4afb5ceSopenharmony_ci */ 137d4afb5ceSopenharmony_ci 138d4afb5ceSopenharmony_ci if (target == LWS_SYSTATE_IFACE_COLDPLUG && 139d4afb5ceSopenharmony_ci context->netlink && 140d4afb5ceSopenharmony_ci !context->nl_initial_done) { 141d4afb5ceSopenharmony_ci lwsl_cx_info(context, "waiting for netlink coldplug"); 142d4afb5ceSopenharmony_ci 143d4afb5ceSopenharmony_ci return 1; 144d4afb5ceSopenharmony_ci } 145d4afb5ceSopenharmony_ci#endif 146d4afb5ceSopenharmony_ci 147d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) && \ 148d4afb5ceSopenharmony_ci defined(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM) 149d4afb5ceSopenharmony_ci /* 150d4afb5ceSopenharmony_ci * Skip this if we are running something without the policy for it 151d4afb5ceSopenharmony_ci * 152d4afb5ceSopenharmony_ci * If root token is empty, skip too. 153d4afb5ceSopenharmony_ci */ 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci ab0 = lws_system_get_blob(context, LWS_SYSBLOB_TYPE_AUTH, 0); 156d4afb5ceSopenharmony_ci ab1 = lws_system_get_blob(context, LWS_SYSBLOB_TYPE_AUTH, 1); 157d4afb5ceSopenharmony_ci 158d4afb5ceSopenharmony_ci if (target == LWS_SYSTATE_AUTH1 && 159d4afb5ceSopenharmony_ci context->pss_policies && ab0 && ab1 && 160d4afb5ceSopenharmony_ci !lws_system_blob_get_size(ab0) && 161d4afb5ceSopenharmony_ci lws_system_blob_get_size(ab1)) { 162d4afb5ceSopenharmony_ci lwsl_cx_info(context, 163d4afb5ceSopenharmony_ci "AUTH1 state triggering api.amazon.com auth"); 164d4afb5ceSopenharmony_ci /* 165d4afb5ceSopenharmony_ci * Start trying to acquire it if it's not already in progress 166d4afb5ceSopenharmony_ci * returns nonzero if we determine it's not needed 167d4afb5ceSopenharmony_ci */ 168d4afb5ceSopenharmony_ci if (!lws_ss_sys_auth_api_amazon_com(context)) 169d4afb5ceSopenharmony_ci return 1; 170d4afb5ceSopenharmony_ci } 171d4afb5ceSopenharmony_ci#endif 172d4afb5ceSopenharmony_ci 173d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 174d4afb5ceSopenharmony_ci#if defined(LWS_WITH_DRIVERS) 175d4afb5ceSopenharmony_ci /* 176d4afb5ceSopenharmony_ci * See if we should do the SS Captive Portal Detection 177d4afb5ceSopenharmony_ci */ 178d4afb5ceSopenharmony_ci if (target == LWS_SYSTATE_CPD_PRE_TIME) { 179d4afb5ceSopenharmony_ci if (lws_system_cpd_state_get(context) == LWS_CPD_INTERNET_OK) 180d4afb5ceSopenharmony_ci return 0; /* allow it */ 181d4afb5ceSopenharmony_ci 182d4afb5ceSopenharmony_ci /* 183d4afb5ceSopenharmony_ci * Don't allow it to move past here until we get an IP and 184d4afb5ceSopenharmony_ci * CPD passes, driven by SMD 185d4afb5ceSopenharmony_ci */ 186d4afb5ceSopenharmony_ci 187d4afb5ceSopenharmony_ci return 1; 188d4afb5ceSopenharmony_ci } 189d4afb5ceSopenharmony_ci#endif 190d4afb5ceSopenharmony_ci 191d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 192d4afb5ceSopenharmony_ci /* 193d4afb5ceSopenharmony_ci * Skip this if we are running something without the policy for it 194d4afb5ceSopenharmony_ci */ 195d4afb5ceSopenharmony_ci if (target == LWS_SYSTATE_POLICY_VALID && 196d4afb5ceSopenharmony_ci context->pss_policies && !context->policy_updated) { 197d4afb5ceSopenharmony_ci 198d4afb5ceSopenharmony_ci if (context->hss_fetch_policy) 199d4afb5ceSopenharmony_ci return 1; 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci lwsl_cx_debug(context, "starting policy fetch"); 202d4afb5ceSopenharmony_ci /* 203d4afb5ceSopenharmony_ci * Start trying to acquire it if it's not already in progress 204d4afb5ceSopenharmony_ci * returns nonzero if we determine it's not needed 205d4afb5ceSopenharmony_ci */ 206d4afb5ceSopenharmony_ci if (!lws_ss_sys_fetch_policy(context)) 207d4afb5ceSopenharmony_ci /* we have it */ 208d4afb5ceSopenharmony_ci return 0; 209d4afb5ceSopenharmony_ci 210d4afb5ceSopenharmony_ci /* deny while we fetch it */ 211d4afb5ceSopenharmony_ci 212d4afb5ceSopenharmony_ci return 1; 213d4afb5ceSopenharmony_ci } 214d4afb5ceSopenharmony_ci#endif 215d4afb5ceSopenharmony_ci#endif 216d4afb5ceSopenharmony_ci 217d4afb5ceSopenharmony_ci /* protocol part */ 218d4afb5ceSopenharmony_ci 219d4afb5ceSopenharmony_ci if (context->protocol_init_done) 220d4afb5ceSopenharmony_ci return 0; 221d4afb5ceSopenharmony_ci 222d4afb5ceSopenharmony_ci if (target != LWS_SYSTATE_POLICY_VALID) 223d4afb5ceSopenharmony_ci return 0; 224d4afb5ceSopenharmony_ci 225d4afb5ceSopenharmony_ci lwsl_cx_info(context, "doing protocol init on POLICY_VALID\n"); 226d4afb5ceSopenharmony_ci 227d4afb5ceSopenharmony_ci return lws_protocol_init(context); 228d4afb5ceSopenharmony_ci} 229d4afb5ceSopenharmony_ci 230d4afb5ceSopenharmony_cistatic void 231d4afb5ceSopenharmony_cilws_context_creation_completion_cb(lws_sorted_usec_list_t *sul) 232d4afb5ceSopenharmony_ci{ 233d4afb5ceSopenharmony_ci struct lws_context *context = lws_container_of(sul, struct lws_context, 234d4afb5ceSopenharmony_ci sul_system_state); 235d4afb5ceSopenharmony_ci 236d4afb5ceSopenharmony_ci /* if nothing is there to intercept anything, go all the way */ 237d4afb5ceSopenharmony_ci lws_state_transition_steps(&context->mgr_system, 238d4afb5ceSopenharmony_ci LWS_SYSTATE_OPERATIONAL); 239d4afb5ceSopenharmony_ci} 240d4afb5ceSopenharmony_ci#endif /* WITH_SYS_STATE */ 241d4afb5ceSopenharmony_ci 242d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 243d4afb5ceSopenharmony_cistatic int 244d4afb5ceSopenharmony_cilws_system_smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp, 245d4afb5ceSopenharmony_ci void *buf, size_t len) 246d4afb5ceSopenharmony_ci{ 247d4afb5ceSopenharmony_ci struct lws_context *cx = (struct lws_context *)opaque; 248d4afb5ceSopenharmony_ci 249d4afb5ceSopenharmony_ci if (_class != LWSSMDCL_NETWORK) 250d4afb5ceSopenharmony_ci return 0; 251d4afb5ceSopenharmony_ci 252d4afb5ceSopenharmony_ci /* something external requested CPD check */ 253d4afb5ceSopenharmony_ci 254d4afb5ceSopenharmony_ci if (!lws_json_simple_strcmp(buf, len, "\"trigger\":", "cpdcheck")) 255d4afb5ceSopenharmony_ci lws_system_cpd_start(cx); 256d4afb5ceSopenharmony_ci else 257d4afb5ceSopenharmony_ci /* 258d4afb5ceSopenharmony_ci * IP acquisition on any interface triggers captive portal 259d4afb5ceSopenharmony_ci * check on default route 260d4afb5ceSopenharmony_ci */ 261d4afb5ceSopenharmony_ci if (!lws_json_simple_strcmp(buf, len, "\"type\":", "ipacq")) 262d4afb5ceSopenharmony_ci lws_system_cpd_start(cx); 263d4afb5ceSopenharmony_ci 264d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_NTPCLIENT) 265d4afb5ceSopenharmony_ci /* 266d4afb5ceSopenharmony_ci * Captive portal detect showing internet workable triggers NTP Client 267d4afb5ceSopenharmony_ci */ 268d4afb5ceSopenharmony_ci if (!lws_json_simple_strcmp(buf, len, "\"type\":", "cps") && 269d4afb5ceSopenharmony_ci !lws_json_simple_strcmp(buf, len, "\"result\":", "OK") && 270d4afb5ceSopenharmony_ci lws_now_secs() < 1594017754) /* 06:42 Mon Jul 6 2020 UTC */ 271d4afb5ceSopenharmony_ci lws_ntpc_trigger(cx); 272d4afb5ceSopenharmony_ci#endif 273d4afb5ceSopenharmony_ci 274d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) && 0 275d4afb5ceSopenharmony_ci /* 276d4afb5ceSopenharmony_ci * Any network interface linkup triggers DHCP 277d4afb5ceSopenharmony_ci */ 278d4afb5ceSopenharmony_ci if (!lws_json_simple_strcmp(buf, len, "\"type\":", "linkup")) 279d4afb5ceSopenharmony_ci lws_ntpc_trigger(cx); 280d4afb5ceSopenharmony_ci 281d4afb5ceSopenharmony_ci#endif 282d4afb5ceSopenharmony_ci 283d4afb5ceSopenharmony_ci#if defined(LWS_WITH_DRIVERS) && defined(LWS_WITH_NETWORK) 284d4afb5ceSopenharmony_ci lws_netdev_smd_cb(opaque, _class, timestamp, buf, len); 285d4afb5ceSopenharmony_ci#endif 286d4afb5ceSopenharmony_ci 287d4afb5ceSopenharmony_ci return 0; 288d4afb5ceSopenharmony_ci} 289d4afb5ceSopenharmony_ci#endif 290d4afb5ceSopenharmony_ci 291d4afb5ceSopenharmony_ci 292d4afb5ceSopenharmony_ci 293d4afb5ceSopenharmony_ci#endif /* NETWORK */ 294d4afb5ceSopenharmony_ci 295d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 296d4afb5ceSopenharmony_ci 297d4afb5ceSopenharmony_cistatic const char * const opts_str = 298d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 299d4afb5ceSopenharmony_ci "NET " 300d4afb5ceSopenharmony_ci#else 301d4afb5ceSopenharmony_ci "NoNET " 302d4afb5ceSopenharmony_ci#endif 303d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 304d4afb5ceSopenharmony_ci "CLI " 305d4afb5ceSopenharmony_ci#endif 306d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 307d4afb5ceSopenharmony_ci "SRV " 308d4afb5ceSopenharmony_ci#endif 309d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) 310d4afb5ceSopenharmony_ci "H1 " 311d4afb5ceSopenharmony_ci#endif 312d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H2) 313d4afb5ceSopenharmony_ci "H2 " 314d4afb5ceSopenharmony_ci#endif 315d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_WS) 316d4afb5ceSopenharmony_ci "WS " 317d4afb5ceSopenharmony_ci#endif 318d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_MQTT) 319d4afb5ceSopenharmony_ci "MQTT " 320d4afb5ceSopenharmony_ci#endif 321d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) && !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 322d4afb5ceSopenharmony_ci "SS-JSON-POL " 323d4afb5ceSopenharmony_ci#endif 324d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) && defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 325d4afb5ceSopenharmony_ci "SS-STATIC-POL " 326d4afb5ceSopenharmony_ci#endif 327d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 328d4afb5ceSopenharmony_ci "SSPROX " 329d4afb5ceSopenharmony_ci#endif 330d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON) 331d4afb5ceSopenharmony_ci "ConMon " 332d4afb5ceSopenharmony_ci#endif 333d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION) 334d4afb5ceSopenharmony_ci "FLTINJ " 335d4afb5ceSopenharmony_ci#endif 336d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 337d4afb5ceSopenharmony_ci "ASYNC_DNS " 338d4afb5ceSopenharmony_ci#endif 339d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_NTPCLIENT) 340d4afb5ceSopenharmony_ci "NTPCLIENT " 341d4afb5ceSopenharmony_ci#endif 342d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) 343d4afb5ceSopenharmony_ci "DHCP_CLIENT " 344d4afb5ceSopenharmony_ci#endif 345d4afb5ceSopenharmony_ci; 346d4afb5ceSopenharmony_ci 347d4afb5ceSopenharmony_ci#endif 348d4afb5ceSopenharmony_ci 349d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS) 350d4afb5ceSopenharmony_cistatic const struct lws_evlib_map { 351d4afb5ceSopenharmony_ci uint64_t flag; 352d4afb5ceSopenharmony_ci const char *name; 353d4afb5ceSopenharmony_ci} map[] = { 354d4afb5ceSopenharmony_ci { LWS_SERVER_OPTION_LIBUV, "evlib_uv" }, 355d4afb5ceSopenharmony_ci { LWS_SERVER_OPTION_LIBEVENT, "evlib_event" }, 356d4afb5ceSopenharmony_ci { LWS_SERVER_OPTION_GLIB, "evlib_glib" }, 357d4afb5ceSopenharmony_ci { LWS_SERVER_OPTION_LIBEV, "evlib_ev" }, 358d4afb5ceSopenharmony_ci { LWS_SERVER_OPTION_SDEVENT, "evlib_sd" }, 359d4afb5ceSopenharmony_ci { LWS_SERVER_OPTION_ULOOP, "evlib_uloop" }, 360d4afb5ceSopenharmony_ci}; 361d4afb5ceSopenharmony_cistatic const char * const dlist[] = { 362d4afb5ceSopenharmony_ci ".", /* Priority 1: plugins in cwd */ 363d4afb5ceSopenharmony_ci LWS_INSTALL_LIBDIR, /* Priority 2: plugins in install dir */ 364d4afb5ceSopenharmony_ci NULL 365d4afb5ceSopenharmony_ci}; 366d4afb5ceSopenharmony_ci#endif 367d4afb5ceSopenharmony_ci 368d4afb5ceSopenharmony_cistruct lws_context * 369d4afb5ceSopenharmony_cilws_create_context(const struct lws_context_creation_info *info) 370d4afb5ceSopenharmony_ci{ 371d4afb5ceSopenharmony_ci struct lws_context *context = NULL; 372d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 373d4afb5ceSopenharmony_ci const char *s = "IPv6-absent"; 374d4afb5ceSopenharmony_ci#endif 375d4afb5ceSopenharmony_ci#if defined(LWS_WITH_FILE_OPS) 376d4afb5ceSopenharmony_ci struct lws_plat_file_ops *prev; 377d4afb5ceSopenharmony_ci#endif 378d4afb5ceSopenharmony_ci#ifndef LWS_NO_DAEMONIZE 379d4afb5ceSopenharmony_ci pid_t pid_daemon = get_daemonize_pid(); 380d4afb5ceSopenharmony_ci#endif 381d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 382d4afb5ceSopenharmony_ci const lws_plugin_evlib_t *plev = NULL; 383d4afb5ceSopenharmony_ci unsigned short count_threads = 1; 384d4afb5ceSopenharmony_ci uint8_t *u; 385d4afb5ceSopenharmony_ci uint16_t us_wait_resolution = 0; 386d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT) 387d4afb5ceSopenharmony_ci struct lws_cache_creation_info ci; 388d4afb5ceSopenharmony_ci#endif 389d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 390d4afb5ceSopenharmony_ci char mbedtls_version[32]; 391d4afb5ceSopenharmony_ci#endif 392d4afb5ceSopenharmony_ci 393d4afb5ceSopenharmony_ci#if defined(__ANDROID__) 394d4afb5ceSopenharmony_ci struct rlimit rt; 395d4afb5ceSopenharmony_ci#endif 396d4afb5ceSopenharmony_ci size_t 397d4afb5ceSopenharmony_ci#if defined(LWS_PLAT_FREERTOS) 398d4afb5ceSopenharmony_ci /* smaller default, can set in info->pt_serv_buf_size */ 399d4afb5ceSopenharmony_ci s1 = 2048, 400d4afb5ceSopenharmony_ci#else 401d4afb5ceSopenharmony_ci s1 = 4096, 402d4afb5ceSopenharmony_ci#endif 403d4afb5ceSopenharmony_ci size = sizeof(struct lws_context); 404d4afb5ceSopenharmony_ci#endif 405d4afb5ceSopenharmony_ci 406d4afb5ceSopenharmony_ci int n; 407d4afb5ceSopenharmony_ci unsigned int lpf = info->fd_limit_per_thread; 408d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS) 409d4afb5ceSopenharmony_ci struct lws_plugin *evlib_plugin_list = NULL; 410d4afb5ceSopenharmony_ci#if defined(_DEBUG) && !defined(LWS_WITH_NO_LOGS) 411d4afb5ceSopenharmony_ci char *ld_env; 412d4afb5ceSopenharmony_ci#endif 413d4afb5ceSopenharmony_ci#endif 414d4afb5ceSopenharmony_ci#if defined(LWS_WITH_LIBUV) 415d4afb5ceSopenharmony_ci char fatal_exit_defer = 0; 416d4afb5ceSopenharmony_ci#endif 417d4afb5ceSopenharmony_ci 418d4afb5ceSopenharmony_ci 419d4afb5ceSopenharmony_ci if (lws_fi(&info->fic, "ctx_createfail1")) 420d4afb5ceSopenharmony_ci goto early_bail; 421d4afb5ceSopenharmony_ci 422d4afb5ceSopenharmony_ci if (lpf) { 423d4afb5ceSopenharmony_ci lpf+= 2; 424d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 425d4afb5ceSopenharmony_ci lpf++; 426d4afb5ceSopenharmony_ci#endif 427d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_NTPCLIENT) 428d4afb5ceSopenharmony_ci lpf++; 429d4afb5ceSopenharmony_ci#endif 430d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) 431d4afb5ceSopenharmony_ci lpf++; 432d4afb5ceSopenharmony_ci#endif 433d4afb5ceSopenharmony_ci } 434d4afb5ceSopenharmony_ci 435d4afb5ceSopenharmony_ci#if defined(LWS_WITH_IPV6) && !defined(LWS_WITH_NO_LOGS) 436d4afb5ceSopenharmony_ci if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_IPV6)) 437d4afb5ceSopenharmony_ci s = "IPV6-on"; 438d4afb5ceSopenharmony_ci else 439d4afb5ceSopenharmony_ci s = "IPV6-off"; 440d4afb5ceSopenharmony_ci#endif 441d4afb5ceSopenharmony_ci 442d4afb5ceSopenharmony_ci if (lws_plat_context_early_init()) 443d4afb5ceSopenharmony_ci goto early_bail; 444d4afb5ceSopenharmony_ci 445d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 446d4afb5ceSopenharmony_ci if (info->count_threads) 447d4afb5ceSopenharmony_ci count_threads = (unsigned short)info->count_threads; 448d4afb5ceSopenharmony_ci 449d4afb5ceSopenharmony_ci if (count_threads > LWS_MAX_SMP) 450d4afb5ceSopenharmony_ci count_threads = LWS_MAX_SMP; 451d4afb5ceSopenharmony_ci 452d4afb5ceSopenharmony_ci if (info->pt_serv_buf_size) 453d4afb5ceSopenharmony_ci s1 = info->pt_serv_buf_size; 454d4afb5ceSopenharmony_ci 455d4afb5ceSopenharmony_ci /* pt fakewsi and the pt serv buf allocations ride after the context */ 456d4afb5ceSopenharmony_ci size += count_threads * s1; 457d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) 458d4afb5ceSopenharmony_ci size += (count_threads * sizeof(struct lws)); 459d4afb5ceSopenharmony_ci#endif 460d4afb5ceSopenharmony_ci 461d4afb5ceSopenharmony_ci if (info->event_lib_custom) { 462d4afb5ceSopenharmony_ci plev = info->event_lib_custom; 463d4afb5ceSopenharmony_ci us_wait_resolution = 0; 464d4afb5ceSopenharmony_ci } 465d4afb5ceSopenharmony_ci#if defined(LWS_WITH_POLL) 466d4afb5ceSopenharmony_ci else { 467d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_poll; 468d4afb5ceSopenharmony_ci plev = &evlib_poll; 469d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) 470d4afb5ceSopenharmony_ci /* 471d4afb5ceSopenharmony_ci * ... freertos has us-resolution select()... 472d4afb5ceSopenharmony_ci * others are to ms-resolution poll() 473d4afb5ceSopenharmony_ci */ 474d4afb5ceSopenharmony_ci us_wait_resolution = 1000; 475d4afb5ceSopenharmony_ci#endif 476d4afb5ceSopenharmony_ci } 477d4afb5ceSopenharmony_ci#endif 478d4afb5ceSopenharmony_ci 479d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS) 480d4afb5ceSopenharmony_ci 481d4afb5ceSopenharmony_ci /* 482d4afb5ceSopenharmony_ci * New style dynamically loaded event lib support 483d4afb5ceSopenharmony_ci * 484d4afb5ceSopenharmony_ci * We have to pick and load the event lib plugin before we allocate 485d4afb5ceSopenharmony_ci * the context object, so we can overallocate it correctly 486d4afb5ceSopenharmony_ci */ 487d4afb5ceSopenharmony_ci 488d4afb5ceSopenharmony_ci#if defined(_DEBUG) && !defined(LWS_WITH_NO_LOGS) 489d4afb5ceSopenharmony_ci ld_env = getenv("LD_LIBRARY_PATH"); 490d4afb5ceSopenharmony_ci lwsl_info("%s: ev lib path %s, '%s'\n", __func__, 491d4afb5ceSopenharmony_ci LWS_INSTALL_LIBDIR, ld_env); 492d4afb5ceSopenharmony_ci#endif 493d4afb5ceSopenharmony_ci 494d4afb5ceSopenharmony_ci for (n = 0; n < (int)LWS_ARRAY_SIZE(map); n++) { 495d4afb5ceSopenharmony_ci char ok = 0; 496d4afb5ceSopenharmony_ci 497d4afb5ceSopenharmony_ci if (!lws_check_opt(info->options, map[n].flag)) 498d4afb5ceSopenharmony_ci continue; 499d4afb5ceSopenharmony_ci 500d4afb5ceSopenharmony_ci if (!lws_plugins_init(&evlib_plugin_list, 501d4afb5ceSopenharmony_ci dlist, "lws_evlib_plugin", 502d4afb5ceSopenharmony_ci map[n].name, NULL, NULL)) 503d4afb5ceSopenharmony_ci ok = 1; 504d4afb5ceSopenharmony_ci 505d4afb5ceSopenharmony_ci if (!ok || lws_fi(&info->fic, "ctx_createfail_plugin_init")) { 506d4afb5ceSopenharmony_ci lwsl_err("%s: failed to load %s\n", __func__, 507d4afb5ceSopenharmony_ci map[n].name); 508d4afb5ceSopenharmony_ci goto bail; 509d4afb5ceSopenharmony_ci } 510d4afb5ceSopenharmony_ci 511d4afb5ceSopenharmony_ci#if defined(LWS_WITH_LIBUV) 512d4afb5ceSopenharmony_ci if (!n) /* libuv */ 513d4afb5ceSopenharmony_ci fatal_exit_defer = !!info->foreign_loops; 514d4afb5ceSopenharmony_ci#endif 515d4afb5ceSopenharmony_ci 516d4afb5ceSopenharmony_ci if (!evlib_plugin_list || 517d4afb5ceSopenharmony_ci lws_fi(&info->fic, "ctx_createfail_evlib_plugin")) { 518d4afb5ceSopenharmony_ci lwsl_err("%s: unable to load evlib plugin %s\n", 519d4afb5ceSopenharmony_ci __func__, map[n].name); 520d4afb5ceSopenharmony_ci 521d4afb5ceSopenharmony_ci goto bail; 522d4afb5ceSopenharmony_ci } 523d4afb5ceSopenharmony_ci plev = (const lws_plugin_evlib_t *)evlib_plugin_list->hdr; 524d4afb5ceSopenharmony_ci break; 525d4afb5ceSopenharmony_ci } 526d4afb5ceSopenharmony_ci#else 527d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVENT_LIBS) 528d4afb5ceSopenharmony_ci /* 529d4afb5ceSopenharmony_ci * set the context event loops ops struct 530d4afb5ceSopenharmony_ci * 531d4afb5ceSopenharmony_ci * after this, all event_loop actions use the generic ops 532d4afb5ceSopenharmony_ci */ 533d4afb5ceSopenharmony_ci 534d4afb5ceSopenharmony_ci /* 535d4afb5ceSopenharmony_ci * oldstyle built-in event lib support 536d4afb5ceSopenharmony_ci * 537d4afb5ceSopenharmony_ci * We have composed them into the libwebsockets lib itself, we can 538d4afb5ceSopenharmony_ci * just pick the ops we want and done 539d4afb5ceSopenharmony_ci */ 540d4afb5ceSopenharmony_ci 541d4afb5ceSopenharmony_ci#if defined(LWS_WITH_LIBUV) 542d4afb5ceSopenharmony_ci if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBUV)) { 543d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_uv; 544d4afb5ceSopenharmony_ci plev = &evlib_uv; 545d4afb5ceSopenharmony_ci fatal_exit_defer = !!info->foreign_loops; 546d4afb5ceSopenharmony_ci us_wait_resolution = 0; 547d4afb5ceSopenharmony_ci } 548d4afb5ceSopenharmony_ci#endif 549d4afb5ceSopenharmony_ci 550d4afb5ceSopenharmony_ci#if defined(LWS_WITH_LIBEVENT) 551d4afb5ceSopenharmony_ci if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEVENT)) { 552d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_event; 553d4afb5ceSopenharmony_ci plev = &evlib_event; 554d4afb5ceSopenharmony_ci us_wait_resolution = 0; 555d4afb5ceSopenharmony_ci } 556d4afb5ceSopenharmony_ci#endif 557d4afb5ceSopenharmony_ci 558d4afb5ceSopenharmony_ci#if defined(LWS_WITH_GLIB) 559d4afb5ceSopenharmony_ci if (lws_check_opt(info->options, LWS_SERVER_OPTION_GLIB)) { 560d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_glib; 561d4afb5ceSopenharmony_ci plev = &evlib_glib; 562d4afb5ceSopenharmony_ci us_wait_resolution = 0; 563d4afb5ceSopenharmony_ci } 564d4afb5ceSopenharmony_ci#endif 565d4afb5ceSopenharmony_ci 566d4afb5ceSopenharmony_ci#if defined(LWS_WITH_LIBEV) 567d4afb5ceSopenharmony_ci if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEV)) { 568d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_ev; 569d4afb5ceSopenharmony_ci plev = &evlib_ev; 570d4afb5ceSopenharmony_ci us_wait_resolution = 0; 571d4afb5ceSopenharmony_ci } 572d4afb5ceSopenharmony_ci#endif 573d4afb5ceSopenharmony_ci 574d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SDEVENT) 575d4afb5ceSopenharmony_ci if (lws_check_opt(info->options, LWS_SERVER_OPTION_SDEVENT)) { 576d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_sd; 577d4afb5ceSopenharmony_ci plev = &evlib_sd; 578d4afb5ceSopenharmony_ci us_wait_resolution = 0; 579d4afb5ceSopenharmony_ci } 580d4afb5ceSopenharmony_ci#endif 581d4afb5ceSopenharmony_ci 582d4afb5ceSopenharmony_ci#if defined(LWS_WITH_ULOOP) 583d4afb5ceSopenharmony_ci if (lws_check_opt(info->options, LWS_SERVER_OPTION_ULOOP)) { 584d4afb5ceSopenharmony_ci extern const lws_plugin_evlib_t evlib_uloop; 585d4afb5ceSopenharmony_ci plev = &evlib_uloop; 586d4afb5ceSopenharmony_ci us_wait_resolution = 0; 587d4afb5ceSopenharmony_ci } 588d4afb5ceSopenharmony_ci#endif 589d4afb5ceSopenharmony_ci 590d4afb5ceSopenharmony_ci#endif /* with event libs */ 591d4afb5ceSopenharmony_ci 592d4afb5ceSopenharmony_ci#endif /* not with ev plugins */ 593d4afb5ceSopenharmony_ci 594d4afb5ceSopenharmony_ci if (!plev || lws_fi(&info->fic, "ctx_createfail_evlib_sel")) 595d4afb5ceSopenharmony_ci goto fail_event_libs; 596d4afb5ceSopenharmony_ci 597d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 598d4afb5ceSopenharmony_ci size += (size_t)plev->ops->evlib_size_ctx /* the ctx evlib priv */ + 599d4afb5ceSopenharmony_ci (count_threads * (size_t)plev->ops->evlib_size_pt) /* the pt evlib priv */; 600d4afb5ceSopenharmony_ci#endif 601d4afb5ceSopenharmony_ci 602d4afb5ceSopenharmony_ci context = lws_zalloc(size, "context"); 603d4afb5ceSopenharmony_ci if (!context || lws_fi(&info->fic, "ctx_createfail_oom_ctx")) { 604d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION) 605d4afb5ceSopenharmony_ci lws_free(context); 606d4afb5ceSopenharmony_ci#endif 607d4afb5ceSopenharmony_ci lwsl_err("OOM"); 608d4afb5ceSopenharmony_ci goto early_bail; 609d4afb5ceSopenharmony_ci } 610d4afb5ceSopenharmony_ci 611d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 612d4afb5ceSopenharmony_ci // NOTE: we need to init this fields because they may be used in logger when context destroying 613d4afb5ceSopenharmony_ci context->mgr_system.state_names = system_state_names; 614d4afb5ceSopenharmony_ci context->mgr_system.context = context; 615d4afb5ceSopenharmony_ci#endif 616d4afb5ceSopenharmony_ci 617d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 618d4afb5ceSopenharmony_ci context->event_loop_ops = plev->ops; 619d4afb5ceSopenharmony_ci context->us_wait_resolution = us_wait_resolution; 620d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS_JIT_TRUST) 621d4afb5ceSopenharmony_ci { 622d4afb5ceSopenharmony_ci struct lws_cache_creation_info ci; 623d4afb5ceSopenharmony_ci 624d4afb5ceSopenharmony_ci memset(&ci, 0, sizeof(ci)); 625d4afb5ceSopenharmony_ci ci.cx = context; 626d4afb5ceSopenharmony_ci ci.ops = &lws_cache_ops_heap; 627d4afb5ceSopenharmony_ci ci.name = "jitt"; 628d4afb5ceSopenharmony_ci ci.max_footprint = info->jitt_cache_max_footprint; 629d4afb5ceSopenharmony_ci context->trust_cache = lws_cache_create(&ci); 630d4afb5ceSopenharmony_ci } 631d4afb5ceSopenharmony_ci#endif 632d4afb5ceSopenharmony_ci#endif 633d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVENT_LIBS) 634d4afb5ceSopenharmony_ci /* at the very end */ 635d4afb5ceSopenharmony_ci context->evlib_ctx = (uint8_t *)context + size - 636d4afb5ceSopenharmony_ci plev->ops->evlib_size_ctx; 637d4afb5ceSopenharmony_ci#endif 638d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS) 639d4afb5ceSopenharmony_ci context->evlib_plugin_list = evlib_plugin_list; 640d4afb5ceSopenharmony_ci#endif 641d4afb5ceSopenharmony_ci 642d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) 643d4afb5ceSopenharmony_ci context->uid = info->uid; 644d4afb5ceSopenharmony_ci context->gid = info->gid; 645d4afb5ceSopenharmony_ci context->username = info->username; 646d4afb5ceSopenharmony_ci context->groupname = info->groupname; 647d4afb5ceSopenharmony_ci#endif 648d4afb5ceSopenharmony_ci context->name = info->vhost_name; 649d4afb5ceSopenharmony_ci if (info->log_cx) 650d4afb5ceSopenharmony_ci context->log_cx = info->log_cx; 651d4afb5ceSopenharmony_ci else 652d4afb5ceSopenharmony_ci context->log_cx = &log_cx; 653d4afb5ceSopenharmony_ci lwsl_refcount_cx(context->log_cx, 1); 654d4afb5ceSopenharmony_ci 655d4afb5ceSopenharmony_ci context->system_ops = info->system_ops; 656d4afb5ceSopenharmony_ci context->pt_serv_buf_size = (unsigned int)s1; 657d4afb5ceSopenharmony_ci context->protocols_copy = info->protocols; 658d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS_JIT_TRUST) 659d4afb5ceSopenharmony_ci context->vh_idle_grace_ms = info->vh_idle_grace_ms ? 660d4afb5ceSopenharmony_ci info->vh_idle_grace_ms : 5000; 661d4afb5ceSopenharmony_ci#endif 662d4afb5ceSopenharmony_ci 663d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION) 664d4afb5ceSopenharmony_ci context->fic.name = "ctx"; 665d4afb5ceSopenharmony_ci if (info->fic.fi_owner.count) 666d4afb5ceSopenharmony_ci /* 667d4afb5ceSopenharmony_ci * This moves all the lws_fi_t from info->fi to the context fi, 668d4afb5ceSopenharmony_ci * leaving it empty, so no injection added to default vhost 669d4afb5ceSopenharmony_ci */ 670d4afb5ceSopenharmony_ci lws_fi_import(&context->fic, &info->fic); 671d4afb5ceSopenharmony_ci#endif 672d4afb5ceSopenharmony_ci 673d4afb5ceSopenharmony_ci 674d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 675d4afb5ceSopenharmony_ci context->smd_ttl_us = info->smd_ttl_us ? info->smd_ttl_us : 676d4afb5ceSopenharmony_ci#if defined(LWS_PLAT_FREERTOS) 677d4afb5ceSopenharmony_ci 5000000; 678d4afb5ceSopenharmony_ci#else 679d4afb5ceSopenharmony_ci 2000000; 680d4afb5ceSopenharmony_ci#endif 681d4afb5ceSopenharmony_ci context->smd_queue_depth = (uint16_t)(info->smd_queue_depth ? 682d4afb5ceSopenharmony_ci info->smd_queue_depth : 683d4afb5ceSopenharmony_ci#if defined(LWS_PLAT_FREERTOS) 684d4afb5ceSopenharmony_ci 20); 685d4afb5ceSopenharmony_ci#else 686d4afb5ceSopenharmony_ci 40); 687d4afb5ceSopenharmony_ci#endif 688d4afb5ceSopenharmony_ci#endif 689d4afb5ceSopenharmony_ci 690d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 691d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI].tag_prefix = "wsi"; 692d4afb5ceSopenharmony_ci context->lcg[LWSLCG_VHOST].tag_prefix = "vh"; 693d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_SERVER].tag_prefix = "wsisrv"; /* adopted */ 694d4afb5ceSopenharmony_ci 695d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT) 696d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_MUX].tag_prefix = "mux"; /* a mux child wsi */ 697d4afb5ceSopenharmony_ci#endif 698d4afb5ceSopenharmony_ci 699d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 700d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_CLIENT].tag_prefix = "wsicli"; 701d4afb5ceSopenharmony_ci#endif 702d4afb5ceSopenharmony_ci 703d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 704d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 705d4afb5ceSopenharmony_ci context->lcg[LWSLCG_SS_CLIENT].tag_prefix = "SScli"; 706d4afb5ceSopenharmony_ci#endif 707d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 708d4afb5ceSopenharmony_ci context->lcg[LWSLCG_SS_SERVER].tag_prefix = "SSsrv"; 709d4afb5ceSopenharmony_ci#endif 710d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 711d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_SS_CLIENT].tag_prefix = "wsiSScli"; 712d4afb5ceSopenharmony_ci#endif 713d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 714d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_SS_SERVER].tag_prefix = "wsiSSsrv"; 715d4afb5ceSopenharmony_ci#endif 716d4afb5ceSopenharmony_ci#endif 717d4afb5ceSopenharmony_ci#endif 718d4afb5ceSopenharmony_ci 719d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) 720d4afb5ceSopenharmony_ci /* 721d4afb5ceSopenharmony_ci * If we're not using secure streams, we can still pass in a linked- 722d4afb5ceSopenharmony_ci * list of metrics policies 723d4afb5ceSopenharmony_ci */ 724d4afb5ceSopenharmony_ci context->metrics_policies = info->metrics_policies; 725d4afb5ceSopenharmony_ci context->metrics_prefix = info->metrics_prefix; 726d4afb5ceSopenharmony_ci 727d4afb5ceSopenharmony_ci context->mt_service = lws_metric_create(context, 728d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US | 729d4afb5ceSopenharmony_ci LWSMTFL_REPORT_ONLY_GO, "cpu.svc"); 730d4afb5ceSopenharmony_ci 731d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 732d4afb5ceSopenharmony_ci 733d4afb5ceSopenharmony_ci context->mt_conn_dns = lws_metric_create(context, 734d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 735d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 736d4afb5ceSopenharmony_ci "n.cn.dns"); 737d4afb5ceSopenharmony_ci context->mt_conn_tcp = lws_metric_create(context, 738d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 739d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 740d4afb5ceSopenharmony_ci "n.cn.tcp"); 741d4afb5ceSopenharmony_ci context->mt_conn_tls = lws_metric_create(context, 742d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 743d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 744d4afb5ceSopenharmony_ci "n.cn.tls"); 745d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 746d4afb5ceSopenharmony_ci context->mt_http_txn = lws_metric_create(context, 747d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 748d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 749d4afb5ceSopenharmony_ci "n.http.txn"); 750d4afb5ceSopenharmony_ci#endif 751d4afb5ceSopenharmony_ci 752d4afb5ceSopenharmony_ci context->mth_conn_failures = lws_metric_create(context, 753d4afb5ceSopenharmony_ci LWSMTFL_REPORT_HIST, "n.cn.failures"); 754d4afb5ceSopenharmony_ci 755d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 756d4afb5ceSopenharmony_ci context->mt_adns_cache = lws_metric_create(context, 757d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 758d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 759d4afb5ceSopenharmony_ci "n.cn.adns"); 760d4afb5ceSopenharmony_ci#endif 761d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 762d4afb5ceSopenharmony_ci context->mth_ss_conn = lws_metric_create(context, LWSMTFL_REPORT_HIST, 763d4afb5ceSopenharmony_ci "n.ss.conn"); 764d4afb5ceSopenharmony_ci#endif 765d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 766d4afb5ceSopenharmony_ci context->mt_ss_cliprox_conn = lws_metric_create(context, 767d4afb5ceSopenharmony_ci LWSMTFL_REPORT_HIST, 768d4afb5ceSopenharmony_ci "n.ss.cliprox.conn"); 769d4afb5ceSopenharmony_ci context->mt_ss_cliprox_paylat = lws_metric_create(context, 770d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 771d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 772d4afb5ceSopenharmony_ci "n.ss.cliprox.paylat"); 773d4afb5ceSopenharmony_ci context->mt_ss_proxcli_paylat = lws_metric_create(context, 774d4afb5ceSopenharmony_ci LWSMTFL_REPORT_MEAN | 775d4afb5ceSopenharmony_ci LWSMTFL_REPORT_DUTY_WALLCLOCK_US, 776d4afb5ceSopenharmony_ci "n.ss.proxcli.paylat"); 777d4afb5ceSopenharmony_ci#endif 778d4afb5ceSopenharmony_ci 779d4afb5ceSopenharmony_ci#endif /* network + metrics + client */ 780d4afb5ceSopenharmony_ci 781d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 782d4afb5ceSopenharmony_ci context->mth_srv = lws_metric_create(context, 783d4afb5ceSopenharmony_ci LWSMTFL_REPORT_HIST, "n.srv"); 784d4afb5ceSopenharmony_ci#endif /* network + metrics + server */ 785d4afb5ceSopenharmony_ci 786d4afb5ceSopenharmony_ci#endif /* network + metrics */ 787d4afb5ceSopenharmony_ci 788d4afb5ceSopenharmony_ci#endif /* network */ 789d4afb5ceSopenharmony_ci 790d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 791d4afb5ceSopenharmony_ci mbedtls_version_get_string(mbedtls_version); 792d4afb5ceSopenharmony_ci#endif 793d4afb5ceSopenharmony_ci 794d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 795d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "LWS: %s, MbedTLS-%s %s%s", library_version, mbedtls_version, opts_str, s); 796d4afb5ceSopenharmony_ci#else 797d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "LWS: %s, %s%s", library_version, opts_str, s); 798d4afb5ceSopenharmony_ci#endif 799d4afb5ceSopenharmony_ci 800d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 801d4afb5ceSopenharmony_ci lwsl_cx_info(context, "Event loop: %s", plev->ops->name); 802d4afb5ceSopenharmony_ci#endif 803d4afb5ceSopenharmony_ci 804d4afb5ceSopenharmony_ci /* 805d4afb5ceSopenharmony_ci * Proxy group 806d4afb5ceSopenharmony_ci */ 807d4afb5ceSopenharmony_ci 808d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 809d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 810d4afb5ceSopenharmony_ci context->lcg[LWSLCG_SSP_CLIENT].tag_prefix = "SSPcli"; 811d4afb5ceSopenharmony_ci#endif 812d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 813d4afb5ceSopenharmony_ci context->lcg[LWSLCG_SSP_ONWARD].tag_prefix = "SSPonw"; 814d4afb5ceSopenharmony_ci#endif 815d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT) 816d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_SSP_CLIENT].tag_prefix = "wsiSSPcli"; 817d4afb5ceSopenharmony_ci#endif 818d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 819d4afb5ceSopenharmony_ci context->lcg[LWSLCG_WSI_SSP_ONWARD].tag_prefix = "wsiSSPonw"; 820d4afb5ceSopenharmony_ci#endif 821d4afb5ceSopenharmony_ci#endif 822d4afb5ceSopenharmony_ci 823d4afb5ceSopenharmony_ci 824d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 825d4afb5ceSopenharmony_ci /* directly use the user-provided policy object list */ 826d4afb5ceSopenharmony_ci context->pss_policies = info->pss_policies; 827d4afb5ceSopenharmony_ci#endif 828d4afb5ceSopenharmony_ci 829d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) && defined(LWS_WITH_CLIENT) 830d4afb5ceSopenharmony_ci context->ss_proxy_bind = info->ss_proxy_bind; 831d4afb5ceSopenharmony_ci context->ss_proxy_port = info->ss_proxy_port; 832d4afb5ceSopenharmony_ci context->ss_proxy_address = info->ss_proxy_address; 833d4afb5ceSopenharmony_ci if (context->ss_proxy_bind && context->ss_proxy_address) 834d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "ss proxy bind '%s', port %d, ads '%s'", 835d4afb5ceSopenharmony_ci context->ss_proxy_bind, context->ss_proxy_port, 836d4afb5ceSopenharmony_ci context->ss_proxy_address); 837d4afb5ceSopenharmony_ci#endif 838d4afb5ceSopenharmony_ci 839d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 840d4afb5ceSopenharmony_ci context->undestroyed_threads = count_threads; 841d4afb5ceSopenharmony_ci context->count_threads = count_threads; 842d4afb5ceSopenharmony_ci 843d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_WS) && defined(LWS_WITHOUT_EXTENSIONS) 844d4afb5ceSopenharmony_ci if (info->extensions) 845d4afb5ceSopenharmony_ci lwsl_cx_warn(context, "WITHOUT_EXTENSIONS but exts ptr set"); 846d4afb5ceSopenharmony_ci#endif 847d4afb5ceSopenharmony_ci#endif /* network */ 848d4afb5ceSopenharmony_ci 849d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 850d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 851d4afb5ceSopenharmony_ci context->pss_policies_json = info->pss_policies_json; 852d4afb5ceSopenharmony_ci#endif 853d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SSPLUGINS) 854d4afb5ceSopenharmony_ci context->pss_plugins = info->pss_plugins; 855d4afb5ceSopenharmony_ci#endif 856d4afb5ceSopenharmony_ci#endif 857d4afb5ceSopenharmony_ci 858d4afb5ceSopenharmony_ci /* if he gave us names, set the uid / gid */ 859d4afb5ceSopenharmony_ci if (lws_plat_drop_app_privileges(context, 0) || 860d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_privdrop")) 861d4afb5ceSopenharmony_ci goto free_context_fail2; 862d4afb5ceSopenharmony_ci 863d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS) && defined(LWS_WITH_NETWORK) 864d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 865d4afb5ceSopenharmony_ci context->tls_ops = &tls_ops_mbedtls; 866d4afb5ceSopenharmony_ci 867d4afb5ceSopenharmony_ci mbedtls_client_preload_filepath = info->mbedtls_client_preload_filepath; 868d4afb5ceSopenharmony_ci#else 869d4afb5ceSopenharmony_ci context->tls_ops = &tls_ops_openssl; 870d4afb5ceSopenharmony_ci#endif 871d4afb5ceSopenharmony_ci#endif 872d4afb5ceSopenharmony_ci 873d4afb5ceSopenharmony_ci#if LWS_MAX_SMP > 1 874d4afb5ceSopenharmony_ci lws_mutex_refcount_init(&context->mr); 875d4afb5ceSopenharmony_ci#endif 876d4afb5ceSopenharmony_ci 877d4afb5ceSopenharmony_ci#if defined(LWS_PLAT_FREERTOS) 878d4afb5ceSopenharmony_ci#if defined(LWS_AMAZON_RTOS) 879d4afb5ceSopenharmony_ci context->last_free_heap = xPortGetFreeHeapSize(); 880d4afb5ceSopenharmony_ci#else 881d4afb5ceSopenharmony_ci context->last_free_heap = esp_get_free_heap_size(); 882d4afb5ceSopenharmony_ci#endif 883d4afb5ceSopenharmony_ci#endif 884d4afb5ceSopenharmony_ci 885d4afb5ceSopenharmony_ci#if defined(LWS_WITH_FILE_OPS) 886d4afb5ceSopenharmony_ci /* default to just the platform fops implementation */ 887d4afb5ceSopenharmony_ci 888d4afb5ceSopenharmony_ci context->fops_platform.LWS_FOP_OPEN = _lws_plat_file_open; 889d4afb5ceSopenharmony_ci context->fops_platform.LWS_FOP_CLOSE = _lws_plat_file_close; 890d4afb5ceSopenharmony_ci context->fops_platform.LWS_FOP_SEEK_CUR = _lws_plat_file_seek_cur; 891d4afb5ceSopenharmony_ci context->fops_platform.LWS_FOP_READ = _lws_plat_file_read; 892d4afb5ceSopenharmony_ci context->fops_platform.LWS_FOP_WRITE = _lws_plat_file_write; 893d4afb5ceSopenharmony_ci context->fops_platform.fi[0].sig = NULL; 894d4afb5ceSopenharmony_ci 895d4afb5ceSopenharmony_ci /* 896d4afb5ceSopenharmony_ci * arrange a linear linked-list of fops starting from context->fops 897d4afb5ceSopenharmony_ci * 898d4afb5ceSopenharmony_ci * platform fops 899d4afb5ceSopenharmony_ci * [ -> fops_zip (copied into context so .next settable) ] 900d4afb5ceSopenharmony_ci * [ -> info->fops ] 901d4afb5ceSopenharmony_ci */ 902d4afb5ceSopenharmony_ci 903d4afb5ceSopenharmony_ci context->fops = &context->fops_platform; 904d4afb5ceSopenharmony_ci prev = (struct lws_plat_file_ops *)context->fops; 905d4afb5ceSopenharmony_ci 906d4afb5ceSopenharmony_ci#if defined(LWS_WITH_ZIP_FOPS) 907d4afb5ceSopenharmony_ci /* make a soft copy so we can set .next */ 908d4afb5ceSopenharmony_ci context->fops_zip = fops_zip; 909d4afb5ceSopenharmony_ci prev->next = &context->fops_zip; 910d4afb5ceSopenharmony_ci prev = (struct lws_plat_file_ops *)prev->next; 911d4afb5ceSopenharmony_ci#endif 912d4afb5ceSopenharmony_ci 913d4afb5ceSopenharmony_ci /* if user provided fops, tack them on the end of the list */ 914d4afb5ceSopenharmony_ci if (info->fops) 915d4afb5ceSopenharmony_ci prev->next = info->fops; 916d4afb5ceSopenharmony_ci#endif 917d4afb5ceSopenharmony_ci 918d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 919d4afb5ceSopenharmony_ci context->reject_service_keywords = info->reject_service_keywords; 920d4afb5ceSopenharmony_ci#endif 921d4afb5ceSopenharmony_ci if (info->external_baggage_free_on_destroy) 922d4afb5ceSopenharmony_ci context->external_baggage_free_on_destroy = 923d4afb5ceSopenharmony_ci info->external_baggage_free_on_destroy; 924d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 925d4afb5ceSopenharmony_ci context->time_up = lws_now_usecs(); 926d4afb5ceSopenharmony_ci#endif 927d4afb5ceSopenharmony_ci context->pcontext_finalize = info->pcontext; 928d4afb5ceSopenharmony_ci 929d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS) && defined(LWS_WITH_NETWORK) 930d4afb5ceSopenharmony_ci context->simultaneous_ssl_restriction = 931d4afb5ceSopenharmony_ci info->simultaneous_ssl_restriction; 932d4afb5ceSopenharmony_ci context->simultaneous_ssl_handshake_restriction = 933d4afb5ceSopenharmony_ci info->simultaneous_ssl_handshake_restriction; 934d4afb5ceSopenharmony_ci#endif 935d4afb5ceSopenharmony_ci 936d4afb5ceSopenharmony_ci context->options = info->options; 937d4afb5ceSopenharmony_ci 938d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE) && !defined(WIN32) 939d4afb5ceSopenharmony_ci /* 940d4afb5ceSopenharmony_ci * If asked, try to set the rlimit / ulimit for process sockets / files. 941d4afb5ceSopenharmony_ci * We read the effective limit in a moment, so we will find out the 942d4afb5ceSopenharmony_ci * real limit according to system constraints then. 943d4afb5ceSopenharmony_ci */ 944d4afb5ceSopenharmony_ci if (info->rlimit_nofile) { 945d4afb5ceSopenharmony_ci struct rlimit rl; 946d4afb5ceSopenharmony_ci 947d4afb5ceSopenharmony_ci rl.rlim_cur = (unsigned int)info->rlimit_nofile; 948d4afb5ceSopenharmony_ci rl.rlim_max = (unsigned int)info->rlimit_nofile; 949d4afb5ceSopenharmony_ci setrlimit(RLIMIT_NOFILE, &rl); 950d4afb5ceSopenharmony_ci } 951d4afb5ceSopenharmony_ci#endif 952d4afb5ceSopenharmony_ci 953d4afb5ceSopenharmony_ci#ifndef LWS_NO_DAEMONIZE 954d4afb5ceSopenharmony_ci if (pid_daemon) { 955d4afb5ceSopenharmony_ci context->started_with_parent = pid_daemon; 956d4afb5ceSopenharmony_ci lwsl_cx_info(context, " Started with daemon pid %u", 957d4afb5ceSopenharmony_ci (unsigned int)pid_daemon); 958d4afb5ceSopenharmony_ci } 959d4afb5ceSopenharmony_ci#endif 960d4afb5ceSopenharmony_ci#if defined(__ANDROID__) 961d4afb5ceSopenharmony_ci n = getrlimit(RLIMIT_NOFILE, &rt); 962d4afb5ceSopenharmony_ci if (n == -1) { 963d4afb5ceSopenharmony_ci lwsl_cx_err(context, "Get RLIMIT_NOFILE failed!"); 964d4afb5ceSopenharmony_ci 965d4afb5ceSopenharmony_ci goto free_context_fail2; 966d4afb5ceSopenharmony_ci } 967d4afb5ceSopenharmony_ci context->max_fds = (unsigned int)rt.rlim_cur; 968d4afb5ceSopenharmony_ci#else 969d4afb5ceSopenharmony_ci#if defined(WIN32) || defined(_WIN32) || defined(LWS_AMAZON_RTOS) || defined(LWS_ESP_PLATFORM) 970d4afb5ceSopenharmony_ci context->max_fds = getdtablesize(); 971d4afb5ceSopenharmony_ci#else 972d4afb5ceSopenharmony_ci { 973d4afb5ceSopenharmony_ci long l = sysconf(_SC_OPEN_MAX); 974d4afb5ceSopenharmony_ci 975d4afb5ceSopenharmony_ci context->max_fds = 2560; 976d4afb5ceSopenharmony_ci 977d4afb5ceSopenharmony_ci if (l > 10000000) 978d4afb5ceSopenharmony_ci lwsl_cx_warn(context, "unreasonable ulimit -n workaround"); 979d4afb5ceSopenharmony_ci else 980d4afb5ceSopenharmony_ci if (l != -1l) 981d4afb5ceSopenharmony_ci context->max_fds = (unsigned int)l; 982d4afb5ceSopenharmony_ci } 983d4afb5ceSopenharmony_ci#endif 984d4afb5ceSopenharmony_ci if ((int)context->max_fds < 0 || 985d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_maxfds")) { 986d4afb5ceSopenharmony_ci lwsl_cx_err(context, "problem getting process max files"); 987d4afb5ceSopenharmony_ci 988d4afb5ceSopenharmony_ci goto free_context_fail2; 989d4afb5ceSopenharmony_ci } 990d4afb5ceSopenharmony_ci#endif 991d4afb5ceSopenharmony_ci 992d4afb5ceSopenharmony_ci /* 993d4afb5ceSopenharmony_ci * deal with any max_fds override, if it's reducing (setting it to 994d4afb5ceSopenharmony_ci * more than ulimit -n is meaningless). The platform init will 995d4afb5ceSopenharmony_ci * figure out what if this is something it can deal with. 996d4afb5ceSopenharmony_ci */ 997d4afb5ceSopenharmony_ci if (info->fd_limit_per_thread) { 998d4afb5ceSopenharmony_ci unsigned int mf = lpf * context->count_threads; 999d4afb5ceSopenharmony_ci 1000d4afb5ceSopenharmony_ci if (mf < context->max_fds) { 1001d4afb5ceSopenharmony_ci context->max_fds_unrelated_to_ulimit = 1; 1002d4afb5ceSopenharmony_ci context->max_fds = mf; 1003d4afb5ceSopenharmony_ci } 1004d4afb5ceSopenharmony_ci } 1005d4afb5ceSopenharmony_ci 1006d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1007d4afb5ceSopenharmony_ci context->token_limits = info->token_limits; 1008d4afb5ceSopenharmony_ci#endif 1009d4afb5ceSopenharmony_ci 1010d4afb5ceSopenharmony_ci 1011d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS) && defined(LWS_WITH_NETWORK) 1012d4afb5ceSopenharmony_ci time(&context->tls.last_cert_check_s); 1013d4afb5ceSopenharmony_ci if (info->alpn) 1014d4afb5ceSopenharmony_ci context->tls.alpn_default = info->alpn; 1015d4afb5ceSopenharmony_ci else { 1016d4afb5ceSopenharmony_ci char *p = context->tls.alpn_discovered, first = 1; 1017d4afb5ceSopenharmony_ci 1018d4afb5ceSopenharmony_ci LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) { 1019d4afb5ceSopenharmony_ci if (ar->alpn) { 1020d4afb5ceSopenharmony_ci if (!first) 1021d4afb5ceSopenharmony_ci *p++ = ','; 1022d4afb5ceSopenharmony_ci p += lws_snprintf(p, (unsigned int)( 1023d4afb5ceSopenharmony_ci (context->tls.alpn_discovered + 1024d4afb5ceSopenharmony_ci sizeof(context->tls.alpn_discovered) - 1025d4afb5ceSopenharmony_ci 2) - p), "%s", ar->alpn); 1026d4afb5ceSopenharmony_ci first = 0; 1027d4afb5ceSopenharmony_ci } 1028d4afb5ceSopenharmony_ci } LWS_FOR_EVERY_AVAILABLE_ROLE_END; 1029d4afb5ceSopenharmony_ci 1030d4afb5ceSopenharmony_ci context->tls.alpn_default = context->tls.alpn_discovered; 1031d4afb5ceSopenharmony_ci } 1032d4afb5ceSopenharmony_ci 1033d4afb5ceSopenharmony_ci#endif 1034d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1035d4afb5ceSopenharmony_ci if (info->timeout_secs) 1036d4afb5ceSopenharmony_ci context->timeout_secs = info->timeout_secs; 1037d4afb5ceSopenharmony_ci else 1038d4afb5ceSopenharmony_ci#endif 1039d4afb5ceSopenharmony_ci context->timeout_secs = 15; 1040d4afb5ceSopenharmony_ci 1041d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 1042d4afb5ceSopenharmony_ci if (info->max_http_header_data) 1043d4afb5ceSopenharmony_ci context->max_http_header_data = info->max_http_header_data; 1044d4afb5ceSopenharmony_ci else 1045d4afb5ceSopenharmony_ci if (info->max_http_header_data2) 1046d4afb5ceSopenharmony_ci context->max_http_header_data = 1047d4afb5ceSopenharmony_ci (unsigned short)info->max_http_header_data2; 1048d4afb5ceSopenharmony_ci else 1049d4afb5ceSopenharmony_ci context->max_http_header_data = LWS_DEF_HEADER_LEN; 1050d4afb5ceSopenharmony_ci 1051d4afb5ceSopenharmony_ci if (info->max_http_header_pool) 1052d4afb5ceSopenharmony_ci context->max_http_header_pool = info->max_http_header_pool; 1053d4afb5ceSopenharmony_ci else 1054d4afb5ceSopenharmony_ci if (info->max_http_header_pool2) 1055d4afb5ceSopenharmony_ci context->max_http_header_pool = 1056d4afb5ceSopenharmony_ci (unsigned short)info->max_http_header_pool2; 1057d4afb5ceSopenharmony_ci else 1058d4afb5ceSopenharmony_ci context->max_http_header_pool = context->max_fds; 1059d4afb5ceSopenharmony_ci#endif 1060d4afb5ceSopenharmony_ci 1061d4afb5ceSopenharmony_ci if (info->fd_limit_per_thread) 1062d4afb5ceSopenharmony_ci context->fd_limit_per_thread = lpf; 1063d4afb5ceSopenharmony_ci else 1064d4afb5ceSopenharmony_ci if (context->count_threads) 1065d4afb5ceSopenharmony_ci context->fd_limit_per_thread = context->max_fds / 1066d4afb5ceSopenharmony_ci context->count_threads; 1067d4afb5ceSopenharmony_ci 1068d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 1069d4afb5ceSopenharmony_ci lws_mutex_init(context->smd.lock_messages); 1070d4afb5ceSopenharmony_ci lws_mutex_init(context->smd.lock_peers); 1071d4afb5ceSopenharmony_ci 1072d4afb5ceSopenharmony_ci /* lws_system smd participant */ 1073d4afb5ceSopenharmony_ci 1074d4afb5ceSopenharmony_ci if (!lws_smd_register(context, context, 0, LWSSMDCL_NETWORK, 1075d4afb5ceSopenharmony_ci lws_system_smd_cb)) { 1076d4afb5ceSopenharmony_ci lwsl_cx_err(context, "early smd register failed"); 1077d4afb5ceSopenharmony_ci } 1078d4afb5ceSopenharmony_ci 1079d4afb5ceSopenharmony_ci /* user smd participant */ 1080d4afb5ceSopenharmony_ci 1081d4afb5ceSopenharmony_ci if (info->early_smd_cb && 1082d4afb5ceSopenharmony_ci !lws_smd_register(context, info->early_smd_opaque, 0, 1083d4afb5ceSopenharmony_ci info->early_smd_class_filter, 1084d4afb5ceSopenharmony_ci info->early_smd_cb)) { 1085d4afb5ceSopenharmony_ci lwsl_cx_err(context, "early smd register failed"); 1086d4afb5ceSopenharmony_ci } 1087d4afb5ceSopenharmony_ci#endif 1088d4afb5ceSopenharmony_ci 1089d4afb5ceSopenharmony_ci n = 0; 1090d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1091d4afb5ceSopenharmony_ci 1092d4afb5ceSopenharmony_ci context->default_retry.retry_ms_table = default_backoff_table; 1093d4afb5ceSopenharmony_ci context->default_retry.conceal_count = 1094d4afb5ceSopenharmony_ci context->default_retry.retry_ms_table_count = 1095d4afb5ceSopenharmony_ci LWS_ARRAY_SIZE(default_backoff_table); 1096d4afb5ceSopenharmony_ci context->default_retry.jitter_percent = 20; 1097d4afb5ceSopenharmony_ci context->default_retry.secs_since_valid_ping = 300; 1098d4afb5ceSopenharmony_ci context->default_retry.secs_since_valid_hangup = 310; 1099d4afb5ceSopenharmony_ci 1100d4afb5ceSopenharmony_ci if (info->retry_and_idle_policy && 1101d4afb5ceSopenharmony_ci info->retry_and_idle_policy->secs_since_valid_ping) { 1102d4afb5ceSopenharmony_ci context->default_retry.secs_since_valid_ping = 1103d4afb5ceSopenharmony_ci info->retry_and_idle_policy->secs_since_valid_ping; 1104d4afb5ceSopenharmony_ci context->default_retry.secs_since_valid_hangup = 1105d4afb5ceSopenharmony_ci info->retry_and_idle_policy->secs_since_valid_hangup; 1106d4afb5ceSopenharmony_ci } 1107d4afb5ceSopenharmony_ci 1108d4afb5ceSopenharmony_ci /* 1109d4afb5ceSopenharmony_ci * Allocate the per-thread storage for scratchpad buffers, 1110d4afb5ceSopenharmony_ci * and header data pool 1111d4afb5ceSopenharmony_ci */ 1112d4afb5ceSopenharmony_ci u = (uint8_t *)&context[1]; 1113d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 1114d4afb5ceSopenharmony_ci context->pt[n].serv_buf = u; 1115d4afb5ceSopenharmony_ci u += context->pt_serv_buf_size; 1116d4afb5ceSopenharmony_ci 1117d4afb5ceSopenharmony_ci context->pt[n].context = context; 1118d4afb5ceSopenharmony_ci context->pt[n].tid = (uint8_t)n; 1119d4afb5ceSopenharmony_ci 1120d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) 1121d4afb5ceSopenharmony_ci /* 1122d4afb5ceSopenharmony_ci * We overallocated for a fakewsi (can't compose it in the 1123d4afb5ceSopenharmony_ci * pt because size isn't known at that time). point to it 1124d4afb5ceSopenharmony_ci * and zero it down. Fakewsis are needed to make callbacks work 1125d4afb5ceSopenharmony_ci * when the source of the callback is not actually from a wsi 1126d4afb5ceSopenharmony_ci * context. 1127d4afb5ceSopenharmony_ci */ 1128d4afb5ceSopenharmony_ci context->pt[n].fake_wsi = (struct lws *)u; 1129d4afb5ceSopenharmony_ci u += sizeof(struct lws); 1130d4afb5ceSopenharmony_ci 1131d4afb5ceSopenharmony_ci memset(context->pt[n].fake_wsi, 0, sizeof(struct lws)); 1132d4afb5ceSopenharmony_ci#endif 1133d4afb5ceSopenharmony_ci 1134d4afb5ceSopenharmony_ci context->pt[n].evlib_pt = u; 1135d4afb5ceSopenharmony_ci u += plev->ops->evlib_size_pt; 1136d4afb5ceSopenharmony_ci 1137d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 1138d4afb5ceSopenharmony_ci context->pt[n].http.ah_list = NULL; 1139d4afb5ceSopenharmony_ci context->pt[n].http.ah_pool_length = 0; 1140d4afb5ceSopenharmony_ci#endif 1141d4afb5ceSopenharmony_ci lws_pt_mutex_init(&context->pt[n]); 1142d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SEQUENCER) 1143d4afb5ceSopenharmony_ci lws_seq_pt_init(&context->pt[n]); 1144d4afb5ceSopenharmony_ci#endif 1145d4afb5ceSopenharmony_ci 1146d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CGI) 1147d4afb5ceSopenharmony_ci if (lws_rops_fidx(&role_ops_cgi, LWS_ROPS_pt_init_destroy)) 1148d4afb5ceSopenharmony_ci (lws_rops_func_fidx(&role_ops_cgi, LWS_ROPS_pt_init_destroy)). 1149d4afb5ceSopenharmony_ci pt_init_destroy(context, info, 1150d4afb5ceSopenharmony_ci &context->pt[n], 0); 1151d4afb5ceSopenharmony_ci#endif 1152d4afb5ceSopenharmony_ci } 1153d4afb5ceSopenharmony_ci 1154d4afb5ceSopenharmony_ci if (!info->ka_interval && info->ka_time > 0) { 1155d4afb5ceSopenharmony_ci lwsl_cx_err(context, "info->ka_interval can't be 0 if ka_time used"); 1156d4afb5ceSopenharmony_ci goto free_context_fail; 1157d4afb5ceSopenharmony_ci } 1158d4afb5ceSopenharmony_ci 1159d4afb5ceSopenharmony_ci#if defined(LWS_WITH_PEER_LIMITS) 1160d4afb5ceSopenharmony_ci /* scale the peer hash table according to the max fds for the process, 1161d4afb5ceSopenharmony_ci * so that the max list depth averages 16. Eg, 1024 fd -> 64, 1162d4afb5ceSopenharmony_ci * 102400 fd -> 6400 1163d4afb5ceSopenharmony_ci */ 1164d4afb5ceSopenharmony_ci 1165d4afb5ceSopenharmony_ci context->pl_hash_elements = 1166d4afb5ceSopenharmony_ci (context->count_threads * context->fd_limit_per_thread) / 16; 1167d4afb5ceSopenharmony_ci context->pl_hash_table = lws_zalloc(sizeof(struct lws_peer *) * 1168d4afb5ceSopenharmony_ci context->pl_hash_elements, "peer limits hash table"); 1169d4afb5ceSopenharmony_ci 1170d4afb5ceSopenharmony_ci context->ip_limit_ah = info->ip_limit_ah; 1171d4afb5ceSopenharmony_ci context->ip_limit_wsi = info->ip_limit_wsi; 1172d4afb5ceSopenharmony_ci context->pl_notify_cb = info->pl_notify_cb; 1173d4afb5ceSopenharmony_ci#endif 1174d4afb5ceSopenharmony_ci 1175d4afb5ceSopenharmony_ci /* 1176d4afb5ceSopenharmony_ci * fds table contains pollfd structs for as many pollfds as we can 1177d4afb5ceSopenharmony_ci * handle... spread across as many service threads as we have going 1178d4afb5ceSopenharmony_ci */ 1179d4afb5ceSopenharmony_ci n = (int)(sizeof(struct lws_pollfd) * context->count_threads * 1180d4afb5ceSopenharmony_ci context->fd_limit_per_thread); 1181d4afb5ceSopenharmony_ci context->pt[0].fds = lws_zalloc((unsigned int)n, "fds table"); 1182d4afb5ceSopenharmony_ci if (context->pt[0].fds == NULL || 1183d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_oom_fds")) { 1184d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION) 1185d4afb5ceSopenharmony_ci lws_free(context->pt[0].fds); 1186d4afb5ceSopenharmony_ci#endif 1187d4afb5ceSopenharmony_ci lwsl_cx_err(context, "OOM allocating %d fds\n", context->max_fds); 1188d4afb5ceSopenharmony_ci goto free_context_fail; 1189d4afb5ceSopenharmony_ci } 1190d4afb5ceSopenharmony_ci#endif 1191d4afb5ceSopenharmony_ci 1192d4afb5ceSopenharmony_ci lwsl_cx_info(context, "ctx: %5luB (%ld ctx + pt(%ld thr x %d)), " 1193d4afb5ceSopenharmony_ci "pt-fds: %d, fdmap: %d", 1194d4afb5ceSopenharmony_ci (long)sizeof(struct lws_context) + 1195d4afb5ceSopenharmony_ci (context->count_threads * context->pt_serv_buf_size), 1196d4afb5ceSopenharmony_ci (long)sizeof(struct lws_context), 1197d4afb5ceSopenharmony_ci (long)context->count_threads, 1198d4afb5ceSopenharmony_ci context->pt_serv_buf_size, 1199d4afb5ceSopenharmony_ci context->fd_limit_per_thread, n); 1200d4afb5ceSopenharmony_ci 1201d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 1202d4afb5ceSopenharmony_ci lwsl_cx_info(context, " http: ah_data: %u, ah: %lu, max count %u", 1203d4afb5ceSopenharmony_ci context->max_http_header_data, 1204d4afb5ceSopenharmony_ci (long)sizeof(struct allocated_headers), 1205d4afb5ceSopenharmony_ci context->max_http_header_pool); 1206d4afb5ceSopenharmony_ci#endif 1207d4afb5ceSopenharmony_ci 1208d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 1209d4afb5ceSopenharmony_ci if (info->server_string) { 1210d4afb5ceSopenharmony_ci context->server_string = info->server_string; 1211d4afb5ceSopenharmony_ci context->server_string_len = (short) 1212d4afb5ceSopenharmony_ci strlen(context->server_string); 1213d4afb5ceSopenharmony_ci } 1214d4afb5ceSopenharmony_ci#endif 1215d4afb5ceSopenharmony_ci 1216d4afb5ceSopenharmony_ci#if LWS_MAX_SMP > 1 1217d4afb5ceSopenharmony_ci /* each thread serves his own chunk of fds */ 1218d4afb5ceSopenharmony_ci for (n = 1; n < (int)context->count_threads; n++) 1219d4afb5ceSopenharmony_ci context->pt[n].fds = context->pt[n - 1].fds + 1220d4afb5ceSopenharmony_ci context->fd_limit_per_thread; 1221d4afb5ceSopenharmony_ci#endif 1222d4afb5ceSopenharmony_ci 1223d4afb5ceSopenharmony_ci 1224d4afb5ceSopenharmony_ci /* 1225d4afb5ceSopenharmony_ci * Past here, we may have added handles to the event lib 1226d4afb5ceSopenharmony_ci * loop and if libuv, have to take care about how to unpick them... 1227d4afb5ceSopenharmony_ci */ 1228d4afb5ceSopenharmony_ci 1229d4afb5ceSopenharmony_ci if (lws_plat_init(context, info) || 1230d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_plat_init")) 1231d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1232d4afb5ceSopenharmony_ci 1233d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1234d4afb5ceSopenharmony_ci 1235d4afb5ceSopenharmony_ci if (lws_fi(&context->fic, "ctx_createfail_evlib_init")) 1236d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1237d4afb5ceSopenharmony_ci 1238d4afb5ceSopenharmony_ci if (context->event_loop_ops->init_context) 1239d4afb5ceSopenharmony_ci if (context->event_loop_ops->init_context(context, info)) 1240d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1241d4afb5ceSopenharmony_ci 1242d4afb5ceSopenharmony_ci if (lws_fi(&context->fic, "ctx_createfail_evlib_pt")) 1243d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1244d4afb5ceSopenharmony_ci 1245d4afb5ceSopenharmony_ci if (context->event_loop_ops->init_pt) 1246d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 1247d4afb5ceSopenharmony_ci void *lp = NULL; 1248d4afb5ceSopenharmony_ci 1249d4afb5ceSopenharmony_ci if (info->foreign_loops) 1250d4afb5ceSopenharmony_ci lp = info->foreign_loops[n]; 1251d4afb5ceSopenharmony_ci 1252d4afb5ceSopenharmony_ci if (context->event_loop_ops->init_pt(context, lp, n)) 1253d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1254d4afb5ceSopenharmony_ci } 1255d4afb5ceSopenharmony_ci 1256d4afb5ceSopenharmony_ci lws_context_lock(context, __func__); 1257d4afb5ceSopenharmony_ci n = __lws_create_event_pipes(context); 1258d4afb5ceSopenharmony_ci lws_context_unlock(context); 1259d4afb5ceSopenharmony_ci if (n) 1260d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1261d4afb5ceSopenharmony_ci 1262d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 1263d4afb5ceSopenharmony_ci LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) { 1264d4afb5ceSopenharmony_ci if (lws_rops_fidx(ar, LWS_ROPS_pt_init_destroy)) 1265d4afb5ceSopenharmony_ci (lws_rops_func_fidx(ar, LWS_ROPS_pt_init_destroy)). 1266d4afb5ceSopenharmony_ci pt_init_destroy(context, info, 1267d4afb5ceSopenharmony_ci &context->pt[n], 0); 1268d4afb5ceSopenharmony_ci } LWS_FOR_EVERY_AVAILABLE_ROLE_END; 1269d4afb5ceSopenharmony_ci } 1270d4afb5ceSopenharmony_ci#endif 1271d4afb5ceSopenharmony_ci 1272d4afb5ceSopenharmony_ci lws_context_init_ssl_library(context, info); 1273d4afb5ceSopenharmony_ci 1274d4afb5ceSopenharmony_ci context->user_space = info->user; 1275d4afb5ceSopenharmony_ci 1276d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER) 1277d4afb5ceSopenharmony_ci strcpy(context->canonical_hostname, "unknown"); 1278d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1279d4afb5ceSopenharmony_ci lws_server_get_canonical_hostname(context, info); 1280d4afb5ceSopenharmony_ci#endif 1281d4afb5ceSopenharmony_ci#endif 1282d4afb5ceSopenharmony_ci 1283d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) 1284d4afb5ceSopenharmony_ci memcpy(context->caps, info->caps, sizeof(context->caps)); 1285d4afb5ceSopenharmony_ci context->count_caps = info->count_caps; 1286d4afb5ceSopenharmony_ci#endif 1287d4afb5ceSopenharmony_ci 1288d4afb5ceSopenharmony_ci 1289d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1290d4afb5ceSopenharmony_ci 1291d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) || defined(LWS_WITH_SYS_NTPCLIENT) || \ 1292d4afb5ceSopenharmony_ci defined(LWS_WITH_SYS_DHCP_CLIENT) 1293d4afb5ceSopenharmony_ci { 1294d4afb5ceSopenharmony_ci /* 1295d4afb5ceSopenharmony_ci * system vhost 1296d4afb5ceSopenharmony_ci */ 1297d4afb5ceSopenharmony_ci 1298d4afb5ceSopenharmony_ci struct lws_context_creation_info ii; 1299d4afb5ceSopenharmony_ci const struct lws_protocols *pp[4]; 1300d4afb5ceSopenharmony_ci struct lws_vhost *vh; 1301d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 1302d4afb5ceSopenharmony_ci extern const struct lws_protocols lws_async_dns_protocol; 1303d4afb5ceSopenharmony_ci#endif 1304d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_NTPCLIENT) 1305d4afb5ceSopenharmony_ci extern const struct lws_protocols lws_system_protocol_ntpc; 1306d4afb5ceSopenharmony_ci#endif 1307d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) 1308d4afb5ceSopenharmony_ci extern const struct lws_protocols lws_system_protocol_dhcpc4; 1309d4afb5ceSopenharmony_ci#endif 1310d4afb5ceSopenharmony_ci 1311d4afb5ceSopenharmony_ci n = 0; 1312d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 1313d4afb5ceSopenharmony_ci pp[n++] = &lws_async_dns_protocol; 1314d4afb5ceSopenharmony_ci#endif 1315d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_NTPCLIENT) 1316d4afb5ceSopenharmony_ci pp[n++] = &lws_system_protocol_ntpc; 1317d4afb5ceSopenharmony_ci#endif 1318d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) 1319d4afb5ceSopenharmony_ci pp[n++] = &lws_system_protocol_dhcpc4; 1320d4afb5ceSopenharmony_ci#endif 1321d4afb5ceSopenharmony_ci pp[n] = NULL; 1322d4afb5ceSopenharmony_ci 1323d4afb5ceSopenharmony_ci memset(&ii, 0, sizeof(ii)); 1324d4afb5ceSopenharmony_ci ii.vhost_name = "system"; 1325d4afb5ceSopenharmony_ci ii.pprotocols = pp; 1326d4afb5ceSopenharmony_ci ii.port = CONTEXT_PORT_NO_LISTEN; 1327d4afb5ceSopenharmony_ci 1328d4afb5ceSopenharmony_ci if (lws_fi(&context->fic, "ctx_createfail_sys_vh")) 1329d4afb5ceSopenharmony_ci vh = NULL; 1330d4afb5ceSopenharmony_ci else 1331d4afb5ceSopenharmony_ci vh = lws_create_vhost(context, &ii); 1332d4afb5ceSopenharmony_ci if (!vh) { 1333d4afb5ceSopenharmony_ci lwsl_cx_err(context, "failed to create system vhost"); 1334d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1335d4afb5ceSopenharmony_ci } 1336d4afb5ceSopenharmony_ci 1337d4afb5ceSopenharmony_ci context->vhost_system = vh; 1338d4afb5ceSopenharmony_ci 1339d4afb5ceSopenharmony_ci if (lws_protocol_init_vhost(vh, NULL) || 1340d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_sys_vh_init")) { 1341d4afb5ceSopenharmony_ci lwsl_cx_err(context, "failed to init system vhost"); 1342d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1343d4afb5ceSopenharmony_ci } 1344d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 1345d4afb5ceSopenharmony_ci lws_async_dns_init(context); 1346d4afb5ceSopenharmony_ci //goto bail_libuv_aware; 1347d4afb5ceSopenharmony_ci#endif 1348d4afb5ceSopenharmony_ci } 1349d4afb5ceSopenharmony_ci 1350d4afb5ceSopenharmony_ci#endif 1351d4afb5ceSopenharmony_ci 1352d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 1353d4afb5ceSopenharmony_ci /* 1354d4afb5ceSopenharmony_ci * init the lws_state mgr for the system state 1355d4afb5ceSopenharmony_ci */ 1356d4afb5ceSopenharmony_ci 1357d4afb5ceSopenharmony_ci context->mgr_system.name = "system"; 1358d4afb5ceSopenharmony_ci context->mgr_system.state = LWS_SYSTATE_CONTEXT_CREATED; 1359d4afb5ceSopenharmony_ci context->mgr_system.parent = context; 1360d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 1361d4afb5ceSopenharmony_ci context->mgr_system.smd_class = LWSSMDCL_SYSTEM_STATE; 1362d4afb5ceSopenharmony_ci#endif 1363d4afb5ceSopenharmony_ci 1364d4afb5ceSopenharmony_ci context->protocols_notify.name = "prot_init"; 1365d4afb5ceSopenharmony_ci context->protocols_notify.notify_cb = lws_state_notify_protocol_init; 1366d4afb5ceSopenharmony_ci 1367d4afb5ceSopenharmony_ci lws_state_reg_notifier(&context->mgr_system, &context->protocols_notify); 1368d4afb5ceSopenharmony_ci 1369d4afb5ceSopenharmony_ci /* 1370d4afb5ceSopenharmony_ci * insert user notifiers here so they can participate with vetoing us 1371d4afb5ceSopenharmony_ci * trying to jump straight to operational, or at least observe us 1372d4afb5ceSopenharmony_ci * reaching 'operational', before we returned from context creation. 1373d4afb5ceSopenharmony_ci */ 1374d4afb5ceSopenharmony_ci 1375d4afb5ceSopenharmony_ci lws_state_reg_notifier_list(&context->mgr_system, 1376d4afb5ceSopenharmony_ci info->register_notifier_list); 1377d4afb5ceSopenharmony_ci#endif 1378d4afb5ceSopenharmony_ci 1379d4afb5ceSopenharmony_ci /* 1380d4afb5ceSopenharmony_ci * if he's not saying he'll make his own vhosts later then act 1381d4afb5ceSopenharmony_ci * compatibly and make a default vhost using the data in the info 1382d4afb5ceSopenharmony_ci */ 1383d4afb5ceSopenharmony_ci if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) { 1384d4afb5ceSopenharmony_ci if (!lws_create_vhost(context, info) || 1385d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_def_vh")) { 1386d4afb5ceSopenharmony_ci lwsl_cx_err(context, "Failed to create default vhost"); 1387d4afb5ceSopenharmony_ci 1388d4afb5ceSopenharmony_ci#if defined(LWS_WITH_PEER_LIMITS) 1389d4afb5ceSopenharmony_ci lws_free_set_NULL(context->pl_hash_table); 1390d4afb5ceSopenharmony_ci#endif 1391d4afb5ceSopenharmony_ci goto bail; 1392d4afb5ceSopenharmony_ci } 1393d4afb5ceSopenharmony_ci } 1394d4afb5ceSopenharmony_ci 1395d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT) 1396d4afb5ceSopenharmony_ci if (info->http_nsc_filepath) { 1397d4afb5ceSopenharmony_ci memset(&ci, 0, sizeof(ci)); 1398d4afb5ceSopenharmony_ci 1399d4afb5ceSopenharmony_ci ci.cx = context; 1400d4afb5ceSopenharmony_ci ci.ops = &lws_cache_ops_nscookiejar; 1401d4afb5ceSopenharmony_ci ci.name = "NSC"; 1402d4afb5ceSopenharmony_ci ci.u.nscookiejar.filepath = info->http_nsc_filepath; 1403d4afb5ceSopenharmony_ci 1404d4afb5ceSopenharmony_ci context->nsc = lws_cache_create(&ci); 1405d4afb5ceSopenharmony_ci if (!context->nsc) 1406d4afb5ceSopenharmony_ci goto bail; 1407d4afb5ceSopenharmony_ci 1408d4afb5ceSopenharmony_ci ci.ops = &lws_cache_ops_heap; 1409d4afb5ceSopenharmony_ci ci.name = "L1"; 1410d4afb5ceSopenharmony_ci ci.parent = context->nsc; 1411d4afb5ceSopenharmony_ci ci.max_footprint = info->http_nsc_heap_max_footprint; 1412d4afb5ceSopenharmony_ci ci.max_items = info->http_nsc_heap_max_items; 1413d4afb5ceSopenharmony_ci ci.max_payload = info->http_nsc_heap_max_payload; 1414d4afb5ceSopenharmony_ci 1415d4afb5ceSopenharmony_ci context->l1 = lws_cache_create(&ci); 1416d4afb5ceSopenharmony_ci if (!context->l1) { 1417d4afb5ceSopenharmony_ci lwsl_cx_err(context, "Failed to init cookiejar"); 1418d4afb5ceSopenharmony_ci goto bail; 1419d4afb5ceSopenharmony_ci } 1420d4afb5ceSopenharmony_ci } 1421d4afb5ceSopenharmony_ci#endif 1422d4afb5ceSopenharmony_ci 1423d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 1424d4afb5ceSopenharmony_ci 1425d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 1426d4afb5ceSopenharmony_ci if (context->pss_policies_json) { 1427d4afb5ceSopenharmony_ci /* 1428d4afb5ceSopenharmony_ci * You must create your context with the explicit vhosts flag 1429d4afb5ceSopenharmony_ci * in order to use secure streams 1430d4afb5ceSopenharmony_ci */ 1431d4afb5ceSopenharmony_ci assert(lws_check_opt(info->options, 1432d4afb5ceSopenharmony_ci LWS_SERVER_OPTION_EXPLICIT_VHOSTS)); 1433d4afb5ceSopenharmony_ci 1434d4afb5ceSopenharmony_ci if (lws_ss_policy_parse_begin(context, 0) || 1435d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_ss_pol1")) { 1436d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION) 1437d4afb5ceSopenharmony_ci lws_ss_policy_parse_abandon(context); 1438d4afb5ceSopenharmony_ci#endif 1439d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1440d4afb5ceSopenharmony_ci } 1441d4afb5ceSopenharmony_ci 1442d4afb5ceSopenharmony_ci n = lws_ss_policy_parse(context, 1443d4afb5ceSopenharmony_ci (uint8_t *)context->pss_policies_json, 1444d4afb5ceSopenharmony_ci strlen(context->pss_policies_json)); 1445d4afb5ceSopenharmony_ci if ((n != LEJP_CONTINUE && n < 0) || 1446d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_ss_pol2")) { 1447d4afb5ceSopenharmony_ci lws_ss_policy_parse_abandon(context); 1448d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1449d4afb5ceSopenharmony_ci } 1450d4afb5ceSopenharmony_ci 1451d4afb5ceSopenharmony_ci if (lws_ss_policy_set(context, "hardcoded") || 1452d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_ss_pol3")) { 1453d4afb5ceSopenharmony_ci lwsl_cx_err(context, "policy set failed"); 1454d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1455d4afb5ceSopenharmony_ci } 1456d4afb5ceSopenharmony_ci } 1457d4afb5ceSopenharmony_ci#else 1458d4afb5ceSopenharmony_ci if (context->pss_policies) { 1459d4afb5ceSopenharmony_ci /* user code set the policy objects directly, no parsing step */ 1460d4afb5ceSopenharmony_ci 1461d4afb5ceSopenharmony_ci if (lws_ss_policy_set(context, "hardcoded") || 1462d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_ss_pol3")) { 1463d4afb5ceSopenharmony_ci lwsl_cx_err(context, "policy set failed"); 1464d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1465d4afb5ceSopenharmony_ci } 1466d4afb5ceSopenharmony_ci } 1467d4afb5ceSopenharmony_ci#endif 1468d4afb5ceSopenharmony_ci#endif 1469d4afb5ceSopenharmony_ci 1470d4afb5ceSopenharmony_ci lws_context_init_extensions(info, context); 1471d4afb5ceSopenharmony_ci 1472d4afb5ceSopenharmony_ci lwsl_cx_info(context, " mem: per-conn: %5lu bytes + protocol rx buf", 1473d4afb5ceSopenharmony_ci (unsigned long)sizeof(struct lws)); 1474d4afb5ceSopenharmony_ci 1475d4afb5ceSopenharmony_ci /* 1476d4afb5ceSopenharmony_ci * drop any root privs for this process 1477d4afb5ceSopenharmony_ci * to listen on port < 1023 we would have needed root, but now we are 1478d4afb5ceSopenharmony_ci * listening, we don't want the power for anything else 1479d4afb5ceSopenharmony_ci */ 1480d4afb5ceSopenharmony_ci if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) 1481d4afb5ceSopenharmony_ci if (lws_plat_drop_app_privileges(context, 1) || 1482d4afb5ceSopenharmony_ci lws_fi(&context->fic, "ctx_createfail_privdrop")) 1483d4afb5ceSopenharmony_ci goto bail_libuv_aware; 1484d4afb5ceSopenharmony_ci 1485d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 1486d4afb5ceSopenharmony_ci /* 1487d4afb5ceSopenharmony_ci * We want to move on the syste, state as far as it can go towards 1488d4afb5ceSopenharmony_ci * OPERATIONAL now. But we have to return from here first so the user 1489d4afb5ceSopenharmony_ci * code that called us can set its copy of context, which it may be 1490d4afb5ceSopenharmony_ci * relying on to perform operations triggered by the state change. 1491d4afb5ceSopenharmony_ci * 1492d4afb5ceSopenharmony_ci * We set up a sul to come back immediately and do the state change. 1493d4afb5ceSopenharmony_ci */ 1494d4afb5ceSopenharmony_ci 1495d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &context->sul_system_state, 1496d4afb5ceSopenharmony_ci lws_context_creation_completion_cb, 1); 1497d4afb5ceSopenharmony_ci#endif 1498d4afb5ceSopenharmony_ci 1499d4afb5ceSopenharmony_ci /* expedite post-context init (eg, protocols) */ 1500d4afb5ceSopenharmony_ci lws_cancel_service(context); 1501d4afb5ceSopenharmony_ci#endif 1502d4afb5ceSopenharmony_ci 1503d4afb5ceSopenharmony_ci return context; 1504d4afb5ceSopenharmony_ci 1505d4afb5ceSopenharmony_ciearly_bail: 1506d4afb5ceSopenharmony_ci lws_fi_destroy(&info->fic); 1507d4afb5ceSopenharmony_ci 1508d4afb5ceSopenharmony_ci return NULL; 1509d4afb5ceSopenharmony_ci 1510d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1511d4afb5ceSopenharmony_cibail: 1512d4afb5ceSopenharmony_ci lws_fi_destroy(&info->fic); 1513d4afb5ceSopenharmony_ci lws_context_destroy(context); 1514d4afb5ceSopenharmony_ci 1515d4afb5ceSopenharmony_ci return NULL; 1516d4afb5ceSopenharmony_ci#endif 1517d4afb5ceSopenharmony_ci 1518d4afb5ceSopenharmony_cibail_libuv_aware: 1519d4afb5ceSopenharmony_ci lws_context_destroy(context); 1520d4afb5ceSopenharmony_ci#if defined(LWS_WITH_LIBUV) 1521d4afb5ceSopenharmony_ci return fatal_exit_defer ? context : NULL; 1522d4afb5ceSopenharmony_ci#else 1523d4afb5ceSopenharmony_ci return NULL; 1524d4afb5ceSopenharmony_ci#endif 1525d4afb5ceSopenharmony_ci 1526d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1527d4afb5ceSopenharmony_cifail_event_libs: 1528d4afb5ceSopenharmony_ci if (context) 1529d4afb5ceSopenharmony_ci lwsl_cx_err(context, "Requested event library support not configured"); 1530d4afb5ceSopenharmony_ci#endif 1531d4afb5ceSopenharmony_ci 1532d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1533d4afb5ceSopenharmony_cifree_context_fail: 1534d4afb5ceSopenharmony_ci if (context) { 1535d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 1536d4afb5ceSopenharmony_ci _lws_smd_destroy(context); 1537d4afb5ceSopenharmony_ci#endif 1538d4afb5ceSopenharmony_ci } 1539d4afb5ceSopenharmony_ci#endif 1540d4afb5ceSopenharmony_cifree_context_fail2: 1541d4afb5ceSopenharmony_ci if (context) { 1542d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) 1543d4afb5ceSopenharmony_ci lws_metrics_destroy(context); 1544d4afb5ceSopenharmony_ci#endif 1545d4afb5ceSopenharmony_ci lws_fi_destroy(&context->fic); 1546d4afb5ceSopenharmony_ci } 1547d4afb5ceSopenharmony_ci lws_fi_destroy(&info->fic); 1548d4afb5ceSopenharmony_ci if (context) { 1549d4afb5ceSopenharmony_ci lwsl_refcount_cx(context->log_cx, -1); 1550d4afb5ceSopenharmony_ci lws_free(context); 1551d4afb5ceSopenharmony_ci } 1552d4afb5ceSopenharmony_ci 1553d4afb5ceSopenharmony_ci return NULL; 1554d4afb5ceSopenharmony_ci} 1555d4afb5ceSopenharmony_ci 1556d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1557d4afb5ceSopenharmony_ciint 1558d4afb5ceSopenharmony_cilws_system_cpd_start(struct lws_context *cx) 1559d4afb5ceSopenharmony_ci{ 1560d4afb5ceSopenharmony_ci cx->captive_portal_detect = LWS_CPD_UNKNOWN; 1561d4afb5ceSopenharmony_ci 1562d4afb5ceSopenharmony_ci /* if there's a platform implementation, use it */ 1563d4afb5ceSopenharmony_ci 1564d4afb5ceSopenharmony_ci if (lws_system_get_ops(cx) && 1565d4afb5ceSopenharmony_ci lws_system_get_ops(cx)->captive_portal_detect_request) 1566d4afb5ceSopenharmony_ci return lws_system_get_ops(cx)->captive_portal_detect_request(cx); 1567d4afb5ceSopenharmony_ci 1568d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 1569d4afb5ceSopenharmony_ci /* 1570d4afb5ceSopenharmony_ci * Otherwise try to use SS "captive_portal_detect" if that's enabled 1571d4afb5ceSopenharmony_ci */ 1572d4afb5ceSopenharmony_ci return lws_ss_sys_cpd(cx); 1573d4afb5ceSopenharmony_ci#else 1574d4afb5ceSopenharmony_ci return 0; 1575d4afb5ceSopenharmony_ci#endif 1576d4afb5ceSopenharmony_ci} 1577d4afb5ceSopenharmony_ci 1578d4afb5ceSopenharmony_cistatic void 1579d4afb5ceSopenharmony_cilws_system_deferred_cb(lws_sorted_usec_list_t *sul) 1580d4afb5ceSopenharmony_ci{ 1581d4afb5ceSopenharmony_ci struct lws_context *cx = 1582d4afb5ceSopenharmony_ci lws_container_of(sul, struct lws_context, sul_cpd_defer); 1583d4afb5ceSopenharmony_ci 1584d4afb5ceSopenharmony_ci lws_system_cpd_start(cx); 1585d4afb5ceSopenharmony_ci} 1586d4afb5ceSopenharmony_ci 1587d4afb5ceSopenharmony_civoid 1588d4afb5ceSopenharmony_cilws_system_cpd_start_defer(struct lws_context *cx, lws_usec_t defer_us) 1589d4afb5ceSopenharmony_ci{ 1590d4afb5ceSopenharmony_ci lws_sul_schedule(cx, 0, &cx->sul_cpd_defer, 1591d4afb5ceSopenharmony_ci lws_system_deferred_cb, defer_us); 1592d4afb5ceSopenharmony_ci} 1593d4afb5ceSopenharmony_ci 1594d4afb5ceSopenharmony_ci#if (defined(LWS_WITH_SYS_STATE) && defined(LWS_WITH_SYS_SMD)) || !defined(LWS_WITH_NO_LOGS) 1595d4afb5ceSopenharmony_cistatic const char *cname[] = { "Unknown", "OK", "Captive", "No internet" }; 1596d4afb5ceSopenharmony_ci#endif 1597d4afb5ceSopenharmony_ci 1598d4afb5ceSopenharmony_civoid 1599d4afb5ceSopenharmony_cilws_system_cpd_set(struct lws_context *cx, lws_cpd_result_t result) 1600d4afb5ceSopenharmony_ci{ 1601d4afb5ceSopenharmony_ci if (cx->captive_portal_detect != LWS_CPD_UNKNOWN) 1602d4afb5ceSopenharmony_ci return; 1603d4afb5ceSopenharmony_ci 1604d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 1605d4afb5ceSopenharmony_ci lwsl_cx_notice(cx, "setting CPD result %s", cname[result]); 1606d4afb5ceSopenharmony_ci#endif 1607d4afb5ceSopenharmony_ci 1608d4afb5ceSopenharmony_ci cx->captive_portal_detect = (uint8_t)result; 1609d4afb5ceSopenharmony_ci 1610d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 1611d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 1612d4afb5ceSopenharmony_ci lws_smd_msg_printf(cx, LWSSMDCL_NETWORK, 1613d4afb5ceSopenharmony_ci "{\"type\":\"cpd\",\"result\":\"%s\"}", 1614d4afb5ceSopenharmony_ci cname[cx->captive_portal_detect]); 1615d4afb5ceSopenharmony_ci#endif 1616d4afb5ceSopenharmony_ci 1617d4afb5ceSopenharmony_ci /* if nothing is there to intercept anything, go all the way */ 1618d4afb5ceSopenharmony_ci if (cx->mgr_system.state != LWS_SYSTATE_POLICY_INVALID) 1619d4afb5ceSopenharmony_ci lws_state_transition_steps(&cx->mgr_system, 1620d4afb5ceSopenharmony_ci LWS_SYSTATE_OPERATIONAL); 1621d4afb5ceSopenharmony_ci#endif 1622d4afb5ceSopenharmony_ci} 1623d4afb5ceSopenharmony_ci 1624d4afb5ceSopenharmony_cilws_cpd_result_t 1625d4afb5ceSopenharmony_cilws_system_cpd_state_get(struct lws_context *cx) 1626d4afb5ceSopenharmony_ci{ 1627d4afb5ceSopenharmony_ci return (lws_cpd_result_t)cx->captive_portal_detect; 1628d4afb5ceSopenharmony_ci} 1629d4afb5ceSopenharmony_ci 1630d4afb5ceSopenharmony_ci#endif 1631d4afb5ceSopenharmony_ci 1632d4afb5ceSopenharmony_ciint 1633d4afb5ceSopenharmony_cilws_context_is_deprecated(struct lws_context *cx) 1634d4afb5ceSopenharmony_ci{ 1635d4afb5ceSopenharmony_ci return cx->deprecated; 1636d4afb5ceSopenharmony_ci} 1637d4afb5ceSopenharmony_ci 1638d4afb5ceSopenharmony_ci/* 1639d4afb5ceSopenharmony_ci * When using an event loop, the context destruction is in three separate 1640d4afb5ceSopenharmony_ci * parts. This is to cover both internal and foreign event loops cleanly. 1641d4afb5ceSopenharmony_ci * 1642d4afb5ceSopenharmony_ci * - lws_context_destroy() simply starts a soft close of all wsi and 1643d4afb5ceSopenharmony_ci * related allocations. The event loop continues. 1644d4afb5ceSopenharmony_ci * 1645d4afb5ceSopenharmony_ci * As the closes complete in the event loop, reference counting is used 1646d4afb5ceSopenharmony_ci * to determine when everything is closed. It then calls 1647d4afb5ceSopenharmony_ci * lws_context_destroy2(). 1648d4afb5ceSopenharmony_ci * 1649d4afb5ceSopenharmony_ci * - lws_context_destroy2() cleans up the rest of the higher-level logical 1650d4afb5ceSopenharmony_ci * lws pieces like vhosts. If the loop was foreign, it then proceeds to 1651d4afb5ceSopenharmony_ci * lws_context_destroy3(). If it the loop is internal, it stops the 1652d4afb5ceSopenharmony_ci * internal loops and waits for lws_context_destroy() to be called again 1653d4afb5ceSopenharmony_ci * outside the event loop (since we cannot destroy the loop from 1654d4afb5ceSopenharmony_ci * within the loop). That will cause lws_context_destroy3() to run 1655d4afb5ceSopenharmony_ci * directly. 1656d4afb5ceSopenharmony_ci * 1657d4afb5ceSopenharmony_ci * - lws_context_destroy3() destroys any internal event loops and then 1658d4afb5ceSopenharmony_ci * destroys the context itself, setting what was info.pcontext to NULL. 1659d4afb5ceSopenharmony_ci */ 1660d4afb5ceSopenharmony_ci 1661d4afb5ceSopenharmony_ci 1662d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1663d4afb5ceSopenharmony_cistatic void 1664d4afb5ceSopenharmony_cilws_pt_destroy(struct lws_context_per_thread *pt) 1665d4afb5ceSopenharmony_ci{ 1666d4afb5ceSopenharmony_ci volatile struct lws_foreign_thread_pollfd *ftp, *next; 1667d4afb5ceSopenharmony_ci volatile struct lws_context_per_thread *vpt; 1668d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CGI) 1669d4afb5ceSopenharmony_ci lws_ctx_t ctx = pt->context; 1670d4afb5ceSopenharmony_ci 1671d4afb5ceSopenharmony_ci if (lws_rops_fidx(&role_ops_cgi, LWS_ROPS_pt_init_destroy)) 1672d4afb5ceSopenharmony_ci (lws_rops_func_fidx(&role_ops_cgi, LWS_ROPS_pt_init_destroy)). 1673d4afb5ceSopenharmony_ci pt_init_destroy(ctx, NULL, pt, 1); 1674d4afb5ceSopenharmony_ci#endif 1675d4afb5ceSopenharmony_ci vpt = (volatile struct lws_context_per_thread *)pt; 1676d4afb5ceSopenharmony_ci ftp = vpt->foreign_pfd_list; 1677d4afb5ceSopenharmony_ci while (ftp) { 1678d4afb5ceSopenharmony_ci next = ftp->next; 1679d4afb5ceSopenharmony_ci lws_free((void *)ftp); 1680d4afb5ceSopenharmony_ci ftp = next; 1681d4afb5ceSopenharmony_ci } 1682d4afb5ceSopenharmony_ci vpt->foreign_pfd_list = NULL; 1683d4afb5ceSopenharmony_ci 1684d4afb5ceSopenharmony_ci lws_pt_lock(pt, __func__); 1685d4afb5ceSopenharmony_ci 1686d4afb5ceSopenharmony_ci if (pt->pipe_wsi) { 1687d4afb5ceSopenharmony_ci lws_destroy_event_pipe(pt->pipe_wsi); 1688d4afb5ceSopenharmony_ci pt->pipe_wsi = NULL; 1689d4afb5ceSopenharmony_ci } 1690d4afb5ceSopenharmony_ci 1691d4afb5ceSopenharmony_ci if ((pt->dummy_pipe_fds[0] || pt->dummy_pipe_fds[1]) 1692d4afb5ceSopenharmony_ci#if !defined(WIN32) 1693d4afb5ceSopenharmony_ci && ((int)pt->dummy_pipe_fds[0] != -1 || (int)pt->dummy_pipe_fds[1] != -1) 1694d4afb5ceSopenharmony_ci#endif 1695d4afb5ceSopenharmony_ci ) { 1696d4afb5ceSopenharmony_ci struct lws wsi; 1697d4afb5ceSopenharmony_ci 1698d4afb5ceSopenharmony_ci memset(&wsi, 0, sizeof(wsi)); 1699d4afb5ceSopenharmony_ci wsi.a.context = pt->context; 1700d4afb5ceSopenharmony_ci wsi.tsi = (char)pt->tid; 1701d4afb5ceSopenharmony_ci lws_plat_pipe_close(&wsi); 1702d4afb5ceSopenharmony_ci } 1703d4afb5ceSopenharmony_ci 1704d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS) 1705d4afb5ceSopenharmony_ci lws_dll2_foreach_safe(&pt->ss_owner, NULL, lws_ss_destroy_dll); 1706d4afb5ceSopenharmony_ci 1707d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) && defined(LWS_WITH_CLIENT) 1708d4afb5ceSopenharmony_ci lws_dll2_foreach_safe(&pt->ss_client_owner, NULL, lws_sspc_destroy_dll); 1709d4afb5ceSopenharmony_ci#endif 1710d4afb5ceSopenharmony_ci 1711d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SEQUENCER) 1712d4afb5ceSopenharmony_ci lws_seq_destroy_all_on_pt(pt); 1713d4afb5ceSopenharmony_ci#endif 1714d4afb5ceSopenharmony_ci 1715d4afb5ceSopenharmony_ci 1716d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 1717d4afb5ceSopenharmony_ci while (pt->http.ah_list) 1718d4afb5ceSopenharmony_ci _lws_destroy_ah(pt, pt->http.ah_list); 1719d4afb5ceSopenharmony_ci#endif 1720d4afb5ceSopenharmony_ci 1721d4afb5ceSopenharmony_ci#endif 1722d4afb5ceSopenharmony_ci 1723d4afb5ceSopenharmony_ci lws_pt_unlock(pt); 1724d4afb5ceSopenharmony_ci pt->pipe_wsi = NULL; 1725d4afb5ceSopenharmony_ci 1726d4afb5ceSopenharmony_ci} 1727d4afb5ceSopenharmony_ci#endif 1728d4afb5ceSopenharmony_ci 1729d4afb5ceSopenharmony_ci/* 1730d4afb5ceSopenharmony_ci * Context destruction is now a state machine that's aware of SMP pts and 1731d4afb5ceSopenharmony_ci * various event lib approaches. 1732d4afb5ceSopenharmony_ci * 1733d4afb5ceSopenharmony_ci * lws_context_destroy() expects to be called at the end of the user code's 1734d4afb5ceSopenharmony_ci * usage of it. But it can also be called non-finally, as a way to stop 1735d4afb5ceSopenharmony_ci * service and exit the outer user service loop, and then complete in the 1736d4afb5ceSopenharmony_ci * final call. 1737d4afb5ceSopenharmony_ci * 1738d4afb5ceSopenharmony_ci * For libuv, with async close, it must decide by refcounting the hamdles on 1739d4afb5ceSopenharmony_ci * the loop if it has extricated itself from the loop and can be destroyed. 1740d4afb5ceSopenharmony_ci * 1741d4afb5ceSopenharmony_ci * The various entry states for the staged destroy 1742d4afb5ceSopenharmony_ci * 1743d4afb5ceSopenharmony_ci * LWSCD_NO_DESTROY: begin destroy process 1744d4afb5ceSopenharmony_ci * - mark context as starting destroy process 1745d4afb5ceSopenharmony_ci * - start vhost destroy 1746d4afb5ceSopenharmony_ci * - stop any further user protocol service 1747d4afb5ceSopenharmony_ci * 1748d4afb5ceSopenharmony_ci * LWSCD_PT_WAS_DEFERRED: come back here if any pt inside service 1749d4afb5ceSopenharmony_ci * - Check for pts that are inside service loop, mark deferral needed if so 1750d4afb5ceSopenharmony_ci * - If not, close all wsi on the pt loop and start logical pt destroy 1751d4afb5ceSopenharmony_ci * - If any deferred, set state to LWSCD_PT_WAS_DEFERRED and exit 1752d4afb5ceSopenharmony_ci * 1753d4afb5ceSopenharmony_ci * LWSCD_PT_WAIT_ALL_DESTROYED: come back here for async loop / pt closes 1754d4afb5ceSopenharmony_ci * - exit if any pt not marked as unused, or destroyed 1755d4afb5ceSopenharmony_ci * - if all pt down, call into evlib to advance context destroy 1756d4afb5ceSopenharmony_ci * - finalize vhost destruction 1757d4afb5ceSopenharmony_ci * - finalize pt destruction 1758d4afb5ceSopenharmony_ci * - if foreign loops, set state to LWSCD_FINALIZATION and exit 1759d4afb5ceSopenharmony_ci * 1760d4afb5ceSopenharmony_ci * LWSCD_FINALIZATION: come back here at final lws_destroy_context() call 1761d4afb5ceSopenharmony_ci * - destroy sundries 1762d4afb5ceSopenharmony_ci * - destroy and free the actual context 1763d4afb5ceSopenharmony_ci */ 1764d4afb5ceSopenharmony_ci 1765d4afb5ceSopenharmony_civoid 1766d4afb5ceSopenharmony_cilws_context_destroy(struct lws_context *context) 1767d4afb5ceSopenharmony_ci{ 1768d4afb5ceSopenharmony_ci struct lws_context **pcontext_finalize; 1769d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1770d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 1771d4afb5ceSopenharmony_ci struct lws_vhost *vh = NULL, *vh1; 1772d4afb5ceSopenharmony_ci int alive = 0, deferred_pt = 0; 1773d4afb5ceSopenharmony_ci#endif 1774d4afb5ceSopenharmony_ci#if defined(LWS_WITH_PEER_LIMITS) 1775d4afb5ceSopenharmony_ci uint32_t nu; 1776d4afb5ceSopenharmony_ci#endif 1777d4afb5ceSopenharmony_ci int n; 1778d4afb5ceSopenharmony_ci 1779d4afb5ceSopenharmony_ci if (!context || context->inside_context_destroy) 1780d4afb5ceSopenharmony_ci return; 1781d4afb5ceSopenharmony_ci 1782d4afb5ceSopenharmony_ci pcontext_finalize = context->pcontext_finalize; 1783d4afb5ceSopenharmony_ci 1784d4afb5ceSopenharmony_ci lws_context_lock(context, __func__); 1785d4afb5ceSopenharmony_ci context->inside_context_destroy = 1; 1786d4afb5ceSopenharmony_ci 1787d4afb5ceSopenharmony_ci lwsl_cx_info(context, "destroy_state %d", context->destroy_state); 1788d4afb5ceSopenharmony_ci 1789d4afb5ceSopenharmony_ci switch (context->destroy_state) { 1790d4afb5ceSopenharmony_ci case LWSCD_NO_DESTROY: 1791d4afb5ceSopenharmony_ci /* 1792d4afb5ceSopenharmony_ci * We're getting started 1793d4afb5ceSopenharmony_ci */ 1794d4afb5ceSopenharmony_ci 1795d4afb5ceSopenharmony_ci lwsl_cx_info(context, "starting context destroy flow"); 1796d4afb5ceSopenharmony_ci context->being_destroyed = 1; 1797d4afb5ceSopenharmony_ci 1798d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1799d4afb5ceSopenharmony_ci 1800d4afb5ceSopenharmony_ci /* 1801d4afb5ceSopenharmony_ci * Close any vhost listen wsi 1802d4afb5ceSopenharmony_ci * 1803d4afb5ceSopenharmony_ci * inform all the protocols that they are done and will have no 1804d4afb5ceSopenharmony_ci * more callbacks. 1805d4afb5ceSopenharmony_ci * 1806d4afb5ceSopenharmony_ci * We can't free things until after the event loop shuts down. 1807d4afb5ceSopenharmony_ci */ 1808d4afb5ceSopenharmony_ci 1809d4afb5ceSopenharmony_ci if (context->protocol_init_done) 1810d4afb5ceSopenharmony_ci vh = context->vhost_list; 1811d4afb5ceSopenharmony_ci 1812d4afb5ceSopenharmony_ci while (vh) { 1813d4afb5ceSopenharmony_ci lwsl_vhost_info(vh, "start close"); 1814d4afb5ceSopenharmony_ci vh1 = vh->vhost_next; 1815d4afb5ceSopenharmony_ci lws_vhost_destroy1(vh); 1816d4afb5ceSopenharmony_ci vh = vh1; 1817d4afb5ceSopenharmony_ci } 1818d4afb5ceSopenharmony_ci#endif 1819d4afb5ceSopenharmony_ci 1820d4afb5ceSopenharmony_ci lws_plat_context_early_destroy(context); 1821d4afb5ceSopenharmony_ci 1822d4afb5ceSopenharmony_ci context->service_no_longer_possible = 1; 1823d4afb5ceSopenharmony_ci context->requested_stop_internal_loops = 1; 1824d4afb5ceSopenharmony_ci 1825d4afb5ceSopenharmony_ci /* fallthru */ 1826d4afb5ceSopenharmony_ci 1827d4afb5ceSopenharmony_ci case LWSCD_PT_WAS_DEFERRED: 1828d4afb5ceSopenharmony_ci 1829d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1830d4afb5ceSopenharmony_ci 1831d4afb5ceSopenharmony_ci /* 1832d4afb5ceSopenharmony_ci * We want to mark the pts as their destruction having been 1833d4afb5ceSopenharmony_ci * initiated, so they will reject any new wsi, and iterate all 1834d4afb5ceSopenharmony_ci * existing pt wsi starting to close them. 1835d4afb5ceSopenharmony_ci * 1836d4afb5ceSopenharmony_ci * If the event loop has async close, we have to return after 1837d4afb5ceSopenharmony_ci * this and try again when all the loops stop after all the 1838d4afb5ceSopenharmony_ci * refcounted wsi are gone. 1839d4afb5ceSopenharmony_ci */ 1840d4afb5ceSopenharmony_ci 1841d4afb5ceSopenharmony_ci pt = context->pt; 1842d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 1843d4afb5ceSopenharmony_ci lws_pt_lock(pt, __func__); 1844d4afb5ceSopenharmony_ci 1845d4afb5ceSopenharmony_ci /* evlib will realize it needs to destroy pt */ 1846d4afb5ceSopenharmony_ci pt->destroy_self = 1; 1847d4afb5ceSopenharmony_ci 1848d4afb5ceSopenharmony_ci if (pt->inside_lws_service) { 1849d4afb5ceSopenharmony_ci pt->event_loop_pt_unused = 1; 1850d4afb5ceSopenharmony_ci deferred_pt = 1; 1851d4afb5ceSopenharmony_ci goto next; 1852d4afb5ceSopenharmony_ci } 1853d4afb5ceSopenharmony_ci 1854d4afb5ceSopenharmony_ci /* 1855d4afb5ceSopenharmony_ci * Close every handle in the fds 1856d4afb5ceSopenharmony_ci */ 1857d4afb5ceSopenharmony_ci 1858d4afb5ceSopenharmony_ci while (pt->fds_count) { 1859d4afb5ceSopenharmony_ci struct lws *wsi = wsi_from_fd(context, 1860d4afb5ceSopenharmony_ci pt->fds[0].fd); 1861d4afb5ceSopenharmony_ci 1862d4afb5ceSopenharmony_ci if (wsi) { 1863d4afb5ceSopenharmony_ci 1864d4afb5ceSopenharmony_ci lwsl_cx_debug(context, 1865d4afb5ceSopenharmony_ci "pt %d: closing wsi %p: role %s", 1866d4afb5ceSopenharmony_ci n, wsi, wsi->role_ops->name); 1867d4afb5ceSopenharmony_ci 1868d4afb5ceSopenharmony_ci lws_close_free_wsi(wsi, 1869d4afb5ceSopenharmony_ci LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY, 1870d4afb5ceSopenharmony_ci "ctx destroy" 1871d4afb5ceSopenharmony_ci /* no protocol close */); 1872d4afb5ceSopenharmony_ci 1873d4afb5ceSopenharmony_ci if (pt->pipe_wsi == wsi) 1874d4afb5ceSopenharmony_ci pt->pipe_wsi = NULL; 1875d4afb5ceSopenharmony_ci } 1876d4afb5ceSopenharmony_ci } 1877d4afb5ceSopenharmony_ci 1878d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CGI) 1879d4afb5ceSopenharmony_ci (lws_rops_func_fidx(&role_ops_cgi, 1880d4afb5ceSopenharmony_ci LWS_ROPS_pt_init_destroy)). 1881d4afb5ceSopenharmony_ci pt_init_destroy(context, NULL, 1882d4afb5ceSopenharmony_ci pt, 1); 1883d4afb5ceSopenharmony_ci#endif 1884d4afb5ceSopenharmony_ci 1885d4afb5ceSopenharmony_ci /* 1886d4afb5ceSopenharmony_ci * This closes handles that belong to the evlib pt 1887d4afb5ceSopenharmony_ci * footprint, eg, timers, idle 1888d4afb5ceSopenharmony_ci */ 1889d4afb5ceSopenharmony_ci 1890d4afb5ceSopenharmony_ci if (context->event_loop_ops->destroy_pt) { 1891d4afb5ceSopenharmony_ci lwsl_cx_info(context, 1892d4afb5ceSopenharmony_ci "calling evlib destroy_pt %d\n", n); 1893d4afb5ceSopenharmony_ci context->event_loop_ops->destroy_pt(context, n); 1894d4afb5ceSopenharmony_ci } 1895d4afb5ceSopenharmony_ci 1896d4afb5ceSopenharmony_cinext: 1897d4afb5ceSopenharmony_ci lws_pt_unlock(pt); 1898d4afb5ceSopenharmony_ci 1899d4afb5ceSopenharmony_ci pt++; 1900d4afb5ceSopenharmony_ci } 1901d4afb5ceSopenharmony_ci 1902d4afb5ceSopenharmony_ci if (deferred_pt) { 1903d4afb5ceSopenharmony_ci context->destroy_state = LWSCD_PT_WAS_DEFERRED; 1904d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "destroy from inside service"); 1905d4afb5ceSopenharmony_ci lws_cancel_service(context); 1906d4afb5ceSopenharmony_ci goto bail; 1907d4afb5ceSopenharmony_ci } 1908d4afb5ceSopenharmony_ci#endif 1909d4afb5ceSopenharmony_ci context->destroy_state = LWSCD_PT_WAIT_ALL_DESTROYED; 1910d4afb5ceSopenharmony_ci 1911d4afb5ceSopenharmony_ci /* 1912d4afb5ceSopenharmony_ci * We have different needs depending if foreign loop or not. 1913d4afb5ceSopenharmony_ci * 1914d4afb5ceSopenharmony_ci * 1) If foreign loop, we really want to advance the 1915d4afb5ceSopenharmony_ci * destroy_context() past here, and block only for libuv- 1916d4afb5ceSopenharmony_ci * style async close completion. 1917d4afb5ceSopenharmony_ci * 1918d4afb5ceSopenharmony_ci * 2a) If poll, and we exited by ourselves and are calling a 1919d4afb5ceSopenharmony_ci * final destroy_context() outside of any service already, 1920d4afb5ceSopenharmony_ci * we want to advance all the way in one step. 1921d4afb5ceSopenharmony_ci * 1922d4afb5ceSopenharmony_ci * 2b) If poll, and we are reacting to a SIGINT, service 1923d4afb5ceSopenharmony_ci * thread(s) may be in poll wait or servicing. We can't 1924d4afb5ceSopenharmony_ci * advance the destroy_context() to the point it's freeing 1925d4afb5ceSopenharmony_ci * things; we have to leave that for the final 1926d4afb5ceSopenharmony_ci * destroy_context() after the service thread(s) are 1927d4afb5ceSopenharmony_ci * finished calling for service. 1928d4afb5ceSopenharmony_ci */ 1929d4afb5ceSopenharmony_ci 1930d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1931d4afb5ceSopenharmony_ci if (context->event_loop_ops->destroy_context1) { 1932d4afb5ceSopenharmony_ci lwsl_cx_info(context, "do evlib destroy_context1 and wait"); 1933d4afb5ceSopenharmony_ci context->event_loop_ops->destroy_context1(context); 1934d4afb5ceSopenharmony_ci 1935d4afb5ceSopenharmony_ci goto bail; 1936d4afb5ceSopenharmony_ci } 1937d4afb5ceSopenharmony_ci 1938d4afb5ceSopenharmony_ci /* 1939d4afb5ceSopenharmony_ci * ...if the more typical sync close, we can clean up the pts 1940d4afb5ceSopenharmony_ci * now ourselves... 1941d4afb5ceSopenharmony_ci */ 1942d4afb5ceSopenharmony_ci 1943d4afb5ceSopenharmony_ci lwsl_cx_info(context, "manually destroying pts"); 1944d4afb5ceSopenharmony_ci 1945d4afb5ceSopenharmony_ci pt = context->pt; 1946d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++, pt++) { 1947d4afb5ceSopenharmony_ci pt->event_loop_pt_unused = 1; 1948d4afb5ceSopenharmony_ci lws_pt_destroy(pt); 1949d4afb5ceSopenharmony_ci } 1950d4afb5ceSopenharmony_ci#endif 1951d4afb5ceSopenharmony_ci /* fallthru */ 1952d4afb5ceSopenharmony_ci 1953d4afb5ceSopenharmony_ci case LWSCD_PT_WAIT_ALL_DESTROYED: 1954d4afb5ceSopenharmony_ci 1955d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1956d4afb5ceSopenharmony_ci 1957d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) 1958d4afb5ceSopenharmony_ci if (!context->pt[n].is_destroyed && 1959d4afb5ceSopenharmony_ci !context->pt[n].event_loop_pt_unused) 1960d4afb5ceSopenharmony_ci alive++; 1961d4afb5ceSopenharmony_ci 1962d4afb5ceSopenharmony_ci lwsl_cx_info(context, "PT_WAIT_ALL_DESTROYED: %d alive", alive); 1963d4afb5ceSopenharmony_ci 1964d4afb5ceSopenharmony_ci if (alive) 1965d4afb5ceSopenharmony_ci break; 1966d4afb5ceSopenharmony_ci 1967d4afb5ceSopenharmony_ci /* 1968d4afb5ceSopenharmony_ci * With foreign loops, removing all our fds from the loop 1969d4afb5ceSopenharmony_ci * means there are no more ways for the foreign loop to give 1970d4afb5ceSopenharmony_ci * us any further CPU once we leave here... so we must make 1971d4afb5ceSopenharmony_ci * sure related service threads are exiting so we can pick up 1972d4afb5ceSopenharmony_ci * again at the original app thread and do the context 1973d4afb5ceSopenharmony_ci * destroy completion 1974d4afb5ceSopenharmony_ci */ 1975d4afb5ceSopenharmony_ci 1976d4afb5ceSopenharmony_ci /* 1977d4afb5ceSopenharmony_ci * evlib specific loop destroy? 1978d4afb5ceSopenharmony_ci */ 1979d4afb5ceSopenharmony_ci if (context->event_loop_ops->destroy_context2) 1980d4afb5ceSopenharmony_ci /* 1981d4afb5ceSopenharmony_ci * He returns nonzero to indicate the evlib must 1982d4afb5ceSopenharmony_ci * continue around the loop before destroy of it is 1983d4afb5ceSopenharmony_ci * completed so it can be freed 1984d4afb5ceSopenharmony_ci */ 1985d4afb5ceSopenharmony_ci context->event_loop_ops->destroy_context2(context); 1986d4afb5ceSopenharmony_ci context->requested_stop_internal_loops = 1; 1987d4afb5ceSopenharmony_ci#endif 1988d4afb5ceSopenharmony_ci 1989d4afb5ceSopenharmony_ci /* 1990d4afb5ceSopenharmony_ci * Every pt and wsi that may depend on the logical vhosts 1991d4afb5ceSopenharmony_ci * is destroyed. We can remove the logical vhosts. 1992d4afb5ceSopenharmony_ci */ 1993d4afb5ceSopenharmony_ci 1994d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) && defined(LWS_WITH_NETWORK) 1995d4afb5ceSopenharmony_ci lws_state_transition(&context->mgr_system, LWS_SYSTATE_POLICY_INVALID); 1996d4afb5ceSopenharmony_ci#endif 1997d4afb5ceSopenharmony_ci 1998d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 1999d4afb5ceSopenharmony_ci /* 2000d4afb5ceSopenharmony_ci * free all the per-vhost allocations 2001d4afb5ceSopenharmony_ci */ 2002d4afb5ceSopenharmony_ci 2003d4afb5ceSopenharmony_ci vh = context->vhost_list; 2004d4afb5ceSopenharmony_ci while (vh) { 2005d4afb5ceSopenharmony_ci vh1 = vh->vhost_next; 2006d4afb5ceSopenharmony_ci // lwsl_vhost_debug(vh, "vh %s destroy2", vh->name); 2007d4afb5ceSopenharmony_ci __lws_vhost_destroy2(vh); 2008d4afb5ceSopenharmony_ci vh = vh1; 2009d4afb5ceSopenharmony_ci } 2010d4afb5ceSopenharmony_ci 2011d4afb5ceSopenharmony_ci /* remove ourselves from the pending destruction list */ 2012d4afb5ceSopenharmony_ci 2013d4afb5ceSopenharmony_ci while (context->vhost_pending_destruction_list) 2014d4afb5ceSopenharmony_ci /* removes itself from list */ 2015d4afb5ceSopenharmony_ci __lws_vhost_destroy2(context->vhost_pending_destruction_list); 2016d4afb5ceSopenharmony_ci#endif 2017d4afb5ceSopenharmony_ci 2018d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 2019d4afb5ceSopenharmony_ci lws_ssl_context_destroy(context); 2020d4afb5ceSopenharmony_ci#endif 2021d4afb5ceSopenharmony_ci lws_plat_context_late_destroy(context); 2022d4afb5ceSopenharmony_ci 2023d4afb5ceSopenharmony_ci#if defined(LWS_WITH_PEER_LIMITS) 2024d4afb5ceSopenharmony_ci if (context->pl_hash_table) 2025d4afb5ceSopenharmony_ci for (nu = 0; nu < context->pl_hash_elements; nu++) { 2026d4afb5ceSopenharmony_ci if (!context->pl_hash_table[nu]) 2027d4afb5ceSopenharmony_ci continue; 2028d4afb5ceSopenharmony_ci lws_start_foreach_llp(struct lws_peer **, peer, 2029d4afb5ceSopenharmony_ci context->pl_hash_table[nu]) { 2030d4afb5ceSopenharmony_ci struct lws_peer *df = *peer; 2031d4afb5ceSopenharmony_ci *peer = df->next; 2032d4afb5ceSopenharmony_ci lws_free(df); 2033d4afb5ceSopenharmony_ci continue; 2034d4afb5ceSopenharmony_ci } lws_end_foreach_llp(peer, next); 2035d4afb5ceSopenharmony_ci } 2036d4afb5ceSopenharmony_ci lws_free(context->pl_hash_table); 2037d4afb5ceSopenharmony_ci#endif 2038d4afb5ceSopenharmony_ci 2039d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 2040d4afb5ceSopenharmony_ci 2041d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 2042d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[n]; 2043d4afb5ceSopenharmony_ci 2044d4afb5ceSopenharmony_ci (void)pt; 2045d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SEQUENCER) 2046d4afb5ceSopenharmony_ci lws_seq_destroy_all_on_pt(pt); 2047d4afb5ceSopenharmony_ci#endif 2048d4afb5ceSopenharmony_ci LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) { 2049d4afb5ceSopenharmony_ci if (lws_rops_fidx(ar, LWS_ROPS_pt_init_destroy)) 2050d4afb5ceSopenharmony_ci (lws_rops_func_fidx(ar, LWS_ROPS_pt_init_destroy)). 2051d4afb5ceSopenharmony_ci pt_init_destroy(context, NULL, pt, 1); 2052d4afb5ceSopenharmony_ci } LWS_FOR_EVERY_AVAILABLE_ROLE_END; 2053d4afb5ceSopenharmony_ci 2054d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CGI) 2055d4afb5ceSopenharmony_ci lws_rops_func_fidx(&role_ops_cgi, 2056d4afb5ceSopenharmony_ci LWS_ROPS_pt_init_destroy). 2057d4afb5ceSopenharmony_ci pt_init_destroy(context, NULL, 2058d4afb5ceSopenharmony_ci pt, 1); 2059d4afb5ceSopenharmony_ci#endif 2060d4afb5ceSopenharmony_ci 2061d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 2062d4afb5ceSopenharmony_ci while (pt->http.ah_list) 2063d4afb5ceSopenharmony_ci _lws_destroy_ah(pt, pt->http.ah_list); 2064d4afb5ceSopenharmony_ci#endif 2065d4afb5ceSopenharmony_ci lwsl_cx_info(context, "pt destroy %d", n); 2066d4afb5ceSopenharmony_ci lws_pt_destroy(pt); 2067d4afb5ceSopenharmony_ci } 2068d4afb5ceSopenharmony_ci#endif /* NETWORK */ 2069d4afb5ceSopenharmony_ci 2070d4afb5ceSopenharmony_ci context->destroy_state = LWSCD_FINALIZATION; 2071d4afb5ceSopenharmony_ci 2072d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 2073d4afb5ceSopenharmony_ci 2074d4afb5ceSopenharmony_ci if (context->pt[0].event_loop_foreign && 2075d4afb5ceSopenharmony_ci context->event_loop_ops->destroy_context1) { 2076d4afb5ceSopenharmony_ci 2077d4afb5ceSopenharmony_ci lwsl_cx_info(context, 2078d4afb5ceSopenharmony_ci "leaving final context destruction" 2079d4afb5ceSopenharmony_ci " for final call"); 2080d4afb5ceSopenharmony_ci goto bail; 2081d4afb5ceSopenharmony_ci } 2082d4afb5ceSopenharmony_ci 2083d4afb5ceSopenharmony_ci if (context->event_loop_ops->destroy_context1 && 2084d4afb5ceSopenharmony_ci !context->pt[0].event_loop_foreign) { 2085d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "waiting for internal loop exit"); 2086d4afb5ceSopenharmony_ci 2087d4afb5ceSopenharmony_ci goto bail; 2088d4afb5ceSopenharmony_ci } 2089d4afb5ceSopenharmony_ci#endif 2090d4afb5ceSopenharmony_ci /* fallthru */ 2091d4afb5ceSopenharmony_ci 2092d4afb5ceSopenharmony_ci case LWSCD_FINALIZATION: 2093d4afb5ceSopenharmony_ci 2094d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) 2095d4afb5ceSopenharmony_ci lws_metrics_dump(context); 2096d4afb5ceSopenharmony_ci#endif 2097d4afb5ceSopenharmony_ci 2098d4afb5ceSopenharmony_ci context->evlib_finalize_destroy_after_int_loops_stop = 1; 2099d4afb5ceSopenharmony_ci 2100d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 2101d4afb5ceSopenharmony_ci if (context->event_loop_ops->destroy_context2) 2102d4afb5ceSopenharmony_ci context->event_loop_ops->destroy_context2(context); 2103d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 2104d4afb5ceSopenharmony_ci lws_state_transition_steps(&context->mgr_system, 2105d4afb5ceSopenharmony_ci LWS_SYSTATE_CONTEXT_DESTROYING); 2106d4afb5ceSopenharmony_ci#endif 2107d4afb5ceSopenharmony_ci /* 2108d4afb5ceSopenharmony_ci * finalize destroy of pt and things hanging off it 2109d4afb5ceSopenharmony_ci */ 2110d4afb5ceSopenharmony_ci 2111d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 2112d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[n]; 2113d4afb5ceSopenharmony_ci 2114d4afb5ceSopenharmony_ci /* 2115d4afb5ceSopenharmony_ci * Destroy the pt-roles 2116d4afb5ceSopenharmony_ci */ 2117d4afb5ceSopenharmony_ci 2118d4afb5ceSopenharmony_ci LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) { 2119d4afb5ceSopenharmony_ci if (lws_rops_fidx(ar, LWS_ROPS_pt_init_destroy)) 2120d4afb5ceSopenharmony_ci (lws_rops_func_fidx(ar, LWS_ROPS_pt_init_destroy)). 2121d4afb5ceSopenharmony_ci pt_init_destroy(context, NULL, pt, 1); 2122d4afb5ceSopenharmony_ci } LWS_FOR_EVERY_AVAILABLE_ROLE_END; 2123d4afb5ceSopenharmony_ci 2124d4afb5ceSopenharmony_ci #if defined(LWS_WITH_CGI) 2125d4afb5ceSopenharmony_ci lws_rops_func_fidx(&role_ops_cgi, LWS_ROPS_pt_init_destroy). 2126d4afb5ceSopenharmony_ci pt_init_destroy(context, NULL, pt, 1); 2127d4afb5ceSopenharmony_ci #endif 2128d4afb5ceSopenharmony_ci 2129d4afb5ceSopenharmony_ci lws_pt_mutex_destroy(pt); 2130d4afb5ceSopenharmony_ci assert(!pt->is_destroyed); 2131d4afb5ceSopenharmony_ci pt->destroy_self = 0; 2132d4afb5ceSopenharmony_ci pt->is_destroyed = 1; 2133d4afb5ceSopenharmony_ci 2134d4afb5ceSopenharmony_ci lwsl_cx_info(context, "pt %d fully destroyed", 2135d4afb5ceSopenharmony_ci (int)(pt - pt->context->pt)); 2136d4afb5ceSopenharmony_ci } 2137d4afb5ceSopenharmony_ci 2138d4afb5ceSopenharmony_ci /* 2139d4afb5ceSopenharmony_ci * wsis are gone, pts are gone, vhosts are gone. 2140d4afb5ceSopenharmony_ci * 2141d4afb5ceSopenharmony_ci * clean up the context and things hanging off it 2142d4afb5ceSopenharmony_ci */ 2143d4afb5ceSopenharmony_ci 2144d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS_JIT_TRUST) 2145d4afb5ceSopenharmony_ci lws_cache_destroy(&context->trust_cache); 2146d4afb5ceSopenharmony_ci lws_tls_jit_trust_inflight_destroy_all(context); 2147d4afb5ceSopenharmony_ci#endif 2148d4afb5ceSopenharmony_ci 2149d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT) 2150d4afb5ceSopenharmony_ci lws_cache_destroy(&context->nsc); 2151d4afb5ceSopenharmony_ci lws_cache_destroy(&context->l1); 2152d4afb5ceSopenharmony_ci#endif 2153d4afb5ceSopenharmony_ci 2154d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD) 2155d4afb5ceSopenharmony_ci _lws_smd_destroy(context); 2156d4afb5ceSopenharmony_ci#endif 2157d4afb5ceSopenharmony_ci 2158d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_ASYNC_DNS) 2159d4afb5ceSopenharmony_ci lws_async_dns_deinit(&context->async_dns); 2160d4afb5ceSopenharmony_ci#endif 2161d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_DHCP_CLIENT) 2162d4afb5ceSopenharmony_ci lws_dhcpc_remove(context, NULL); 2163d4afb5ceSopenharmony_ci#endif 2164d4afb5ceSopenharmony_ci 2165d4afb5ceSopenharmony_ci if (context->pt[0].fds) 2166d4afb5ceSopenharmony_ci lws_free_set_NULL(context->pt[0].fds); 2167d4afb5ceSopenharmony_ci#endif 2168d4afb5ceSopenharmony_ci lws_context_deinit_ssl_library(context); 2169d4afb5ceSopenharmony_ci 2170d4afb5ceSopenharmony_ci#if defined(LWS_WITH_DETAILED_LATENCIES) 2171d4afb5ceSopenharmony_ci if (context->latencies_fd != -1) 2172d4afb5ceSopenharmony_ci compatible_close(context->latencies_fd); 2173d4afb5ceSopenharmony_ci#endif 2174d4afb5ceSopenharmony_ci 2175d4afb5ceSopenharmony_ci for (n = 0; n < LWS_SYSBLOB_TYPE_COUNT; n++) 2176d4afb5ceSopenharmony_ci lws_system_blob_destroy( 2177d4afb5ceSopenharmony_ci lws_system_get_blob(context, (lws_system_blob_item_t)n, 0)); 2178d4afb5ceSopenharmony_ci 2179d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) && defined(LWS_WITH_SECURE_STREAMS) && \ 2180d4afb5ceSopenharmony_ci !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 2181d4afb5ceSopenharmony_ci 2182d4afb5ceSopenharmony_ci while (context->server_der_list) { 2183d4afb5ceSopenharmony_ci struct lws_ss_x509 *x = context->server_der_list; 2184d4afb5ceSopenharmony_ci 2185d4afb5ceSopenharmony_ci context->server_der_list = x->next; 2186d4afb5ceSopenharmony_ci lws_free((void *)x->ca_der); 2187d4afb5ceSopenharmony_ci } 2188d4afb5ceSopenharmony_ci 2189d4afb5ceSopenharmony_ci if (context->ac_policy) 2190d4afb5ceSopenharmony_ci lwsac_free(&context->ac_policy); 2191d4afb5ceSopenharmony_ci#endif 2192d4afb5ceSopenharmony_ci 2193d4afb5ceSopenharmony_ci /* 2194d4afb5ceSopenharmony_ci * Context lock is about to go away 2195d4afb5ceSopenharmony_ci */ 2196d4afb5ceSopenharmony_ci 2197d4afb5ceSopenharmony_ci lws_context_unlock(context); 2198d4afb5ceSopenharmony_ci 2199d4afb5ceSopenharmony_ci#if LWS_MAX_SMP > 1 2200d4afb5ceSopenharmony_ci lws_mutex_refcount_destroy(&context->mr); 2201d4afb5ceSopenharmony_ci#endif 2202d4afb5ceSopenharmony_ci 2203d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) && defined(LWS_WITH_NETWORK) 2204d4afb5ceSopenharmony_ci lws_metrics_destroy(context); 2205d4afb5ceSopenharmony_ci#endif 2206d4afb5ceSopenharmony_ci 2207d4afb5ceSopenharmony_ci if (context->external_baggage_free_on_destroy) 2208d4afb5ceSopenharmony_ci free(context->external_baggage_free_on_destroy); 2209d4afb5ceSopenharmony_ci 2210d4afb5ceSopenharmony_ci#if defined(LWS_PLAT_FREERTOS) 2211d4afb5ceSopenharmony_ci#if defined(LWS_AMAZON_RTOS) 2212d4afb5ceSopenharmony_ci context->last_free_heap = xPortGetFreeHeapSize(); 2213d4afb5ceSopenharmony_ci#else 2214d4afb5ceSopenharmony_ci context->last_free_heap = esp_get_free_heap_size(); 2215d4afb5ceSopenharmony_ci#endif 2216d4afb5ceSopenharmony_ci#endif 2217d4afb5ceSopenharmony_ci 2218d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS) 2219d4afb5ceSopenharmony_ci if (context->evlib_plugin_list) 2220d4afb5ceSopenharmony_ci lws_plugins_destroy(&context->evlib_plugin_list, 2221d4afb5ceSopenharmony_ci NULL, NULL); 2222d4afb5ceSopenharmony_ci#endif 2223d4afb5ceSopenharmony_ci 2224d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION) 2225d4afb5ceSopenharmony_ci lws_fi_destroy(&context->fic); 2226d4afb5ceSopenharmony_ci#endif 2227d4afb5ceSopenharmony_ci 2228d4afb5ceSopenharmony_ci lwsl_refcount_cx(context->log_cx, -1); 2229d4afb5ceSopenharmony_ci 2230d4afb5ceSopenharmony_ci lws_free(context); 2231d4afb5ceSopenharmony_ci 2232d4afb5ceSopenharmony_ci if (pcontext_finalize) 2233d4afb5ceSopenharmony_ci *pcontext_finalize = NULL; 2234d4afb5ceSopenharmony_ci 2235d4afb5ceSopenharmony_ci return; 2236d4afb5ceSopenharmony_ci } 2237d4afb5ceSopenharmony_ci 2238d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 2239d4afb5ceSopenharmony_cibail: 2240d4afb5ceSopenharmony_ci#endif 2241d4afb5ceSopenharmony_ci lwsl_cx_info(context, "leaving"); 2242d4afb5ceSopenharmony_ci context->inside_context_destroy = 0; 2243d4afb5ceSopenharmony_ci lws_context_unlock(context); 2244d4afb5ceSopenharmony_ci} 2245d4afb5ceSopenharmony_ci 2246d4afb5ceSopenharmony_ciint 2247d4afb5ceSopenharmony_cilws_context_is_being_destroyed(struct lws_context *context) 2248d4afb5ceSopenharmony_ci{ 2249d4afb5ceSopenharmony_ci return !!context->being_destroyed; 2250d4afb5ceSopenharmony_ci} 2251d4afb5ceSopenharmony_ci 2252d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_STATE) 2253d4afb5ceSopenharmony_cistruct lws_context * 2254d4afb5ceSopenharmony_cilws_system_context_from_system_mgr(lws_state_manager_t *mgr) 2255d4afb5ceSopenharmony_ci{ 2256d4afb5ceSopenharmony_ci#if defined(LWS_WITH_NETWORK) 2257d4afb5ceSopenharmony_ci return mgr->context; 2258d4afb5ceSopenharmony_ci#else 2259d4afb5ceSopenharmony_ci return NULL; 2260d4afb5ceSopenharmony_ci#endif 2261d4afb5ceSopenharmony_ci} 2262d4afb5ceSopenharmony_ci#endif 2263d4afb5ceSopenharmony_ci 2264d4afb5ceSopenharmony_civoid 2265d4afb5ceSopenharmony_cilws_log_prepend_context(struct lws_log_cx *cx, void *obj, char **p, char *e) 2266d4afb5ceSopenharmony_ci{ 2267d4afb5ceSopenharmony_ci struct lws_context *lcx = (struct lws_context *)obj; 2268d4afb5ceSopenharmony_ci 2269d4afb5ceSopenharmony_ci if (lcx->name) 2270d4afb5ceSopenharmony_ci *p += lws_snprintf(*p, lws_ptr_diff_size_t(e, (*p)), "%s: ", 2271d4afb5ceSopenharmony_ci lcx->name); 2272d4afb5ceSopenharmony_ci} 2273d4afb5ceSopenharmony_ci 2274d4afb5ceSopenharmony_cistruct lws_log_cx * 2275d4afb5ceSopenharmony_cilwsl_context_get_cx(struct lws_context *cx) 2276d4afb5ceSopenharmony_ci{ 2277d4afb5ceSopenharmony_ci if (!cx) 2278d4afb5ceSopenharmony_ci return NULL; 2279d4afb5ceSopenharmony_ci 2280d4afb5ceSopenharmony_ci return cx->log_cx; 2281d4afb5ceSopenharmony_ci} 2282