{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1750739108,
"reponame":"libwebsockets",
"desc":"libwebsockets lightweight C networking library",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"8eeb16e7db7c63097742ac1c64539d9d",
"commit": {"type":"commit",
"time": 1525315776,
"time_ofs": 480,
"oid_tree": { "oid": "9ba035a29a35efd69ef021c22a416d5252d9fbd9", "alias": []},
"oid":{ "oid": "de064fd65aa8cab0f9314853116b33c1162fdd44", "alias": []},
"msg": "refactor: core code in lib/core and private-libwebsockets.h to core/private.h",
"sig_commit": { "git_time": { "time": 1525315776, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },
"sig_author": { "git_time": { "time": 1525315776, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }},
"body": "refactor: core code in lib/core and private-libwebsockets.h to core/private.h\n\nThis commit is coverity-clean as tested\n\ncmake .. -DLWS_WITH_MINIMAL_EXAMPLES\u003d1 -DLWS_WITHOUT_EXTENSIONS\u003d1 -DLWS_WITH_ACME\u003d1 -DLWS_WITH_LWSWS\u003d1 -DLWS_WITH_LIBUV\u003d1 -DLWS_WITH_HTTP2\u003d1 -DLWS_WITHOUT_CLIENT\u003d0 -DLWS_WITHOUT_SERVER\u003d0 -DLWS_UNIX_SOCK\u003d1 -DLWS_WITH_TLS\u003d0 -DLWS_WITH_MBEDTLS\u003d0 -DLWS_WITH_CGI\u003d1 -DCMAKE_BUILD_TYPE\u003dDEBUG -DLWS_WITH_GENERIC_SESSIONS\u003d1 -DLWS_WITH_RANGES\u003d1 -DLWS_ROLE_WS\u003d1 -DLWS_MAX_SMP\u003d16 -DLWS_ROLE_H1\u003d1 -DLWS_WITH_WOLFSSL\u003d0 -DLWS_WITH_LIBEV\u003d0 -DLWS_WITH_LIBEVENT\u003d1"
,
"diff": "diff --git a/.gitignore b/.gitignore\nindex 74c0e3c..eea4395 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -49,3 +49,4 @@ build/\n doc\n /build2/\n /build3/\n+/cov-int/\ndiff --git a/CMakeLists.txt b/CMakeLists.txt\nindex 93d7210..c59bc99 100644\n--- a/CMakeLists.txt\n+++ b/CMakeLists.txt\n@@ -718,7 +718,7 @@ include_directories(\u0022${PROJECT_SOURCE_DIR}/lib\u0022)\n # Group headers and sources.\n # Some IDEs use this for nicer file structure.\n set(HDR_PRIVATE\n-\tlib/private-libwebsockets.h)\n+\tlib/core/private.h)\n \n set(HDR_PUBLIC\n \t\u0022${PROJECT_SOURCE_DIR}/lib/libwebsockets.h\u0022\n@@ -728,12 +728,12 @@ set(HDR_PUBLIC\n \n set(SOURCES\n \tlib/misc/base64-decode.c\n-\tlib/libwebsockets.c\n-\tlib/service.c\n-\tlib/pollfd.c\n-\tlib/output.c\n-\tlib/context.c\n-\tlib/alloc.c\n+\tlib/core/libwebsockets.c\n+\tlib/core/service.c\n+\tlib/core/pollfd.c\n+\tlib/core/output.c\n+\tlib/core/context.c\n+\tlib/core/alloc.c\n \tlib/roles/pipe/ops-pipe.c\n \tlib/misc/lws-ring.c)\n \n@@ -1645,29 +1645,6 @@ if ((LWS_ROLE_H1 OR LWS_ROLE_H2) AND NOT LWS_WITHOUT_TESTAPPS)\n \t\t\t\t\t\u0022\u0022\n \t\t\t\t\t\u0022\u0022)\n \t\t\tendif()\n-\t\t\tif (NOT ((CMAKE_C_COMPILER_ID MATCHES \u0022Clang\u0022) OR (CMAKE_CXX_COMPILER_ID MATCHES \u0022Clang\u0022))\n-\t\t\t\tAND LWS_WITH_LIBEV)\n-\t\t\t\tcreate_test_app(test-server-libev\n-\t\t\t\t\t\u0022test-apps/test-server-libev.c\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022)\n-\t\t\t\t# libev generates a big mess of warnings with gcc, maintainer claims gcc to blame\n-\t\t\t\tset_source_files_properties( test-apps/test-server-libev.c PROPERTIES COMPILE_FLAGS \u0022-Wno-error\u0022 )\n-\n-\t\t\tendif()\n-\t\t\tif (NOT ((CMAKE_C_COMPILER_ID MATCHES \u0022Clang\u0022) OR (CMAKE_CXX_COMPILER_ID MATCHES \u0022Clang\u0022))\n-\t\t\t\tAND LWS_WITH_LIBEVENT)\n-\t\t\t\tcreate_test_app(test-server-libevent\n-\t\t\t\t\t\u0022test-apps/test-server-libevent.c\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022\n-\t\t\t\t\t\u0022\u0022)\n-\t\t\tendif()\n \t\tendif()\n \n \t\t#\ndiff --git a/lib/README.md b/lib/README.md\nnew file mode 100644\nindex 0000000..d6475b8\n--- /dev/null\n+++ b/lib/README.md\n@@ -0,0 +1,14 @@\n+## Library sources layout\n+\n+Code that goes in the libwebsockets library itself lives down ./lib\n+\n+Path|Sources\n+---|---\n+lib/core|Core lws code related to generic fd and wsi servicing and management\n+lib/event-libs|Code containing optional event-lib specific adaptations\n+lib/misc|Code for various mostly optional miscellaneous features\n+lib/plat|Platform-specific adaptation code\n+lib/roles|Code for specific optional wsi roles, eg, http/1, h2, ws, raw, etc\n+lib/tls|Code supporting the various TLS libraries\n+libwebsockets.h|Public API header for the whole of lws\n+\ndiff --git a/lib/alloc.c b/lib/alloc.c\ndeleted file mode 100644\nindex e8a3766..0000000\n--- a/lib/alloc.c\n+++ /dev/null\n@@ -1,92 +0,0 @@\n-#include \u0022private-libwebsockets.h\u0022\n-\n-#if defined(LWS_PLAT_OPTEE)\n-\n-#define TEE_USER_MEM_HINT_NO_FILL_ZERO 0x80000000\n-\n-void *__attribute__((weak))\n-\tTEE_Malloc(uint32_t size, uint32_t hint)\n-{\n-\treturn NULL;\n-}\n-void *__attribute__((weak))\n-\tTEE_Realloc(void *buffer, uint32_t newSize)\n-{\n-\treturn NULL;\n-}\n-void __attribute__((weak))\n-\tTEE_Free(void *buffer)\n-{\n-}\n-\n-void *lws_realloc(void *ptr, size_t size, const char *reason)\n-{\n-\treturn TEE_Realloc(ptr, size);\n-}\n-\n-void *lws_malloc(size_t size, const char *reason)\n-{\n-\treturn TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO);\n-}\n-\n-void lws_free(void *p)\n-{\n-\tTEE_Free(p);\n-}\n-\n-void *lws_zalloc(size_t size, const char *reason)\n-{\n-\tvoid *ptr \u003d TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO);\n-\tif (ptr)\n-\t\tmemset(ptr, 0, size);\n-\treturn ptr;\n-}\n-\n-void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason))\n-{\n-\t(void)cb;\n-}\n-#else\n-\n-static void *_realloc(void *ptr, size_t size, const char *reason)\n-{\n-\tif (size) {\n-#if defined(LWS_WITH_ESP32)\n-\t\tlwsl_notice(\u0022%s: size %lu: %s (free heap %d)\u005cn\u0022, __func__,\n-\t\t\t (unsigned long)size, reason, (unsigned int)esp_get_free_heap_size() - (int)size);\n-#else\n-\t\tlwsl_debug(\u0022%s: size %lu: %s\u005cn\u0022, __func__,\n-\t\t\t (unsigned long)size, reason);\n-#endif\n-#if defined(LWS_PLAT_OPTEE)\n-\t\treturn (void *)TEE_Realloc(ptr, size);\n-#else\n-\t\treturn (void *)realloc(ptr, size);\n-#endif\n-\t}\n-\tif (ptr)\n-\t\tfree(ptr);\n-\n-\treturn NULL;\n-}\n-\n-void *(*_lws_realloc)(void *ptr, size_t size, const char *reason) \u003d _realloc;\n-\n-void *lws_realloc(void *ptr, size_t size, const char *reason)\n-{\n-\treturn _lws_realloc(ptr, size, reason);\n-}\n-\n-void *lws_zalloc(size_t size, const char *reason)\n-{\n-\tvoid *ptr \u003d _lws_realloc(NULL, size, reason);\n-\tif (ptr)\n-\t\tmemset(ptr, 0, size);\n-\treturn ptr;\n-}\n-\n-void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason))\n-{\n-\t_lws_realloc \u003d cb;\n-}\n-#endif\ndiff --git a/lib/context.c b/lib/context.c\ndeleted file mode 100644\nindex 2ccfbe9..0000000\n--- a/lib/context.c\n+++ /dev/null\n@@ -1,1957 +0,0 @@\n-/*\n- * libwebsockets - small server side websockets and web server implementation\n- *\n- * Copyright (C) 2010-2018 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This library is free software; you can redistribute it and/or\n- * modify it under the terms of the GNU Lesser General Public\n- * License as published by the Free Software Foundation:\n- * version 2.1 of the License.\n- *\n- * This library is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * Lesser General Public License for more details.\n- *\n- * You should have received a copy of the GNU Lesser General Public\n- * License along with this library; if not, write to the Free Software\n- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n- * MA 02110-1301 USA\n- */\n-\n-#include \u0022private-libwebsockets.h\u0022\n-\n-#ifndef LWS_BUILD_HASH\n-#define LWS_BUILD_HASH \u0022unknown-build-hash\u0022\n-#endif\n-\n-const struct lws_role_ops *available_roles[] \u003d {\n-#if defined(LWS_ROLE_H2)\n-\t\u0026role_ops_h2,\n-#endif\n-#if defined(LWS_ROLE_H1)\n-\t\u0026role_ops_h1,\n-#endif\n-#if defined(LWS_ROLE_WS)\n-\t\u0026role_ops_ws,\n-#endif\n-\tNULL\n-};\n-\n-const struct lws_event_loop_ops *available_event_libs[] \u003d {\n-#if defined(LWS_WITH_POLL)\n-\t\u0026event_loop_ops_poll,\n-#endif\n-#if defined(LWS_WITH_LIBUV)\n-\t\u0026event_loop_ops_uv,\n-#endif\n-#if defined(LWS_WITH_LIBEVENT)\n-\t\u0026event_loop_ops_event,\n-#endif\n-#if defined(LWS_WITH_LIBEV)\n-\t\u0026event_loop_ops_ev,\n-#endif\n-\tNULL\n-};\n-\n-static const char *library_version \u003d LWS_LIBRARY_VERSION \u0022 \u0022 LWS_BUILD_HASH;\n-\n-/**\n- * lws_get_library_version: get version and git hash library built from\n- *\n- *\treturns a const char * to a string like \u00221.1 178d78c\u0022\n- *\trepresenting the library version followed by the git head hash it\n- *\twas built from\n- */\n-LWS_VISIBLE const char *\n-lws_get_library_version(void)\n-{\n-\treturn library_version;\n-}\n-\n-int\n-lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn)\n-{\n-#if defined(LWS_WITH_TLS)\n-\tif (!alpn)\n-\t\treturn 0;\n-\n-\tlwsl_info(\u0022%s: '%s'\u005cn\u0022, __func__, alpn);\n-\n-\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)\n-\t\tif (ar-\u003ealpn \u0026\u0026 !strcmp(ar-\u003ealpn, alpn) \u0026\u0026 ar-\u003ealpn_negotiated)\n-\t\t\treturn ar-\u003ealpn_negotiated(wsi, alpn);\n-\tLWS_FOR_EVERY_AVAILABLE_ROLE_END;\n-#endif\n-\treturn 0;\n-}\n-\n-static const char * const mount_protocols[] \u003d {\n-\t\u0022http://\u0022,\n-\t\u0022https://\u0022,\n-\t\u0022file://\u0022,\n-\t\u0022cgi://\u0022,\n-\t\u0022\u003ehttp://\u0022,\n-\t\u0022\u003ehttps://\u0022,\n-\t\u0022callback://\u0022\n-};\n-\n-LWS_VISIBLE void *\n-lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,\n-\t\t\t const struct lws_protocols *prot, int size)\n-{\n-\tint n \u003d 0;\n-\n-\t/* allocate the vh priv array only on demand */\n-\tif (!vhost-\u003eprotocol_vh_privs) {\n-\t\tvhost-\u003eprotocol_vh_privs \u003d (void **)lws_zalloc(\n-\t\t\t\tvhost-\u003ecount_protocols * sizeof(void *),\n-\t\t\t\t\u0022protocol_vh_privs\u0022);\n-\t\tif (!vhost-\u003eprotocol_vh_privs)\n-\t\t\treturn NULL;\n-\t}\n-\n-\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026 \u0026vhost-\u003eprotocols[n] !\u003d prot)\n-\t\tn++;\n-\n-\tif (n \u003d\u003d vhost-\u003ecount_protocols) {\n-\t\tn \u003d 0;\n-\t\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026\n-\t\t strcmp(vhost-\u003eprotocols[n].name, prot-\u003ename))\n-\t\t\tn++;\n-\n-\t\tif (n \u003d\u003d vhost-\u003ecount_protocols)\n-\t\t\treturn NULL;\n-\t}\n-\n-\tvhost-\u003eprotocol_vh_privs[n] \u003d lws_zalloc(size, \u0022vh priv\u0022);\n-\treturn vhost-\u003eprotocol_vh_privs[n];\n-}\n-\n-LWS_VISIBLE void *\n-lws_protocol_vh_priv_get(struct lws_vhost *vhost,\n-\t\t\t const struct lws_protocols *prot)\n-{\n-\tint n \u003d 0;\n-\n-\tif (!vhost || !vhost-\u003eprotocol_vh_privs)\n-\t\treturn NULL;\n-\n-\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026 \u0026vhost-\u003eprotocols[n] !\u003d prot)\n-\t\tn++;\n-\n-\tif (n \u003d\u003d vhost-\u003ecount_protocols) {\n-\t\tn \u003d 0;\n-\t\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026\n-\t\t strcmp(vhost-\u003eprotocols[n].name, prot-\u003ename))\n-\t\t\tn++;\n-\n-\t\tif (n \u003d\u003d vhost-\u003ecount_protocols) {\n-\t\t\tlwsl_err(\u0022%s: unknown protocol %p\u005cn\u0022, __func__, prot);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\treturn vhost-\u003eprotocol_vh_privs[n];\n-}\n-\n-static const struct lws_protocol_vhost_options *\n-lws_vhost_protocol_options(struct lws_vhost *vh, const char *name)\n-{\n-\tconst struct lws_protocol_vhost_options *pvo \u003d vh-\u003epvo;\n-\n-\tif (!name)\n-\t\treturn NULL;\n-\n-\twhile (pvo) {\n-\t\tif (!strcmp(pvo-\u003ename, name))\n-\t\t\treturn pvo;\n-\t\tpvo \u003d pvo-\u003enext;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-/*\n- * inform every vhost that hasn't already done it, that\n- * his protocols are initializing\n- */\n-LWS_VISIBLE int\n-lws_protocol_init(struct lws_context *context)\n-{\n-\tstruct lws_vhost *vh \u003d context-\u003evhost_list;\n-\tconst struct lws_protocol_vhost_options *pvo, *pvo1;\n-\tstruct lws wsi;\n-\tint n, any \u003d 0;\n-\n-\tif (context-\u003edoing_protocol_init)\n-\t\treturn 0;\n-\n-\tcontext-\u003edoing_protocol_init \u003d 1;\n-\n-\tmemset(\u0026wsi, 0, sizeof(wsi));\n-\twsi.context \u003d context;\n-\n-\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n-\n-\twhile (vh) {\n-\t\twsi.vhost \u003d vh;\n-\n-\t\t/* only do the protocol init once for a given vhost */\n-\t\tif (vh-\u003ecreated_vhost_protocols ||\n-\t\t (vh-\u003eoptions \u0026 LWS_SERVER_OPTION_SKIP_PROTOCOL_INIT))\n-\t\t\tgoto next;\n-\n-\t\t/* initialize supported protocols on this vhost */\n-\n-\t\tfor (n \u003d 0; n \u003c vh-\u003ecount_protocols; n++) {\n-\t\t\twsi.protocol \u003d \u0026vh-\u003eprotocols[n];\n-\t\t\tif (!vh-\u003eprotocols[n].name)\n-\t\t\t\tcontinue;\n-\t\t\tpvo \u003d lws_vhost_protocol_options(vh,\n-\t\t\t\t\t\t\t vh-\u003eprotocols[n].name);\n-\t\t\tif (pvo) {\n-\t\t\t\t/*\n-\t\t\t\t * linked list of options specific to\n-\t\t\t\t * vh + protocol\n-\t\t\t\t */\n-\t\t\t\tpvo1 \u003d pvo;\n-\t\t\t\tpvo \u003d pvo1-\u003eoptions;\n-\n-\t\t\t\twhile (pvo) {\n-\t\t\t\t\tlwsl_debug(\n-\t\t\t\t\t\t\u0022 vhost \u005c\u0022%s\u005c\u0022, \u0022\n-\t\t\t\t\t\t\u0022protocol \u005c\u0022%s\u005c\u0022, \u0022\n-\t\t\t\t\t\t\u0022option \u005c\u0022%s\u005c\u0022\u005cn\u0022,\n-\t\t\t\t\t\t\tvh-\u003ename,\n-\t\t\t\t\t\t\tvh-\u003eprotocols[n].name,\n-\t\t\t\t\t\t\tpvo-\u003ename);\n-\n-\t\t\t\t\tif (!strcmp(pvo-\u003ename, \u0022default\u0022)) {\n-\t\t\t\t\t\tlwsl_info(\u0022Setting default \u0022\n-\t\t\t\t\t\t \u0022protocol for vh %s to %s\u005cn\u0022,\n-\t\t\t\t\t\t vh-\u003ename,\n-\t\t\t\t\t\t vh-\u003eprotocols[n].name);\n-\t\t\t\t\t\tvh-\u003edefault_protocol_index \u003d n;\n-\t\t\t\t\t}\n-\t\t\t\t\tif (!strcmp(pvo-\u003ename, \u0022raw\u0022)) {\n-\t\t\t\t\t\tlwsl_info(\u0022Setting raw \u0022\n-\t\t\t\t\t\t \u0022protocol for vh %s to %s\u005cn\u0022,\n-\t\t\t\t\t\t vh-\u003ename,\n-\t\t\t\t\t\t vh-\u003eprotocols[n].name);\n-\t\t\t\t\t\tvh-\u003eraw_protocol_index \u003d n;\n-\t\t\t\t\t}\n-\t\t\t\t\tpvo \u003d pvo-\u003enext;\n-\t\t\t\t}\n-\n-\t\t\t\tpvo \u003d pvo1-\u003eoptions;\n-\t\t\t}\n-\n-#if defined(LWS_WITH_TLS)\n-\t\t\tany |\u003d !!vh-\u003etls.ssl_ctx;\n-#endif\n-\n-\t\t\t/*\n-\t\t\t * inform all the protocols that they are doing their\n-\t\t\t * one-time initialization if they want to.\n-\t\t\t *\n-\t\t\t * NOTE the wsi is all zeros except for the context, vh\n-\t\t\t * + protocol ptrs so lws_get_context(wsi) etc can work\n-\t\t\t */\n-\t\t\tif (vh-\u003eprotocols[n].callback(\u0026wsi,\n-\t\t\t\t\tLWS_CALLBACK_PROTOCOL_INIT, NULL,\n-\t\t\t\t\t(void *)pvo, 0)) {\n-\t\t\t\tlws_free(vh-\u003eprotocol_vh_privs[n]);\n-\t\t\t\tvh-\u003eprotocol_vh_privs[n] \u003d NULL;\n-\t\t\t\tlwsl_err(\u0022%s: protocol %s failed init\u005cn\u0022, __func__,\n-\t\t\t\t\t vh-\u003eprotocols[n].name);\n-\t\t\t}\n-\t\t}\n-\n-\t\tvh-\u003ecreated_vhost_protocols \u003d 1;\n-next:\n-\t\tvh \u003d vh-\u003evhost_next;\n-\t}\n-\n-\tcontext-\u003edoing_protocol_init \u003d 0;\n-\n-\tif (!context-\u003eprotocol_init_done)\n-\t\tlws_finalize_startup(context);\n-\n-\tcontext-\u003eprotocol_init_done \u003d 1;\n-\n-\tif (any)\n-\t\tlws_tls_check_all_cert_lifetimes(context);\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE int\n-lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,\n-\t\t void *user, void *in, size_t len)\n-{\n-\tstruct lws_ssl_info *si;\n-#ifdef LWS_WITH_CGI\n-\tstruct lws_cgi_args *args;\n-#endif\n-#if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY)\n-\tchar buf[512];\n-\tint n;\n-#endif\n-\n-\tswitch (reason) {\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tcase LWS_CALLBACK_HTTP:\n-#ifndef LWS_NO_SERVER\n-\t\tif (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL))\n-\t\t\treturn -1;\n-\n-\t\tif (lws_http_transaction_completed(wsi))\n-#endif\n-\t\t\treturn -1;\n-\t\tbreak;\n-#if !defined(LWS_NO_SERVER)\n-\tcase LWS_CALLBACK_HTTP_FILE_COMPLETION:\n-\t\tif (lws_http_transaction_completed(wsi))\n-\t\t\treturn -1;\n-\t\tbreak;\n-#endif\n-\n-\tcase LWS_CALLBACK_HTTP_WRITEABLE:\n-#ifdef LWS_WITH_CGI\n-\t\tif (wsi-\u003ereason_bf \u0026 (LWS_CB_REASON_AUX_BF__CGI_HEADERS |\n-\t\t\t\t LWS_CB_REASON_AUX_BF__CGI)) {\n-\t\t\tn \u003d lws_cgi_write_split_stdout_headers(wsi);\n-\t\t\tif (n \u003c 0) {\n-\t\t\t\tlwsl_debug(\u0022AUX_BF__CGI forcing close\u005cn\u0022);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tif (!n)\n-\t\t\t\tlws_rx_flow_control(\n-\t\t\t\t\twsi-\u003ehttp.cgi-\u003estdwsi[LWS_STDOUT], 1);\n-\n-\t\t\tif (wsi-\u003ereason_bf \u0026 LWS_CB_REASON_AUX_BF__CGI_HEADERS)\n-\t\t\t\twsi-\u003ereason_bf \u0026\u003d\n-\t\t\t\t\t~LWS_CB_REASON_AUX_BF__CGI_HEADERS;\n-\t\t\telse\n-\t\t\t\twsi-\u003ereason_bf \u0026\u003d ~LWS_CB_REASON_AUX_BF__CGI;\n-\t\t\tbreak;\n-\t\t}\n-\n-\t\tif (wsi-\u003ereason_bf \u0026 LWS_CB_REASON_AUX_BF__CGI_CHUNK_END) {\n-\t\t\tif (!wsi-\u003ehttp2_substream) {\n-\t\t\t\tmemcpy(buf + LWS_PRE, \u00220\u005cx0d\u005cx0a\u005cx0d\u005cx0a\u0022, 5);\n-\t\t\t\tlwsl_debug(\u0022writing chunk term and exiting\u005cn\u0022);\n-\t\t\t\tn \u003d lws_write(wsi, (unsigned char *)buf +\n-\t\t\t\t\t\t LWS_PRE, 5, LWS_WRITE_HTTP);\n-\t\t\t} else\n-\t\t\t\tn \u003d lws_write(wsi, (unsigned char *)buf +\n-\t\t\t\t\t\t LWS_PRE, 0,\n-\t\t\t\t\t\t LWS_WRITE_HTTP_FINAL);\n-\n-\t\t\t/* always close after sending it */\n-\t\t\treturn -1;\n-\t\t}\n-#endif\n-#if defined(LWS_WITH_HTTP_PROXY)\n-\t\tif (wsi-\u003ereason_bf \u0026 LWS_CB_REASON_AUX_BF__PROXY) {\n-\t\t\tchar *px \u003d buf + LWS_PRE;\n-\t\t\tint lenx \u003d sizeof(buf) - LWS_PRE;\n-\n-\t\t\t/*\n-\t\t\t * our sink is writeable and our source has something\n-\t\t\t * to read. So read a lump of source material of\n-\t\t\t * suitable size to send or what's available, whichever\n-\t\t\t * is the smaller.\n-\t\t\t */\n-\t\t\twsi-\u003ereason_bf \u0026\u003d ~LWS_CB_REASON_AUX_BF__PROXY;\n-\t\t\tif (!lws_get_child(wsi))\n-\t\t\t\tbreak;\n-\t\t\tif (lws_http_client_read(lws_get_child(wsi), \u0026px,\n-\t\t\t\t\t\t \u0026lenx) \u003c 0)\n-\t\t\t\treturn -1;\n-\t\t\tbreak;\n-\t\t}\n-#endif\n-\t\tbreak;\n-\n-#if defined(LWS_WITH_HTTP_PROXY)\n-\tcase LWS_CALLBACK_RECEIVE_CLIENT_HTTP:\n-\t\tassert(lws_get_parent(wsi));\n-\t\tif (!lws_get_parent(wsi))\n-\t\t\tbreak;\n-\t\tlws_get_parent(wsi)-\u003ereason_bf |\u003d LWS_CB_REASON_AUX_BF__PROXY;\n-\t\tlws_callback_on_writable(lws_get_parent(wsi));\n-\t\tbreak;\n-\n-\tcase LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:\n-\t\tassert(lws_get_parent(wsi));\n-\t\tn \u003d lws_write(lws_get_parent(wsi), (unsigned char *)in,\n-\t\t\t\tlen, LWS_WRITE_HTTP);\n-\t\tif (n \u003c 0)\n-\t\t\treturn -1;\n-\t\tbreak;\n-\n-\tcase LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: {\n-\t\tunsigned char *p, *end;\n-\t\tchar ctype[64], ctlen \u003d 0;\n-\t\n-\t\tp \u003d (unsigned char *)buf + LWS_PRE;\n-\t\tend \u003d p + sizeof(buf) - LWS_PRE;\n-\n-\t\tif (lws_add_http_header_status(lws_get_parent(wsi),\n-\t\t\t\t\t HTTP_STATUS_OK, \u0026p, end))\n-\t\t\treturn 1;\n-\t\tif (lws_add_http_header_by_token(lws_get_parent(wsi),\n-\t\t\t\tWSI_TOKEN_HTTP_SERVER,\n-\t\t\t \t(unsigned char *)\u0022libwebsockets\u0022,\n-\t\t\t\t13, \u0026p, end))\n-\t\t\treturn 1;\n-\n-\t\tctlen \u003d lws_hdr_copy(wsi, ctype, sizeof(ctype),\n-\t\t\t\t WSI_TOKEN_HTTP_CONTENT_TYPE);\n-\t\tif (ctlen \u003e 0) {\n-\t\t\tif (lws_add_http_header_by_token(lws_get_parent(wsi),\n-\t\t\t\tWSI_TOKEN_HTTP_CONTENT_TYPE,\n-\t\t\t\t(unsigned char *)ctype, ctlen, \u0026p, end))\n-\t\t\t\treturn 1;\n-\t\t}\n-\n-\t\tif (lws_finalize_http_header(lws_get_parent(wsi), \u0026p, end))\n-\t\t\treturn 1;\n-\n-\t\t*p \u003d '\u005c0';\n-\t\tn \u003d lws_write(lws_get_parent(wsi),\n-\t\t\t (unsigned char *)buf + LWS_PRE,\n-\t\t\t p - ((unsigned char *)buf + LWS_PRE),\n-\t\t\t LWS_WRITE_HTTP_HEADERS);\n-\t\tif (n \u003c 0)\n-\t\t\treturn -1;\n-\n-\t\tbreak; }\n-\n-#endif\n-\n-#ifdef LWS_WITH_CGI\n-\t/* CGI IO events (POLLIN/OUT) appear here, our default policy is:\n-\t *\n-\t * - POST data goes on subprocess stdin\n-\t * - subprocess stdout goes on http via writeable callback\n-\t * - subprocess stderr goes to the logs\n-\t */\n-\tcase LWS_CALLBACK_CGI:\n-\t\targs \u003d (struct lws_cgi_args *)in;\n-\t\tswitch (args-\u003ech) { /* which of stdin/out/err ? */\n-\t\tcase LWS_STDIN:\n-\t\t\t/* TBD stdin rx flow control */\n-\t\t\tbreak;\n-\t\tcase LWS_STDOUT:\n-\t\t\t/* quench POLLIN on STDOUT until MASTER got writeable */\n-\t\t\tlws_rx_flow_control(args-\u003estdwsi[LWS_STDOUT], 0);\n-\t\t\twsi-\u003ereason_bf |\u003d LWS_CB_REASON_AUX_BF__CGI;\n-\t\t\t/* when writing to MASTER would not block */\n-\t\t\tlws_callback_on_writable(wsi);\n-\t\t\tbreak;\n-\t\tcase LWS_STDERR:\n-\t\t\tn \u003d lws_get_socket_fd(args-\u003estdwsi[LWS_STDERR]);\n-\t\t\tif (n \u003c 0)\n-\t\t\t\tbreak;\n-\t\t\tn \u003d read(n, buf, sizeof(buf) - 2);\n-\t\t\tif (n \u003e 0) {\n-\t\t\t\tif (buf[n - 1] !\u003d '\u005cn')\n-\t\t\t\t\tbuf[n++] \u003d '\u005cn';\n-\t\t\t\tbuf[n] \u003d '\u005c0';\n-\t\t\t\tlwsl_notice(\u0022CGI-stderr: %s\u005cn\u0022, buf);\n-\t\t\t}\n-\t\t\tbreak;\n-\t\t}\n-\t\tbreak;\n-\n-\tcase LWS_CALLBACK_CGI_TERMINATED:\n-\t\tlwsl_debug(\u0022LWS_CALLBACK_CGI_TERMINATED: %d %\u0022 PRIu64 \u0022\u005cn\u0022,\n-\t\t\t\twsi-\u003ehttp.cgi-\u003eexplicitly_chunked,\n-\t\t\t\t(uint64_t)wsi-\u003ehttp.cgi-\u003econtent_length);\n-\t\tif (!wsi-\u003ehttp.cgi-\u003eexplicitly_chunked \u0026\u0026\n-\t\t !wsi-\u003ehttp.cgi-\u003econtent_length) {\n-\t\t\t/* send terminating chunk */\n-\t\t\tlwsl_debug(\u0022LWS_CALLBACK_CGI_TERMINATED: ending\u005cn\u0022);\n-\t\t\twsi-\u003ereason_bf |\u003d LWS_CB_REASON_AUX_BF__CGI_CHUNK_END;\n-\t\t\tlws_callback_on_writable(wsi);\n-\t\t\tlws_set_timeout(wsi, PENDING_TIMEOUT_CGI, 3);\n-\t\t\tbreak;\n-\t\t}\n-\t\treturn -1;\n-\n-\tcase LWS_CALLBACK_CGI_STDIN_DATA: /* POST body for stdin */\n-\t\targs \u003d (struct lws_cgi_args *)in;\n-\t\targs-\u003edata[args-\u003elen] \u003d '\u005c0';\n-\t\tn \u003d lws_get_socket_fd(args-\u003estdwsi[LWS_STDIN]);\n-\t\tif (n \u003c 0)\n-\t\t\treturn -1;\n-\t\tn \u003d write(n, args-\u003edata, args-\u003elen);\n-\t\tif (n \u003c args-\u003elen)\n-\t\t\tlwsl_notice(\u0022LWS_CALLBACK_CGI_STDIN_DATA: \u0022\n-\t\t\t\t \u0022sent %d only %d went\u0022, n, args-\u003elen);\n-\t\treturn n;\n-#endif\n-#endif\n-\tcase LWS_CALLBACK_SSL_INFO:\n-\t\tsi \u003d in;\n-\n-\t\t(void)si;\n-\t\tlwsl_notice(\u0022LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\u005cn\u0022,\n-\t\t\t si-\u003ewhere, si-\u003eret);\n-\t\tbreak;\n-\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/* list of supported protocols and callbacks */\n-\n-static const struct lws_protocols protocols_dummy[] \u003d {\n-\t/* first protocol must always be HTTP handler */\n-\n-\t{\n-\t\t\u0022http-only\u0022,\t\t\t/* name */\n-\t\tlws_callback_http_dummy,\t/* callback */\n-\t\t0,\t\t\t\t/* per_session_data_size */\n-\t\t0,\t\t\t\t/* rx_buffer_size */\n-\t\t0,\t\t\t\t/* id */\n-\t\tNULL,\t\t\t\t/* user */\n-\t\t0\t\t\t\t/* tx_packet_size */\n-\t},\n-\t/*\n-\t * the other protocols are provided by lws plugins\n-\t */\n-\t{ NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */\n-};\n-\n-#ifdef LWS_PLAT_OPTEE\n-#undef LWS_HAVE_GETENV\n-#endif\n-\n-static void\n-lws_vhost_destroy2(struct lws_vhost *vh);\n-\n-LWS_VISIBLE struct lws_vhost *\n-lws_create_vhost(struct lws_context *context,\n-\t\t const struct lws_context_creation_info *info)\n-{\n-\tstruct lws_vhost *vh \u003d lws_zalloc(sizeof(*vh), \u0022create vhost\u0022),\n-\t\t\t **vh1 \u003d \u0026context-\u003evhost_list;\n-\tconst struct lws_http_mount *mounts;\n-\tconst struct lws_protocols *pcols \u003d info-\u003eprotocols;\n-\tconst struct lws_protocol_vhost_options *pvo;\n-#ifdef LWS_WITH_PLUGINS\n-\tstruct lws_plugin *plugin \u003d context-\u003eplugin_list;\n-#endif\n-\tstruct lws_protocols *lwsp;\n-\tint m, f \u003d !info-\u003epvo;\n-\tchar buf[20];\n-#if !defined(LWS_WITHOUT_CLIENT) \u0026\u0026 defined(LWS_HAVE_GETENV)\n-\tchar *p;\n-#endif\n-\tint n;\n-\n-\tif (!vh)\n-\t\treturn NULL;\n-\n-#if LWS_MAX_SMP \u003e 1\n-\tpthread_mutex_init(\u0026vh-\u003elock, NULL);\n-#endif\n-\n-\tif (!pcols)\n-\t\tpcols \u003d \u0026protocols_dummy[0];\n-\n-\tvh-\u003econtext \u003d context;\n-\tif (!info-\u003evhost_name)\n-\t\tvh-\u003ename \u003d \u0022default\u0022;\n-\telse\n-\t\tvh-\u003ename \u003d info-\u003evhost_name;\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tvh-\u003ehttp.error_document_404 \u003d info-\u003eerror_document_404;\n-#endif\n-\n-\tif (info-\u003eoptions \u0026 LWS_SERVER_OPTION_ONLY_RAW)\n-\t\tlwsl_info(\u0022%s set to only support RAW\u005cn\u0022, vh-\u003ename);\n-\n-\tvh-\u003eiface \u003d info-\u003eiface;\n-#if !defined(LWS_WITH_ESP32) \u0026\u0026 \u005c\n- !defined(OPTEE_TA) \u0026\u0026 !defined(WIN32)\n-\tvh-\u003ebind_iface \u003d info-\u003ebind_iface;\n-#endif\n-\n-\tfor (vh-\u003ecount_protocols \u003d 0;\n-\t pcols[vh-\u003ecount_protocols].callback;\n-\t vh-\u003ecount_protocols++)\n-\t\t;\n-\n-\tvh-\u003eoptions \u003d info-\u003eoptions;\n-\tvh-\u003epvo \u003d info-\u003epvo;\n-\tvh-\u003eheaders \u003d info-\u003eheaders;\n-\tvh-\u003euser \u003d info-\u003euser;\n-\n-\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)\n-\t\tif (ar-\u003einit_vhost)\n-\t\t\tif (ar-\u003einit_vhost(vh, info))\n-\t\t\t\treturn NULL;\n-\tLWS_FOR_EVERY_AVAILABLE_ROLE_END;\n-\n-\n-\tif (info-\u003ekeepalive_timeout)\n-\t\tvh-\u003ekeepalive_timeout \u003d info-\u003ekeepalive_timeout;\n-\telse\n-\t\tvh-\u003ekeepalive_timeout \u003d 5;\n-\n-\tif (info-\u003etimeout_secs_ah_idle)\n-\t\tvh-\u003etimeout_secs_ah_idle \u003d info-\u003etimeout_secs_ah_idle;\n-\telse\n-\t\tvh-\u003etimeout_secs_ah_idle \u003d 10;\n-\n-#if defined(LWS_WITH_TLS)\n-\n-\tvh-\u003etls.alpn \u003d info-\u003ealpn;\n-\tvh-\u003etls.ssl_info_event_mask \u003d info-\u003essl_info_event_mask;\n-\n-\tif (info-\u003eecdh_curve)\n-\t\tlws_strncpy(vh-\u003etls.ecdh_curve, info-\u003eecdh_curve,\n-\t\t\t sizeof(vh-\u003etls.ecdh_curve));\n-\n-\t/* carefully allocate and take a copy of cert + key paths if present */\n-\tn \u003d 0;\n-\tif (info-\u003essl_cert_filepath)\n-\t\tn +\u003d (int)strlen(info-\u003essl_cert_filepath) + 1;\n-\tif (info-\u003essl_private_key_filepath)\n-\t\tn +\u003d (int)strlen(info-\u003essl_private_key_filepath) + 1;\n-\n-\tif (n) {\n-\t\tvh-\u003etls.key_path \u003d vh-\u003etls.alloc_cert_path \u003d lws_malloc(n, \u0022vh paths\u0022);\n-\t\tif (info-\u003essl_cert_filepath) {\n-\t\t\tn \u003d (int)strlen(info-\u003essl_cert_filepath) + 1;\n-\t\t\tmemcpy(vh-\u003etls.alloc_cert_path, info-\u003essl_cert_filepath, n);\n-\t\t\tvh-\u003etls.key_path +\u003d n;\n-\t\t}\n-\t\tif (info-\u003essl_private_key_filepath)\n-\t\t\tmemcpy(vh-\u003etls.key_path, info-\u003essl_private_key_filepath,\n-\t\t\t strlen(info-\u003essl_private_key_filepath) + 1);\n-\t}\n-#endif\n-\n-\t/*\n-\t * give the vhost a unified list of protocols including the\n-\t * ones that came from plugins\n-\t */\n-\tlwsp \u003d lws_zalloc(sizeof(struct lws_protocols) * (vh-\u003ecount_protocols +\n-\t\t\t\t context-\u003eplugin_protocol_count + 1),\n-\t\t\t\t \u0022vhost-specific plugin table\u0022);\n-\tif (!lwsp) {\n-\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n-\t\treturn NULL;\n-\t}\n-\n-\tm \u003d vh-\u003ecount_protocols;\n-\tmemcpy(lwsp, pcols, sizeof(struct lws_protocols) * m);\n-\n-\t/* for compatibility, all protocols enabled on vhost if only\n-\t * the default vhost exists. Otherwise only vhosts who ask\n-\t * for a protocol get it enabled.\n-\t */\n-\n-\tif (context-\u003eoptions \u0026 LWS_SERVER_OPTION_EXPLICIT_VHOSTS)\n-\t\tf \u003d 0;\n-\t(void)f;\n-#ifdef LWS_WITH_PLUGINS\n-\tif (plugin) {\n-\n-\t\twhile (plugin) {\n-\t\t\tfor (n \u003d 0; n \u003c plugin-\u003ecaps.count_protocols; n++) {\n-\t\t\t\t/*\n-\t\t\t\t * for compatibility's sake, no pvo implies\n-\t\t\t\t * allow all protocols\n-\t\t\t\t */\n-\t\t\t\tif (f || lws_vhost_protocol_options(vh,\n-\t\t\t\t plugin-\u003ecaps.protocols[n].name)) {\n-\t\t\t\t\tmemcpy(\u0026lwsp[m],\n-\t\t\t\t\t \u0026plugin-\u003ecaps.protocols[n],\n-\t\t\t\t\t sizeof(struct lws_protocols));\n-\t\t\t\t\tm++;\n-\t\t\t\t\tvh-\u003ecount_protocols++;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tplugin \u003d plugin-\u003elist;\n-\t\t}\n-\t}\n-#endif\n-\n-\tif (\n-#ifdef LWS_WITH_PLUGINS\n-\t (context-\u003eplugin_list) ||\n-#endif\n-\t context-\u003eoptions \u0026 LWS_SERVER_OPTION_EXPLICIT_VHOSTS)\n-\t\tvh-\u003eprotocols \u003d lwsp;\n-\telse {\n-\t\tvh-\u003eprotocols \u003d pcols;\n-\t\tlws_free(lwsp);\n-\t}\n-\n-\tvh-\u003esame_vh_protocol_list \u003d (struct lws **)\n-\t\t\tlws_zalloc(sizeof(struct lws *) * vh-\u003ecount_protocols,\n-\t\t\t\t \u0022same vh list\u0022);\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tvh-\u003ehttp.mount_list \u003d info-\u003emounts;\n-#endif\n-\n-#ifdef LWS_WITH_UNIX_SOCK\n-\tif (LWS_UNIX_SOCK_ENABLED(context)) {\n-\t\tlwsl_notice(\u0022Creating Vhost '%s' path \u005c\u0022%s\u005c\u0022, %d protocols\u005cn\u0022,\n-\t\t\t\tvh-\u003ename, vh-\u003eiface, vh-\u003ecount_protocols);\n-\t} else\n-#endif\n-\t{\n-\t\tswitch(info-\u003eport) {\n-\t\tcase CONTEXT_PORT_NO_LISTEN:\n-\t\t\tstrcpy(buf, \u0022(serving disabled)\u0022);\n-\t\t\tbreak;\n-\t\tcase CONTEXT_PORT_NO_LISTEN_SERVER:\n-\t\t\tstrcpy(buf, \u0022(no listener)\u0022);\n-\t\t\tbreak;\n-\t\tdefault:\n-\t\t\tlws_snprintf(buf, sizeof(buf), \u0022port %u\u0022, info-\u003eport);\n-\t\t\tbreak;\n-\t\t}\n-\t\tlwsl_notice(\u0022Creating Vhost '%s' %s, %d protocols, IPv6 %s\u005cn\u0022,\n-\t\t\t\tvh-\u003ename, buf, vh-\u003ecount_protocols,\n-\t\t\t\tLWS_IPV6_ENABLED(vh) ? \u0022on\u0022 : \u0022off\u0022);\n-\t}\n-\tmounts \u003d info-\u003emounts;\n-\twhile (mounts) {\n-\t\t(void)mount_protocols[0];\n-\t\tlwsl_info(\u0022 mounting %s%s to %s\u005cn\u0022,\n-\t\t\t mount_protocols[mounts-\u003eorigin_protocol],\n-\t\t\t mounts-\u003eorigin, mounts-\u003emountpoint);\n-\n-\t\t/* convert interpreter protocol names to pointers */\n-\t\tpvo \u003d mounts-\u003einterpret;\n-\t\twhile (pvo) {\n-\t\t\tfor (n \u003d 0; n \u003c vh-\u003ecount_protocols; n++) {\n-\t\t\t\tif (strcmp(pvo-\u003evalue, vh-\u003eprotocols[n].name))\n-\t\t\t\t\tcontinue;\n-\t\t\t\t((struct lws_protocol_vhost_options *)pvo)-\u003e\n-\t\t\t\t\tvalue \u003d (const char *)(lws_intptr_t)n;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tif (n \u003d\u003d vh-\u003ecount_protocols)\n-\t\t\t\tlwsl_err(\u0022ignoring unknown interp pr %s\u005cn\u0022,\n-\t\t\t\t\t pvo-\u003evalue);\n-\t\t\tpvo \u003d pvo-\u003enext;\n-\t\t}\n-\n-\t\tmounts \u003d mounts-\u003emount_next;\n-\t}\n-\n-\tvh-\u003elisten_port \u003d info-\u003eport;\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tvh-\u003ehttp.http_proxy_port \u003d 0;\n-\tvh-\u003ehttp.http_proxy_address[0] \u003d '\u005c0';\n-#endif\n-#if defined(LWS_WITH_SOCKS5)\n-\tvh-\u003esocks_proxy_port \u003d 0;\n-\tvh-\u003esocks_proxy_address[0] \u003d '\u005c0';\n-#endif\n-\n-#if !defined(LWS_WITHOUT_CLIENT)\n-\t/* either use proxy from info, or try get it from env var */\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\t/* http proxy */\n-\tif (info-\u003ehttp_proxy_address) {\n-\t\t/* override for backwards compatibility */\n-\t\tif (info-\u003ehttp_proxy_port)\n-\t\t\tvh-\u003ehttp.http_proxy_port \u003d info-\u003ehttp_proxy_port;\n-\t\tlws_set_proxy(vh, info-\u003ehttp_proxy_address);\n-\t} else\n-#endif\n-\t{\n-#ifdef LWS_HAVE_GETENV\n-\t\tp \u003d getenv(\u0022http_proxy\u0022);\n-\t\tif (p)\n-\t\t\tlws_set_proxy(vh, p);\n-#endif\n-\t}\n-#endif\n-#if defined(LWS_WITH_SOCKS5)\n-\t/* socks proxy */\n-\tif (info-\u003esocks_proxy_address) {\n-\t\t/* override for backwards compatibility */\n-\t\tif (info-\u003esocks_proxy_port)\n-\t\t\tvh-\u003esocks_proxy_port \u003d info-\u003esocks_proxy_port;\n-\t\tlws_set_socks(vh, info-\u003esocks_proxy_address);\n-\t} else {\n-#ifdef LWS_HAVE_GETENV\n-\t\tp \u003d getenv(\u0022socks_proxy\u0022);\n-\t\tif (p)\n-\t\t\tlws_set_socks(vh, p);\n-#endif\n-\t}\n-#endif\n-\n-\tvh-\u003eka_time \u003d info-\u003eka_time;\n-\tvh-\u003eka_interval \u003d info-\u003eka_interval;\n-\tvh-\u003eka_probes \u003d info-\u003eka_probes;\n-\n-\tif (vh-\u003eoptions \u0026 LWS_SERVER_OPTION_STS)\n-\t\tlwsl_notice(\u0022 STS enabled\u005cn\u0022);\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-\tif (info-\u003elog_filepath) {\n-\t\tvh-\u003elog_fd \u003d open(info-\u003elog_filepath,\n-\t\t\t\t O_CREAT | O_APPEND | O_RDWR, 0600);\n-\t\tif (vh-\u003elog_fd \u003d\u003d (int)LWS_INVALID_FILE) {\n-\t\t\tlwsl_err(\u0022unable to open log filepath %s\u005cn\u0022,\n-\t\t\t\t info-\u003elog_filepath);\n-\t\t\tgoto bail;\n-\t\t}\n-#ifndef WIN32\n-\t\tif (context-\u003euid !\u003d -1)\n-\t\t\tif (chown(info-\u003elog_filepath, context-\u003euid,\n-\t\t\t\t context-\u003egid) \u003d\u003d -1)\n-\t\t\t\tlwsl_err(\u0022unable to chown log file %s\u005cn\u0022,\n-\t\t\t\t\t\tinfo-\u003elog_filepath);\n-#endif\n-\t} else\n-\t\tvh-\u003elog_fd \u003d (int)LWS_INVALID_FILE;\n-#endif\n-\tif (lws_context_init_server_ssl(info, vh)) {\n-\t\tlwsl_err(\u0022%s: lws_context_init_server_ssl failed\u005cn\u0022, __func__);\n-\t\tgoto bail1;\n-\t}\n-\tif (lws_context_init_client_ssl(info, vh)) {\n-\t\tlwsl_err(\u0022%s: lws_context_init_client_ssl failed\u005cn\u0022, __func__);\n-\t\tgoto bail1;\n-\t}\n-\tlws_context_lock(context);\n-\tn \u003d _lws_vhost_init_server(info, vh);\n-\tlws_context_unlock(context);\n-\tif (n \u003c 0) {\n-\t\tlwsl_err(\u0022init server failed\u005cn\u0022);\n-\t\tgoto bail1;\n-\t}\n-\n-\n-\twhile (1) {\n-\t\tif (!(*vh1)) {\n-\t\t\t*vh1 \u003d vh;\n-\t\t\tbreak;\n-\t\t}\n-\t\tvh1 \u003d \u0026(*vh1)-\u003evhost_next;\n-\t};\n-\n-\t/* for the case we are adding a vhost much later, after server init */\n-\n-\tif (context-\u003eprotocol_init_done)\n-\t\tif (lws_protocol_init(context)) {\n-\t\t\tlwsl_err(\u0022%s: lws_protocol_init failed\u005cn\u0022, __func__);\n-\t\t\tgoto bail1;\n-\t\t}\n-\n-\treturn vh;\n-\n-bail1:\n-\tlws_vhost_destroy(vh);\n-\tlws_vhost_destroy2(vh);\n-\n-\treturn NULL;\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-bail:\n-\tlws_free(vh);\n-#endif\n-\n-\treturn NULL;\n-}\n-\n-LWS_VISIBLE int\n-lws_init_vhost_client_ssl(const struct lws_context_creation_info *info,\n-\t\t\t struct lws_vhost *vhost)\n-{\n-\tstruct lws_context_creation_info i;\n-\n-\tmemcpy(\u0026i, info, sizeof(i));\n-\ti.port \u003d CONTEXT_PORT_NO_LISTEN;\n-\n-\treturn lws_context_init_client_ssl(\u0026i, vhost);\n-}\n-\n-LWS_VISIBLE void\n-lws_cancel_service_pt(struct lws *wsi)\n-{\n-\tlws_plat_pipe_signal(wsi);\n-}\n-\n-LWS_VISIBLE void\n-lws_cancel_service(struct lws_context *context)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n-\tshort m \u003d context-\u003ecount_threads;\n-\n-\tif (context-\u003ebeing_destroyed1)\n-\t\treturn;\n-\n-\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n-\n-\twhile (m--) {\n-\t\tif (pt-\u003epipe_wsi)\n-\t\t\tlws_plat_pipe_signal(pt-\u003epipe_wsi);\n-\t\tpt++;\n-\t}\n-}\n-\n-int\n-lws_create_event_pipes(struct lws_context *context)\n-{\n-\tstruct lws *wsi;\n-\tint n;\n-\n-\t/*\n-\t * Create the pt event pipes... these are unique in that they are\n-\t * not bound to a vhost or protocol (both are NULL)\n-\t */\n-\n-\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\tif (context-\u003ept[n].pipe_wsi)\n-\t\t\tcontinue;\n-\n-\t\twsi \u003d lws_zalloc(sizeof(*wsi), \u0022event pipe wsi\u0022);\n-\t\tif (!wsi) {\n-\t\t\tlwsl_err(\u0022Out of mem\u005cn\u0022);\n-\t\t\treturn 1;\n-\t\t}\n-\t\twsi-\u003econtext \u003d context;\n-\t\tlws_role_transition(wsi, 0, LRS_UNCONNECTED, \u0026role_ops_pipe);\n-\t\twsi-\u003eprotocol \u003d NULL;\n-\t\twsi-\u003etsi \u003d n;\n-\t\twsi-\u003evhost \u003d NULL;\n-\t\twsi-\u003eevent_pipe \u003d 1;\n-\n-\t\tif (lws_plat_pipe_create(wsi)) {\n-\t\t\tlws_free(wsi);\n-\t\t\tcontinue;\n-\t\t}\n-\t\twsi-\u003edesc.sockfd \u003d context-\u003ept[n].dummy_pipe_fds[0];\n-\t\tlwsl_debug(\u0022event pipe fd %d\u005cn\u0022, wsi-\u003edesc.sockfd);\n-\n-\t\tcontext-\u003ept[n].pipe_wsi \u003d wsi;\n-\n-\t\tif (context-\u003eevent_loop_ops-\u003eaccept)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003eaccept(wsi);\n-\n-\t\tif (__insert_wsi_socket_into_fds(context, wsi))\n-\t\t\treturn 1;\n-\n-\t\t//lws_change_pollfd(context-\u003ept[n].pipe_wsi, 0, LWS_POLLIN);\n-\t\tcontext-\u003ecount_wsi_allocated++;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-void\n-lws_destroy_event_pipe(struct lws *wsi)\n-{\n-\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n-\t__remove_wsi_socket_from_fds(wsi);\n-\n-\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close) {\n-\t\twsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close(wsi);\n-\t\tlws_plat_pipe_close(wsi);\n-\t\treturn;\n-\t}\n-\n-\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi)\n-\t\twsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi(wsi);\n-\tlws_plat_pipe_close(wsi);\n-\twsi-\u003econtext-\u003ecount_wsi_allocated--;\n-\tlws_free(wsi);\n-}\n-\n-LWS_VISIBLE struct lws_context *\n-lws_create_context(const struct lws_context_creation_info *info)\n-{\n-\tstruct lws_context *context \u003d NULL;\n-\tstruct lws_plat_file_ops *prev;\n-#ifndef LWS_NO_DAEMONIZE\n-\tint pid_daemon \u003d get_daemonize_pid();\n-#endif\n-\tint n;\n-#if defined(__ANDROID__)\n-\tstruct rlimit rt;\n-#endif\n-\n-\n-\n-\tlwsl_info(\u0022Initial logging level %d\u005cn\u0022, log_level);\n-\tlwsl_info(\u0022Libwebsockets version: %s\u005cn\u0022, library_version);\n-#if defined(GCC_VER)\n-\tlwsl_info(\u0022Compiled with %s\u005cn\u0022, GCC_VER);\n-#endif\n-\n-#ifdef LWS_WITH_IPV6\n-\tif (!lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_DISABLE_IPV6))\n-\t\tlwsl_info(\u0022IPV6 compiled in and enabled\u005cn\u0022);\n-\telse\n-\t\tlwsl_info(\u0022IPV6 compiled in but disabled\u005cn\u0022);\n-#else\n-\tlwsl_info(\u0022IPV6 not compiled in\u005cn\u0022);\n-#endif\n-\n-\tlwsl_info(\u0022 LWS_DEF_HEADER_LEN : %u\u005cn\u0022, LWS_DEF_HEADER_LEN);\n-\tlwsl_info(\u0022 LWS_MAX_PROTOCOLS : %u\u005cn\u0022, LWS_MAX_PROTOCOLS);\n-\tlwsl_info(\u0022 LWS_MAX_SMP : %u\u005cn\u0022, LWS_MAX_SMP);\n-\tlwsl_info(\u0022 sizeof (*info) : %ld\u005cn\u0022, (long)sizeof(*info));\n-#if defined(LWS_WITH_STATS)\n-\tlwsl_info(\u0022 LWS_WITH_STATS : on\u005cn\u0022);\n-#endif\n-\tlwsl_info(\u0022 SYSTEM_RANDOM_FILEPATH: '%s'\u005cn\u0022, SYSTEM_RANDOM_FILEPATH);\n-#if defined(LWS_WITH_HTTP2)\n-\tlwsl_info(\u0022 HTTP2 support : available\u005cn\u0022);\n-#else\n-\tlwsl_info(\u0022 HTTP2 support : not configured\u005cn\u0022);\n-#endif\n-\tif (lws_plat_context_early_init())\n-\t\treturn NULL;\n-\n-\tcontext \u003d lws_zalloc(sizeof(struct lws_context), \u0022context\u0022);\n-\tif (!context) {\n-\t\tlwsl_err(\u0022No memory for websocket context\u005cn\u0022);\n-\t\treturn NULL;\n-\t}\n-\n-#if defined(LWS_WITH_TLS)\n-#if defined(LWS_WITH_MBEDTLS)\n-\tcontext-\u003etls_ops \u003d \u0026tls_ops_mbedtls;\n-#else\n-\tcontext-\u003etls_ops \u003d \u0026tls_ops_openssl;\n-#endif\n-#endif\n-\n-\tif (info-\u003ept_serv_buf_size)\n-\t\tcontext-\u003ept_serv_buf_size \u003d info-\u003ept_serv_buf_size;\n-\telse\n-\t\tcontext-\u003ept_serv_buf_size \u003d 4096;\n-\n-#if defined(LWS_ROLE_H2)\n-\trole_ops_h2.init_context(context, info);\n-#endif\n-\n-#if LWS_MAX_SMP \u003e 1\n-\tpthread_mutex_init(\u0026context-\u003elock, NULL);\n-#endif\n-\n-#if defined(LWS_WITH_ESP32)\n-\tcontext-\u003elast_free_heap \u003d esp_get_free_heap_size();\n-#endif\n-\n-\t/* default to just the platform fops implementation */\n-\n-\tcontext-\u003efops_platform.LWS_FOP_OPEN\t\u003d _lws_plat_file_open;\n-\tcontext-\u003efops_platform.LWS_FOP_CLOSE\t\u003d _lws_plat_file_close;\n-\tcontext-\u003efops_platform.LWS_FOP_SEEK_CUR\t\u003d _lws_plat_file_seek_cur;\n-\tcontext-\u003efops_platform.LWS_FOP_READ\t\u003d _lws_plat_file_read;\n-\tcontext-\u003efops_platform.LWS_FOP_WRITE\t\u003d _lws_plat_file_write;\n-\tcontext-\u003efops_platform.fi[0].sig\t\u003d NULL;\n-\n-\t/*\n-\t * arrange a linear linked-list of fops starting from context-\u003efops\n-\t *\n-\t * platform fops\n-\t * [ -\u003e fops_zip (copied into context so .next settable) ]\n-\t * [ -\u003e info-\u003efops ]\n-\t */\n-\n-\tcontext-\u003efops \u003d \u0026context-\u003efops_platform;\n-\tprev \u003d (struct lws_plat_file_ops *)context-\u003efops;\n-\n-#if defined(LWS_WITH_ZIP_FOPS)\n-\t/* make a soft copy so we can set .next */\n-\tcontext-\u003efops_zip \u003d fops_zip;\n-\tprev-\u003enext \u003d \u0026context-\u003efops_zip;\n-\tprev \u003d (struct lws_plat_file_ops *)prev-\u003enext;\n-#endif\n-\n-\t/* if user provided fops, tack them on the end of the list */\n-\tif (info-\u003efops)\n-\t\tprev-\u003enext \u003d info-\u003efops;\n-\n-\tcontext-\u003ereject_service_keywords \u003d info-\u003ereject_service_keywords;\n-\tif (info-\u003eexternal_baggage_free_on_destroy)\n-\t\tcontext-\u003eexternal_baggage_free_on_destroy \u003d\n-\t\t\tinfo-\u003eexternal_baggage_free_on_destroy;\n-\n-\tcontext-\u003etime_up \u003d time(NULL);\n-\tcontext-\u003epcontext_finalize \u003d info-\u003epcontext;\n-\n-\tcontext-\u003esimultaneous_ssl_restriction \u003d\n-\t\t\tinfo-\u003esimultaneous_ssl_restriction;\n-\n-#ifndef LWS_NO_DAEMONIZE\n-\tif (pid_daemon) {\n-\t\tcontext-\u003estarted_with_parent \u003d pid_daemon;\n-\t\tlwsl_info(\u0022 Started with daemon pid %d\u005cn\u0022, pid_daemon);\n-\t}\n-#endif\n-#if defined(__ANDROID__)\n-\t\tn \u003d getrlimit ( RLIMIT_NOFILE,\u0026rt);\n-\t\tif (-1 \u003d\u003d n) {\n-\t\t\tlwsl_err(\u0022Get RLIMIT_NOFILE failed!\u005cn\u0022);\n-\t\t\treturn NULL;\n-\t\t}\n-\t\tcontext-\u003emax_fds \u003d rt.rlim_cur;\n-#else\n-\t\tcontext-\u003emax_fds \u003d getdtablesize();\n-#endif\n-\n-\tif (info-\u003ecount_threads)\n-\t\tcontext-\u003ecount_threads \u003d info-\u003ecount_threads;\n-\telse\n-\t\tcontext-\u003ecount_threads \u003d 1;\n-\n-\tif (context-\u003ecount_threads \u003e LWS_MAX_SMP)\n-\t\tcontext-\u003ecount_threads \u003d LWS_MAX_SMP;\n-\n-\tcontext-\u003etoken_limits \u003d info-\u003etoken_limits;\n-\n-\tcontext-\u003eoptions \u003d info-\u003eoptions;\n-\n-\t/*\n-\t * set the context event loops ops struct\n-\t *\n-\t * after this, all event_loop actions use the generic ops\n-\t */\n-\n-#if defined(LWS_WITH_POLL)\n-\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_poll;\n-#endif\n-\n-\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_LIBUV))\n-#if defined(LWS_WITH_LIBUV)\n-\t\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_uv;\n-#else\n-\t\tgoto fail_event_libs;\n-#endif\n-\n-\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_LIBEV))\n-#if defined(LWS_WITH_LIBEV)\n-\t\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_ev;\n-#else\n-\t\tgoto fail_event_libs;\n-#endif\n-\n-\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_LIBEVENT))\n-#if defined(LWS_WITH_LIBEVENT)\n-\t\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_event;\n-#else\n-\t\tgoto fail_event_libs;\n-#endif\n-\n-\tif (!context-\u003eevent_loop_ops)\n-\t\tgoto fail_event_libs;\n-\n-\tlwsl_info(\u0022Using event loop: %s\u005cn\u0022, context-\u003eevent_loop_ops-\u003ename);\n-\n-#if defined(LWS_WITH_TLS)\n-\ttime(\u0026context-\u003etls.last_cert_check_s);\n-\tif (info-\u003ealpn)\n-\t\tcontext-\u003etls.alpn_default \u003d info-\u003ealpn;\n-\telse {\n-\t\tchar *p \u003d context-\u003etls.alpn_discovered, first \u003d 1;\n-\n-\t\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) {\n-\t\t\tif (ar-\u003ealpn) {\n-\t\t\t\tif (!first)\n-\t\t\t\t\t*p++ \u003d ',';\n-\t\t\t\tp +\u003d lws_snprintf(p,\n-\t\t\t\t\tcontext-\u003etls.alpn_discovered +\n-\t\t\t\t\tsizeof(context-\u003etls.alpn_discovered) -\n-\t\t\t\t\t2 - p, \u0022%s\u0022, ar-\u003ealpn);\n-\t\t\t\tfirst \u003d 0;\n-\t\t\t}\n-\t\t} LWS_FOR_EVERY_AVAILABLE_ROLE_END;\n-\n-\t\tcontext-\u003etls.alpn_default \u003d context-\u003etls.alpn_discovered;\n-\t}\n-\n-\tlwsl_info(\u0022Default ALPN advertisment: %s\u005cn\u0022, context-\u003etls.alpn_default);\n-#endif\n-\n-\tif (info-\u003etimeout_secs)\n-\t\tcontext-\u003etimeout_secs \u003d info-\u003etimeout_secs;\n-\telse\n-\t\tcontext-\u003etimeout_secs \u003d AWAITING_TIMEOUT;\n-\n-\tcontext-\u003ews_ping_pong_interval \u003d info-\u003ews_ping_pong_interval;\n-\n-\tlwsl_info(\u0022 default timeout (secs): %u\u005cn\u0022, context-\u003etimeout_secs);\n-\n-\tif (info-\u003emax_http_header_data)\n-\t\tcontext-\u003emax_http_header_data \u003d info-\u003emax_http_header_data;\n-\telse\n-\t\tif (info-\u003emax_http_header_data2)\n-\t\t\tcontext-\u003emax_http_header_data \u003d\n-\t\t\t\t\tinfo-\u003emax_http_header_data2;\n-\t\telse\n-\t\t\tcontext-\u003emax_http_header_data \u003d LWS_DEF_HEADER_LEN;\n-\n-\tif (info-\u003emax_http_header_pool)\n-\t\tcontext-\u003emax_http_header_pool \u003d info-\u003emax_http_header_pool;\n-\telse\n-\t\tcontext-\u003emax_http_header_pool \u003d context-\u003emax_fds;\n-\n-\tif (info-\u003efd_limit_per_thread)\n-\t\tcontext-\u003efd_limit_per_thread \u003d info-\u003efd_limit_per_thread;\n-\telse\n-\t\tcontext-\u003efd_limit_per_thread \u003d context-\u003emax_fds /\n-\t\t\t\t\t context-\u003ecount_threads;\n-\n-\t/*\n-\t * Allocate the per-thread storage for scratchpad buffers,\n-\t * and header data pool\n-\t */\n-\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\tcontext-\u003ept[n].serv_buf \u003d lws_malloc(context-\u003ept_serv_buf_size,\n-\t\t\t\t\t\t \u0022pt_serv_buf\u0022);\n-\t\tif (!context-\u003ept[n].serv_buf) {\n-\t\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n-\t\t\treturn NULL;\n-\t\t}\n-\n-\t\tcontext-\u003ept[n].context \u003d context;\n-\t\tcontext-\u003ept[n].tid \u003d n;\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\t\tcontext-\u003ept[n].http.ah_list \u003d NULL;\n-\t\tcontext-\u003ept[n].http.ah_pool_length \u003d 0;\n-#endif\n-\t\tlws_pt_mutex_init(\u0026context-\u003ept[n]);\n-\t}\n-\n-\tlwsl_info(\u0022 Threads: %d each %d fds\u005cn\u0022, context-\u003ecount_threads,\n-\t\t context-\u003efd_limit_per_thread);\n-\n-\tif (!info-\u003eka_interval \u0026\u0026 info-\u003eka_time \u003e 0) {\n-\t\tlwsl_err(\u0022info-\u003eka_interval can't be 0 if ka_time used\u005cn\u0022);\n-\t\treturn NULL;\n-\t}\n-\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\t/* scale the peer hash table according to the max fds for the process,\n-\t * so that the max list depth averages 16. Eg, 1024 fd -\u003e 64,\n-\t * 102400 fd -\u003e 6400\n-\t */\n-\tcontext-\u003epl_hash_elements \u003d\n-\t\t(context-\u003ecount_threads * context-\u003efd_limit_per_thread) / 16;\n-\tcontext-\u003epl_hash_table \u003d lws_zalloc(sizeof(struct lws_peer *) *\n-\t\t\tcontext-\u003epl_hash_elements, \u0022peer limits hash table\u0022);\n-\tcontext-\u003eip_limit_ah \u003d info-\u003eip_limit_ah;\n-\tcontext-\u003eip_limit_wsi \u003d info-\u003eip_limit_wsi;\n-#endif\n-\n-\tlwsl_info(\u0022 mem: context: %5lu B (%ld ctx + (%ld thr x %d))\u005cn\u0022,\n-\t\t (long)sizeof(struct lws_context) +\n-\t\t (context-\u003ecount_threads * context-\u003ept_serv_buf_size),\n-\t\t (long)sizeof(struct lws_context),\n-\t\t (long)context-\u003ecount_threads,\n-\t\t context-\u003ept_serv_buf_size);\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tlwsl_info(\u0022 mem: http hdr rsvd: %5lu B (%u thr x (%u + %lu) x %u))\u005cn\u0022,\n-\t\t (long)(context-\u003emax_http_header_data +\n-\t\t sizeof(struct allocated_headers)) *\n-\t\t context-\u003emax_http_header_pool * context-\u003ecount_threads,\n-\t\t context-\u003ecount_threads,\n-\t\t context-\u003emax_http_header_data,\n-\t\t (long)sizeof(struct allocated_headers),\n-\t\t context-\u003emax_http_header_pool);\n-#endif\n-\tn \u003d sizeof(struct lws_pollfd) * context-\u003ecount_threads *\n-\t context-\u003efd_limit_per_thread;\n-\tcontext-\u003ept[0].fds \u003d lws_zalloc(n, \u0022fds table\u0022);\n-\tif (context-\u003ept[0].fds \u003d\u003d NULL) {\n-\t\tlwsl_err(\u0022OOM allocating %d fds\u005cn\u0022, context-\u003emax_fds);\n-\t\tgoto bail;\n-\t}\n-\tlwsl_info(\u0022 mem: pollfd map: %5u\u005cn\u0022, n);\n-\n-\tif (info-\u003eserver_string) {\n-\t\tcontext-\u003eserver_string \u003d info-\u003eserver_string;\n-\t\tcontext-\u003eserver_string_len \u003d (short)\n-\t\t\t\tstrlen(context-\u003eserver_string);\n-\t}\n-\n-#if LWS_MAX_SMP \u003e 1\n-\t/* each thread serves his own chunk of fds */\n-\tfor (n \u003d 1; n \u003c (int)info-\u003ecount_threads; n++)\n-\t\tcontext-\u003ept[n].fds \u003d context-\u003ept[n - 1].fds +\n-\t\t\t\t context-\u003efd_limit_per_thread;\n-#endif\n-\n-\tif (lws_plat_init(context, info))\n-\t\tgoto bail;\n-\n-\tif (context-\u003eevent_loop_ops-\u003einit_context)\n-\t\tif (context-\u003eevent_loop_ops-\u003einit_context(context, info))\n-\t\t\tgoto bail;\n-\n-\n-\tif (context-\u003eevent_loop_ops-\u003einit_pt)\n-\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\t\tvoid *lp \u003d NULL;\n-\n-\t\t\tif (info-\u003eforeign_loops)\n-\t\t\t\tlp \u003d info-\u003eforeign_loops[n];\n-\n-\t\t\tif (context-\u003eevent_loop_ops-\u003einit_pt(context, lp, n))\n-\t\t\t\tgoto bail;\n-\t\t}\n-\n-\tif (lws_create_event_pipes(context))\n-\t\tgoto bail;\n-\n-\tlws_context_init_ssl_library(info);\n-\n-\tcontext-\u003euser_space \u003d info-\u003euser;\n-\n-\t/*\n-\t * if he's not saying he'll make his own vhosts later then act\n-\t * compatibly and make a default vhost using the data in the info\n-\t */\n-\tif (!lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n-\t\tif (!lws_create_vhost(context, info)) {\n-\t\t\tlwsl_err(\u0022Failed to create default vhost\u005cn\u0022);\n-\t\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++)\n-\t\t\t\tlws_free_set_NULL(context-\u003ept[n].serv_buf);\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\t\t\tlws_free_set_NULL(context-\u003epl_hash_table);\n-#endif\n-\t\t\tlws_free_set_NULL(context-\u003ept[0].fds);\n-\t\t\tlws_plat_context_late_destroy(context);\n-\t\t\tlws_free_set_NULL(context);\n-\t\t\treturn NULL;\n-\t\t}\n-\n-\tlws_context_init_extensions(info, context);\n-\n-\tlwsl_info(\u0022 mem: per-conn: %5lu bytes + protocol rx buf\u005cn\u0022,\n-\t\t (unsigned long)sizeof(struct lws));\n-\n-\tstrcpy(context-\u003ecanonical_hostname, \u0022unknown\u0022);\n-\tlws_server_get_canonical_hostname(context, info);\n-\n-\tcontext-\u003euid \u003d info-\u003euid;\n-\tcontext-\u003egid \u003d info-\u003egid;\n-\n-#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n-\tmemcpy(context-\u003ecaps, info-\u003ecaps, sizeof(context-\u003ecaps));\n-\tcontext-\u003ecount_caps \u003d info-\u003ecount_caps;\n-#endif\n-\n-\t/*\n-\t * drop any root privs for this process\n-\t * to listen on port \u003c 1023 we would have needed root, but now we are\n-\t * listening, we don't want the power for anything else\n-\t */\n-\tif (!lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n-\t\tlws_plat_drop_app_privileges(info);\n-\n-\t/* expedite post-context init (eg, protocols) */\n-\tlws_cancel_service(context);\n-\n-#if defined(LWS_WITH_SELFTESTS)\n-\tlws_jws_selftest();\n-#endif\n-\n-\treturn context;\n-\n-bail:\n-\tlws_context_destroy(context);\n-\n-\treturn NULL;\n-\n-fail_event_libs:\n-\tlwsl_err(\u0022Requested event library support not configured, available:\u005cn\u0022);\n-\t{\n-\t\tconst struct lws_event_loop_ops **elops \u003d available_event_libs;\n-\n-\t\twhile (*elops) {\n-\t\t\tlwsl_err(\u0022 - %s\u005cn\u0022, (*elops)-\u003ename);\n-\t\t\telops++;\n-\t\t}\n-\t}\n-\tlws_free(context);\n-\n-\treturn NULL;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_context_deprecate(struct lws_context *context, lws_reload_func cb)\n-{\n-\tstruct lws_vhost *vh \u003d context-\u003evhost_list, *vh1;\n-\tstruct lws *wsi;\n-\n-\t/*\n-\t * \u0022deprecation\u0022 means disable the context from accepting any new\n-\t * connections and free up listen sockets to be used by a replacement\n-\t * context.\n-\t *\n-\t * Otherwise the deprecated context remains operational, until its\n-\t * number of connected sockets falls to zero, when it is deleted.\n-\t */\n-\n-\t/* for each vhost, close his listen socket */\n-\n-\twhile (vh) {\n-\t\twsi \u003d vh-\u003elserv_wsi;\n-\t\tif (wsi) {\n-\t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, \u0022ctx deprecate\u0022);\n-\t\t\twsi-\u003econtext-\u003edeprecation_pending_listen_close_count++;\n-\t\t\t/*\n-\t\t\t * other vhosts can share the listen port, they\n-\t\t\t * point to the same wsi. So zap those too.\n-\t\t\t */\n-\t\t\tvh1 \u003d context-\u003evhost_list;\n-\t\t\twhile (vh1) {\n-\t\t\t\tif (vh1-\u003elserv_wsi \u003d\u003d wsi)\n-\t\t\t\t\tvh1-\u003elserv_wsi \u003d NULL;\n-\t\t\t\tvh1 \u003d vh1-\u003evhost_next;\n-\t\t\t}\n-\t\t}\n-\t\tvh \u003d vh-\u003evhost_next;\n-\t}\n-\n-\tcontext-\u003edeprecated \u003d 1;\n-\tcontext-\u003edeprecation_cb \u003d cb;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_context_is_deprecated(struct lws_context *context)\n-{\n-\treturn context-\u003edeprecated;\n-}\n-\n-void\n-lws_vhost_destroy1(struct lws_vhost *vh)\n-{\n-\tconst struct lws_protocols *protocol \u003d NULL;\n-\tstruct lws_context_per_thread *pt;\n-\tint n, m \u003d vh-\u003econtext-\u003ecount_threads;\n-\tstruct lws_context *context \u003d vh-\u003econtext;\n-\tstruct lws wsi;\n-\n-\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n-\n-\tif (vh-\u003ebeing_destroyed)\n-\t\treturn;\n-\n-\tvh-\u003ebeing_destroyed \u003d 1;\n-\n-\t/*\n-\t * Are there other vhosts that are piggybacking on our listen socket?\n-\t * If so we need to hand the listen socket off to one of the others\n-\t * so it will remain open. If not, leave it attached to the closing\n-\t * vhost and it will get closed.\n-\t */\n-\n-\tif (vh-\u003elserv_wsi)\n-\t\tlws_start_foreach_ll(struct lws_vhost *, v,\n-\t\t\t\t context-\u003evhost_list) {\n-\t\t\tif (v !\u003d vh \u0026\u0026\n-\t\t\t !v-\u003ebeing_destroyed \u0026\u0026\n-\t\t\t v-\u003elisten_port \u003d\u003d vh-\u003elisten_port \u0026\u0026\n-\t\t\t ((!v-\u003eiface \u0026\u0026 !vh-\u003eiface) ||\n-\t\t\t (v-\u003eiface \u0026\u0026 vh-\u003eiface \u0026\u0026\n-\t\t\t !strcmp(v-\u003eiface, vh-\u003eiface)))) {\n-\t\t\t\t/*\n-\t\t\t\t * this can only be a listen wsi, which is\n-\t\t\t\t * restricted... it has no protocol or other\n-\t\t\t\t * bindings or states. So we can simply\n-\t\t\t\t * swap it to a vhost that has the same\n-\t\t\t\t * iface + port, but is not closing.\n-\t\t\t\t */\n-\t\t\t\tassert(v-\u003elserv_wsi \u003d\u003d NULL);\n-\t\t\t\tv-\u003elserv_wsi \u003d vh-\u003elserv_wsi;\n-\t\t\t\tvh-\u003elserv_wsi \u003d NULL;\n-\t\t\t\tif (v-\u003elserv_wsi)\n-\t\t\t\t\tv-\u003elserv_wsi-\u003evhost \u003d v;\n-\n-\t\t\t\tlwsl_notice(\u0022%s: listen skt from %s to %s\u005cn\u0022,\n-\t\t\t\t\t __func__, vh-\u003ename, v-\u003ename);\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t} lws_end_foreach_ll(v, vhost_next);\n-\n-\t/*\n-\t * Forcibly close every wsi assoicated with this vhost. That will\n-\t * include the listen socket if it is still associated with the closing\n-\t * vhost.\n-\t */\n-\n-\twhile (m--) {\n-\t\tpt \u003d \u0026context-\u003ept[m];\n-\n-\t\tfor (n \u003d 0; (unsigned int)n \u003c context-\u003ept[m].fds_count; n++) {\n-\t\t\tstruct lws *wsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n-\t\t\tif (!wsi)\n-\t\t\t\tcontinue;\n-\t\t\tif (wsi-\u003evhost !\u003d vh)\n-\t\t\t\tcontinue;\n-\n-\t\t\tlws_close_free_wsi(wsi,\n-\t\t\t\tLWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY,\n-\t\t\t\t\u0022vh destroy\u0022\n-\t\t\t\t/* no protocol close */);\n-\t\t\tn--;\n-\t\t}\n-\t}\n-\n-\t/*\n-\t * destroy any pending timed events\n-\t */\n-\n-\twhile (vh-\u003etimed_vh_protocol_list)\n-\t\tlws_timed_callback_remove(vh, vh-\u003etimed_vh_protocol_list);\n-\n-\t/*\n-\t * let the protocols destroy the per-vhost protocol objects\n-\t */\n-\n-\tmemset(\u0026wsi, 0, sizeof(wsi));\n-\twsi.context \u003d vh-\u003econtext;\n-\twsi.vhost \u003d vh;\n-\tprotocol \u003d vh-\u003eprotocols;\n-\tif (protocol \u0026\u0026 vh-\u003ecreated_vhost_protocols) {\n-\t\tn \u003d 0;\n-\t\twhile (n \u003c vh-\u003ecount_protocols) {\n-\t\t\twsi.protocol \u003d protocol;\n-\t\t\tprotocol-\u003ecallback(\u0026wsi, LWS_CALLBACK_PROTOCOL_DESTROY,\n-\t\t\t\t\t NULL, NULL, 0);\n-\t\t\tprotocol++;\n-\t\t\tn++;\n-\t\t}\n-\t}\n-\n-\t/*\n-\t * remove vhost from context list of vhosts\n-\t */\n-\n-\tlws_start_foreach_llp(struct lws_vhost **, pv, context-\u003evhost_list) {\n-\t\tif (*pv \u003d\u003d vh) {\n-\t\t\t*pv \u003d vh-\u003evhost_next;\n-\t\t\tbreak;\n-\t\t}\n-\t} lws_end_foreach_llp(pv, vhost_next);\n-\n-\t/* add ourselves to the pending destruction list */\n-\n-\tvh-\u003evhost_next \u003d vh-\u003econtext-\u003evhost_pending_destruction_list;\n-\tvh-\u003econtext-\u003evhost_pending_destruction_list \u003d vh;\n-}\n-\n-static void\n-lws_vhost_destroy2(struct lws_vhost *vh)\n-{\n-\tconst struct lws_protocols *protocol \u003d NULL;\n-\tstruct lws_context *context \u003d vh-\u003econtext;\n-\tstruct lws_deferred_free *df;\n-\tint n;\n-\n-\tlwsl_info(\u0022%s: %p\u005cn\u0022, __func__, vh);\n-\n-\t/* if we are still on deferred free list, remove ourselves */\n-\n-\tlws_start_foreach_llp(struct lws_deferred_free **, pdf,\n-\t\t\t context-\u003edeferred_free_list) {\n-\t\tif ((*pdf)-\u003epayload \u003d\u003d vh) {\n-\t\t\tdf \u003d *pdf;\n-\t\t\t*pdf \u003d df-\u003enext;\n-\t\t\tlws_free(df);\n-\t\t\tbreak;\n-\t\t}\n-\t} lws_end_foreach_llp(pdf, next);\n-\n-\t/* remove ourselves from the pending destruction list */\n-\n-\tlws_start_foreach_llp(struct lws_vhost **, pv,\n-\t\t\t context-\u003evhost_pending_destruction_list) {\n-\t\tif ((*pv) \u003d\u003d vh) {\n-\t\t\t*pv \u003d (*pv)-\u003evhost_next;\n-\t\t\tbreak;\n-\t\t}\n-\t} lws_end_foreach_llp(pv, vhost_next);\n-\n-\t/*\n-\t * Free all the allocations associated with the vhost\n-\t */\n-\n-\tprotocol \u003d vh-\u003eprotocols;\n-\tif (protocol) {\n-\t\tn \u003d 0;\n-\t\twhile (n \u003c vh-\u003ecount_protocols) {\n-\t\t\tif (vh-\u003eprotocol_vh_privs \u0026\u0026\n-\t\t\t vh-\u003eprotocol_vh_privs[n]) {\n-\t\t\t\tlws_free(vh-\u003eprotocol_vh_privs[n]);\n-\t\t\t\tvh-\u003eprotocol_vh_privs[n] \u003d NULL;\n-\t\t\t}\n-\t\t\tprotocol++;\n-\t\t\tn++;\n-\t\t}\n-\t}\n-\tif (vh-\u003eprotocol_vh_privs)\n-\t\tlws_free(vh-\u003eprotocol_vh_privs);\n-\tlws_ssl_SSL_CTX_destroy(vh);\n-\tlws_free(vh-\u003esame_vh_protocol_list);\n-\n-\tif (context-\u003eplugin_list ||\n-\t (context-\u003eoptions \u0026 LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n-\t\tlws_free((void *)vh-\u003eprotocols);\n-\n-\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)\n-\t\tif (ar-\u003edestroy_vhost)\n-\t\t\tar-\u003edestroy_vhost(vh);\n-\tLWS_FOR_EVERY_AVAILABLE_ROLE_END;\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-\tif (vh-\u003elog_fd !\u003d (int)LWS_INVALID_FILE)\n-\t\tclose(vh-\u003elog_fd);\n-#endif\n-\n-#if defined (LWS_WITH_TLS)\n-\tlws_free_set_NULL(vh-\u003etls.alloc_cert_path);\n-#endif\n-\n-#if LWS_MAX_SMP \u003e 1\n- pthread_mutex_destroy(\u0026vh-\u003elock);\n-#endif\n-\n-#if defined(LWS_WITH_UNIX_SOCK)\n-\tif (LWS_UNIX_SOCK_ENABLED(context)) {\n-\t\tn \u003d unlink(vh-\u003eiface);\n-\t\tif (n)\n-\t\t\tlwsl_info(\u0022Closing unix socket %s: errno %d\u005cn\u0022,\n-\t\t\t\t vh-\u003eiface, errno);\n-\t}\n-#endif\n-\t/*\n-\t * although async event callbacks may still come for wsi handles with\n-\t * pending close in the case of asycn event library like libuv,\n-\t * they do not refer to the vhost. So it's safe to free.\n-\t */\n-\n-\tlwsl_info(\u0022 %s: Freeing vhost %p\u005cn\u0022, __func__, vh);\n-\n-\tmemset(vh, 0, sizeof(*vh));\n-\tlws_free(vh);\n-}\n-\n-int\n-lws_check_deferred_free(struct lws_context *context, int force)\n-{\n-\tstruct lws_deferred_free *df;\n-\ttime_t now \u003d lws_now_secs();\n-\n-\tlws_start_foreach_llp(struct lws_deferred_free **, pdf,\n-\t\t\t context-\u003edeferred_free_list) {\n-\t\tif (force ||\n-\t\t lws_compare_time_t(context, now, (*pdf)-\u003edeadline) \u003e 5) {\n-\t\t\tdf \u003d *pdf;\n-\t\t\t*pdf \u003d df-\u003enext;\n-\t\t\t/* finalize vh destruction */\n-\t\t\tlwsl_notice(\u0022deferred vh %p destroy\u005cn\u0022, df-\u003epayload);\n-\t\t\tlws_vhost_destroy2(df-\u003epayload);\n-\t\t\tlws_free(df);\n-\t\t\tcontinue; /* after deletion we already point to next */\n-\t\t}\n-\t} lws_end_foreach_llp(pdf, next);\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE void\n-lws_vhost_destroy(struct lws_vhost *vh)\n-{\n-\tstruct lws_deferred_free *df \u003d lws_malloc(sizeof(*df), \u0022deferred free\u0022);\n-\n-\tif (!df)\n-\t\treturn;\n-\n-\tlws_vhost_destroy1(vh);\n-\n-\t/* part 2 is deferred to allow all the handle closes to complete */\n-\n-\tdf-\u003enext \u003d vh-\u003econtext-\u003edeferred_free_list;\n-\tdf-\u003edeadline \u003d lws_now_secs();\n-\tdf-\u003epayload \u003d vh;\n-\tvh-\u003econtext-\u003edeferred_free_list \u003d df;\n-}\n-\n-/*\n- * When using an event loop, the context destruction is in three separate\n- * parts. This is to cover both internal and foreign event loops cleanly.\n- *\n- * - lws_context_destroy() simply starts a soft close of all wsi and\n- * related allocations. The event loop continues.\n- *\n- * As the closes complete in the event loop, reference counting is used\n- * to determine when everything is closed. It then calls\n- * lws_context_destroy2().\n- *\n- * - lws_context_destroy2() cleans up the rest of the higher-level logical\n- * lws pieces like vhosts. If the loop was foreign, it then proceeds to\n- * lws_context_destroy3(). If it the loop is internal, it stops the\n- * internal loops and waits for lws_context_destroy() to be called again\n- * outside the event loop (since we cannot destroy the loop from\n- * within the loop). That will cause lws_context_destroy3() to run\n- * directly.\n- *\n- * - lws_context_destroy3() destroys any internal event loops and then\n- * destroys the context itself, setting what was info.pcontext to NULL.\n- */\n-\n-/*\n- * destroy the actual context itself\n- */\n-\n-static void\n-lws_context_destroy3(struct lws_context *context)\n-{\n-\tstruct lws_context **pcontext_finalize \u003d context-\u003epcontext_finalize;\n-\tstruct lws_context_per_thread *pt;\n-\tint n;\n-\n-\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\tpt \u003d \u0026context-\u003ept[n];\n-\n-\t\tif (context-\u003eevent_loop_ops-\u003edestroy_pt)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003edestroy_pt(context, n);\n-\n-\t\tlws_free_set_NULL(context-\u003ept[n].serv_buf);\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\t\twhile (pt-\u003ehttp.ah_list)\n-\t\t\t_lws_destroy_ah(pt, pt-\u003ehttp.ah_list);\n-#endif\n-\t}\n-\n-\tlws_free(context);\n-\tlwsl_info(\u0022%s: ctx %p freed\u005cn\u0022, __func__, context);\n-\n-\tif (pcontext_finalize)\n-\t\t*pcontext_finalize \u003d NULL;\n-}\n-\n-/*\n- * really start destroying things\n- */\n-\n-void\n-lws_context_destroy2(struct lws_context *context)\n-{\n-\tstruct lws_vhost *vh \u003d NULL, *vh1;\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tuint32_t nu;\n-#endif\n-\tint n;\n-\n-\tlwsl_info(\u0022%s: ctx %p\u005cn\u0022, __func__, context);\n-\n-\tcontext-\u003ebeing_destroyed2 \u003d 1;\n-\n-\tif (context-\u003ept[0].fds)\n-\t\tlws_free_set_NULL(context-\u003ept[0].fds);\n-\n-\t/*\n-\t * free all the per-vhost allocations\n-\t */\n-\n-\tvh \u003d context-\u003evhost_list;\n-\twhile (vh) {\n-\t\tvh1 \u003d vh-\u003evhost_next;\n-\t\tlws_vhost_destroy2(vh);\n-\t\tvh \u003d vh1;\n-\t}\n-\n-\t/* remove ourselves from the pending destruction list */\n-\n-\twhile (context-\u003evhost_pending_destruction_list)\n-\t\t/* removes itself from list */\n-\t\tlws_vhost_destroy2(context-\u003evhost_pending_destruction_list);\n-\n-\n-\tlws_stats_log_dump(context);\n-\n-\tlws_ssl_context_destroy(context);\n-\tlws_plat_context_late_destroy(context);\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tfor (nu \u003d 0; nu \u003c context-\u003epl_hash_elements; nu++)\t{\n-\t\tlws_start_foreach_llp(struct lws_peer **, peer,\n-\t\t\t\t context-\u003epl_hash_table[nu]) {\n-\t\t\tstruct lws_peer *df \u003d *peer;\n-\t\t\t*peer \u003d df-\u003enext;\n-\t\t\tlws_free(df);\n-\t\t\tcontinue;\n-\t\t} lws_end_foreach_llp(peer, next);\n-\t}\n-\tlws_free(context-\u003epl_hash_table);\n-#endif\n-\n-\tif (context-\u003eexternal_baggage_free_on_destroy)\n-\t\tfree(context-\u003eexternal_baggage_free_on_destroy);\n-\n-\tlws_check_deferred_free(context, 1);\n-\n-#if LWS_MAX_SMP \u003e 1\n-\tpthread_mutex_destroy(\u0026context-\u003elock);\n-#endif\n-\n-\tif (context-\u003eevent_loop_ops-\u003edestroy_context2)\n-\t\tif (context-\u003eevent_loop_ops-\u003edestroy_context2(context)) {\n-\t\t\tcontext-\u003efinalize_destroy_after_internal_loops_stopped \u003d 1;\n-\t\t\treturn;\n-\t\t}\n-\n-\tif (!context-\u003ept[0].event_loop_foreign)\n-\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++)\n-\t\t\tif (context-\u003ept[n].inside_service)\n-\t\t\t\treturn;\n-\n-\tlws_context_destroy3(context);\n-}\n-\n-/*\n- * Begin the context takedown\n- */\n-\n-LWS_VISIBLE void\n-lws_context_destroy(struct lws_context *context)\n-{\n-\tvolatile struct lws_foreign_thread_pollfd *ftp, *next;\n-\tvolatile struct lws_context_per_thread *vpt;\n-\tstruct lws_context_per_thread *pt;\n-\tstruct lws_vhost *vh \u003d NULL;\n-\tstruct lws wsi;\n-\tint n, m;\n-\n-\tif (!context)\n-\t\treturn;\n-\n-\tif (context-\u003efinalize_destroy_after_internal_loops_stopped) {\n-\t\tif (context-\u003eevent_loop_ops-\u003edestroy_context2)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003edestroy_context2(context);\n-\n-\t\tlws_context_destroy3(context);\n-\n-\t\treturn;\n-\t}\n-\n-\tif (context-\u003ebeing_destroyed1) {\n-\t\tif (!context-\u003ebeing_destroyed2) {\n-\t\t\tlws_context_destroy2(context);\n-\n-\t\t\treturn;\n-\t\t}\n-\t\tlwsl_info(\u0022%s: ctx %p: already being destroyed\u005cn\u0022,\n-\t\t\t __func__, context);\n-\n-\t\tlws_context_destroy3(context);\n-\t\treturn;\n-\t}\n-\n-\tlwsl_info(\u0022%s: ctx %p\u005cn\u0022, __func__, context);\n-\n-\tm \u003d context-\u003ecount_threads;\n-\tcontext-\u003ebeing_destroyed \u003d 1;\n-\tcontext-\u003ebeing_destroyed1 \u003d 1;\n-\tcontext-\u003erequested_kill \u003d 1;\n-\n-\tmemset(\u0026wsi, 0, sizeof(wsi));\n-\twsi.context \u003d context;\n-\n-#ifdef LWS_LATENCY\n-\tif (context-\u003eworst_latency_info[0])\n-\t\tlwsl_notice(\u0022Worst latency: %s\u005cn\u0022, context-\u003eworst_latency_info);\n-#endif\n-\n-\twhile (m--) {\n-\t\tpt \u003d \u0026context-\u003ept[m];\n-\t\tvpt \u003d (volatile struct lws_context_per_thread *)pt;\n-\n-\t\tftp \u003d vpt-\u003eforeign_pfd_list;\n-\t\twhile (ftp) {\n-\t\t\tnext \u003d ftp-\u003enext;\n-\t\t\tlws_free((void *)ftp);\n-\t\t\tftp \u003d next;\n-\t\t}\n-\t\tvpt-\u003eforeign_pfd_list \u003d NULL;\n-\n-\t\tfor (n \u003d 0; (unsigned int)n \u003c context-\u003ept[m].fds_count; n++) {\n-\t\t\tstruct lws *wsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n-\t\t\tif (!wsi)\n-\t\t\t\tcontinue;\n-\n-\t\t\tif (wsi-\u003eevent_pipe)\n-\t\t\t\tlws_destroy_event_pipe(wsi);\n-\t\t\telse\n-\t\t\t\tlws_close_free_wsi(wsi,\n-\t\t\t\t\tLWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY,\n-\t\t\t\t\t\u0022ctx destroy\u0022\n-\t\t\t\t\t/* no protocol close */);\n-\t\t\tn--;\n-\t\t}\n-\t\tlws_pt_mutex_destroy(pt);\n-\t}\n-\n-\t/*\n-\t * inform all the protocols that they are done and will have no more\n-\t * callbacks.\n-\t *\n-\t * We can't free things until after the event loop shuts down.\n-\t */\n-\tif (context-\u003eprotocol_init_done)\n-\t\tvh \u003d context-\u003evhost_list;\n-\twhile (vh) {\n-\t\tstruct lws_vhost *vhn \u003d vh-\u003evhost_next;\n-\t\tlws_vhost_destroy1(vh);\n-\t\tvh \u003d vhn;\n-\t}\n-\n-\tlws_plat_context_early_destroy(context);\n-\n-\t/*\n-\t * We face two different needs depending if foreign loop or not.\n-\t *\n-\t * 1) If foreign loop, we really want to advance the destroy_context()\n-\t * past here, and block only for libuv-style async close completion.\n-\t *\n-\t * 2a) If poll, and we exited by ourselves and are calling a final\n-\t * destroy_context() outside of any service already, we want to\n-\t * advance all the way in one step.\n-\t *\n-\t * 2b) If poll, and we are reacting to a SIGINT, service thread(s) may\n-\t * be in poll wait or servicing. We can't advance the\n-\t * destroy_context() to the point it's freeing things; we have to\n-\t * leave that for the final destroy_context() after the service\n-\t * thread(s) are finished calling for service.\n-\t */\n-\n-\tif (context-\u003eevent_loop_ops-\u003edestroy_context1) {\n-\t\tcontext-\u003eevent_loop_ops-\u003edestroy_context1(context);\n-\n-\t\treturn;\n-\t}\n-\n-\tlws_context_destroy2(context);\n-}\ndiff --git a/lib/core/alloc.c b/lib/core/alloc.c\nnew file mode 100644\nindex 0000000..f169fc3\n--- /dev/null\n+++ b/lib/core/alloc.c\n@@ -0,0 +1,92 @@\n+#include \u0022core/private.h\u0022\n+\n+#if defined(LWS_PLAT_OPTEE)\n+\n+#define TEE_USER_MEM_HINT_NO_FILL_ZERO 0x80000000\n+\n+void *__attribute__((weak))\n+\tTEE_Malloc(uint32_t size, uint32_t hint)\n+{\n+\treturn NULL;\n+}\n+void *__attribute__((weak))\n+\tTEE_Realloc(void *buffer, uint32_t newSize)\n+{\n+\treturn NULL;\n+}\n+void __attribute__((weak))\n+\tTEE_Free(void *buffer)\n+{\n+}\n+\n+void *lws_realloc(void *ptr, size_t size, const char *reason)\n+{\n+\treturn TEE_Realloc(ptr, size);\n+}\n+\n+void *lws_malloc(size_t size, const char *reason)\n+{\n+\treturn TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO);\n+}\n+\n+void lws_free(void *p)\n+{\n+\tTEE_Free(p);\n+}\n+\n+void *lws_zalloc(size_t size, const char *reason)\n+{\n+\tvoid *ptr \u003d TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO);\n+\tif (ptr)\n+\t\tmemset(ptr, 0, size);\n+\treturn ptr;\n+}\n+\n+void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason))\n+{\n+\t(void)cb;\n+}\n+#else\n+\n+static void *_realloc(void *ptr, size_t size, const char *reason)\n+{\n+\tif (size) {\n+#if defined(LWS_WITH_ESP32)\n+\t\tlwsl_notice(\u0022%s: size %lu: %s (free heap %d)\u005cn\u0022, __func__,\n+\t\t\t (unsigned long)size, reason, (unsigned int)esp_get_free_heap_size() - (int)size);\n+#else\n+\t\tlwsl_debug(\u0022%s: size %lu: %s\u005cn\u0022, __func__,\n+\t\t\t (unsigned long)size, reason);\n+#endif\n+#if defined(LWS_PLAT_OPTEE)\n+\t\treturn (void *)TEE_Realloc(ptr, size);\n+#else\n+\t\treturn (void *)realloc(ptr, size);\n+#endif\n+\t}\n+\tif (ptr)\n+\t\tfree(ptr);\n+\n+\treturn NULL;\n+}\n+\n+void *(*_lws_realloc)(void *ptr, size_t size, const char *reason) \u003d _realloc;\n+\n+void *lws_realloc(void *ptr, size_t size, const char *reason)\n+{\n+\treturn _lws_realloc(ptr, size, reason);\n+}\n+\n+void *lws_zalloc(size_t size, const char *reason)\n+{\n+\tvoid *ptr \u003d _lws_realloc(NULL, size, reason);\n+\tif (ptr)\n+\t\tmemset(ptr, 0, size);\n+\treturn ptr;\n+}\n+\n+void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason))\n+{\n+\t_lws_realloc \u003d cb;\n+}\n+#endif\ndiff --git a/lib/core/context.c b/lib/core/context.c\nnew file mode 100644\nindex 0000000..db9151b\n--- /dev/null\n+++ b/lib/core/context.c\n@@ -0,0 +1,1957 @@\n+/*\n+ * libwebsockets - small server side websockets and web server implementation\n+ *\n+ * Copyright (C) 2010-2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022core/private.h\u0022\n+\n+#ifndef LWS_BUILD_HASH\n+#define LWS_BUILD_HASH \u0022unknown-build-hash\u0022\n+#endif\n+\n+const struct lws_role_ops *available_roles[] \u003d {\n+#if defined(LWS_ROLE_H2)\n+\t\u0026role_ops_h2,\n+#endif\n+#if defined(LWS_ROLE_H1)\n+\t\u0026role_ops_h1,\n+#endif\n+#if defined(LWS_ROLE_WS)\n+\t\u0026role_ops_ws,\n+#endif\n+\tNULL\n+};\n+\n+const struct lws_event_loop_ops *available_event_libs[] \u003d {\n+#if defined(LWS_WITH_POLL)\n+\t\u0026event_loop_ops_poll,\n+#endif\n+#if defined(LWS_WITH_LIBUV)\n+\t\u0026event_loop_ops_uv,\n+#endif\n+#if defined(LWS_WITH_LIBEVENT)\n+\t\u0026event_loop_ops_event,\n+#endif\n+#if defined(LWS_WITH_LIBEV)\n+\t\u0026event_loop_ops_ev,\n+#endif\n+\tNULL\n+};\n+\n+static const char *library_version \u003d LWS_LIBRARY_VERSION \u0022 \u0022 LWS_BUILD_HASH;\n+\n+/**\n+ * lws_get_library_version: get version and git hash library built from\n+ *\n+ *\treturns a const char * to a string like \u00221.1 178d78c\u0022\n+ *\trepresenting the library version followed by the git head hash it\n+ *\twas built from\n+ */\n+LWS_VISIBLE const char *\n+lws_get_library_version(void)\n+{\n+\treturn library_version;\n+}\n+\n+int\n+lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn)\n+{\n+#if defined(LWS_WITH_TLS)\n+\tif (!alpn)\n+\t\treturn 0;\n+\n+\tlwsl_info(\u0022%s: '%s'\u005cn\u0022, __func__, alpn);\n+\n+\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)\n+\t\tif (ar-\u003ealpn \u0026\u0026 !strcmp(ar-\u003ealpn, alpn) \u0026\u0026 ar-\u003ealpn_negotiated)\n+\t\t\treturn ar-\u003ealpn_negotiated(wsi, alpn);\n+\tLWS_FOR_EVERY_AVAILABLE_ROLE_END;\n+#endif\n+\treturn 0;\n+}\n+\n+static const char * const mount_protocols[] \u003d {\n+\t\u0022http://\u0022,\n+\t\u0022https://\u0022,\n+\t\u0022file://\u0022,\n+\t\u0022cgi://\u0022,\n+\t\u0022\u003ehttp://\u0022,\n+\t\u0022\u003ehttps://\u0022,\n+\t\u0022callback://\u0022\n+};\n+\n+LWS_VISIBLE void *\n+lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,\n+\t\t\t const struct lws_protocols *prot, int size)\n+{\n+\tint n \u003d 0;\n+\n+\t/* allocate the vh priv array only on demand */\n+\tif (!vhost-\u003eprotocol_vh_privs) {\n+\t\tvhost-\u003eprotocol_vh_privs \u003d (void **)lws_zalloc(\n+\t\t\t\tvhost-\u003ecount_protocols * sizeof(void *),\n+\t\t\t\t\u0022protocol_vh_privs\u0022);\n+\t\tif (!vhost-\u003eprotocol_vh_privs)\n+\t\t\treturn NULL;\n+\t}\n+\n+\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026 \u0026vhost-\u003eprotocols[n] !\u003d prot)\n+\t\tn++;\n+\n+\tif (n \u003d\u003d vhost-\u003ecount_protocols) {\n+\t\tn \u003d 0;\n+\t\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026\n+\t\t strcmp(vhost-\u003eprotocols[n].name, prot-\u003ename))\n+\t\t\tn++;\n+\n+\t\tif (n \u003d\u003d vhost-\u003ecount_protocols)\n+\t\t\treturn NULL;\n+\t}\n+\n+\tvhost-\u003eprotocol_vh_privs[n] \u003d lws_zalloc(size, \u0022vh priv\u0022);\n+\treturn vhost-\u003eprotocol_vh_privs[n];\n+}\n+\n+LWS_VISIBLE void *\n+lws_protocol_vh_priv_get(struct lws_vhost *vhost,\n+\t\t\t const struct lws_protocols *prot)\n+{\n+\tint n \u003d 0;\n+\n+\tif (!vhost || !vhost-\u003eprotocol_vh_privs)\n+\t\treturn NULL;\n+\n+\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026 \u0026vhost-\u003eprotocols[n] !\u003d prot)\n+\t\tn++;\n+\n+\tif (n \u003d\u003d vhost-\u003ecount_protocols) {\n+\t\tn \u003d 0;\n+\t\twhile (n \u003c vhost-\u003ecount_protocols \u0026\u0026\n+\t\t strcmp(vhost-\u003eprotocols[n].name, prot-\u003ename))\n+\t\t\tn++;\n+\n+\t\tif (n \u003d\u003d vhost-\u003ecount_protocols) {\n+\t\t\tlwsl_err(\u0022%s: unknown protocol %p\u005cn\u0022, __func__, prot);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\treturn vhost-\u003eprotocol_vh_privs[n];\n+}\n+\n+static const struct lws_protocol_vhost_options *\n+lws_vhost_protocol_options(struct lws_vhost *vh, const char *name)\n+{\n+\tconst struct lws_protocol_vhost_options *pvo \u003d vh-\u003epvo;\n+\n+\tif (!name)\n+\t\treturn NULL;\n+\n+\twhile (pvo) {\n+\t\tif (!strcmp(pvo-\u003ename, name))\n+\t\t\treturn pvo;\n+\t\tpvo \u003d pvo-\u003enext;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+/*\n+ * inform every vhost that hasn't already done it, that\n+ * his protocols are initializing\n+ */\n+LWS_VISIBLE int\n+lws_protocol_init(struct lws_context *context)\n+{\n+\tstruct lws_vhost *vh \u003d context-\u003evhost_list;\n+\tconst struct lws_protocol_vhost_options *pvo, *pvo1;\n+\tstruct lws wsi;\n+\tint n, any \u003d 0;\n+\n+\tif (context-\u003edoing_protocol_init)\n+\t\treturn 0;\n+\n+\tcontext-\u003edoing_protocol_init \u003d 1;\n+\n+\tmemset(\u0026wsi, 0, sizeof(wsi));\n+\twsi.context \u003d context;\n+\n+\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n+\n+\twhile (vh) {\n+\t\twsi.vhost \u003d vh;\n+\n+\t\t/* only do the protocol init once for a given vhost */\n+\t\tif (vh-\u003ecreated_vhost_protocols ||\n+\t\t (vh-\u003eoptions \u0026 LWS_SERVER_OPTION_SKIP_PROTOCOL_INIT))\n+\t\t\tgoto next;\n+\n+\t\t/* initialize supported protocols on this vhost */\n+\n+\t\tfor (n \u003d 0; n \u003c vh-\u003ecount_protocols; n++) {\n+\t\t\twsi.protocol \u003d \u0026vh-\u003eprotocols[n];\n+\t\t\tif (!vh-\u003eprotocols[n].name)\n+\t\t\t\tcontinue;\n+\t\t\tpvo \u003d lws_vhost_protocol_options(vh,\n+\t\t\t\t\t\t\t vh-\u003eprotocols[n].name);\n+\t\t\tif (pvo) {\n+\t\t\t\t/*\n+\t\t\t\t * linked list of options specific to\n+\t\t\t\t * vh + protocol\n+\t\t\t\t */\n+\t\t\t\tpvo1 \u003d pvo;\n+\t\t\t\tpvo \u003d pvo1-\u003eoptions;\n+\n+\t\t\t\twhile (pvo) {\n+\t\t\t\t\tlwsl_debug(\n+\t\t\t\t\t\t\u0022 vhost \u005c\u0022%s\u005c\u0022, \u0022\n+\t\t\t\t\t\t\u0022protocol \u005c\u0022%s\u005c\u0022, \u0022\n+\t\t\t\t\t\t\u0022option \u005c\u0022%s\u005c\u0022\u005cn\u0022,\n+\t\t\t\t\t\t\tvh-\u003ename,\n+\t\t\t\t\t\t\tvh-\u003eprotocols[n].name,\n+\t\t\t\t\t\t\tpvo-\u003ename);\n+\n+\t\t\t\t\tif (!strcmp(pvo-\u003ename, \u0022default\u0022)) {\n+\t\t\t\t\t\tlwsl_info(\u0022Setting default \u0022\n+\t\t\t\t\t\t \u0022protocol for vh %s to %s\u005cn\u0022,\n+\t\t\t\t\t\t vh-\u003ename,\n+\t\t\t\t\t\t vh-\u003eprotocols[n].name);\n+\t\t\t\t\t\tvh-\u003edefault_protocol_index \u003d n;\n+\t\t\t\t\t}\n+\t\t\t\t\tif (!strcmp(pvo-\u003ename, \u0022raw\u0022)) {\n+\t\t\t\t\t\tlwsl_info(\u0022Setting raw \u0022\n+\t\t\t\t\t\t \u0022protocol for vh %s to %s\u005cn\u0022,\n+\t\t\t\t\t\t vh-\u003ename,\n+\t\t\t\t\t\t vh-\u003eprotocols[n].name);\n+\t\t\t\t\t\tvh-\u003eraw_protocol_index \u003d n;\n+\t\t\t\t\t}\n+\t\t\t\t\tpvo \u003d pvo-\u003enext;\n+\t\t\t\t}\n+\n+\t\t\t\tpvo \u003d pvo1-\u003eoptions;\n+\t\t\t}\n+\n+#if defined(LWS_WITH_TLS)\n+\t\t\tany |\u003d !!vh-\u003etls.ssl_ctx;\n+#endif\n+\n+\t\t\t/*\n+\t\t\t * inform all the protocols that they are doing their\n+\t\t\t * one-time initialization if they want to.\n+\t\t\t *\n+\t\t\t * NOTE the wsi is all zeros except for the context, vh\n+\t\t\t * + protocol ptrs so lws_get_context(wsi) etc can work\n+\t\t\t */\n+\t\t\tif (vh-\u003eprotocols[n].callback(\u0026wsi,\n+\t\t\t\t\tLWS_CALLBACK_PROTOCOL_INIT, NULL,\n+\t\t\t\t\t(void *)pvo, 0)) {\n+\t\t\t\tlws_free(vh-\u003eprotocol_vh_privs[n]);\n+\t\t\t\tvh-\u003eprotocol_vh_privs[n] \u003d NULL;\n+\t\t\t\tlwsl_err(\u0022%s: protocol %s failed init\u005cn\u0022, __func__,\n+\t\t\t\t\t vh-\u003eprotocols[n].name);\n+\t\t\t}\n+\t\t}\n+\n+\t\tvh-\u003ecreated_vhost_protocols \u003d 1;\n+next:\n+\t\tvh \u003d vh-\u003evhost_next;\n+\t}\n+\n+\tcontext-\u003edoing_protocol_init \u003d 0;\n+\n+\tif (!context-\u003eprotocol_init_done)\n+\t\tlws_finalize_startup(context);\n+\n+\tcontext-\u003eprotocol_init_done \u003d 1;\n+\n+\tif (any)\n+\t\tlws_tls_check_all_cert_lifetimes(context);\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE int\n+lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,\n+\t\t void *user, void *in, size_t len)\n+{\n+\tstruct lws_ssl_info *si;\n+#ifdef LWS_WITH_CGI\n+\tstruct lws_cgi_args *args;\n+#endif\n+#if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY)\n+\tchar buf[512];\n+\tint n;\n+#endif\n+\n+\tswitch (reason) {\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tcase LWS_CALLBACK_HTTP:\n+#ifndef LWS_NO_SERVER\n+\t\tif (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL))\n+\t\t\treturn -1;\n+\n+\t\tif (lws_http_transaction_completed(wsi))\n+#endif\n+\t\t\treturn -1;\n+\t\tbreak;\n+#if !defined(LWS_NO_SERVER)\n+\tcase LWS_CALLBACK_HTTP_FILE_COMPLETION:\n+\t\tif (lws_http_transaction_completed(wsi))\n+\t\t\treturn -1;\n+\t\tbreak;\n+#endif\n+\n+\tcase LWS_CALLBACK_HTTP_WRITEABLE:\n+#ifdef LWS_WITH_CGI\n+\t\tif (wsi-\u003ereason_bf \u0026 (LWS_CB_REASON_AUX_BF__CGI_HEADERS |\n+\t\t\t\t LWS_CB_REASON_AUX_BF__CGI)) {\n+\t\t\tn \u003d lws_cgi_write_split_stdout_headers(wsi);\n+\t\t\tif (n \u003c 0) {\n+\t\t\t\tlwsl_debug(\u0022AUX_BF__CGI forcing close\u005cn\u0022);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tif (!n)\n+\t\t\t\tlws_rx_flow_control(\n+\t\t\t\t\twsi-\u003ehttp.cgi-\u003estdwsi[LWS_STDOUT], 1);\n+\n+\t\t\tif (wsi-\u003ereason_bf \u0026 LWS_CB_REASON_AUX_BF__CGI_HEADERS)\n+\t\t\t\twsi-\u003ereason_bf \u0026\u003d\n+\t\t\t\t\t~LWS_CB_REASON_AUX_BF__CGI_HEADERS;\n+\t\t\telse\n+\t\t\t\twsi-\u003ereason_bf \u0026\u003d ~LWS_CB_REASON_AUX_BF__CGI;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (wsi-\u003ereason_bf \u0026 LWS_CB_REASON_AUX_BF__CGI_CHUNK_END) {\n+\t\t\tif (!wsi-\u003ehttp2_substream) {\n+\t\t\t\tmemcpy(buf + LWS_PRE, \u00220\u005cx0d\u005cx0a\u005cx0d\u005cx0a\u0022, 5);\n+\t\t\t\tlwsl_debug(\u0022writing chunk term and exiting\u005cn\u0022);\n+\t\t\t\tn \u003d lws_write(wsi, (unsigned char *)buf +\n+\t\t\t\t\t\t LWS_PRE, 5, LWS_WRITE_HTTP);\n+\t\t\t} else\n+\t\t\t\tn \u003d lws_write(wsi, (unsigned char *)buf +\n+\t\t\t\t\t\t LWS_PRE, 0,\n+\t\t\t\t\t\t LWS_WRITE_HTTP_FINAL);\n+\n+\t\t\t/* always close after sending it */\n+\t\t\treturn -1;\n+\t\t}\n+#endif\n+#if defined(LWS_WITH_HTTP_PROXY)\n+\t\tif (wsi-\u003ereason_bf \u0026 LWS_CB_REASON_AUX_BF__PROXY) {\n+\t\t\tchar *px \u003d buf + LWS_PRE;\n+\t\t\tint lenx \u003d sizeof(buf) - LWS_PRE;\n+\n+\t\t\t/*\n+\t\t\t * our sink is writeable and our source has something\n+\t\t\t * to read. So read a lump of source material of\n+\t\t\t * suitable size to send or what's available, whichever\n+\t\t\t * is the smaller.\n+\t\t\t */\n+\t\t\twsi-\u003ereason_bf \u0026\u003d ~LWS_CB_REASON_AUX_BF__PROXY;\n+\t\t\tif (!lws_get_child(wsi))\n+\t\t\t\tbreak;\n+\t\t\tif (lws_http_client_read(lws_get_child(wsi), \u0026px,\n+\t\t\t\t\t\t \u0026lenx) \u003c 0)\n+\t\t\t\treturn -1;\n+\t\t\tbreak;\n+\t\t}\n+#endif\n+\t\tbreak;\n+\n+#if defined(LWS_WITH_HTTP_PROXY)\n+\tcase LWS_CALLBACK_RECEIVE_CLIENT_HTTP:\n+\t\tassert(lws_get_parent(wsi));\n+\t\tif (!lws_get_parent(wsi))\n+\t\t\tbreak;\n+\t\tlws_get_parent(wsi)-\u003ereason_bf |\u003d LWS_CB_REASON_AUX_BF__PROXY;\n+\t\tlws_callback_on_writable(lws_get_parent(wsi));\n+\t\tbreak;\n+\n+\tcase LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:\n+\t\tassert(lws_get_parent(wsi));\n+\t\tn \u003d lws_write(lws_get_parent(wsi), (unsigned char *)in,\n+\t\t\t\tlen, LWS_WRITE_HTTP);\n+\t\tif (n \u003c 0)\n+\t\t\treturn -1;\n+\t\tbreak;\n+\n+\tcase LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: {\n+\t\tunsigned char *p, *end;\n+\t\tchar ctype[64], ctlen \u003d 0;\n+\t\n+\t\tp \u003d (unsigned char *)buf + LWS_PRE;\n+\t\tend \u003d p + sizeof(buf) - LWS_PRE;\n+\n+\t\tif (lws_add_http_header_status(lws_get_parent(wsi),\n+\t\t\t\t\t HTTP_STATUS_OK, \u0026p, end))\n+\t\t\treturn 1;\n+\t\tif (lws_add_http_header_by_token(lws_get_parent(wsi),\n+\t\t\t\tWSI_TOKEN_HTTP_SERVER,\n+\t\t\t \t(unsigned char *)\u0022libwebsockets\u0022,\n+\t\t\t\t13, \u0026p, end))\n+\t\t\treturn 1;\n+\n+\t\tctlen \u003d lws_hdr_copy(wsi, ctype, sizeof(ctype),\n+\t\t\t\t WSI_TOKEN_HTTP_CONTENT_TYPE);\n+\t\tif (ctlen \u003e 0) {\n+\t\t\tif (lws_add_http_header_by_token(lws_get_parent(wsi),\n+\t\t\t\tWSI_TOKEN_HTTP_CONTENT_TYPE,\n+\t\t\t\t(unsigned char *)ctype, ctlen, \u0026p, end))\n+\t\t\t\treturn 1;\n+\t\t}\n+\n+\t\tif (lws_finalize_http_header(lws_get_parent(wsi), \u0026p, end))\n+\t\t\treturn 1;\n+\n+\t\t*p \u003d '\u005c0';\n+\t\tn \u003d lws_write(lws_get_parent(wsi),\n+\t\t\t (unsigned char *)buf + LWS_PRE,\n+\t\t\t p - ((unsigned char *)buf + LWS_PRE),\n+\t\t\t LWS_WRITE_HTTP_HEADERS);\n+\t\tif (n \u003c 0)\n+\t\t\treturn -1;\n+\n+\t\tbreak; }\n+\n+#endif\n+\n+#ifdef LWS_WITH_CGI\n+\t/* CGI IO events (POLLIN/OUT) appear here, our default policy is:\n+\t *\n+\t * - POST data goes on subprocess stdin\n+\t * - subprocess stdout goes on http via writeable callback\n+\t * - subprocess stderr goes to the logs\n+\t */\n+\tcase LWS_CALLBACK_CGI:\n+\t\targs \u003d (struct lws_cgi_args *)in;\n+\t\tswitch (args-\u003ech) { /* which of stdin/out/err ? */\n+\t\tcase LWS_STDIN:\n+\t\t\t/* TBD stdin rx flow control */\n+\t\t\tbreak;\n+\t\tcase LWS_STDOUT:\n+\t\t\t/* quench POLLIN on STDOUT until MASTER got writeable */\n+\t\t\tlws_rx_flow_control(args-\u003estdwsi[LWS_STDOUT], 0);\n+\t\t\twsi-\u003ereason_bf |\u003d LWS_CB_REASON_AUX_BF__CGI;\n+\t\t\t/* when writing to MASTER would not block */\n+\t\t\tlws_callback_on_writable(wsi);\n+\t\t\tbreak;\n+\t\tcase LWS_STDERR:\n+\t\t\tn \u003d lws_get_socket_fd(args-\u003estdwsi[LWS_STDERR]);\n+\t\t\tif (n \u003c 0)\n+\t\t\t\tbreak;\n+\t\t\tn \u003d read(n, buf, sizeof(buf) - 2);\n+\t\t\tif (n \u003e 0) {\n+\t\t\t\tif (buf[n - 1] !\u003d '\u005cn')\n+\t\t\t\t\tbuf[n++] \u003d '\u005cn';\n+\t\t\t\tbuf[n] \u003d '\u005c0';\n+\t\t\t\tlwsl_notice(\u0022CGI-stderr: %s\u005cn\u0022, buf);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\n+\tcase LWS_CALLBACK_CGI_TERMINATED:\n+\t\tlwsl_debug(\u0022LWS_CALLBACK_CGI_TERMINATED: %d %\u0022 PRIu64 \u0022\u005cn\u0022,\n+\t\t\t\twsi-\u003ehttp.cgi-\u003eexplicitly_chunked,\n+\t\t\t\t(uint64_t)wsi-\u003ehttp.cgi-\u003econtent_length);\n+\t\tif (!wsi-\u003ehttp.cgi-\u003eexplicitly_chunked \u0026\u0026\n+\t\t !wsi-\u003ehttp.cgi-\u003econtent_length) {\n+\t\t\t/* send terminating chunk */\n+\t\t\tlwsl_debug(\u0022LWS_CALLBACK_CGI_TERMINATED: ending\u005cn\u0022);\n+\t\t\twsi-\u003ereason_bf |\u003d LWS_CB_REASON_AUX_BF__CGI_CHUNK_END;\n+\t\t\tlws_callback_on_writable(wsi);\n+\t\t\tlws_set_timeout(wsi, PENDING_TIMEOUT_CGI, 3);\n+\t\t\tbreak;\n+\t\t}\n+\t\treturn -1;\n+\n+\tcase LWS_CALLBACK_CGI_STDIN_DATA: /* POST body for stdin */\n+\t\targs \u003d (struct lws_cgi_args *)in;\n+\t\targs-\u003edata[args-\u003elen] \u003d '\u005c0';\n+\t\tn \u003d lws_get_socket_fd(args-\u003estdwsi[LWS_STDIN]);\n+\t\tif (n \u003c 0)\n+\t\t\treturn -1;\n+\t\tn \u003d write(n, args-\u003edata, args-\u003elen);\n+\t\tif (n \u003c args-\u003elen)\n+\t\t\tlwsl_notice(\u0022LWS_CALLBACK_CGI_STDIN_DATA: \u0022\n+\t\t\t\t \u0022sent %d only %d went\u0022, n, args-\u003elen);\n+\t\treturn n;\n+#endif\n+#endif\n+\tcase LWS_CALLBACK_SSL_INFO:\n+\t\tsi \u003d in;\n+\n+\t\t(void)si;\n+\t\tlwsl_notice(\u0022LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\u005cn\u0022,\n+\t\t\t si-\u003ewhere, si-\u003eret);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* list of supported protocols and callbacks */\n+\n+static const struct lws_protocols protocols_dummy[] \u003d {\n+\t/* first protocol must always be HTTP handler */\n+\n+\t{\n+\t\t\u0022http-only\u0022,\t\t\t/* name */\n+\t\tlws_callback_http_dummy,\t/* callback */\n+\t\t0,\t\t\t\t/* per_session_data_size */\n+\t\t0,\t\t\t\t/* rx_buffer_size */\n+\t\t0,\t\t\t\t/* id */\n+\t\tNULL,\t\t\t\t/* user */\n+\t\t0\t\t\t\t/* tx_packet_size */\n+\t},\n+\t/*\n+\t * the other protocols are provided by lws plugins\n+\t */\n+\t{ NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */\n+};\n+\n+#ifdef LWS_PLAT_OPTEE\n+#undef LWS_HAVE_GETENV\n+#endif\n+\n+static void\n+lws_vhost_destroy2(struct lws_vhost *vh);\n+\n+LWS_VISIBLE struct lws_vhost *\n+lws_create_vhost(struct lws_context *context,\n+\t\t const struct lws_context_creation_info *info)\n+{\n+\tstruct lws_vhost *vh \u003d lws_zalloc(sizeof(*vh), \u0022create vhost\u0022),\n+\t\t\t **vh1 \u003d \u0026context-\u003evhost_list;\n+\tconst struct lws_http_mount *mounts;\n+\tconst struct lws_protocols *pcols \u003d info-\u003eprotocols;\n+\tconst struct lws_protocol_vhost_options *pvo;\n+#ifdef LWS_WITH_PLUGINS\n+\tstruct lws_plugin *plugin \u003d context-\u003eplugin_list;\n+#endif\n+\tstruct lws_protocols *lwsp;\n+\tint m, f \u003d !info-\u003epvo;\n+\tchar buf[20];\n+#if !defined(LWS_WITHOUT_CLIENT) \u0026\u0026 defined(LWS_HAVE_GETENV)\n+\tchar *p;\n+#endif\n+\tint n;\n+\n+\tif (!vh)\n+\t\treturn NULL;\n+\n+#if LWS_MAX_SMP \u003e 1\n+\tpthread_mutex_init(\u0026vh-\u003elock, NULL);\n+#endif\n+\n+\tif (!pcols)\n+\t\tpcols \u003d \u0026protocols_dummy[0];\n+\n+\tvh-\u003econtext \u003d context;\n+\tif (!info-\u003evhost_name)\n+\t\tvh-\u003ename \u003d \u0022default\u0022;\n+\telse\n+\t\tvh-\u003ename \u003d info-\u003evhost_name;\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tvh-\u003ehttp.error_document_404 \u003d info-\u003eerror_document_404;\n+#endif\n+\n+\tif (info-\u003eoptions \u0026 LWS_SERVER_OPTION_ONLY_RAW)\n+\t\tlwsl_info(\u0022%s set to only support RAW\u005cn\u0022, vh-\u003ename);\n+\n+\tvh-\u003eiface \u003d info-\u003eiface;\n+#if !defined(LWS_WITH_ESP32) \u0026\u0026 \u005c\n+ !defined(OPTEE_TA) \u0026\u0026 !defined(WIN32)\n+\tvh-\u003ebind_iface \u003d info-\u003ebind_iface;\n+#endif\n+\n+\tfor (vh-\u003ecount_protocols \u003d 0;\n+\t pcols[vh-\u003ecount_protocols].callback;\n+\t vh-\u003ecount_protocols++)\n+\t\t;\n+\n+\tvh-\u003eoptions \u003d info-\u003eoptions;\n+\tvh-\u003epvo \u003d info-\u003epvo;\n+\tvh-\u003eheaders \u003d info-\u003eheaders;\n+\tvh-\u003euser \u003d info-\u003euser;\n+\n+\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)\n+\t\tif (ar-\u003einit_vhost)\n+\t\t\tif (ar-\u003einit_vhost(vh, info))\n+\t\t\t\treturn NULL;\n+\tLWS_FOR_EVERY_AVAILABLE_ROLE_END;\n+\n+\n+\tif (info-\u003ekeepalive_timeout)\n+\t\tvh-\u003ekeepalive_timeout \u003d info-\u003ekeepalive_timeout;\n+\telse\n+\t\tvh-\u003ekeepalive_timeout \u003d 5;\n+\n+\tif (info-\u003etimeout_secs_ah_idle)\n+\t\tvh-\u003etimeout_secs_ah_idle \u003d info-\u003etimeout_secs_ah_idle;\n+\telse\n+\t\tvh-\u003etimeout_secs_ah_idle \u003d 10;\n+\n+#if defined(LWS_WITH_TLS)\n+\n+\tvh-\u003etls.alpn \u003d info-\u003ealpn;\n+\tvh-\u003etls.ssl_info_event_mask \u003d info-\u003essl_info_event_mask;\n+\n+\tif (info-\u003eecdh_curve)\n+\t\tlws_strncpy(vh-\u003etls.ecdh_curve, info-\u003eecdh_curve,\n+\t\t\t sizeof(vh-\u003etls.ecdh_curve));\n+\n+\t/* carefully allocate and take a copy of cert + key paths if present */\n+\tn \u003d 0;\n+\tif (info-\u003essl_cert_filepath)\n+\t\tn +\u003d (int)strlen(info-\u003essl_cert_filepath) + 1;\n+\tif (info-\u003essl_private_key_filepath)\n+\t\tn +\u003d (int)strlen(info-\u003essl_private_key_filepath) + 1;\n+\n+\tif (n) {\n+\t\tvh-\u003etls.key_path \u003d vh-\u003etls.alloc_cert_path \u003d lws_malloc(n, \u0022vh paths\u0022);\n+\t\tif (info-\u003essl_cert_filepath) {\n+\t\t\tn \u003d (int)strlen(info-\u003essl_cert_filepath) + 1;\n+\t\t\tmemcpy(vh-\u003etls.alloc_cert_path, info-\u003essl_cert_filepath, n);\n+\t\t\tvh-\u003etls.key_path +\u003d n;\n+\t\t}\n+\t\tif (info-\u003essl_private_key_filepath)\n+\t\t\tmemcpy(vh-\u003etls.key_path, info-\u003essl_private_key_filepath,\n+\t\t\t strlen(info-\u003essl_private_key_filepath) + 1);\n+\t}\n+#endif\n+\n+\t/*\n+\t * give the vhost a unified list of protocols including the\n+\t * ones that came from plugins\n+\t */\n+\tlwsp \u003d lws_zalloc(sizeof(struct lws_protocols) * (vh-\u003ecount_protocols +\n+\t\t\t\t context-\u003eplugin_protocol_count + 1),\n+\t\t\t\t \u0022vhost-specific plugin table\u0022);\n+\tif (!lwsp) {\n+\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n+\t\treturn NULL;\n+\t}\n+\n+\tm \u003d vh-\u003ecount_protocols;\n+\tmemcpy(lwsp, pcols, sizeof(struct lws_protocols) * m);\n+\n+\t/* for compatibility, all protocols enabled on vhost if only\n+\t * the default vhost exists. Otherwise only vhosts who ask\n+\t * for a protocol get it enabled.\n+\t */\n+\n+\tif (context-\u003eoptions \u0026 LWS_SERVER_OPTION_EXPLICIT_VHOSTS)\n+\t\tf \u003d 0;\n+\t(void)f;\n+#ifdef LWS_WITH_PLUGINS\n+\tif (plugin) {\n+\n+\t\twhile (plugin) {\n+\t\t\tfor (n \u003d 0; n \u003c plugin-\u003ecaps.count_protocols; n++) {\n+\t\t\t\t/*\n+\t\t\t\t * for compatibility's sake, no pvo implies\n+\t\t\t\t * allow all protocols\n+\t\t\t\t */\n+\t\t\t\tif (f || lws_vhost_protocol_options(vh,\n+\t\t\t\t plugin-\u003ecaps.protocols[n].name)) {\n+\t\t\t\t\tmemcpy(\u0026lwsp[m],\n+\t\t\t\t\t \u0026plugin-\u003ecaps.protocols[n],\n+\t\t\t\t\t sizeof(struct lws_protocols));\n+\t\t\t\t\tm++;\n+\t\t\t\t\tvh-\u003ecount_protocols++;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tplugin \u003d plugin-\u003elist;\n+\t\t}\n+\t}\n+#endif\n+\n+\tif (\n+#ifdef LWS_WITH_PLUGINS\n+\t (context-\u003eplugin_list) ||\n+#endif\n+\t context-\u003eoptions \u0026 LWS_SERVER_OPTION_EXPLICIT_VHOSTS)\n+\t\tvh-\u003eprotocols \u003d lwsp;\n+\telse {\n+\t\tvh-\u003eprotocols \u003d pcols;\n+\t\tlws_free(lwsp);\n+\t}\n+\n+\tvh-\u003esame_vh_protocol_list \u003d (struct lws **)\n+\t\t\tlws_zalloc(sizeof(struct lws *) * vh-\u003ecount_protocols,\n+\t\t\t\t \u0022same vh list\u0022);\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tvh-\u003ehttp.mount_list \u003d info-\u003emounts;\n+#endif\n+\n+#ifdef LWS_WITH_UNIX_SOCK\n+\tif (LWS_UNIX_SOCK_ENABLED(context)) {\n+\t\tlwsl_notice(\u0022Creating Vhost '%s' path \u005c\u0022%s\u005c\u0022, %d protocols\u005cn\u0022,\n+\t\t\t\tvh-\u003ename, vh-\u003eiface, vh-\u003ecount_protocols);\n+\t} else\n+#endif\n+\t{\n+\t\tswitch(info-\u003eport) {\n+\t\tcase CONTEXT_PORT_NO_LISTEN:\n+\t\t\tstrcpy(buf, \u0022(serving disabled)\u0022);\n+\t\t\tbreak;\n+\t\tcase CONTEXT_PORT_NO_LISTEN_SERVER:\n+\t\t\tstrcpy(buf, \u0022(no listener)\u0022);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tlws_snprintf(buf, sizeof(buf), \u0022port %u\u0022, info-\u003eport);\n+\t\t\tbreak;\n+\t\t}\n+\t\tlwsl_notice(\u0022Creating Vhost '%s' %s, %d protocols, IPv6 %s\u005cn\u0022,\n+\t\t\t\tvh-\u003ename, buf, vh-\u003ecount_protocols,\n+\t\t\t\tLWS_IPV6_ENABLED(vh) ? \u0022on\u0022 : \u0022off\u0022);\n+\t}\n+\tmounts \u003d info-\u003emounts;\n+\twhile (mounts) {\n+\t\t(void)mount_protocols[0];\n+\t\tlwsl_info(\u0022 mounting %s%s to %s\u005cn\u0022,\n+\t\t\t mount_protocols[mounts-\u003eorigin_protocol],\n+\t\t\t mounts-\u003eorigin, mounts-\u003emountpoint);\n+\n+\t\t/* convert interpreter protocol names to pointers */\n+\t\tpvo \u003d mounts-\u003einterpret;\n+\t\twhile (pvo) {\n+\t\t\tfor (n \u003d 0; n \u003c vh-\u003ecount_protocols; n++) {\n+\t\t\t\tif (strcmp(pvo-\u003evalue, vh-\u003eprotocols[n].name))\n+\t\t\t\t\tcontinue;\n+\t\t\t\t((struct lws_protocol_vhost_options *)pvo)-\u003e\n+\t\t\t\t\tvalue \u003d (const char *)(lws_intptr_t)n;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (n \u003d\u003d vh-\u003ecount_protocols)\n+\t\t\t\tlwsl_err(\u0022ignoring unknown interp pr %s\u005cn\u0022,\n+\t\t\t\t\t pvo-\u003evalue);\n+\t\t\tpvo \u003d pvo-\u003enext;\n+\t\t}\n+\n+\t\tmounts \u003d mounts-\u003emount_next;\n+\t}\n+\n+\tvh-\u003elisten_port \u003d info-\u003eport;\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tvh-\u003ehttp.http_proxy_port \u003d 0;\n+\tvh-\u003ehttp.http_proxy_address[0] \u003d '\u005c0';\n+#endif\n+#if defined(LWS_WITH_SOCKS5)\n+\tvh-\u003esocks_proxy_port \u003d 0;\n+\tvh-\u003esocks_proxy_address[0] \u003d '\u005c0';\n+#endif\n+\n+#if !defined(LWS_WITHOUT_CLIENT)\n+\t/* either use proxy from info, or try get it from env var */\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\t/* http proxy */\n+\tif (info-\u003ehttp_proxy_address) {\n+\t\t/* override for backwards compatibility */\n+\t\tif (info-\u003ehttp_proxy_port)\n+\t\t\tvh-\u003ehttp.http_proxy_port \u003d info-\u003ehttp_proxy_port;\n+\t\tlws_set_proxy(vh, info-\u003ehttp_proxy_address);\n+\t} else\n+#endif\n+\t{\n+#ifdef LWS_HAVE_GETENV\n+\t\tp \u003d getenv(\u0022http_proxy\u0022);\n+\t\tif (p)\n+\t\t\tlws_set_proxy(vh, p);\n+#endif\n+\t}\n+#endif\n+#if defined(LWS_WITH_SOCKS5)\n+\t/* socks proxy */\n+\tif (info-\u003esocks_proxy_address) {\n+\t\t/* override for backwards compatibility */\n+\t\tif (info-\u003esocks_proxy_port)\n+\t\t\tvh-\u003esocks_proxy_port \u003d info-\u003esocks_proxy_port;\n+\t\tlws_set_socks(vh, info-\u003esocks_proxy_address);\n+\t} else {\n+#ifdef LWS_HAVE_GETENV\n+\t\tp \u003d getenv(\u0022socks_proxy\u0022);\n+\t\tif (p)\n+\t\t\tlws_set_socks(vh, p);\n+#endif\n+\t}\n+#endif\n+\n+\tvh-\u003eka_time \u003d info-\u003eka_time;\n+\tvh-\u003eka_interval \u003d info-\u003eka_interval;\n+\tvh-\u003eka_probes \u003d info-\u003eka_probes;\n+\n+\tif (vh-\u003eoptions \u0026 LWS_SERVER_OPTION_STS)\n+\t\tlwsl_notice(\u0022 STS enabled\u005cn\u0022);\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+\tif (info-\u003elog_filepath) {\n+\t\tvh-\u003elog_fd \u003d open(info-\u003elog_filepath,\n+\t\t\t\t O_CREAT | O_APPEND | O_RDWR, 0600);\n+\t\tif (vh-\u003elog_fd \u003d\u003d (int)LWS_INVALID_FILE) {\n+\t\t\tlwsl_err(\u0022unable to open log filepath %s\u005cn\u0022,\n+\t\t\t\t info-\u003elog_filepath);\n+\t\t\tgoto bail;\n+\t\t}\n+#ifndef WIN32\n+\t\tif (context-\u003euid !\u003d -1)\n+\t\t\tif (chown(info-\u003elog_filepath, context-\u003euid,\n+\t\t\t\t context-\u003egid) \u003d\u003d -1)\n+\t\t\t\tlwsl_err(\u0022unable to chown log file %s\u005cn\u0022,\n+\t\t\t\t\t\tinfo-\u003elog_filepath);\n+#endif\n+\t} else\n+\t\tvh-\u003elog_fd \u003d (int)LWS_INVALID_FILE;\n+#endif\n+\tif (lws_context_init_server_ssl(info, vh)) {\n+\t\tlwsl_err(\u0022%s: lws_context_init_server_ssl failed\u005cn\u0022, __func__);\n+\t\tgoto bail1;\n+\t}\n+\tif (lws_context_init_client_ssl(info, vh)) {\n+\t\tlwsl_err(\u0022%s: lws_context_init_client_ssl failed\u005cn\u0022, __func__);\n+\t\tgoto bail1;\n+\t}\n+\tlws_context_lock(context);\n+\tn \u003d _lws_vhost_init_server(info, vh);\n+\tlws_context_unlock(context);\n+\tif (n \u003c 0) {\n+\t\tlwsl_err(\u0022init server failed\u005cn\u0022);\n+\t\tgoto bail1;\n+\t}\n+\n+\n+\twhile (1) {\n+\t\tif (!(*vh1)) {\n+\t\t\t*vh1 \u003d vh;\n+\t\t\tbreak;\n+\t\t}\n+\t\tvh1 \u003d \u0026(*vh1)-\u003evhost_next;\n+\t};\n+\n+\t/* for the case we are adding a vhost much later, after server init */\n+\n+\tif (context-\u003eprotocol_init_done)\n+\t\tif (lws_protocol_init(context)) {\n+\t\t\tlwsl_err(\u0022%s: lws_protocol_init failed\u005cn\u0022, __func__);\n+\t\t\tgoto bail1;\n+\t\t}\n+\n+\treturn vh;\n+\n+bail1:\n+\tlws_vhost_destroy(vh);\n+\tlws_vhost_destroy2(vh);\n+\n+\treturn NULL;\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+bail:\n+\tlws_free(vh);\n+#endif\n+\n+\treturn NULL;\n+}\n+\n+LWS_VISIBLE int\n+lws_init_vhost_client_ssl(const struct lws_context_creation_info *info,\n+\t\t\t struct lws_vhost *vhost)\n+{\n+\tstruct lws_context_creation_info i;\n+\n+\tmemcpy(\u0026i, info, sizeof(i));\n+\ti.port \u003d CONTEXT_PORT_NO_LISTEN;\n+\n+\treturn lws_context_init_client_ssl(\u0026i, vhost);\n+}\n+\n+LWS_VISIBLE void\n+lws_cancel_service_pt(struct lws *wsi)\n+{\n+\tlws_plat_pipe_signal(wsi);\n+}\n+\n+LWS_VISIBLE void\n+lws_cancel_service(struct lws_context *context)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n+\tshort m \u003d context-\u003ecount_threads;\n+\n+\tif (context-\u003ebeing_destroyed1)\n+\t\treturn;\n+\n+\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n+\n+\twhile (m--) {\n+\t\tif (pt-\u003epipe_wsi)\n+\t\t\tlws_plat_pipe_signal(pt-\u003epipe_wsi);\n+\t\tpt++;\n+\t}\n+}\n+\n+int\n+lws_create_event_pipes(struct lws_context *context)\n+{\n+\tstruct lws *wsi;\n+\tint n;\n+\n+\t/*\n+\t * Create the pt event pipes... these are unique in that they are\n+\t * not bound to a vhost or protocol (both are NULL)\n+\t */\n+\n+\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\tif (context-\u003ept[n].pipe_wsi)\n+\t\t\tcontinue;\n+\n+\t\twsi \u003d lws_zalloc(sizeof(*wsi), \u0022event pipe wsi\u0022);\n+\t\tif (!wsi) {\n+\t\t\tlwsl_err(\u0022Out of mem\u005cn\u0022);\n+\t\t\treturn 1;\n+\t\t}\n+\t\twsi-\u003econtext \u003d context;\n+\t\tlws_role_transition(wsi, 0, LRS_UNCONNECTED, \u0026role_ops_pipe);\n+\t\twsi-\u003eprotocol \u003d NULL;\n+\t\twsi-\u003etsi \u003d n;\n+\t\twsi-\u003evhost \u003d NULL;\n+\t\twsi-\u003eevent_pipe \u003d 1;\n+\n+\t\tif (lws_plat_pipe_create(wsi)) {\n+\t\t\tlws_free(wsi);\n+\t\t\tcontinue;\n+\t\t}\n+\t\twsi-\u003edesc.sockfd \u003d context-\u003ept[n].dummy_pipe_fds[0];\n+\t\tlwsl_debug(\u0022event pipe fd %d\u005cn\u0022, wsi-\u003edesc.sockfd);\n+\n+\t\tcontext-\u003ept[n].pipe_wsi \u003d wsi;\n+\n+\t\tif (context-\u003eevent_loop_ops-\u003eaccept)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003eaccept(wsi);\n+\n+\t\tif (__insert_wsi_socket_into_fds(context, wsi))\n+\t\t\treturn 1;\n+\n+\t\t//lws_change_pollfd(context-\u003ept[n].pipe_wsi, 0, LWS_POLLIN);\n+\t\tcontext-\u003ecount_wsi_allocated++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+lws_destroy_event_pipe(struct lws *wsi)\n+{\n+\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n+\t__remove_wsi_socket_from_fds(wsi);\n+\n+\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close) {\n+\t\twsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close(wsi);\n+\t\tlws_plat_pipe_close(wsi);\n+\t\treturn;\n+\t}\n+\n+\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi)\n+\t\twsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi(wsi);\n+\tlws_plat_pipe_close(wsi);\n+\twsi-\u003econtext-\u003ecount_wsi_allocated--;\n+\tlws_free(wsi);\n+}\n+\n+LWS_VISIBLE struct lws_context *\n+lws_create_context(const struct lws_context_creation_info *info)\n+{\n+\tstruct lws_context *context \u003d NULL;\n+\tstruct lws_plat_file_ops *prev;\n+#ifndef LWS_NO_DAEMONIZE\n+\tint pid_daemon \u003d get_daemonize_pid();\n+#endif\n+\tint n;\n+#if defined(__ANDROID__)\n+\tstruct rlimit rt;\n+#endif\n+\n+\n+\n+\tlwsl_info(\u0022Initial logging level %d\u005cn\u0022, log_level);\n+\tlwsl_info(\u0022Libwebsockets version: %s\u005cn\u0022, library_version);\n+#if defined(GCC_VER)\n+\tlwsl_info(\u0022Compiled with %s\u005cn\u0022, GCC_VER);\n+#endif\n+\n+#ifdef LWS_WITH_IPV6\n+\tif (!lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_DISABLE_IPV6))\n+\t\tlwsl_info(\u0022IPV6 compiled in and enabled\u005cn\u0022);\n+\telse\n+\t\tlwsl_info(\u0022IPV6 compiled in but disabled\u005cn\u0022);\n+#else\n+\tlwsl_info(\u0022IPV6 not compiled in\u005cn\u0022);\n+#endif\n+\n+\tlwsl_info(\u0022 LWS_DEF_HEADER_LEN : %u\u005cn\u0022, LWS_DEF_HEADER_LEN);\n+\tlwsl_info(\u0022 LWS_MAX_PROTOCOLS : %u\u005cn\u0022, LWS_MAX_PROTOCOLS);\n+\tlwsl_info(\u0022 LWS_MAX_SMP : %u\u005cn\u0022, LWS_MAX_SMP);\n+\tlwsl_info(\u0022 sizeof (*info) : %ld\u005cn\u0022, (long)sizeof(*info));\n+#if defined(LWS_WITH_STATS)\n+\tlwsl_info(\u0022 LWS_WITH_STATS : on\u005cn\u0022);\n+#endif\n+\tlwsl_info(\u0022 SYSTEM_RANDOM_FILEPATH: '%s'\u005cn\u0022, SYSTEM_RANDOM_FILEPATH);\n+#if defined(LWS_WITH_HTTP2)\n+\tlwsl_info(\u0022 HTTP2 support : available\u005cn\u0022);\n+#else\n+\tlwsl_info(\u0022 HTTP2 support : not configured\u005cn\u0022);\n+#endif\n+\tif (lws_plat_context_early_init())\n+\t\treturn NULL;\n+\n+\tcontext \u003d lws_zalloc(sizeof(struct lws_context), \u0022context\u0022);\n+\tif (!context) {\n+\t\tlwsl_err(\u0022No memory for websocket context\u005cn\u0022);\n+\t\treturn NULL;\n+\t}\n+\n+#if defined(LWS_WITH_TLS)\n+#if defined(LWS_WITH_MBEDTLS)\n+\tcontext-\u003etls_ops \u003d \u0026tls_ops_mbedtls;\n+#else\n+\tcontext-\u003etls_ops \u003d \u0026tls_ops_openssl;\n+#endif\n+#endif\n+\n+\tif (info-\u003ept_serv_buf_size)\n+\t\tcontext-\u003ept_serv_buf_size \u003d info-\u003ept_serv_buf_size;\n+\telse\n+\t\tcontext-\u003ept_serv_buf_size \u003d 4096;\n+\n+#if defined(LWS_ROLE_H2)\n+\trole_ops_h2.init_context(context, info);\n+#endif\n+\n+#if LWS_MAX_SMP \u003e 1\n+\tpthread_mutex_init(\u0026context-\u003elock, NULL);\n+#endif\n+\n+#if defined(LWS_WITH_ESP32)\n+\tcontext-\u003elast_free_heap \u003d esp_get_free_heap_size();\n+#endif\n+\n+\t/* default to just the platform fops implementation */\n+\n+\tcontext-\u003efops_platform.LWS_FOP_OPEN\t\u003d _lws_plat_file_open;\n+\tcontext-\u003efops_platform.LWS_FOP_CLOSE\t\u003d _lws_plat_file_close;\n+\tcontext-\u003efops_platform.LWS_FOP_SEEK_CUR\t\u003d _lws_plat_file_seek_cur;\n+\tcontext-\u003efops_platform.LWS_FOP_READ\t\u003d _lws_plat_file_read;\n+\tcontext-\u003efops_platform.LWS_FOP_WRITE\t\u003d _lws_plat_file_write;\n+\tcontext-\u003efops_platform.fi[0].sig\t\u003d NULL;\n+\n+\t/*\n+\t * arrange a linear linked-list of fops starting from context-\u003efops\n+\t *\n+\t * platform fops\n+\t * [ -\u003e fops_zip (copied into context so .next settable) ]\n+\t * [ -\u003e info-\u003efops ]\n+\t */\n+\n+\tcontext-\u003efops \u003d \u0026context-\u003efops_platform;\n+\tprev \u003d (struct lws_plat_file_ops *)context-\u003efops;\n+\n+#if defined(LWS_WITH_ZIP_FOPS)\n+\t/* make a soft copy so we can set .next */\n+\tcontext-\u003efops_zip \u003d fops_zip;\n+\tprev-\u003enext \u003d \u0026context-\u003efops_zip;\n+\tprev \u003d (struct lws_plat_file_ops *)prev-\u003enext;\n+#endif\n+\n+\t/* if user provided fops, tack them on the end of the list */\n+\tif (info-\u003efops)\n+\t\tprev-\u003enext \u003d info-\u003efops;\n+\n+\tcontext-\u003ereject_service_keywords \u003d info-\u003ereject_service_keywords;\n+\tif (info-\u003eexternal_baggage_free_on_destroy)\n+\t\tcontext-\u003eexternal_baggage_free_on_destroy \u003d\n+\t\t\tinfo-\u003eexternal_baggage_free_on_destroy;\n+\n+\tcontext-\u003etime_up \u003d time(NULL);\n+\tcontext-\u003epcontext_finalize \u003d info-\u003epcontext;\n+\n+\tcontext-\u003esimultaneous_ssl_restriction \u003d\n+\t\t\tinfo-\u003esimultaneous_ssl_restriction;\n+\n+#ifndef LWS_NO_DAEMONIZE\n+\tif (pid_daemon) {\n+\t\tcontext-\u003estarted_with_parent \u003d pid_daemon;\n+\t\tlwsl_info(\u0022 Started with daemon pid %d\u005cn\u0022, pid_daemon);\n+\t}\n+#endif\n+#if defined(__ANDROID__)\n+\t\tn \u003d getrlimit ( RLIMIT_NOFILE,\u0026rt);\n+\t\tif (-1 \u003d\u003d n) {\n+\t\t\tlwsl_err(\u0022Get RLIMIT_NOFILE failed!\u005cn\u0022);\n+\t\t\treturn NULL;\n+\t\t}\n+\t\tcontext-\u003emax_fds \u003d rt.rlim_cur;\n+#else\n+\t\tcontext-\u003emax_fds \u003d getdtablesize();\n+#endif\n+\n+\tif (info-\u003ecount_threads)\n+\t\tcontext-\u003ecount_threads \u003d info-\u003ecount_threads;\n+\telse\n+\t\tcontext-\u003ecount_threads \u003d 1;\n+\n+\tif (context-\u003ecount_threads \u003e LWS_MAX_SMP)\n+\t\tcontext-\u003ecount_threads \u003d LWS_MAX_SMP;\n+\n+\tcontext-\u003etoken_limits \u003d info-\u003etoken_limits;\n+\n+\tcontext-\u003eoptions \u003d info-\u003eoptions;\n+\n+\t/*\n+\t * set the context event loops ops struct\n+\t *\n+\t * after this, all event_loop actions use the generic ops\n+\t */\n+\n+#if defined(LWS_WITH_POLL)\n+\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_poll;\n+#endif\n+\n+\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_LIBUV))\n+#if defined(LWS_WITH_LIBUV)\n+\t\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_uv;\n+#else\n+\t\tgoto fail_event_libs;\n+#endif\n+\n+\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_LIBEV))\n+#if defined(LWS_WITH_LIBEV)\n+\t\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_ev;\n+#else\n+\t\tgoto fail_event_libs;\n+#endif\n+\n+\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_LIBEVENT))\n+#if defined(LWS_WITH_LIBEVENT)\n+\t\tcontext-\u003eevent_loop_ops \u003d \u0026event_loop_ops_event;\n+#else\n+\t\tgoto fail_event_libs;\n+#endif\n+\n+\tif (!context-\u003eevent_loop_ops)\n+\t\tgoto fail_event_libs;\n+\n+\tlwsl_info(\u0022Using event loop: %s\u005cn\u0022, context-\u003eevent_loop_ops-\u003ename);\n+\n+#if defined(LWS_WITH_TLS)\n+\ttime(\u0026context-\u003etls.last_cert_check_s);\n+\tif (info-\u003ealpn)\n+\t\tcontext-\u003etls.alpn_default \u003d info-\u003ealpn;\n+\telse {\n+\t\tchar *p \u003d context-\u003etls.alpn_discovered, first \u003d 1;\n+\n+\t\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) {\n+\t\t\tif (ar-\u003ealpn) {\n+\t\t\t\tif (!first)\n+\t\t\t\t\t*p++ \u003d ',';\n+\t\t\t\tp +\u003d lws_snprintf(p,\n+\t\t\t\t\tcontext-\u003etls.alpn_discovered +\n+\t\t\t\t\tsizeof(context-\u003etls.alpn_discovered) -\n+\t\t\t\t\t2 - p, \u0022%s\u0022, ar-\u003ealpn);\n+\t\t\t\tfirst \u003d 0;\n+\t\t\t}\n+\t\t} LWS_FOR_EVERY_AVAILABLE_ROLE_END;\n+\n+\t\tcontext-\u003etls.alpn_default \u003d context-\u003etls.alpn_discovered;\n+\t}\n+\n+\tlwsl_info(\u0022Default ALPN advertisment: %s\u005cn\u0022, context-\u003etls.alpn_default);\n+#endif\n+\n+\tif (info-\u003etimeout_secs)\n+\t\tcontext-\u003etimeout_secs \u003d info-\u003etimeout_secs;\n+\telse\n+\t\tcontext-\u003etimeout_secs \u003d AWAITING_TIMEOUT;\n+\n+\tcontext-\u003ews_ping_pong_interval \u003d info-\u003ews_ping_pong_interval;\n+\n+\tlwsl_info(\u0022 default timeout (secs): %u\u005cn\u0022, context-\u003etimeout_secs);\n+\n+\tif (info-\u003emax_http_header_data)\n+\t\tcontext-\u003emax_http_header_data \u003d info-\u003emax_http_header_data;\n+\telse\n+\t\tif (info-\u003emax_http_header_data2)\n+\t\t\tcontext-\u003emax_http_header_data \u003d\n+\t\t\t\t\tinfo-\u003emax_http_header_data2;\n+\t\telse\n+\t\t\tcontext-\u003emax_http_header_data \u003d LWS_DEF_HEADER_LEN;\n+\n+\tif (info-\u003emax_http_header_pool)\n+\t\tcontext-\u003emax_http_header_pool \u003d info-\u003emax_http_header_pool;\n+\telse\n+\t\tcontext-\u003emax_http_header_pool \u003d context-\u003emax_fds;\n+\n+\tif (info-\u003efd_limit_per_thread)\n+\t\tcontext-\u003efd_limit_per_thread \u003d info-\u003efd_limit_per_thread;\n+\telse\n+\t\tcontext-\u003efd_limit_per_thread \u003d context-\u003emax_fds /\n+\t\t\t\t\t context-\u003ecount_threads;\n+\n+\t/*\n+\t * Allocate the per-thread storage for scratchpad buffers,\n+\t * and header data pool\n+\t */\n+\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\tcontext-\u003ept[n].serv_buf \u003d lws_malloc(context-\u003ept_serv_buf_size,\n+\t\t\t\t\t\t \u0022pt_serv_buf\u0022);\n+\t\tif (!context-\u003ept[n].serv_buf) {\n+\t\t\tlwsl_err(\u0022OOM\u005cn\u0022);\n+\t\t\treturn NULL;\n+\t\t}\n+\n+\t\tcontext-\u003ept[n].context \u003d context;\n+\t\tcontext-\u003ept[n].tid \u003d n;\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\t\tcontext-\u003ept[n].http.ah_list \u003d NULL;\n+\t\tcontext-\u003ept[n].http.ah_pool_length \u003d 0;\n+#endif\n+\t\tlws_pt_mutex_init(\u0026context-\u003ept[n]);\n+\t}\n+\n+\tlwsl_info(\u0022 Threads: %d each %d fds\u005cn\u0022, context-\u003ecount_threads,\n+\t\t context-\u003efd_limit_per_thread);\n+\n+\tif (!info-\u003eka_interval \u0026\u0026 info-\u003eka_time \u003e 0) {\n+\t\tlwsl_err(\u0022info-\u003eka_interval can't be 0 if ka_time used\u005cn\u0022);\n+\t\treturn NULL;\n+\t}\n+\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\t/* scale the peer hash table according to the max fds for the process,\n+\t * so that the max list depth averages 16. Eg, 1024 fd -\u003e 64,\n+\t * 102400 fd -\u003e 6400\n+\t */\n+\tcontext-\u003epl_hash_elements \u003d\n+\t\t(context-\u003ecount_threads * context-\u003efd_limit_per_thread) / 16;\n+\tcontext-\u003epl_hash_table \u003d lws_zalloc(sizeof(struct lws_peer *) *\n+\t\t\tcontext-\u003epl_hash_elements, \u0022peer limits hash table\u0022);\n+\tcontext-\u003eip_limit_ah \u003d info-\u003eip_limit_ah;\n+\tcontext-\u003eip_limit_wsi \u003d info-\u003eip_limit_wsi;\n+#endif\n+\n+\tlwsl_info(\u0022 mem: context: %5lu B (%ld ctx + (%ld thr x %d))\u005cn\u0022,\n+\t\t (long)sizeof(struct lws_context) +\n+\t\t (context-\u003ecount_threads * context-\u003ept_serv_buf_size),\n+\t\t (long)sizeof(struct lws_context),\n+\t\t (long)context-\u003ecount_threads,\n+\t\t context-\u003ept_serv_buf_size);\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tlwsl_info(\u0022 mem: http hdr rsvd: %5lu B (%u thr x (%u + %lu) x %u))\u005cn\u0022,\n+\t\t (long)(context-\u003emax_http_header_data +\n+\t\t sizeof(struct allocated_headers)) *\n+\t\t context-\u003emax_http_header_pool * context-\u003ecount_threads,\n+\t\t context-\u003ecount_threads,\n+\t\t context-\u003emax_http_header_data,\n+\t\t (long)sizeof(struct allocated_headers),\n+\t\t context-\u003emax_http_header_pool);\n+#endif\n+\tn \u003d sizeof(struct lws_pollfd) * context-\u003ecount_threads *\n+\t context-\u003efd_limit_per_thread;\n+\tcontext-\u003ept[0].fds \u003d lws_zalloc(n, \u0022fds table\u0022);\n+\tif (context-\u003ept[0].fds \u003d\u003d NULL) {\n+\t\tlwsl_err(\u0022OOM allocating %d fds\u005cn\u0022, context-\u003emax_fds);\n+\t\tgoto bail;\n+\t}\n+\tlwsl_info(\u0022 mem: pollfd map: %5u\u005cn\u0022, n);\n+\n+\tif (info-\u003eserver_string) {\n+\t\tcontext-\u003eserver_string \u003d info-\u003eserver_string;\n+\t\tcontext-\u003eserver_string_len \u003d (short)\n+\t\t\t\tstrlen(context-\u003eserver_string);\n+\t}\n+\n+#if LWS_MAX_SMP \u003e 1\n+\t/* each thread serves his own chunk of fds */\n+\tfor (n \u003d 1; n \u003c (int)info-\u003ecount_threads; n++)\n+\t\tcontext-\u003ept[n].fds \u003d context-\u003ept[n - 1].fds +\n+\t\t\t\t context-\u003efd_limit_per_thread;\n+#endif\n+\n+\tif (lws_plat_init(context, info))\n+\t\tgoto bail;\n+\n+\tif (context-\u003eevent_loop_ops-\u003einit_context)\n+\t\tif (context-\u003eevent_loop_ops-\u003einit_context(context, info))\n+\t\t\tgoto bail;\n+\n+\n+\tif (context-\u003eevent_loop_ops-\u003einit_pt)\n+\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\t\tvoid *lp \u003d NULL;\n+\n+\t\t\tif (info-\u003eforeign_loops)\n+\t\t\t\tlp \u003d info-\u003eforeign_loops[n];\n+\n+\t\t\tif (context-\u003eevent_loop_ops-\u003einit_pt(context, lp, n))\n+\t\t\t\tgoto bail;\n+\t\t}\n+\n+\tif (lws_create_event_pipes(context))\n+\t\tgoto bail;\n+\n+\tlws_context_init_ssl_library(info);\n+\n+\tcontext-\u003euser_space \u003d info-\u003euser;\n+\n+\t/*\n+\t * if he's not saying he'll make his own vhosts later then act\n+\t * compatibly and make a default vhost using the data in the info\n+\t */\n+\tif (!lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n+\t\tif (!lws_create_vhost(context, info)) {\n+\t\t\tlwsl_err(\u0022Failed to create default vhost\u005cn\u0022);\n+\t\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++)\n+\t\t\t\tlws_free_set_NULL(context-\u003ept[n].serv_buf);\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\t\t\tlws_free_set_NULL(context-\u003epl_hash_table);\n+#endif\n+\t\t\tlws_free_set_NULL(context-\u003ept[0].fds);\n+\t\t\tlws_plat_context_late_destroy(context);\n+\t\t\tlws_free_set_NULL(context);\n+\t\t\treturn NULL;\n+\t\t}\n+\n+\tlws_context_init_extensions(info, context);\n+\n+\tlwsl_info(\u0022 mem: per-conn: %5lu bytes + protocol rx buf\u005cn\u0022,\n+\t\t (unsigned long)sizeof(struct lws));\n+\n+\tstrcpy(context-\u003ecanonical_hostname, \u0022unknown\u0022);\n+\tlws_server_get_canonical_hostname(context, info);\n+\n+\tcontext-\u003euid \u003d info-\u003euid;\n+\tcontext-\u003egid \u003d info-\u003egid;\n+\n+#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n+\tmemcpy(context-\u003ecaps, info-\u003ecaps, sizeof(context-\u003ecaps));\n+\tcontext-\u003ecount_caps \u003d info-\u003ecount_caps;\n+#endif\n+\n+\t/*\n+\t * drop any root privs for this process\n+\t * to listen on port \u003c 1023 we would have needed root, but now we are\n+\t * listening, we don't want the power for anything else\n+\t */\n+\tif (!lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n+\t\tlws_plat_drop_app_privileges(info);\n+\n+\t/* expedite post-context init (eg, protocols) */\n+\tlws_cancel_service(context);\n+\n+#if defined(LWS_WITH_SELFTESTS)\n+\tlws_jws_selftest();\n+#endif\n+\n+\treturn context;\n+\n+bail:\n+\tlws_context_destroy(context);\n+\n+\treturn NULL;\n+\n+fail_event_libs:\n+\tlwsl_err(\u0022Requested event library support not configured, available:\u005cn\u0022);\n+\t{\n+\t\tconst struct lws_event_loop_ops **elops \u003d available_event_libs;\n+\n+\t\twhile (*elops) {\n+\t\t\tlwsl_err(\u0022 - %s\u005cn\u0022, (*elops)-\u003ename);\n+\t\t\telops++;\n+\t\t}\n+\t}\n+\tlws_free(context);\n+\n+\treturn NULL;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_context_deprecate(struct lws_context *context, lws_reload_func cb)\n+{\n+\tstruct lws_vhost *vh \u003d context-\u003evhost_list, *vh1;\n+\tstruct lws *wsi;\n+\n+\t/*\n+\t * \u0022deprecation\u0022 means disable the context from accepting any new\n+\t * connections and free up listen sockets to be used by a replacement\n+\t * context.\n+\t *\n+\t * Otherwise the deprecated context remains operational, until its\n+\t * number of connected sockets falls to zero, when it is deleted.\n+\t */\n+\n+\t/* for each vhost, close his listen socket */\n+\n+\twhile (vh) {\n+\t\twsi \u003d vh-\u003elserv_wsi;\n+\t\tif (wsi) {\n+\t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, \u0022ctx deprecate\u0022);\n+\t\t\twsi-\u003econtext-\u003edeprecation_pending_listen_close_count++;\n+\t\t\t/*\n+\t\t\t * other vhosts can share the listen port, they\n+\t\t\t * point to the same wsi. So zap those too.\n+\t\t\t */\n+\t\t\tvh1 \u003d context-\u003evhost_list;\n+\t\t\twhile (vh1) {\n+\t\t\t\tif (vh1-\u003elserv_wsi \u003d\u003d wsi)\n+\t\t\t\t\tvh1-\u003elserv_wsi \u003d NULL;\n+\t\t\t\tvh1 \u003d vh1-\u003evhost_next;\n+\t\t\t}\n+\t\t}\n+\t\tvh \u003d vh-\u003evhost_next;\n+\t}\n+\n+\tcontext-\u003edeprecated \u003d 1;\n+\tcontext-\u003edeprecation_cb \u003d cb;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_context_is_deprecated(struct lws_context *context)\n+{\n+\treturn context-\u003edeprecated;\n+}\n+\n+void\n+lws_vhost_destroy1(struct lws_vhost *vh)\n+{\n+\tconst struct lws_protocols *protocol \u003d NULL;\n+\tstruct lws_context_per_thread *pt;\n+\tint n, m \u003d vh-\u003econtext-\u003ecount_threads;\n+\tstruct lws_context *context \u003d vh-\u003econtext;\n+\tstruct lws wsi;\n+\n+\tlwsl_info(\u0022%s\u005cn\u0022, __func__);\n+\n+\tif (vh-\u003ebeing_destroyed)\n+\t\treturn;\n+\n+\tvh-\u003ebeing_destroyed \u003d 1;\n+\n+\t/*\n+\t * Are there other vhosts that are piggybacking on our listen socket?\n+\t * If so we need to hand the listen socket off to one of the others\n+\t * so it will remain open. If not, leave it attached to the closing\n+\t * vhost and it will get closed.\n+\t */\n+\n+\tif (vh-\u003elserv_wsi)\n+\t\tlws_start_foreach_ll(struct lws_vhost *, v,\n+\t\t\t\t context-\u003evhost_list) {\n+\t\t\tif (v !\u003d vh \u0026\u0026\n+\t\t\t !v-\u003ebeing_destroyed \u0026\u0026\n+\t\t\t v-\u003elisten_port \u003d\u003d vh-\u003elisten_port \u0026\u0026\n+\t\t\t ((!v-\u003eiface \u0026\u0026 !vh-\u003eiface) ||\n+\t\t\t (v-\u003eiface \u0026\u0026 vh-\u003eiface \u0026\u0026\n+\t\t\t !strcmp(v-\u003eiface, vh-\u003eiface)))) {\n+\t\t\t\t/*\n+\t\t\t\t * this can only be a listen wsi, which is\n+\t\t\t\t * restricted... it has no protocol or other\n+\t\t\t\t * bindings or states. So we can simply\n+\t\t\t\t * swap it to a vhost that has the same\n+\t\t\t\t * iface + port, but is not closing.\n+\t\t\t\t */\n+\t\t\t\tassert(v-\u003elserv_wsi \u003d\u003d NULL);\n+\t\t\t\tv-\u003elserv_wsi \u003d vh-\u003elserv_wsi;\n+\t\t\t\tvh-\u003elserv_wsi \u003d NULL;\n+\t\t\t\tif (v-\u003elserv_wsi)\n+\t\t\t\t\tv-\u003elserv_wsi-\u003evhost \u003d v;\n+\n+\t\t\t\tlwsl_notice(\u0022%s: listen skt from %s to %s\u005cn\u0022,\n+\t\t\t\t\t __func__, vh-\u003ename, v-\u003ename);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t} lws_end_foreach_ll(v, vhost_next);\n+\n+\t/*\n+\t * Forcibly close every wsi assoicated with this vhost. That will\n+\t * include the listen socket if it is still associated with the closing\n+\t * vhost.\n+\t */\n+\n+\twhile (m--) {\n+\t\tpt \u003d \u0026context-\u003ept[m];\n+\n+\t\tfor (n \u003d 0; (unsigned int)n \u003c context-\u003ept[m].fds_count; n++) {\n+\t\t\tstruct lws *wsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n+\t\t\tif (!wsi)\n+\t\t\t\tcontinue;\n+\t\t\tif (wsi-\u003evhost !\u003d vh)\n+\t\t\t\tcontinue;\n+\n+\t\t\tlws_close_free_wsi(wsi,\n+\t\t\t\tLWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY,\n+\t\t\t\t\u0022vh destroy\u0022\n+\t\t\t\t/* no protocol close */);\n+\t\t\tn--;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * destroy any pending timed events\n+\t */\n+\n+\twhile (vh-\u003etimed_vh_protocol_list)\n+\t\tlws_timed_callback_remove(vh, vh-\u003etimed_vh_protocol_list);\n+\n+\t/*\n+\t * let the protocols destroy the per-vhost protocol objects\n+\t */\n+\n+\tmemset(\u0026wsi, 0, sizeof(wsi));\n+\twsi.context \u003d vh-\u003econtext;\n+\twsi.vhost \u003d vh;\n+\tprotocol \u003d vh-\u003eprotocols;\n+\tif (protocol \u0026\u0026 vh-\u003ecreated_vhost_protocols) {\n+\t\tn \u003d 0;\n+\t\twhile (n \u003c vh-\u003ecount_protocols) {\n+\t\t\twsi.protocol \u003d protocol;\n+\t\t\tprotocol-\u003ecallback(\u0026wsi, LWS_CALLBACK_PROTOCOL_DESTROY,\n+\t\t\t\t\t NULL, NULL, 0);\n+\t\t\tprotocol++;\n+\t\t\tn++;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * remove vhost from context list of vhosts\n+\t */\n+\n+\tlws_start_foreach_llp(struct lws_vhost **, pv, context-\u003evhost_list) {\n+\t\tif (*pv \u003d\u003d vh) {\n+\t\t\t*pv \u003d vh-\u003evhost_next;\n+\t\t\tbreak;\n+\t\t}\n+\t} lws_end_foreach_llp(pv, vhost_next);\n+\n+\t/* add ourselves to the pending destruction list */\n+\n+\tvh-\u003evhost_next \u003d vh-\u003econtext-\u003evhost_pending_destruction_list;\n+\tvh-\u003econtext-\u003evhost_pending_destruction_list \u003d vh;\n+}\n+\n+static void\n+lws_vhost_destroy2(struct lws_vhost *vh)\n+{\n+\tconst struct lws_protocols *protocol \u003d NULL;\n+\tstruct lws_context *context \u003d vh-\u003econtext;\n+\tstruct lws_deferred_free *df;\n+\tint n;\n+\n+\tlwsl_info(\u0022%s: %p\u005cn\u0022, __func__, vh);\n+\n+\t/* if we are still on deferred free list, remove ourselves */\n+\n+\tlws_start_foreach_llp(struct lws_deferred_free **, pdf,\n+\t\t\t context-\u003edeferred_free_list) {\n+\t\tif ((*pdf)-\u003epayload \u003d\u003d vh) {\n+\t\t\tdf \u003d *pdf;\n+\t\t\t*pdf \u003d df-\u003enext;\n+\t\t\tlws_free(df);\n+\t\t\tbreak;\n+\t\t}\n+\t} lws_end_foreach_llp(pdf, next);\n+\n+\t/* remove ourselves from the pending destruction list */\n+\n+\tlws_start_foreach_llp(struct lws_vhost **, pv,\n+\t\t\t context-\u003evhost_pending_destruction_list) {\n+\t\tif ((*pv) \u003d\u003d vh) {\n+\t\t\t*pv \u003d (*pv)-\u003evhost_next;\n+\t\t\tbreak;\n+\t\t}\n+\t} lws_end_foreach_llp(pv, vhost_next);\n+\n+\t/*\n+\t * Free all the allocations associated with the vhost\n+\t */\n+\n+\tprotocol \u003d vh-\u003eprotocols;\n+\tif (protocol) {\n+\t\tn \u003d 0;\n+\t\twhile (n \u003c vh-\u003ecount_protocols) {\n+\t\t\tif (vh-\u003eprotocol_vh_privs \u0026\u0026\n+\t\t\t vh-\u003eprotocol_vh_privs[n]) {\n+\t\t\t\tlws_free(vh-\u003eprotocol_vh_privs[n]);\n+\t\t\t\tvh-\u003eprotocol_vh_privs[n] \u003d NULL;\n+\t\t\t}\n+\t\t\tprotocol++;\n+\t\t\tn++;\n+\t\t}\n+\t}\n+\tif (vh-\u003eprotocol_vh_privs)\n+\t\tlws_free(vh-\u003eprotocol_vh_privs);\n+\tlws_ssl_SSL_CTX_destroy(vh);\n+\tlws_free(vh-\u003esame_vh_protocol_list);\n+\n+\tif (context-\u003eplugin_list ||\n+\t (context-\u003eoptions \u0026 LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n+\t\tlws_free((void *)vh-\u003eprotocols);\n+\n+\tLWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)\n+\t\tif (ar-\u003edestroy_vhost)\n+\t\t\tar-\u003edestroy_vhost(vh);\n+\tLWS_FOR_EVERY_AVAILABLE_ROLE_END;\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+\tif (vh-\u003elog_fd !\u003d (int)LWS_INVALID_FILE)\n+\t\tclose(vh-\u003elog_fd);\n+#endif\n+\n+#if defined (LWS_WITH_TLS)\n+\tlws_free_set_NULL(vh-\u003etls.alloc_cert_path);\n+#endif\n+\n+#if LWS_MAX_SMP \u003e 1\n+ pthread_mutex_destroy(\u0026vh-\u003elock);\n+#endif\n+\n+#if defined(LWS_WITH_UNIX_SOCK)\n+\tif (LWS_UNIX_SOCK_ENABLED(context)) {\n+\t\tn \u003d unlink(vh-\u003eiface);\n+\t\tif (n)\n+\t\t\tlwsl_info(\u0022Closing unix socket %s: errno %d\u005cn\u0022,\n+\t\t\t\t vh-\u003eiface, errno);\n+\t}\n+#endif\n+\t/*\n+\t * although async event callbacks may still come for wsi handles with\n+\t * pending close in the case of asycn event library like libuv,\n+\t * they do not refer to the vhost. So it's safe to free.\n+\t */\n+\n+\tlwsl_info(\u0022 %s: Freeing vhost %p\u005cn\u0022, __func__, vh);\n+\n+\tmemset(vh, 0, sizeof(*vh));\n+\tlws_free(vh);\n+}\n+\n+int\n+lws_check_deferred_free(struct lws_context *context, int force)\n+{\n+\tstruct lws_deferred_free *df;\n+\ttime_t now \u003d lws_now_secs();\n+\n+\tlws_start_foreach_llp(struct lws_deferred_free **, pdf,\n+\t\t\t context-\u003edeferred_free_list) {\n+\t\tif (force ||\n+\t\t lws_compare_time_t(context, now, (*pdf)-\u003edeadline) \u003e 5) {\n+\t\t\tdf \u003d *pdf;\n+\t\t\t*pdf \u003d df-\u003enext;\n+\t\t\t/* finalize vh destruction */\n+\t\t\tlwsl_notice(\u0022deferred vh %p destroy\u005cn\u0022, df-\u003epayload);\n+\t\t\tlws_vhost_destroy2(df-\u003epayload);\n+\t\t\tlws_free(df);\n+\t\t\tcontinue; /* after deletion we already point to next */\n+\t\t}\n+\t} lws_end_foreach_llp(pdf, next);\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE void\n+lws_vhost_destroy(struct lws_vhost *vh)\n+{\n+\tstruct lws_deferred_free *df \u003d lws_malloc(sizeof(*df), \u0022deferred free\u0022);\n+\n+\tif (!df)\n+\t\treturn;\n+\n+\tlws_vhost_destroy1(vh);\n+\n+\t/* part 2 is deferred to allow all the handle closes to complete */\n+\n+\tdf-\u003enext \u003d vh-\u003econtext-\u003edeferred_free_list;\n+\tdf-\u003edeadline \u003d lws_now_secs();\n+\tdf-\u003epayload \u003d vh;\n+\tvh-\u003econtext-\u003edeferred_free_list \u003d df;\n+}\n+\n+/*\n+ * When using an event loop, the context destruction is in three separate\n+ * parts. This is to cover both internal and foreign event loops cleanly.\n+ *\n+ * - lws_context_destroy() simply starts a soft close of all wsi and\n+ * related allocations. The event loop continues.\n+ *\n+ * As the closes complete in the event loop, reference counting is used\n+ * to determine when everything is closed. It then calls\n+ * lws_context_destroy2().\n+ *\n+ * - lws_context_destroy2() cleans up the rest of the higher-level logical\n+ * lws pieces like vhosts. If the loop was foreign, it then proceeds to\n+ * lws_context_destroy3(). If it the loop is internal, it stops the\n+ * internal loops and waits for lws_context_destroy() to be called again\n+ * outside the event loop (since we cannot destroy the loop from\n+ * within the loop). That will cause lws_context_destroy3() to run\n+ * directly.\n+ *\n+ * - lws_context_destroy3() destroys any internal event loops and then\n+ * destroys the context itself, setting what was info.pcontext to NULL.\n+ */\n+\n+/*\n+ * destroy the actual context itself\n+ */\n+\n+static void\n+lws_context_destroy3(struct lws_context *context)\n+{\n+\tstruct lws_context **pcontext_finalize \u003d context-\u003epcontext_finalize;\n+\tstruct lws_context_per_thread *pt;\n+\tint n;\n+\n+\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\tpt \u003d \u0026context-\u003ept[n];\n+\n+\t\tif (context-\u003eevent_loop_ops-\u003edestroy_pt)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003edestroy_pt(context, n);\n+\n+\t\tlws_free_set_NULL(context-\u003ept[n].serv_buf);\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\t\twhile (pt-\u003ehttp.ah_list)\n+\t\t\t_lws_destroy_ah(pt, pt-\u003ehttp.ah_list);\n+#endif\n+\t}\n+\n+\tlws_free(context);\n+\tlwsl_info(\u0022%s: ctx %p freed\u005cn\u0022, __func__, context);\n+\n+\tif (pcontext_finalize)\n+\t\t*pcontext_finalize \u003d NULL;\n+}\n+\n+/*\n+ * really start destroying things\n+ */\n+\n+void\n+lws_context_destroy2(struct lws_context *context)\n+{\n+\tstruct lws_vhost *vh \u003d NULL, *vh1;\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tuint32_t nu;\n+#endif\n+\tint n;\n+\n+\tlwsl_info(\u0022%s: ctx %p\u005cn\u0022, __func__, context);\n+\n+\tcontext-\u003ebeing_destroyed2 \u003d 1;\n+\n+\tif (context-\u003ept[0].fds)\n+\t\tlws_free_set_NULL(context-\u003ept[0].fds);\n+\n+\t/*\n+\t * free all the per-vhost allocations\n+\t */\n+\n+\tvh \u003d context-\u003evhost_list;\n+\twhile (vh) {\n+\t\tvh1 \u003d vh-\u003evhost_next;\n+\t\tlws_vhost_destroy2(vh);\n+\t\tvh \u003d vh1;\n+\t}\n+\n+\t/* remove ourselves from the pending destruction list */\n+\n+\twhile (context-\u003evhost_pending_destruction_list)\n+\t\t/* removes itself from list */\n+\t\tlws_vhost_destroy2(context-\u003evhost_pending_destruction_list);\n+\n+\n+\tlws_stats_log_dump(context);\n+\n+\tlws_ssl_context_destroy(context);\n+\tlws_plat_context_late_destroy(context);\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tfor (nu \u003d 0; nu \u003c context-\u003epl_hash_elements; nu++)\t{\n+\t\tlws_start_foreach_llp(struct lws_peer **, peer,\n+\t\t\t\t context-\u003epl_hash_table[nu]) {\n+\t\t\tstruct lws_peer *df \u003d *peer;\n+\t\t\t*peer \u003d df-\u003enext;\n+\t\t\tlws_free(df);\n+\t\t\tcontinue;\n+\t\t} lws_end_foreach_llp(peer, next);\n+\t}\n+\tlws_free(context-\u003epl_hash_table);\n+#endif\n+\n+\tif (context-\u003eexternal_baggage_free_on_destroy)\n+\t\tfree(context-\u003eexternal_baggage_free_on_destroy);\n+\n+\tlws_check_deferred_free(context, 1);\n+\n+#if LWS_MAX_SMP \u003e 1\n+\tpthread_mutex_destroy(\u0026context-\u003elock);\n+#endif\n+\n+\tif (context-\u003eevent_loop_ops-\u003edestroy_context2)\n+\t\tif (context-\u003eevent_loop_ops-\u003edestroy_context2(context)) {\n+\t\t\tcontext-\u003efinalize_destroy_after_internal_loops_stopped \u003d 1;\n+\t\t\treturn;\n+\t\t}\n+\n+\tif (!context-\u003ept[0].event_loop_foreign)\n+\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++)\n+\t\t\tif (context-\u003ept[n].inside_service)\n+\t\t\t\treturn;\n+\n+\tlws_context_destroy3(context);\n+}\n+\n+/*\n+ * Begin the context takedown\n+ */\n+\n+LWS_VISIBLE void\n+lws_context_destroy(struct lws_context *context)\n+{\n+\tvolatile struct lws_foreign_thread_pollfd *ftp, *next;\n+\tvolatile struct lws_context_per_thread *vpt;\n+\tstruct lws_context_per_thread *pt;\n+\tstruct lws_vhost *vh \u003d NULL;\n+\tstruct lws wsi;\n+\tint n, m;\n+\n+\tif (!context)\n+\t\treturn;\n+\n+\tif (context-\u003efinalize_destroy_after_internal_loops_stopped) {\n+\t\tif (context-\u003eevent_loop_ops-\u003edestroy_context2)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003edestroy_context2(context);\n+\n+\t\tlws_context_destroy3(context);\n+\n+\t\treturn;\n+\t}\n+\n+\tif (context-\u003ebeing_destroyed1) {\n+\t\tif (!context-\u003ebeing_destroyed2) {\n+\t\t\tlws_context_destroy2(context);\n+\n+\t\t\treturn;\n+\t\t}\n+\t\tlwsl_info(\u0022%s: ctx %p: already being destroyed\u005cn\u0022,\n+\t\t\t __func__, context);\n+\n+\t\tlws_context_destroy3(context);\n+\t\treturn;\n+\t}\n+\n+\tlwsl_info(\u0022%s: ctx %p\u005cn\u0022, __func__, context);\n+\n+\tm \u003d context-\u003ecount_threads;\n+\tcontext-\u003ebeing_destroyed \u003d 1;\n+\tcontext-\u003ebeing_destroyed1 \u003d 1;\n+\tcontext-\u003erequested_kill \u003d 1;\n+\n+\tmemset(\u0026wsi, 0, sizeof(wsi));\n+\twsi.context \u003d context;\n+\n+#ifdef LWS_LATENCY\n+\tif (context-\u003eworst_latency_info[0])\n+\t\tlwsl_notice(\u0022Worst latency: %s\u005cn\u0022, context-\u003eworst_latency_info);\n+#endif\n+\n+\twhile (m--) {\n+\t\tpt \u003d \u0026context-\u003ept[m];\n+\t\tvpt \u003d (volatile struct lws_context_per_thread *)pt;\n+\n+\t\tftp \u003d vpt-\u003eforeign_pfd_list;\n+\t\twhile (ftp) {\n+\t\t\tnext \u003d ftp-\u003enext;\n+\t\t\tlws_free((void *)ftp);\n+\t\t\tftp \u003d next;\n+\t\t}\n+\t\tvpt-\u003eforeign_pfd_list \u003d NULL;\n+\n+\t\tfor (n \u003d 0; (unsigned int)n \u003c context-\u003ept[m].fds_count; n++) {\n+\t\t\tstruct lws *wsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n+\t\t\tif (!wsi)\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (wsi-\u003eevent_pipe)\n+\t\t\t\tlws_destroy_event_pipe(wsi);\n+\t\t\telse\n+\t\t\t\tlws_close_free_wsi(wsi,\n+\t\t\t\t\tLWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY,\n+\t\t\t\t\t\u0022ctx destroy\u0022\n+\t\t\t\t\t/* no protocol close */);\n+\t\t\tn--;\n+\t\t}\n+\t\tlws_pt_mutex_destroy(pt);\n+\t}\n+\n+\t/*\n+\t * inform all the protocols that they are done and will have no more\n+\t * callbacks.\n+\t *\n+\t * We can't free things until after the event loop shuts down.\n+\t */\n+\tif (context-\u003eprotocol_init_done)\n+\t\tvh \u003d context-\u003evhost_list;\n+\twhile (vh) {\n+\t\tstruct lws_vhost *vhn \u003d vh-\u003evhost_next;\n+\t\tlws_vhost_destroy1(vh);\n+\t\tvh \u003d vhn;\n+\t}\n+\n+\tlws_plat_context_early_destroy(context);\n+\n+\t/*\n+\t * We face two different needs depending if foreign loop or not.\n+\t *\n+\t * 1) If foreign loop, we really want to advance the destroy_context()\n+\t * past here, and block only for libuv-style async close completion.\n+\t *\n+\t * 2a) If poll, and we exited by ourselves and are calling a final\n+\t * destroy_context() outside of any service already, we want to\n+\t * advance all the way in one step.\n+\t *\n+\t * 2b) If poll, and we are reacting to a SIGINT, service thread(s) may\n+\t * be in poll wait or servicing. We can't advance the\n+\t * destroy_context() to the point it's freeing things; we have to\n+\t * leave that for the final destroy_context() after the service\n+\t * thread(s) are finished calling for service.\n+\t */\n+\n+\tif (context-\u003eevent_loop_ops-\u003edestroy_context1) {\n+\t\tcontext-\u003eevent_loop_ops-\u003edestroy_context1(context);\n+\n+\t\treturn;\n+\t}\n+\n+\tlws_context_destroy2(context);\n+}\ndiff --git a/lib/core/libwebsockets.c b/lib/core/libwebsockets.c\nnew file mode 100644\nindex 0000000..343b63b\n--- /dev/null\n+++ b/lib/core/libwebsockets.c\n@@ -0,0 +1,3429 @@\n+/*\n+ * libwebsockets - small server side websockets and web server implementation\n+ *\n+ * Copyright (C) 2010-2017 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022core/private.h\u0022\n+\n+#ifdef LWS_HAVE_SYS_TYPES_H\n+#include \u003csys/types.h\u003e\n+#endif\n+\n+#ifdef LWS_WITH_IPV6\n+#if defined(WIN32) || defined(_WIN32)\n+#include \u003cwincrypt.h\u003e\n+#include \u003cIphlpapi.h\u003e\n+#else\n+#include \u003cnet/if.h\u003e\n+#endif\n+#endif\n+\n+int log_level \u003d LLL_ERR | LLL_WARN | LLL_NOTICE;\n+static void (*lwsl_emit)(int level, const char *line)\n+#ifndef LWS_PLAT_OPTEE\n+\t\u003d lwsl_emit_stderr\n+#endif\n+\t;\n+#ifndef LWS_PLAT_OPTEE\n+static const char * const log_level_names[] \u003d {\n+\t\u0022ERR\u0022,\n+\t\u0022WARN\u0022,\n+\t\u0022NOTICE\u0022,\n+\t\u0022INFO\u0022,\n+\t\u0022DEBUG\u0022,\n+\t\u0022PARSER\u0022,\n+\t\u0022HEADER\u0022,\n+\t\u0022EXTENSION\u0022,\n+\t\u0022CLIENT\u0022,\n+\t\u0022LATENCY\u0022,\n+\t\u0022USER\u0022,\n+\t\u0022?\u0022,\n+\t\u0022?\u0022\n+};\n+#endif\n+\n+#if defined (_DEBUG)\n+void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role)\n+{\n+\twsi-\u003ewsistate \u003d (wsi-\u003ewsistate \u0026 (~LWSI_ROLE_MASK)) | role;\n+\n+\tlwsl_debug(\u0022lwsi_set_role(%p, 0x%x)\u005cn\u0022, wsi, wsi-\u003ewsistate);\n+}\n+\n+void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs)\n+{\n+\twsi-\u003ewsistate \u003d (wsi-\u003ewsistate \u0026 (~LRS_MASK)) | lrs;\n+\n+\tlwsl_debug(\u0022lwsi_set_state(%p, 0x%x)\u005cn\u0022, wsi, wsi-\u003ewsistate);\n+}\n+#endif\n+\n+signed char char_to_hex(const char c)\n+{\n+\tif (c \u003e\u003d '0' \u0026\u0026 c \u003c\u003d '9')\n+\t\treturn c - '0';\n+\n+\tif (c \u003e\u003d 'a' \u0026\u0026 c \u003c\u003d 'f')\n+\t\treturn c - 'a' + 10;\n+\n+\tif (c \u003e\u003d 'A' \u0026\u0026 c \u003c\u003d 'F')\n+\t\treturn c - 'A' + 10;\n+\n+\treturn -1;\n+}\n+\n+void\n+__lws_free_wsi(struct lws *wsi)\n+{\n+\tif (!wsi)\n+\t\treturn;\n+\n+\t/*\n+\t * Protocol user data may be allocated either internally by lws\n+\t * or by specified the user. We should only free what we allocated.\n+\t */\n+\tif (wsi-\u003eprotocol \u0026\u0026 wsi-\u003eprotocol-\u003eper_session_data_size \u0026\u0026\n+\t wsi-\u003euser_space \u0026\u0026 !wsi-\u003euser_space_externally_allocated)\n+\t\tlws_free(wsi-\u003euser_space);\n+\n+\tlws_buflist_destroy_all_segments(\u0026wsi-\u003ebuflist);\n+\tlws_free_set_NULL(wsi-\u003etrunc_alloc);\n+\tlws_free_set_NULL(wsi-\u003eudp);\n+\n+\tif (wsi-\u003evhost \u0026\u0026 wsi-\u003evhost-\u003elserv_wsi \u003d\u003d wsi)\n+\t\twsi-\u003evhost-\u003elserv_wsi \u003d NULL;\n+\n+\t// lws_peer_dump_from_wsi(wsi);\n+\n+\tif (wsi-\u003erole_ops-\u003edestroy_role)\n+\t\twsi-\u003erole_ops-\u003edestroy_role(wsi);\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tlws_peer_track_wsi_close(wsi-\u003econtext, wsi-\u003epeer);\n+\twsi-\u003epeer \u003d NULL;\n+#endif\n+\n+\t/* since we will destroy the wsi, make absolutely sure now */\n+\n+#if defined(LWS_WITH_OPENSSL)\n+\t__lws_ssl_remove_wsi_from_buffered_list(wsi);\n+#endif\n+\t__lws_remove_from_timeout_list(wsi);\n+\n+\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi)\n+\t\twsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi(wsi);\n+\n+\twsi-\u003econtext-\u003ecount_wsi_allocated--;\n+\tlwsl_debug(\u0022%s: %p, remaining wsi %d\u005cn\u0022, __func__, wsi,\n+\t\t\twsi-\u003econtext-\u003ecount_wsi_allocated);\n+\n+\tlws_free(wsi);\n+}\n+\n+void\n+lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead)\n+{\n+\tif (d-\u003eprev)\n+\t\treturn;\n+\n+\t/* our next guy is current first guy */\n+\td-\u003enext \u003d phead-\u003enext;\n+\t/* if there is a next guy, set his prev ptr to our next ptr */\n+\tif (d-\u003enext)\n+\t\td-\u003enext-\u003eprev \u003d d;\n+\t/* our prev ptr is first ptr */\n+\td-\u003eprev \u003d phead;\n+\t/* set the first guy to be us */\n+\tphead-\u003enext \u003d d;\n+}\n+\n+/* situation is:\n+ *\n+ * HEAD: struct lws_dll * \u003d \u0026entry1\n+ *\n+ * Entry 1: struct lws_dll .pprev \u003d \u0026HEAD , .next \u003d Entry 2\n+ * Entry 2: struct lws_dll .pprev \u003d \u0026entry1 , .next \u003d \u0026entry2\n+ * Entry 3: struct lws_dll .pprev \u003d \u0026entry2 , .next \u003d NULL\n+ *\n+ * Delete Entry1:\n+ *\n+ * - HEAD \u003d \u0026entry2\n+ * - Entry2: .pprev \u003d \u0026HEAD, .next \u003d \u0026entry3\n+ * - Entry3: .pprev \u003d \u0026entry2, .next \u003d NULL\n+ *\n+ * Delete Entry2:\n+ *\n+ * - HEAD \u003d \u0026entry1\n+ * - Entry1: .pprev \u003d \u0026HEAD, .next \u003d \u0026entry3\n+ * - Entry3: .pprev \u003d \u0026entry1, .next \u003d NULL\n+ *\n+ * Delete Entry3:\n+ *\n+ * - HEAD \u003d \u0026entry1\n+ * - Entry1: .pprev \u003d \u0026HEAD, .next \u003d \u0026entry2\n+ * - Entry2: .pprev \u003d \u0026entry1, .next \u003d NULL\n+ *\n+ */\n+\n+void\n+lws_dll_remove(struct lws_dll *d)\n+{\n+\tif (!d-\u003eprev) /* ie, not part of the list */\n+\t\treturn;\n+\n+\t/*\n+\t * remove us\n+\t *\n+\t * USp \u003c-\u003e us \u003c-\u003e USn --\u003e USp \u003c-\u003e USn\n+\t */\n+\n+\t/* if we have a next guy, set his prev to our prev */\n+\tif (d-\u003enext)\n+\t\td-\u003enext-\u003eprev \u003d d-\u003eprev;\n+\n+\t/* set our prev guy to our next guy instead of us */\n+\tif (d-\u003eprev)\n+\t\td-\u003eprev-\u003enext \u003d d-\u003enext;\n+\n+\t/* we're out of the list, we should not point anywhere any more */\n+\td-\u003eprev \u003d NULL;\n+\td-\u003enext \u003d NULL;\n+}\n+\n+void\n+__lws_remove_from_timeout_list(struct lws *wsi)\n+{\n+\tlws_dll_lws_remove(\u0026wsi-\u003edll_timeout);\n+}\n+\n+void\n+lws_remove_from_timeout_list(struct lws *wsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\n+\tlws_pt_lock(pt, __func__);\n+\t__lws_remove_from_timeout_list(wsi);\n+\tlws_pt_unlock(pt);\n+}\n+\n+void\n+lws_dll_dump(struct lws_dll_lws *head, const char *title)\n+{\n+\tint n \u003d 0;\n+\n+\t(void)n;\n+\tlwsl_notice(\u0022%s: %s (head.next %p)\u005cn\u0022, __func__, title, head-\u003enext);\n+\n+\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, head-\u003enext) {\n+\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_hrtimer);\n+\n+\t\t(void)wsi;\n+\n+\t\tlwsl_notice(\u0022 %d: wsi %p: %llu\u005cn\u0022, n++, wsi,\n+\t\t\t\t(unsigned long long)wsi-\u003epending_timer);\n+\t} lws_end_foreach_dll_safe(d, d1);\n+}\n+\n+void\n+__lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tstruct lws_dll_lws *dd \u003d \u0026pt-\u003edll_head_hrtimer;\n+\tstruct timeval now;\n+\tstruct lws *wsi1;\n+\tint bef \u003d 0;\n+\n+\tlws_dll_lws_remove(\u0026wsi-\u003edll_hrtimer);\n+\n+\tif (usecs \u003d\u003d LWS_SET_TIMER_USEC_CANCEL)\n+\t\treturn;\n+\n+\tgettimeofday(\u0026now, NULL);\n+\twsi-\u003epending_timer \u003d ((now.tv_sec * 1000000ll) + now.tv_usec) + usecs;\n+\n+\t/*\n+\t * we sort the hrtimer list with the earliest timeout first\n+\t */\n+\n+\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n+\t\t\t\t pt-\u003edll_head_hrtimer.next) {\n+\t\tdd \u003d d;\n+\t\twsi1 \u003d lws_container_of(d, struct lws, dll_hrtimer);\n+\n+\t\tif (wsi1-\u003epending_timer \u003e\u003d wsi-\u003epending_timer) {\n+\t\t\t/* d, dprev's next, is \u003e\u003d our time */\n+\t\t\tbef \u003d 1;\n+\t\t\tbreak;\n+\t\t}\n+\t} lws_end_foreach_dll_safe(d, d1);\n+\n+\tif (bef) {\n+\t\t/*\n+\t\t * we go before dd\n+\t\t * DDp \u003c-\u003e DD \u003c-\u003e DDn --\u003e DDp \u003c-\u003e us \u003c-\u003e DD \u003c-\u003e DDn\n+\t\t */\n+\t\t/* we point forward to dd */\n+\t\twsi-\u003edll_hrtimer.next \u003d dd;\n+\t\t/* we point back to what dd used to point back to */\n+\t\twsi-\u003edll_hrtimer.prev \u003d dd-\u003eprev;\n+\t\t/* DDp points forward to us now */\n+\t\tdd-\u003eprev-\u003enext \u003d \u0026wsi-\u003edll_hrtimer;\n+\t\t/* DD points back to us now */\n+\t\tdd-\u003eprev \u003d \u0026wsi-\u003edll_hrtimer;\n+\t} else {\n+\t\t/*\n+\t\t * we go after dd\n+\t\t * DDp \u003c-\u003e DD \u003c-\u003e DDn --\u003e DDp \u003c-\u003e DD \u003c-\u003e us \u003c-\u003e DDn\n+\t\t */\n+\t\t/* we point forward to what dd used to point forward to */\n+\t\twsi-\u003edll_hrtimer.next \u003d dd-\u003enext;\n+\t\t/* we point back to dd */\n+\t\twsi-\u003edll_hrtimer.prev \u003d dd;\n+\t\t/* DDn points back to us */\n+\t\tif (dd-\u003enext)\n+\t\t\tdd-\u003enext-\u003eprev \u003d \u0026wsi-\u003edll_hrtimer;\n+\t\t/* DD points forward to us */\n+\t\tdd-\u003enext \u003d \u0026wsi-\u003edll_hrtimer;\n+\t}\n+\n+//\tlws_dll_dump(\u0026pt-\u003edll_head_hrtimer, \u0022after set_timer_usec\u0022);\n+}\n+\n+LWS_VISIBLE void\n+lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs)\n+{\n+\t__lws_set_timer_usecs(wsi, usecs);\n+}\n+\n+lws_usec_t\n+__lws_hrtimer_service(struct lws_context_per_thread *pt)\n+{\n+\tstruct timeval now;\n+\tstruct lws *wsi;\n+\tlws_usec_t t;\n+\n+\tgettimeofday(\u0026now, NULL);\n+\tt \u003d (now.tv_sec * 1000000ll) + now.tv_usec;\n+\n+\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n+\t\t\t\t pt-\u003edll_head_hrtimer.next) {\n+\t\twsi \u003d lws_container_of(d, struct lws, dll_hrtimer);\n+\n+\t\t/*\n+\t\t * if we met one in the future, we are done, because the list\n+\t\t * is sorted by time in the future.\n+\t\t */\n+\t\tif (wsi-\u003epending_timer \u003e t)\n+\t\t\tbreak;\n+\n+\t\tlws_set_timer_usecs(wsi, LWS_SET_TIMER_USEC_CANCEL);\n+\n+\t\t/* it's time for the timer to be serviced */\n+\n+\t\tif (wsi-\u003eprotocol \u0026\u0026\n+\t\t wsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_TIMER,\n+\t\t\t\t\t wsi-\u003euser_space, NULL, 0))\n+\t\t\t__lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n+\t\t\t\t\t \u0022timer cb errored\u0022);\n+\t} lws_end_foreach_dll_safe(d, d1);\n+\n+\t/* return an estimate how many us until next timer hit */\n+\n+\tif (!pt-\u003edll_head_hrtimer.next)\n+\t\treturn LWS_HRTIMER_NOWAIT;\n+\n+\twsi \u003d lws_container_of(pt-\u003edll_head_hrtimer.next, struct lws, dll_hrtimer);\n+\n+\tgettimeofday(\u0026now, NULL);\n+\tt \u003d (now.tv_sec * 1000000ll) + now.tv_usec;\n+\n+\tif (wsi-\u003epending_timer \u003c t)\n+\t\treturn 0;\n+\n+\treturn wsi-\u003epending_timer - t;\n+}\n+\n+void\n+__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\ttime_t now;\n+\n+\ttime(\u0026now);\n+\n+\tlwsl_debug(\u0022%s: %p: %d secs\u005cn\u0022, __func__, wsi, secs);\n+\twsi-\u003epending_timeout_limit \u003d secs;\n+\twsi-\u003epending_timeout_set \u003d now;\n+\twsi-\u003epending_timeout \u003d reason;\n+\n+\tif (!reason)\n+\t\tlws_dll_lws_remove(\u0026wsi-\u003edll_timeout);\n+\telse\n+\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_timeout, \u0026pt-\u003edll_head_timeout);\n+}\n+\n+LWS_VISIBLE void\n+lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\n+\tif (secs \u003d\u003d LWS_TO_KILL_SYNC) {\n+\t\tlws_remove_from_timeout_list(wsi);\n+\t\tlwsl_debug(\u0022synchronously killing %p\u005cn\u0022, wsi);\n+\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, \u0022to sync kill\u0022);\n+\t\treturn;\n+\t}\n+\n+\tlws_pt_lock(pt, __func__);\n+\t__lws_set_timeout(wsi, reason, secs);\n+\tlws_pt_unlock(pt);\n+}\n+\n+int\n+lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p)\n+{\n+\tlws_start_foreach_llp(struct lws_timed_vh_protocol **, pt,\n+\t\t\t vh-\u003etimed_vh_protocol_list) {\n+\t\tif (*pt \u003d\u003d p) {\n+\t\t\t*pt \u003d p-\u003enext;\n+\t\t\tlws_free(p);\n+\n+\t\t\treturn 0;\n+\t\t}\n+\t} lws_end_foreach_llp(pt, next);\n+\n+\treturn 1;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols *prot,\n+\t\t\t int reason, int secs)\n+{\n+\tstruct lws_timed_vh_protocol *p \u003d (struct lws_timed_vh_protocol *)\n+\t\t\tlws_malloc(sizeof(*p), \u0022timed_vh\u0022);\n+\n+\tif (!p)\n+\t\treturn 1;\n+\n+\tp-\u003eprotocol \u003d prot;\n+\tp-\u003ereason \u003d reason;\n+\tp-\u003etime \u003d lws_now_secs() + secs;\n+\tp-\u003enext \u003d vh-\u003etimed_vh_protocol_list;\n+\n+\tvh-\u003etimed_vh_protocol_list \u003d p;\n+\n+\treturn 0;\n+}\n+\n+static void\n+lws_remove_child_from_any_parent(struct lws *wsi)\n+{\n+\tstruct lws **pwsi;\n+\tint seen \u003d 0;\n+\n+\tif (!wsi-\u003eparent)\n+\t\treturn;\n+\n+\t/* detach ourselves from parent's child list */\n+\tpwsi \u003d \u0026wsi-\u003eparent-\u003echild_list;\n+\twhile (*pwsi) {\n+\t\tif (*pwsi \u003d\u003d wsi) {\n+\t\t\tlwsl_info(\u0022%s: detach %p from parent %p\u005cn\u0022, __func__,\n+\t\t\t\t wsi, wsi-\u003eparent);\n+\n+\t\t\tif (wsi-\u003eparent-\u003eprotocol)\n+\t\t\t\twsi-\u003eparent-\u003eprotocol-\u003ecallback(wsi,\n+\t\t\t\t\t\tLWS_CALLBACK_CHILD_CLOSING,\n+\t\t\t\t\t wsi-\u003eparent-\u003euser_space, wsi, 0);\n+\n+\t\t\t*pwsi \u003d wsi-\u003esibling_list;\n+\t\t\tseen \u003d 1;\n+\t\t\tbreak;\n+\t\t}\n+\t\tpwsi \u003d \u0026(*pwsi)-\u003esibling_list;\n+\t}\n+\tif (!seen)\n+\t\tlwsl_err(\u0022%s: failed to detach from parent\u005cn\u0022, __func__);\n+\n+\twsi-\u003eparent \u003d NULL;\n+}\n+\n+int\n+lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)\n+{\n+//\tif (wsi-\u003eprotocol \u003d\u003d p)\n+//\t\treturn 0;\n+\tconst struct lws_protocols *vp \u003d wsi-\u003evhost-\u003eprotocols, *vpo;\n+\n+\tif (wsi-\u003eprotocol \u0026\u0026 wsi-\u003eprotocol_bind_balance) {\n+\t\twsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,\n+\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n+\t\twsi-\u003eprotocol_bind_balance \u003d 0;\n+\t}\n+\tif (!wsi-\u003euser_space_externally_allocated)\n+\t\tlws_free_set_NULL(wsi-\u003euser_space);\n+\n+\tlws_same_vh_protocol_remove(wsi);\n+\n+\twsi-\u003eprotocol \u003d p;\n+\tif (!p)\n+\t\treturn 0;\n+\n+\tif (lws_ensure_user_space(wsi))\n+\t\treturn 1;\n+\n+\tif (p \u003e vp \u0026\u0026 p \u003c \u0026vp[wsi-\u003evhost-\u003ecount_protocols])\n+\t\tlws_same_vh_protocol_insert(wsi, (int)(p - vp));\n+\telse {\n+\t\tint n \u003d wsi-\u003evhost-\u003ecount_protocols;\n+\t\tint hit \u003d 0;\n+\n+\t\tvpo \u003d vp;\n+\n+\t\twhile (n--) {\n+\t\t\tif (p-\u003ename \u0026\u0026 vp-\u003ename \u0026\u0026 !strcmp(p-\u003ename, vp-\u003ename)) {\n+\t\t\t\thit \u003d 1;\n+\t\t\t\tlws_same_vh_protocol_insert(wsi, (int)(vp - vpo));\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tvp++;\n+\t\t}\n+\t\tif (!hit)\n+\t\t\tlwsl_err(\u0022%s: %p is not in vhost '%s' protocols list\u005cn\u0022,\n+\t\t\t\t __func__, p, wsi-\u003evhost-\u003ename);\n+\t}\n+\n+\tif (wsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL,\n+\t\t\t\t wsi-\u003euser_space, NULL, 0))\n+\t\treturn 1;\n+\n+\twsi-\u003eprotocol_bind_balance \u003d 1;\n+\n+\treturn 0;\n+}\n+\n+void\n+__lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller)\n+{\n+\tstruct lws_context_per_thread *pt;\n+\tstruct lws *wsi1, *wsi2;\n+\tstruct lws_context *context;\n+\tint n;\n+\n+\tlwsl_info(\u0022%s: %p: caller: %s\u005cn\u0022, __func__, wsi, caller);\n+\n+\tif (!wsi)\n+\t\treturn;\n+\n+\tlws_access_log(wsi);\n+\n+\tcontext \u003d wsi-\u003econtext;\n+\tpt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_API_CLOSE, 1);\n+\n+#if !defined(LWS_NO_CLIENT)\n+\n+\tlws_free_set_NULL(wsi-\u003eclient_hostname_copy);\n+\t/* we are no longer an active client connection that can piggyback */\n+\tlws_dll_lws_remove(\u0026wsi-\u003edll_active_client_conns);\n+\n+\t/*\n+\t * if we have wsi in our transaction queue, if we are closing we\n+\t * must go through and close all those first\n+\t */\n+\tif (wsi-\u003evhost) {\n+\t\tif ((int)reason !\u003d -1)\n+\t\t\tlws_vhost_lock(wsi-\u003evhost);\n+\t\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n+\t\t\t\t\twsi-\u003edll_client_transaction_queue_head.next) {\n+\t\t\tstruct lws *w \u003d lws_container_of(d, struct lws,\n+\t\t\t\t\t\t\t dll_client_transaction_queue);\n+\n+\t\t\t__lws_close_free_wsi(w, -1, \u0022trans q leader closing\u0022);\n+\t\t} lws_end_foreach_dll_safe(d, d1);\n+\n+\t\t/*\n+\t\t * !!! If we are closing, but we have pending pipelined transaction\n+\t\t * results we already sent headers for, that's going to destroy sync\n+\t\t * for HTTP/1 and leave H2 stream with no live swsi.\n+\t\t *\n+\t\t * However this is normal if we are being closed because the transaction\n+\t\t * queue leader is closing.\n+\t\t */\n+\t\tlws_dll_lws_remove(\u0026wsi-\u003edll_client_transaction_queue);\n+\t\tif ((int)reason !\u003d-1)\n+\t\t\tlws_vhost_unlock(wsi-\u003evhost);\n+\t}\n+#endif\n+\n+\t/* if we have children, close them first */\n+\tif (wsi-\u003echild_list) {\n+\t\twsi2 \u003d wsi-\u003echild_list;\n+\t\twhile (wsi2) {\n+\t\t\twsi1 \u003d wsi2-\u003esibling_list;\n+\t\t\twsi2-\u003eparent \u003d NULL;\n+\t\t\t/* stop it doing shutdown processing */\n+\t\t\twsi2-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\t\t__lws_close_free_wsi(wsi2, reason, \u0022general child recurse\u0022);\n+\t\t\twsi2 \u003d wsi1;\n+\t\t}\n+\t\twsi-\u003echild_list \u003d NULL;\n+\t}\n+\n+\tif (wsi-\u003erole_ops \u003d\u003d \u0026role_ops_raw_file) {\n+\t\tlws_remove_child_from_any_parent(wsi);\n+\t\t__remove_wsi_socket_from_fds(wsi);\n+\t\twsi-\u003eprotocol-\u003ecallback(wsi, wsi-\u003erole_ops-\u003eclose_cb[0],\n+\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n+\t\tgoto async_close;\n+\t}\n+\n+\twsi-\u003ewsistate_pre_close \u003d wsi-\u003ewsistate;\n+\n+#ifdef LWS_WITH_CGI\n+\tif (wsi-\u003erole_ops \u003d\u003d \u0026role_ops_cgi) {\n+\t\t/* we are not a network connection, but a handler for CGI io */\n+\t\tif (wsi-\u003eparent \u0026\u0026 wsi-\u003eparent-\u003ehttp.cgi) {\n+\n+\t\t\tif (wsi-\u003ecgi_channel \u003d\u003d LWS_STDOUT)\n+\t\t\t\tlws_cgi_remove_and_kill(wsi-\u003eparent);\n+\n+\t\t\t/* end the binding between us and master */\n+\t\t\twsi-\u003eparent-\u003ehttp.cgi-\u003estdwsi[(int)wsi-\u003ecgi_channel] \u003d NULL;\n+\t\t}\n+\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\n+\t\tgoto just_kill_connection;\n+\t}\n+\n+\tif (wsi-\u003ehttp.cgi)\n+\t\tlws_cgi_remove_and_kill(wsi);\n+#endif\n+\n+#if !defined(LWS_NO_CLIENT)\n+\tlws_client_stash_destroy(wsi);\n+#endif\n+\n+\tif (wsi-\u003erole_ops \u003d\u003d \u0026role_ops_raw_skt) {\n+\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\tgoto just_kill_connection;\n+\t}\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tif (lwsi_role_http(wsi) \u0026\u0026 lwsi_role_server(wsi) \u0026\u0026\n+\t wsi-\u003ehttp.fop_fd !\u003d NULL)\n+\t\tlws_vfs_file_close(\u0026wsi-\u003ehttp.fop_fd);\n+#endif\n+\n+\tif (lwsi_state(wsi) \u003d\u003d LRS_DEAD_SOCKET)\n+\t\treturn;\n+\n+\tif (wsi-\u003esocket_is_permanently_unusable ||\n+\t reason \u003d\u003d LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY ||\n+\t lwsi_state(wsi) \u003d\u003d LRS_SHUTDOWN)\n+\t\tgoto just_kill_connection;\n+\n+\tswitch (lwsi_state_PRE_CLOSE(wsi)) {\n+\tcase LRS_DEAD_SOCKET:\n+\t\treturn;\n+\n+\t/* we tried the polite way... */\n+\tcase LRS_WAITING_TO_SEND_CLOSE:\n+\tcase LRS_AWAITING_CLOSE_ACK:\n+\tcase LRS_RETURNED_CLOSE:\n+\t\tgoto just_kill_connection;\n+\n+\tcase LRS_FLUSHING_BEFORE_CLOSE:\n+\t\tif (wsi-\u003etrunc_len) {\n+\t\t\tlws_callback_on_writable(wsi);\n+\t\t\treturn;\n+\t\t}\n+\t\tlwsl_info(\u0022%p: end LRS_FLUSHING_BEFORE_CLOSE\u005cn\u0022, wsi);\n+\t\tgoto just_kill_connection;\n+\tdefault:\n+\t\tif (wsi-\u003etrunc_len) {\n+\t\t\tlwsl_info(\u0022%p: LRS_FLUSHING_BEFORE_CLOSE\u005cn\u0022, wsi);\n+\t\t\tlwsi_set_state(wsi, LRS_FLUSHING_BEFORE_CLOSE);\n+\t\t\t__lws_set_timeout(wsi,\n+\t\t\t\tPENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);\n+\t\t\treturn;\n+\t\t}\n+\t\tbreak;\n+\t}\n+\n+\tif (lwsi_state(wsi) \u003d\u003d LRS_WAITING_CONNECT ||\n+\t lwsi_state(wsi) \u003d\u003d LRS_H1C_ISSUE_HANDSHAKE)\n+\t\tgoto just_kill_connection;\n+\n+\tif (!wsi-\u003etold_user_closed \u0026\u0026 lwsi_role_http(wsi) \u0026\u0026\n+\t lwsi_role_server(wsi)) {\n+\t\tif (wsi-\u003euser_space \u0026\u0026 wsi-\u003eprotocol \u0026\u0026\n+\t\t wsi-\u003eprotocol_bind_balance) {\n+\t\t\twsi-\u003eprotocol-\u003ecallback(wsi,\n+\t\t\t\t\t\tLWS_CALLBACK_HTTP_DROP_PROTOCOL,\n+\t\t\t\t\t wsi-\u003euser_space, NULL, 0);\n+\t\t\twsi-\u003eprotocol_bind_balance \u003d 0;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * signal we are closing, lws_write will\n+\t * add any necessary version-specific stuff. If the write fails,\n+\t * no worries we are closing anyway. If we didn't initiate this\n+\t * close, then our state has been changed to\n+\t * LRS_RETURNED_CLOSE and we will skip this.\n+\t *\n+\t * Likewise if it's a second call to close this connection after we\n+\t * sent the close indication to the peer already, we are in state\n+\t * LRS_AWAITING_CLOSE_ACK and will skip doing this a second time.\n+\t */\n+\n+\tif (wsi-\u003erole_ops-\u003eclose_via_role_protocol \u0026\u0026\n+\t wsi-\u003erole_ops-\u003eclose_via_role_protocol(wsi, reason))\n+\t\treturn;\n+\n+just_kill_connection:\n+\n+\tif (wsi-\u003erole_ops-\u003eclose_kill_connection)\n+\t\twsi-\u003erole_ops-\u003eclose_kill_connection(wsi, reason);\n+\n+\tlws_remove_child_from_any_parent(wsi);\n+\tn \u003d 0;\n+\n+\tif (!wsi-\u003etold_user_closed \u0026\u0026 wsi-\u003euser_space \u0026\u0026\n+\t wsi-\u003eprotocol_bind_balance) {\n+\t\tlwsl_debug(\u0022%s: %p: DROP_PROTOCOL %s\u005cn\u0022, __func__, wsi,\n+\t\t wsi-\u003eprotocol-\u003ename);\n+\t\twsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,\n+\t\t\t\t wsi-\u003euser_space, NULL, 0);\n+\t\twsi-\u003eprotocol_bind_balance \u003d 0;\n+\t}\n+\n+\tif ((lwsi_state(wsi) \u003d\u003d LRS_WAITING_SERVER_REPLY ||\n+\t lwsi_state(wsi) \u003d\u003d LRS_WAITING_CONNECT) \u0026\u0026 !wsi-\u003ealready_did_cce)\n+\t\twsi-\u003eprotocol-\u003ecallback(wsi,\n+\t\t\t\t LWS_CALLBACK_CLIENT_CONNECTION_ERROR,\n+\t\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n+\n+\t/*\n+\t * Testing with ab shows that we have to stage the socket close when\n+\t * the system is under stress... shutdown any further TX, change the\n+\t * state to one that won't emit anything more, and wait with a timeout\n+\t * for the POLLIN to show a zero-size rx before coming back and doing\n+\t * the actual close.\n+\t */\n+\tif (wsi-\u003erole_ops !\u003d \u0026role_ops_raw_skt \u0026\u0026 !lwsi_role_client(wsi) \u0026\u0026\n+\t lwsi_state(wsi) !\u003d LRS_SHUTDOWN \u0026\u0026\n+\t lwsi_state(wsi) !\u003d LRS_UNCONNECTED \u0026\u0026\n+\t reason !\u003d LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY \u0026\u0026\n+\t !wsi-\u003esocket_is_permanently_unusable) {\n+\n+#if defined(LWS_WITH_TLS)\n+\tif (lws_is_ssl(wsi) \u0026\u0026 wsi-\u003etls.ssl) {\n+\t\tn \u003d 0;\n+\t\tswitch (__lws_tls_shutdown(wsi)) {\n+\t\tcase LWS_SSL_CAPABLE_DONE:\n+\t\tcase LWS_SSL_CAPABLE_ERROR:\n+\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_READ:\n+\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_WRITE:\n+\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE:\n+\t\t\tbreak;\n+\t\t}\n+\t} else\n+#endif\n+\t\t{\n+\t\t\tlwsl_info(\u0022%s: shutdown conn: %p (sock %d, state 0x%x)\u005cn\u0022,\n+\t\t\t\t __func__, wsi, (int)(long)wsi-\u003edesc.sockfd,\n+\t\t\t\t lwsi_state(wsi));\n+\t\t\tif (!wsi-\u003esocket_is_permanently_unusable \u0026\u0026\n+\t\t\t lws_sockfd_valid(wsi-\u003edesc.sockfd)) {\n+\t\t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\t\t\tn \u003d shutdown(wsi-\u003edesc.sockfd, SHUT_WR);\n+\t\t\t}\n+\t\t}\n+\t\tif (n)\n+\t\t\tlwsl_debug(\u0022closing: shutdown (state 0x%x) ret %d\u005cn\u0022,\n+\t\t\t\t lwsi_state(wsi), LWS_ERRNO);\n+\n+\t\t/*\n+\t\t * This causes problems on WINCE / ESP32 with disconnection\n+\t\t * when the events are half closing connection\n+\t\t */\n+#if !defined(_WIN32_WCE) \u0026\u0026 !defined(LWS_WITH_ESP32)\n+\t\t/* libuv: no event available to guarantee completion */\n+\t\tif (!wsi-\u003esocket_is_permanently_unusable \u0026\u0026\n+\t\t lws_sockfd_valid(wsi-\u003edesc.sockfd) \u0026\u0026\n+\t\t lwsi_state(wsi) !\u003d LRS_SHUTDOWN \u0026\u0026\n+\t\t context-\u003eevent_loop_ops-\u003eperiodic_events_available) {\n+\t\t\t__lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);\n+\t\t\tlwsi_set_state(wsi, LRS_SHUTDOWN);\n+\t\t\t__lws_set_timeout(wsi, PENDING_TIMEOUT_SHUTDOWN_FLUSH,\n+\t\t\t\t\t context-\u003etimeout_secs);\n+\n+\t\t\treturn;\n+\t\t}\n+#endif\n+\t}\n+\n+\tlwsl_debug(\u0022%s: real just_kill_connection: %p (sockfd %d)\u005cn\u0022, __func__,\n+\t\t wsi, wsi-\u003edesc.sockfd);\n+\t\n+#ifdef LWS_WITH_HTTP_PROXY\n+\tif (wsi-\u003ehttp.rw) {\n+\t\tlws_rewrite_destroy(wsi-\u003ehttp.rw);\n+\t\twsi-\u003ehttp.rw \u003d NULL;\n+\t}\n+#endif\n+\t/*\n+\t * we won't be servicing or receiving anything further from this guy\n+\t * delete socket from the internal poll list if still present\n+\t */\n+\t__lws_ssl_remove_wsi_from_buffered_list(wsi);\n+\t__lws_remove_from_timeout_list(wsi);\n+\tlws_dll_lws_remove(\u0026wsi-\u003edll_hrtimer);\n+\n+\t/* don't repeat event loop stuff */\n+\tif (wsi-\u003etold_event_loop_closed)\n+\t\treturn;\n+\n+\t/* checking return redundant since we anyway close */\n+\tif (wsi-\u003edesc.sockfd !\u003d LWS_SOCK_INVALID)\n+\t\t__remove_wsi_socket_from_fds(wsi);\n+\telse\n+\t\tlws_same_vh_protocol_remove(wsi);\n+\n+\tlwsi_set_state(wsi, LRS_DEAD_SOCKET);\n+\tlws_buflist_destroy_all_segments(\u0026wsi-\u003ebuflist);\n+\tlws_dll_lws_remove(\u0026wsi-\u003edll_buflist);\n+\n+\tif (wsi-\u003erole_ops-\u003eclose_role)\n+\t wsi-\u003erole_ops-\u003eclose_role(pt, wsi);\n+\n+\t/* tell the user it's all over for this guy */\n+\n+\tif (lwsi_state_est_PRE_CLOSE(wsi) \u0026\u0026 !wsi-\u003etold_user_closed \u0026\u0026\n+\t wsi-\u003erole_ops-\u003eclose_cb[lwsi_role_server(wsi)]) {\n+\t\tconst struct lws_protocols *pro \u003d wsi-\u003eprotocol;\n+\n+\t\tif (!wsi-\u003eprotocol)\n+\t\t\tpro \u003d \u0026wsi-\u003evhost-\u003eprotocols[0];\n+\n+\t\tpro-\u003ecallback(wsi,\n+\t\t\t wsi-\u003erole_ops-\u003eclose_cb[lwsi_role_server(wsi)],\n+\t\t\t wsi-\u003euser_space, NULL, 0);\n+\t\twsi-\u003etold_user_closed \u003d 1;\n+\t}\n+\n+async_close:\n+\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\n+\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close)\n+\t\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close(wsi))\n+\t\t\treturn;\n+\n+\t__lws_close_free_wsi_final(wsi);\n+}\n+\n+void\n+__lws_close_free_wsi_final(struct lws *wsi)\n+{\n+\tint n;\n+\n+\tif (lws_socket_is_valid(wsi-\u003edesc.sockfd) \u0026\u0026 !lws_ssl_close(wsi)) {\n+\t\tn \u003d compatible_close(wsi-\u003edesc.sockfd);\n+\t\tif (n)\n+\t\t\tlwsl_debug(\u0022closing: close ret %d\u005cn\u0022, LWS_ERRNO);\n+\n+\t\twsi-\u003edesc.sockfd \u003d LWS_SOCK_INVALID;\n+\t}\n+\n+\t/* outermost destroy notification for wsi (user_space still intact) */\n+\tif (wsi-\u003evhost)\n+\t\twsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,\n+\t\t\t\t\t\t wsi-\u003euser_space, NULL, 0);\n+\n+#ifdef LWS_WITH_CGI\n+\tif (wsi-\u003ehttp.cgi) {\n+\n+\t\tfor (n \u003d 0; n \u003c 3; n++) {\n+\t\t\tif (wsi-\u003ehttp.cgi-\u003epipe_fds[n][!!(n \u003d\u003d 0)] \u003d\u003d 0)\n+\t\t\t\tlwsl_err(\u0022ZERO FD IN CGI CLOSE\u0022);\n+\n+\t\t\tif (wsi-\u003ehttp.cgi-\u003epipe_fds[n][!!(n \u003d\u003d 0)] \u003e\u003d 0)\n+\t\t\t\tclose(wsi-\u003ehttp.cgi-\u003epipe_fds[n][!!(n \u003d\u003d 0)]);\n+\t\t}\n+\n+\t\tlws_free(wsi-\u003ehttp.cgi);\n+\t}\n+#endif\n+\n+\t__lws_free_wsi(wsi);\n+}\n+\n+\n+void\n+lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\n+\tlws_pt_lock(pt, __func__);\n+\t__lws_close_free_wsi(wsi, reason, caller);\n+\tlws_pt_unlock(pt);\n+}\n+\n+/* lws_buflist */\n+\n+int\n+lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,\n+\t\t\t size_t len)\n+{\n+\tstruct lws_buflist *nbuf;\n+\tint first \u003d !*head;\n+\tvoid *p \u003d *head;\n+\tint sanity \u003d 1024;\n+\n+\tassert(buf);\n+\tassert(len);\n+\n+\t/* append at the tail */\n+\twhile (*head) {\n+\t\tif (!--sanity || head \u003d\u003d \u0026((*head)-\u003enext)) {\n+\t\t\tlwsl_err(\u0022%s: corrupt list points to self\u005cn\u0022, __func__);\n+\t\t\treturn -1;\n+\t\t}\n+\t\thead \u003d \u0026((*head)-\u003enext);\n+\t}\n+\n+\tlwsl_info(\u0022%s: len %u first %d %p\u005cn\u0022, __func__, (uint32_t)len, first, p);\n+\n+\tnbuf \u003d (struct lws_buflist *)\n+\t\t\tlws_malloc(sizeof(**head) + len, __func__);\n+\tif (!nbuf) {\n+\t\tlwsl_err(\u0022%s: OOM\u005cn\u0022, __func__);\n+\t\treturn -1;\n+\t}\n+\n+\tnbuf-\u003elen \u003d len;\n+\tnbuf-\u003epos \u003d 0;\n+\tnbuf-\u003enext \u003d NULL;\n+\n+\tp \u003d (void *)nbuf-\u003ebuf;\n+\tmemcpy(p, buf, len);\n+\n+\t*head \u003d nbuf;\n+\n+\treturn first; /* returns 1 if first segment just created */\n+}\n+\n+static int\n+lws_buflist_destroy_segment(struct lws_buflist **head)\n+{\n+\tstruct lws_buflist *old \u003d *head;\n+\n+\tassert(*head);\n+\t*head \u003d (*head)-\u003enext;\n+\told-\u003enext \u003d NULL;\n+\tlws_free(old);\n+\n+\treturn !*head; /* returns 1 if last segment just destroyed */\n+}\n+\n+void\n+lws_buflist_destroy_all_segments(struct lws_buflist **head)\n+{\n+\tstruct lws_buflist *p \u003d *head, *p1;\n+\n+\twhile (p) {\n+\t\tp1 \u003d p-\u003enext;\n+\t\tp-\u003enext \u003d NULL;\n+\t\tlws_free(p);\n+\t\tp \u003d p1;\n+\t}\n+\n+\t*head \u003d NULL;\n+}\n+\n+size_t\n+lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf)\n+{\n+\tif (!*head) {\n+\t\tif (buf)\n+\t\t\t*buf \u003d NULL;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!(*head)-\u003elen \u0026\u0026 (*head)-\u003enext)\n+\t\tlws_buflist_destroy_segment(head);\n+\n+\tif (!*head) {\n+\t\tif (buf)\n+\t\t\t*buf \u003d NULL;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tassert((*head)-\u003epos \u003c (*head)-\u003elen);\n+\n+\tif (buf)\n+\t\t*buf \u003d (*head)-\u003ebuf + (*head)-\u003epos;\n+\n+\treturn (*head)-\u003elen - (*head)-\u003epos;\n+}\n+\n+int\n+lws_buflist_use_segment(struct lws_buflist **head, size_t len)\n+{\n+\tassert(*head);\n+\tassert(len);\n+\tassert((*head)-\u003epos + len \u003c\u003d (*head)-\u003elen);\n+\n+\t(*head)-\u003epos +\u003d len;\n+\tif ((*head)-\u003epos \u003d\u003d (*head)-\u003elen)\n+\t\tlws_buflist_destroy_segment(head);\n+\n+\tif (!*head)\n+\t\treturn 0;\n+\n+\treturn (int)((*head)-\u003elen - (*head)-\u003epos);\n+}\n+\n+void\n+lws_buflist_describe(struct lws_buflist **head, void *id)\n+{\n+\tstruct lws_buflist *old;\n+\tint n \u003d 0;\n+\n+\tif (*head \u003d\u003d NULL)\n+\t\tlwsl_notice(\u0022%p: buflist empty\u005cn\u0022, id);\n+\n+\twhile (*head) {\n+\t\tlwsl_notice(\u0022%p: %d: %llu / %llu (%llu left)\u005cn\u0022, id, n,\n+\t\t\t (unsigned long long)(*head)-\u003epos,\n+\t\t\t (unsigned long long)(*head)-\u003elen,\n+\t\t\t (unsigned long long)(*head)-\u003elen - (*head)-\u003epos);\n+\t\told \u003d *head;\n+\t\thead \u003d \u0026((*head)-\u003enext);\n+\t\tif (*head \u003d\u003d old) {\n+\t\t\tlwsl_err(\u0022%s: next points to self\u005cn\u0022, __func__);\n+\t\t\tbreak;\n+\t\t}\n+\t\tn++;\n+\t}\n+}\n+\n+/* ... */\n+\n+LWS_VISIBLE LWS_EXTERN const char *\n+lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)\n+{\n+\tint n \u003d 0, sl \u003d (int)strlen(name);\n+\n+\twhile (lws_hdr_copy_fragment(wsi, buf, len,\n+\t\t\t WSI_TOKEN_HTTP_URI_ARGS, n) \u003e\u003d 0) {\n+\n+\t\tif (!strncmp(buf, name, sl))\n+\t\t\treturn buf + sl;\n+\n+\t\tn++;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+#if !defined(LWS_WITH_ESP32)\n+LWS_VISIBLE int\n+interface_to_sa(struct lws_vhost *vh, const char *ifname,\n+\t\tstruct sockaddr_in *addr, size_t addrlen)\n+{\n+\tint ipv6 \u003d 0;\n+#ifdef LWS_WITH_IPV6\n+\tipv6 \u003d LWS_IPV6_ENABLED(vh);\n+#endif\n+\t(void)vh;\n+\n+\treturn lws_interface_to_sa(ipv6, ifname, addr, addrlen);\n+}\n+#endif\n+\n+#ifndef LWS_PLAT_OPTEE\n+static int\n+lws_get_addresses(struct lws_vhost *vh, void *ads, char *name,\n+\t\t int name_len, char *rip, int rip_len)\n+{\n+\tstruct addrinfo ai, *res;\n+\tstruct sockaddr_in addr4;\n+\n+\trip[0] \u003d '\u005c0';\n+\tname[0] \u003d '\u005c0';\n+\taddr4.sin_family \u003d AF_UNSPEC;\n+\n+#ifdef LWS_WITH_IPV6\n+\tif (LWS_IPV6_ENABLED(vh)) {\n+\t\tif (!lws_plat_inet_ntop(AF_INET6,\n+\t\t\t\t\t\u0026((struct sockaddr_in6 *)ads)-\u003esin6_addr,\n+\t\t\t\t\trip, rip_len)) {\n+\t\t\tlwsl_err(\u0022inet_ntop: %s\u0022, strerror(LWS_ERRNO));\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t// Strip off the IPv4 to IPv6 header if one exists\n+\t\tif (strncmp(rip, \u0022::ffff:\u0022, 7) \u003d\u003d 0)\n+\t\t\tmemmove(rip, rip + 7, strlen(rip) - 6);\n+\n+\t\tgetnameinfo((struct sockaddr *)ads, sizeof(struct sockaddr_in6),\n+\t\t\t name, name_len, NULL, 0, 0);\n+\n+\t\treturn 0;\n+\t} else\n+#endif\n+\t{\n+\t\tstruct addrinfo *result;\n+\n+\t\tmemset(\u0026ai, 0, sizeof ai);\n+\t\tai.ai_family \u003d PF_UNSPEC;\n+\t\tai.ai_socktype \u003d SOCK_STREAM;\n+#if !defined(LWS_WITH_ESP32)\n+\t\tif (getnameinfo((struct sockaddr *)ads,\n+\t\t\t\tsizeof(struct sockaddr_in),\n+\t\t\t\tname, name_len, NULL, 0, 0))\n+\t\t\treturn -1;\n+#endif\n+\n+\t\tif (getaddrinfo(name, NULL, \u0026ai, \u0026result))\n+\t\t\treturn -1;\n+\n+\t\tres \u003d result;\n+\t\twhile (addr4.sin_family \u003d\u003d AF_UNSPEC \u0026\u0026 res) {\n+\t\t\tswitch (res-\u003eai_family) {\n+\t\t\tcase AF_INET:\n+\t\t\t\taddr4.sin_addr \u003d\n+\t\t\t\t ((struct sockaddr_in *)res-\u003eai_addr)-\u003esin_addr;\n+\t\t\t\taddr4.sin_family \u003d AF_INET;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tres \u003d res-\u003eai_next;\n+\t\t}\n+\t\tfreeaddrinfo(result);\n+\t}\n+\n+\tif (addr4.sin_family \u003d\u003d AF_UNSPEC)\n+\t\treturn -1;\n+\n+\tif (lws_plat_inet_ntop(AF_INET, \u0026addr4.sin_addr, rip, rip_len) \u003d\u003d NULL)\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+\n+LWS_VISIBLE const char *\n+lws_get_peer_simple(struct lws *wsi, char *name, int namelen)\n+{\n+\tsocklen_t len, olen;\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 sin6;\n+#endif\n+\tstruct sockaddr_in sin4;\n+\tint af \u003d AF_INET;\n+\tvoid *p, *q;\n+\n+\twsi \u003d lws_get_network_wsi(wsi);\n+\n+\tif (wsi-\u003eparent_carries_io)\n+\t\twsi \u003d wsi-\u003eparent;\n+\n+#ifdef LWS_WITH_IPV6\n+\tif (LWS_IPV6_ENABLED(wsi-\u003evhost)) {\n+\t\tlen \u003d sizeof(sin6);\n+\t\tp \u003d \u0026sin6;\n+\t\taf \u003d AF_INET6;\n+\t\tq \u003d \u0026sin6.sin6_addr;\n+\t} else\n+#endif\n+\t{\n+\t\tlen \u003d sizeof(sin4);\n+\t\tp \u003d \u0026sin4;\n+\t\tq \u003d \u0026sin4.sin_addr;\n+\t}\n+\n+\tolen \u003d len;\n+\tif (getpeername(wsi-\u003edesc.sockfd, p, \u0026len) \u003c 0 || len \u003e olen) {\n+\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n+\t\treturn NULL;\n+\t}\n+\n+\treturn lws_plat_inet_ntop(af, q, name, namelen);\n+}\n+#endif\n+\n+LWS_VISIBLE void\n+lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name,\n+\t\t int name_len, char *rip, int rip_len)\n+{\n+#ifndef LWS_PLAT_OPTEE\n+\tsocklen_t len;\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 sin6;\n+#endif\n+\tstruct sockaddr_in sin4;\n+\tstruct lws_context *context \u003d wsi-\u003econtext;\n+\tint ret \u003d -1;\n+\tvoid *p;\n+\n+\trip[0] \u003d '\u005c0';\n+\tname[0] \u003d '\u005c0';\n+\n+\tlws_latency_pre(context, wsi);\n+\n+#ifdef LWS_WITH_IPV6\n+\tif (LWS_IPV6_ENABLED(wsi-\u003evhost)) {\n+\t\tlen \u003d sizeof(sin6);\n+\t\tp \u003d \u0026sin6;\n+\t} else\n+#endif\n+\t{\n+\t\tlen \u003d sizeof(sin4);\n+\t\tp \u003d \u0026sin4;\n+\t}\n+\n+\tif (getpeername(fd, p, \u0026len) \u003c 0) {\n+\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n+\t\tgoto bail;\n+\t}\n+\n+\tret \u003d lws_get_addresses(wsi-\u003evhost, p, name, name_len, rip, rip_len);\n+\n+bail:\n+\tlws_latency(context, wsi, \u0022lws_get_peer_addresses\u0022, ret, 1);\n+#endif\n+\t(void)wsi;\n+\t(void)fd;\n+\t(void)name;\n+\t(void)name_len;\n+\t(void)rip;\n+\t(void)rip_len;\n+\n+}\n+\n+LWS_EXTERN void *\n+lws_vhost_user(struct lws_vhost *vhost)\n+{\n+\treturn vhost-\u003euser;\n+}\n+\n+LWS_EXTERN void *\n+lws_context_user(struct lws_context *context)\n+{\n+\treturn context-\u003euser_space;\n+}\n+\n+LWS_VISIBLE struct lws_vhost *\n+lws_vhost_get(struct lws *wsi)\n+{\n+\treturn wsi-\u003evhost;\n+}\n+\n+LWS_VISIBLE struct lws_vhost *\n+lws_get_vhost(struct lws *wsi)\n+{\n+\treturn wsi-\u003evhost;\n+}\n+\n+LWS_VISIBLE const struct lws_protocols *\n+lws_protocol_get(struct lws *wsi)\n+{\n+\treturn wsi-\u003eprotocol;\n+}\n+\n+LWS_VISIBLE const struct lws_udp *\n+lws_get_udp(const struct lws *wsi)\n+{\n+\treturn wsi-\u003eudp;\n+}\n+\n+LWS_VISIBLE struct lws *\n+lws_get_network_wsi(struct lws *wsi)\n+{\n+\tif (!wsi)\n+\t\treturn NULL;\n+\n+#if defined(LWS_WITH_HTTP2)\n+\tif (!wsi-\u003ehttp2_substream \u0026\u0026 !wsi-\u003eclient_h2_substream)\n+\t\treturn wsi;\n+\n+\twhile (wsi-\u003eh2.parent_wsi)\n+\t\twsi \u003d wsi-\u003eh2.parent_wsi;\n+#endif\n+\n+\treturn wsi;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN const struct lws_protocols *\n+lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name)\n+{\n+\tint n;\n+\n+\tfor (n \u003d 0; n \u003c vh-\u003ecount_protocols; n++)\n+\t\tif (!strcmp(name, vh-\u003eprotocols[n].name))\n+\t\t\treturn \u0026vh-\u003eprotocols[n];\n+\n+\treturn NULL;\n+}\n+\n+LWS_VISIBLE int\n+lws_callback_all_protocol(struct lws_context *context,\n+\t\t\t const struct lws_protocols *protocol, int reason)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n+\tunsigned int n, m \u003d context-\u003ecount_threads;\n+\tstruct lws *wsi;\n+\n+\twhile (m--) {\n+\t\tfor (n \u003d 0; n \u003c pt-\u003efds_count; n++) {\n+\t\t\twsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n+\t\t\tif (!wsi)\n+\t\t\t\tcontinue;\n+\t\t\tif (wsi-\u003eprotocol \u003d\u003d protocol)\n+\t\t\t\tprotocol-\u003ecallback(wsi, reason, wsi-\u003euser_space,\n+\t\t\t\t\t\t NULL, 0);\n+\t\t}\n+\t\tpt++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE int\n+lws_callback_all_protocol_vhost_args(struct lws_vhost *vh,\n+\t\t\t const struct lws_protocols *protocol, int reason,\n+\t\t\t void *argp, size_t len)\n+{\n+\tstruct lws_context *context \u003d vh-\u003econtext;\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n+\tunsigned int n, m \u003d context-\u003ecount_threads;\n+\tstruct lws *wsi;\n+\n+\twhile (m--) {\n+\t\tfor (n \u003d 0; n \u003c pt-\u003efds_count; n++) {\n+\t\t\twsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n+\t\t\tif (!wsi)\n+\t\t\t\tcontinue;\n+\t\t\tif (wsi-\u003evhost \u003d\u003d vh \u0026\u0026 (wsi-\u003eprotocol \u003d\u003d protocol ||\n+\t\t\t\t\t\t !protocol))\n+\t\t\t\twsi-\u003eprotocol-\u003ecallback(wsi, reason,\n+\t\t\t\t\t\twsi-\u003euser_space, argp, len);\n+\t\t}\n+\t\tpt++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE int\n+lws_callback_all_protocol_vhost(struct lws_vhost *vh,\n+\t\t\t const struct lws_protocols *protocol, int reason)\n+{\n+\treturn lws_callback_all_protocol_vhost_args(vh, protocol, reason, NULL, 0);\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len)\n+{\n+\tint n;\n+\n+\tfor (n \u003d 0; n \u003c wsi-\u003evhost-\u003ecount_protocols; n++)\n+\t\tif (wsi-\u003evhost-\u003eprotocols[n].callback(wsi, reason, NULL, in, len))\n+\t\t\treturn 1;\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void *in,\n+\t\t\t\t size_t len)\n+{\n+\tint n;\n+\tstruct lws *wsi \u003d lws_zalloc(sizeof(*wsi), \u0022fake wsi\u0022);\n+\n+\twsi-\u003econtext \u003d vh-\u003econtext;\n+\twsi-\u003evhost \u003d vh;\n+\n+\tfor (n \u003d 0; n \u003c wsi-\u003evhost-\u003ecount_protocols; n++) {\n+\t\twsi-\u003eprotocol \u003d \u0026vh-\u003eprotocols[n];\n+\t\tif (wsi-\u003eprotocol-\u003ecallback(wsi, reason, NULL, in, len)) {\n+\t\t\tlws_free(wsi);\n+\t\t\treturn 1;\n+\t\t}\n+\t}\n+\n+\tlws_free(wsi);\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops)\n+{\n+\tcontext-\u003efops \u003d fops;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN lws_filepos_t\n+lws_vfs_tell(lws_fop_fd_t fop_fd)\n+{\n+\treturn fop_fd-\u003epos;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN lws_filepos_t\n+lws_vfs_get_length(lws_fop_fd_t fop_fd)\n+{\n+\treturn fop_fd-\u003elen;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN uint32_t\n+lws_vfs_get_mod_time(lws_fop_fd_t fop_fd)\n+{\n+\treturn fop_fd-\u003emod_time;\n+}\n+\n+LWS_VISIBLE lws_fileofs_t\n+lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset)\n+{\n+\tlws_fileofs_t ofs;\n+\n+\tofs \u003d fop_fd-\u003efops-\u003eLWS_FOP_SEEK_CUR(fop_fd, offset - fop_fd-\u003epos);\n+\n+\treturn ofs;\n+}\n+\n+\n+LWS_VISIBLE lws_fileofs_t\n+lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset)\n+{\n+\treturn fop_fd-\u003efops-\u003eLWS_FOP_SEEK_CUR(fop_fd, fop_fd-\u003elen +\n+\t\t\t\t\t fop_fd-\u003epos + offset);\n+}\n+\n+\n+const struct lws_plat_file_ops *\n+lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,\n+\t\t const char **vpath)\n+{\n+\tconst struct lws_plat_file_ops *pf;\n+\tconst char *p \u003d vfs_path;\n+\tint n;\n+\n+\t*vpath \u003d NULL;\n+\n+\t/* no non-platform fops, just use that */\n+\n+\tif (!fops-\u003enext)\n+\t\treturn fops;\n+\n+\t/*\n+\t * scan the vfs path looking for indications we are to be\n+\t * handled by a specific fops\n+\t */\n+\n+\twhile (p \u0026\u0026 *p) {\n+\t\tif (*p !\u003d '/') {\n+\t\t\tp++;\n+\t\t\tcontinue;\n+\t\t}\n+\t\t/* the first one is always platform fops, so skip */\n+\t\tpf \u003d fops-\u003enext;\n+\t\twhile (pf) {\n+\t\t\tn \u003d 0;\n+\t\t\twhile (n \u003c (int)ARRAY_SIZE(pf-\u003efi) \u0026\u0026 pf-\u003efi[n].sig) {\n+\t\t\t\tif (p \u003e\u003d vfs_path + pf-\u003efi[n].len)\n+\t\t\t\t\tif (!strncmp(p - (pf-\u003efi[n].len - 1),\n+\t\t\t\t\t\t pf-\u003efi[n].sig,\n+\t\t\t\t\t\t pf-\u003efi[n].len - 1)) {\n+\t\t\t\t\t\t*vpath \u003d p + 1;\n+\t\t\t\t\t\treturn pf;\n+\t\t\t\t\t}\n+\n+\t\t\t\tn++;\n+\t\t\t}\n+\t\t\tpf \u003d pf-\u003enext;\n+\t\t}\n+\t\tp++;\n+\t}\n+\n+\treturn fops;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT\n+lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path,\n+\t\t lws_fop_flags_t *flags)\n+{\n+\tconst char *vpath \u003d \u0022\u0022;\n+\tconst struct lws_plat_file_ops *selected;\n+\n+\tselected \u003d lws_vfs_select_fops(fops, vfs_path, \u0026vpath);\n+\n+\treturn selected-\u003eLWS_FOP_OPEN(fops, vfs_path, vpath, flags);\n+}\n+\n+\n+/**\n+ * lws_now_secs() - seconds since 1970-1-1\n+ *\n+ */\n+LWS_VISIBLE LWS_EXTERN unsigned long\n+lws_now_secs(void)\n+{\n+\tstruct timeval tv;\n+\n+\tgettimeofday(\u0026tv, NULL);\n+\n+\treturn tv.tv_sec;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2)\n+{\n+\tif (t1 \u003c context-\u003etime_discontiguity)\n+\t\tt1 +\u003d context-\u003etime_fixup;\n+\n+\tif (t2 \u003c context-\u003etime_discontiguity)\n+\t\tt2 +\u003d context-\u003etime_fixup;\n+\n+\treturn (int)(t1 - t2);\n+}\n+\n+LWS_VISIBLE lws_sockfd_type\n+lws_get_socket_fd(struct lws *wsi)\n+{\n+\tif (!wsi)\n+\t\treturn -1;\n+\treturn wsi-\u003edesc.sockfd;\n+}\n+\n+#ifdef LWS_LATENCY\n+void\n+lws_latency(struct lws_context *context, struct lws *wsi, const char *action,\n+\t int ret, int completed)\n+{\n+\tunsigned long long u;\n+\tchar buf[256];\n+\n+\tu \u003d time_in_microseconds();\n+\n+\tif (!action) {\n+\t\twsi-\u003elatency_start \u003d u;\n+\t\tif (!wsi-\u003eaction_start)\n+\t\t\twsi-\u003eaction_start \u003d u;\n+\t\treturn;\n+\t}\n+\tif (completed) {\n+\t\tif (wsi-\u003eaction_start \u003d\u003d wsi-\u003elatency_start)\n+\t\t\tsprintf(buf,\n+\t\t\t \u0022Completion first try lat %lluus: %p: ret %d: %s\u005cn\u0022,\n+\t\t\t\t\tu - wsi-\u003elatency_start,\n+\t\t\t\t\t\t (void *)wsi, ret, action);\n+\t\telse\n+\t\t\tsprintf(buf,\n+\t\t\t \u0022Completion %lluus: lat %lluus: %p: ret %d: %s\u005cn\u0022,\n+\t\t\t\tu - wsi-\u003eaction_start,\n+\t\t\t\t\tu - wsi-\u003elatency_start,\n+\t\t\t\t\t\t (void *)wsi, ret, action);\n+\t\twsi-\u003eaction_start \u003d 0;\n+\t} else\n+\t\tsprintf(buf, \u0022lat %lluus: %p: ret %d: %s\u005cn\u0022,\n+\t\t\t u - wsi-\u003elatency_start, (void *)wsi, ret, action);\n+\n+\tif (u - wsi-\u003elatency_start \u003e context-\u003eworst_latency) {\n+\t\tcontext-\u003eworst_latency \u003d u - wsi-\u003elatency_start;\n+\t\tstrcpy(context-\u003eworst_latency_info, buf);\n+\t}\n+\tlwsl_latency(\u0022%s\u0022, buf);\n+}\n+#endif\n+\n+LWS_VISIBLE int\n+lws_rx_flow_control(struct lws *wsi, int _enable)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tint en \u003d _enable;\n+\n+\t// h2 ignores rx flow control atm\n+\tif (lwsi_role_h2(wsi) || wsi-\u003ehttp2_substream ||\n+\t lwsi_role_h2_ENCAPSULATION(wsi))\n+\t\treturn 0; // !!!\n+\n+\tlwsl_info(\u0022%s: %p 0x%x\u005cn\u0022, __func__, wsi, _enable);\n+\n+\tif (!(_enable \u0026 LWS_RXFLOW_REASON_APPLIES)) {\n+\t\t/*\n+\t\t * convert user bool style to bitmap style... in user simple\n+\t\t * bool style _enable \u003d 0 \u003d flow control it, \u003d 1 \u003d allow rx\n+\t\t */\n+\t\ten \u003d LWS_RXFLOW_REASON_APPLIES | LWS_RXFLOW_REASON_USER_BOOL;\n+\t\tif (_enable \u0026 1)\n+\t\t\ten |\u003d LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT;\n+\t}\n+\n+\tlws_pt_lock(pt, __func__);\n+\n+\t/* any bit set in rxflow_bitmap DISABLEs rxflow control */\n+\tif (en \u0026 LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT)\n+\t\twsi-\u003erxflow_bitmap \u0026\u003d ~(en \u0026 0xff);\n+\telse\n+\t\twsi-\u003erxflow_bitmap |\u003d en \u0026 0xff;\n+\n+\tif ((LWS_RXFLOW_PENDING_CHANGE | (!wsi-\u003erxflow_bitmap)) \u003d\u003d\n+\t wsi-\u003erxflow_change_to)\n+\t\tgoto skip;\n+\n+\twsi-\u003erxflow_change_to \u003d LWS_RXFLOW_PENDING_CHANGE | !wsi-\u003erxflow_bitmap;\n+\n+\tlwsl_info(\u0022%s: %p: bitmap 0x%x: en 0x%x, ch 0x%x\u005cn\u0022, __func__, wsi,\n+\t\t wsi-\u003erxflow_bitmap, en, wsi-\u003erxflow_change_to);\n+\n+\tif (_enable \u0026 LWS_RXFLOW_REASON_FLAG_PROCESS_NOW ||\n+\t !wsi-\u003erxflow_will_be_applied) {\n+\t\ten \u003d __lws_rx_flow_control(wsi);\n+\t\tlws_pt_unlock(pt);\n+\n+\t\treturn en;\n+\t}\n+\n+skip:\n+\tlws_pt_unlock(pt);\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE void\n+lws_rx_flow_allow_all_protocol(const struct lws_context *context,\n+\t\t\t const struct lws_protocols *protocol)\n+{\n+\tconst struct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n+\tstruct lws *wsi;\n+\tunsigned int n, m \u003d context-\u003ecount_threads;\n+\n+\twhile (m--) {\n+\t\tfor (n \u003d 0; n \u003c pt-\u003efds_count; n++) {\n+\t\t\twsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n+\t\t\tif (!wsi)\n+\t\t\t\tcontinue;\n+\t\t\tif (wsi-\u003eprotocol \u003d\u003d protocol)\n+\t\t\t\tlws_rx_flow_control(wsi, LWS_RXFLOW_ALLOW);\n+\t\t}\n+\t\tpt++;\n+\t}\n+}\n+\n+int\n+lws_broadcast(struct lws_context *context, int reason, void *in, size_t len)\n+{\n+\tstruct lws_vhost *v \u003d context-\u003evhost_list;\n+\tstruct lws wsi;\n+\tint n, ret \u003d 0;\n+\n+\tmemset(\u0026wsi, 0, sizeof(wsi));\n+\twsi.context \u003d context;\n+\n+\twhile (v) {\n+\t\tconst struct lws_protocols *p \u003d v-\u003eprotocols;\n+\t\twsi.vhost \u003d v;\n+\n+\t\tfor (n \u003d 0; n \u003c v-\u003ecount_protocols; n++) {\n+\t\t\twsi.protocol \u003d p;\n+\t\t\tif (p-\u003ecallback \u0026\u0026\n+\t\t\t p-\u003ecallback(\u0026wsi, reason, NULL, in, len))\n+\t\t\t\tret |\u003d 1;\n+\t\t\tp++;\n+\t\t}\n+\t\tv \u003d v-\u003evhost_next;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+LWS_VISIBLE extern const char *\n+lws_canonical_hostname(struct lws_context *context)\n+{\n+\treturn (const char *)context-\u003ecanonical_hostname;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN const char *\n+lws_get_vhost_name(struct lws_vhost *vhost)\n+{\n+\treturn vhost-\u003ename;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_get_vhost_port(struct lws_vhost *vhost)\n+{\n+\treturn vhost-\u003elisten_port;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void *\n+lws_get_vhost_user(struct lws_vhost *vhost)\n+{\n+\treturn vhost-\u003euser;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN const char *\n+lws_get_vhost_iface(struct lws_vhost *vhost)\n+{\n+\treturn vhost-\u003eiface;\n+}\n+\n+int user_callback_handle_rxflow(lws_callback_function callback_function,\n+\t\t\t\tstruct lws *wsi,\n+\t\t\t\tenum lws_callback_reasons reason, void *user,\n+\t\t\t\tvoid *in, size_t len)\n+{\n+\tint n;\n+\n+\twsi-\u003erxflow_will_be_applied \u003d 1;\n+\tn \u003d callback_function(wsi, reason, user, in, len);\n+\twsi-\u003erxflow_will_be_applied \u003d 0;\n+\tif (!n)\n+\t\tn \u003d __lws_rx_flow_control(wsi);\n+\n+\treturn n;\n+}\n+\n+#if !defined(LWS_WITHOUT_CLIENT)\n+LWS_VISIBLE int\n+lws_set_proxy(struct lws_vhost *vhost, const char *proxy)\n+{\n+\tchar *p;\n+\tchar authstring[96];\n+\n+\tif (!proxy)\n+\t\treturn -1;\n+\n+\t/* we have to deal with a possible redundant leading http:// */\n+\tif (!strncmp(proxy, \u0022http://\u0022, 7))\n+\t\tproxy +\u003d 7;\n+\n+\tp \u003d strrchr(proxy, '@');\n+\tif (p) { /* auth is around */\n+\n+\t\tif ((unsigned int)(p - proxy) \u003e sizeof(authstring) - 1)\n+\t\t\tgoto auth_too_long;\n+\n+\t\tlws_strncpy(authstring, proxy, p - proxy + 1);\n+\t\t// null termination not needed on input\n+\t\tif (lws_b64_encode_string(authstring, lws_ptr_diff(p, proxy),\n+\t\t\t\tvhost-\u003eproxy_basic_auth_token,\n+\t\t sizeof vhost-\u003eproxy_basic_auth_token) \u003c 0)\n+\t\t\tgoto auth_too_long;\n+\n+\t\tlwsl_info(\u0022 Proxy auth in use\u005cn\u0022);\n+\n+\t\tproxy \u003d p + 1;\n+\t} else\n+\t\tvhost-\u003eproxy_basic_auth_token[0] \u003d '\u005c0';\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tlws_strncpy(vhost-\u003ehttp.http_proxy_address, proxy,\n+\t\t sizeof(vhost-\u003ehttp.http_proxy_address));\n+\n+\tp \u003d strchr(vhost-\u003ehttp.http_proxy_address, ':');\n+\tif (!p \u0026\u0026 !vhost-\u003ehttp.http_proxy_port) {\n+\t\tlwsl_err(\u0022http_proxy needs to be ads:port\u005cn\u0022);\n+\n+\t\treturn -1;\n+\t} else {\n+\t\tif (p) {\n+\t\t\t*p \u003d '\u005c0';\n+\t\t\tvhost-\u003ehttp.http_proxy_port \u003d atoi(p + 1);\n+\t\t}\n+\t}\n+\n+\tlwsl_info(\u0022 Proxy %s:%u\u005cn\u0022, vhost-\u003ehttp.http_proxy_address,\n+\t\t\tvhost-\u003ehttp.http_proxy_port);\n+#endif\n+\treturn 0;\n+\n+auth_too_long:\n+\tlwsl_err(\u0022proxy auth too long\u005cn\u0022);\n+\n+\treturn -1;\n+}\n+#endif\n+\n+#if defined(LWS_WITH_SOCKS5)\n+LWS_VISIBLE int\n+lws_set_socks(struct lws_vhost *vhost, const char *socks)\n+{\n+\tchar *p_at, *p_colon;\n+\tchar user[96];\n+\tchar password[96];\n+\n+\tif (!socks)\n+\t\treturn -1;\n+\n+\tvhost-\u003esocks_user[0] \u003d '\u005c0';\n+\tvhost-\u003esocks_password[0] \u003d '\u005c0';\n+\n+\tp_at \u003d strrchr(socks, '@');\n+\tif (p_at) { /* auth is around */\n+\t\tif ((unsigned int)(p_at - socks) \u003e (sizeof(user)\n+\t\t\t+ sizeof(password) - 2)) {\n+\t\t\tlwsl_err(\u0022Socks auth too long\u005cn\u0022);\n+\t\t\tgoto bail;\n+\t\t}\n+\n+\t\tp_colon \u003d strchr(socks, ':');\n+\t\tif (p_colon) {\n+\t\t\tif ((unsigned int)(p_colon - socks) \u003e (sizeof(user)\n+\t\t\t\t- 1) ) {\n+\t\t\t\tlwsl_err(\u0022Socks user too long\u005cn\u0022);\n+\t\t\t\tgoto bail;\n+\t\t\t}\n+\t\t\tif ((unsigned int)(p_at - p_colon) \u003e (sizeof(password)\n+\t\t\t\t- 1) ) {\n+\t\t\t\tlwsl_err(\u0022Socks password too long\u005cn\u0022);\n+\t\t\t\tgoto bail;\n+\t\t\t}\n+\n+\t\t\tlws_strncpy(vhost-\u003esocks_user, socks, p_colon - socks + 1);\n+\t\t\tlws_strncpy(vhost-\u003esocks_password, p_colon + 1,\n+\t\t\t\tp_at - (p_colon + 1) + 1);\n+\t\t}\n+\n+\t\tlwsl_info(\u0022 Socks auth, user: %s, password: %s\u005cn\u0022,\n+\t\t\tvhost-\u003esocks_user, vhost-\u003esocks_password );\n+\n+\t\tsocks \u003d p_at + 1;\n+\t}\n+\n+\tlws_strncpy(vhost-\u003esocks_proxy_address, socks,\n+\t\t sizeof(vhost-\u003esocks_proxy_address));\n+\n+\tp_colon \u003d strchr(vhost-\u003esocks_proxy_address, ':');\n+\tif (!p_colon \u0026\u0026 !vhost-\u003esocks_proxy_port) {\n+\t\tlwsl_err(\u0022socks_proxy needs to be address:port\u005cn\u0022);\n+\t\treturn -1;\n+\t} else {\n+\t\tif (p_colon) {\n+\t\t\t*p_colon \u003d '\u005c0';\n+\t\t\tvhost-\u003esocks_proxy_port \u003d atoi(p_colon + 1);\n+\t\t}\n+\t}\n+\n+\tlwsl_info(\u0022 Socks %s:%u\u005cn\u0022, vhost-\u003esocks_proxy_address,\n+\t\t\tvhost-\u003esocks_proxy_port);\n+\n+\treturn 0;\n+\n+bail:\n+\treturn -1;\n+}\n+#endif\n+\n+LWS_VISIBLE const struct lws_protocols *\n+lws_get_protocol(struct lws *wsi)\n+{\n+\treturn wsi-\u003eprotocol;\n+}\n+\n+\n+int\n+lws_ensure_user_space(struct lws *wsi)\n+{\n+\tif (!wsi-\u003eprotocol)\n+\t\treturn 0;\n+\n+\t/* allocate the per-connection user memory (if any) */\n+\n+\tif (wsi-\u003eprotocol-\u003eper_session_data_size \u0026\u0026 !wsi-\u003euser_space) {\n+\t\twsi-\u003euser_space \u003d lws_zalloc(\n+\t\t\t wsi-\u003eprotocol-\u003eper_session_data_size, \u0022user space\u0022);\n+\t\tif (wsi-\u003euser_space \u003d\u003d NULL) {\n+\t\t\tlwsl_err(\u0022%s: OOM\u005cn\u0022, __func__);\n+\t\t\treturn 1;\n+\t\t}\n+\t} else\n+\t\tlwsl_debug(\u0022%s: %p protocol pss %lu, user_space\u003d%p\u005cn\u0022, __func__,\n+\t\t\t wsi, (long)wsi-\u003eprotocol-\u003eper_session_data_size,\n+\t\t\t wsi-\u003euser_space);\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE void *\n+lws_adjust_protocol_psds(struct lws *wsi, size_t new_size)\n+{\n+\t((struct lws_protocols *)lws_get_protocol(wsi))-\u003eper_session_data_size \u003d\n+\t\tnew_size;\n+\n+\tif (lws_ensure_user_space(wsi))\n+\t\t\treturn NULL;\n+\n+\treturn wsi-\u003euser_space;\n+}\n+\n+LWS_VISIBLE int\n+lwsl_timestamp(int level, char *p, int len)\n+{\n+#ifndef LWS_PLAT_OPTEE\n+\ttime_t o_now \u003d time(NULL);\n+\tunsigned long long now;\n+\tstruct tm *ptm \u003d NULL;\n+#ifndef WIN32\n+\tstruct tm tm;\n+#endif\n+\tint n;\n+\n+#ifndef _WIN32_WCE\n+#ifdef WIN32\n+\tptm \u003d localtime(\u0026o_now);\n+#else\n+\tif (localtime_r(\u0026o_now, \u0026tm))\n+\t\tptm \u003d \u0026tm;\n+#endif\n+#endif\n+\tp[0] \u003d '\u005c0';\n+\tfor (n \u003d 0; n \u003c LLL_COUNT; n++) {\n+\t\tif (level !\u003d (1 \u003c\u003c n))\n+\t\t\tcontinue;\n+\t\tnow \u003d time_in_microseconds() / 100;\n+\t\tif (ptm)\n+\t\t\tn \u003d lws_snprintf(p, len,\n+\t\t\t\t\u0022[%04d/%02d/%02d %02d:%02d:%02d:%04d] %s: \u0022,\n+\t\t\t\tptm-\u003etm_year + 1900,\n+\t\t\t\tptm-\u003etm_mon + 1,\n+\t\t\t\tptm-\u003etm_mday,\n+\t\t\t\tptm-\u003etm_hour,\n+\t\t\t\tptm-\u003etm_min,\n+\t\t\t\tptm-\u003etm_sec,\n+\t\t\t\t(int)(now % 10000), log_level_names[n]);\n+\t\telse\n+\t\t\tn \u003d lws_snprintf(p, len, \u0022[%llu:%04d] %s: \u0022,\n+\t\t\t\t\t(unsigned long long) now / 10000,\n+\t\t\t\t\t(int)(now % 10000), log_level_names[n]);\n+\t\treturn n;\n+\t}\n+#else\n+\tp[0] \u003d '\u005c0';\n+#endif\n+\n+\treturn 0;\n+}\n+\n+#ifndef LWS_PLAT_OPTEE\n+static const char * const colours[] \u003d {\n+\t\u0022[31;1m\u0022, /* LLL_ERR */\n+\t\u0022[36;1m\u0022, /* LLL_WARN */\n+\t\u0022[35;1m\u0022, /* LLL_NOTICE */\n+\t\u0022[32;1m\u0022, /* LLL_INFO */\n+\t\u0022[34;1m\u0022, /* LLL_DEBUG */\n+\t\u0022[33;1m\u0022, /* LLL_PARSER */\n+\t\u0022[33;1m\u0022, /* LLL_HEADER */\n+\t\u0022[33;1m\u0022, /* LLL_EXT */\n+\t\u0022[33;1m\u0022, /* LLL_CLIENT */\n+\t\u0022[33;1m\u0022, /* LLL_LATENCY */\n+\t\u0022[30;1m\u0022, /* LLL_USER */\n+};\n+\n+LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)\n+{\n+\tchar buf[50];\n+\tstatic char tty \u003d 3;\n+\tint n, m \u003d ARRAY_SIZE(colours) - 1;\n+\n+\tif (!tty)\n+\t\ttty \u003d isatty(2) | 2;\n+\tlwsl_timestamp(level, buf, sizeof(buf));\n+\n+\tif (tty \u003d\u003d 3) {\n+\t\tn \u003d 1 \u003c\u003c (ARRAY_SIZE(colours) - 1);\n+\t\twhile (n) {\n+\t\t\tif (level \u0026 n)\n+\t\t\t\tbreak;\n+\t\t\tm--;\n+\t\t\tn \u003e\u003e\u003d 1;\n+\t\t}\n+\t\tfprintf(stderr, \u0022%c%s%s%s%c[0m\u0022, 27, colours[m], buf, line, 27);\n+\t} else\n+\t\tfprintf(stderr, \u0022%s%s\u0022, buf, line);\n+}\n+#endif\n+\n+LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl)\n+{\n+\tchar buf[256];\n+\tint n;\n+\n+\tif (!(log_level \u0026 filter))\n+\t\treturn;\n+\n+\tn \u003d vsnprintf(buf, sizeof(buf) - 1, format, vl);\n+\t(void)n;\n+\t/* vnsprintf returns what it would have written, even if truncated */\n+\tif (n \u003e (int)sizeof(buf) - 1)\n+\t\tn \u003d sizeof(buf) - 1;\n+\tif (n \u003e 0)\n+\t\tbuf[n] \u003d '\u005c0';\n+\n+\tlwsl_emit(filter, buf);\n+}\n+\n+LWS_VISIBLE void _lws_log(int filter, const char *format, ...)\n+{\n+\tva_list ap;\n+\n+\tva_start(ap, format);\n+\t_lws_logv(filter, format, ap);\n+\tva_end(ap);\n+}\n+\n+LWS_VISIBLE void lws_set_log_level(int level,\n+\t\t\t\t void (*func)(int level, const char *line))\n+{\n+\tlog_level \u003d level;\n+\tif (func)\n+\t\tlwsl_emit \u003d func;\n+}\n+\n+LWS_VISIBLE int lwsl_visible(int level)\n+{\n+\treturn log_level \u0026 level;\n+}\n+\n+LWS_VISIBLE void\n+lwsl_hexdump_level(int hexdump_level, const void *vbuf, size_t len)\n+{\n+\tunsigned char *buf \u003d (unsigned char *)vbuf;\n+\tunsigned int n, m, start;\n+\tchar line[80];\n+\tchar *p;\n+\n+\tif (!lwsl_visible(hexdump_level))\n+\t\treturn;\n+\n+\tif (!len)\n+\t\treturn;\n+\n+\tif (!vbuf)\n+\t\treturn;\n+\n+\t_lws_log(hexdump_level, \u0022\u005cn\u0022);\n+\n+\tfor (n \u003d 0; n \u003c len;) {\n+\t\tstart \u003d n;\n+\t\tp \u003d line;\n+\n+\t\tp +\u003d sprintf(p, \u0022%04X: \u0022, start);\n+\n+\t\tfor (m \u003d 0; m \u003c 16 \u0026\u0026 n \u003c len; m++)\n+\t\t\tp +\u003d sprintf(p, \u0022%02X \u0022, buf[n++]);\n+\t\twhile (m++ \u003c 16)\n+\t\t\tp +\u003d sprintf(p, \u0022 \u0022);\n+\n+\t\tp +\u003d sprintf(p, \u0022 \u0022);\n+\n+\t\tfor (m \u003d 0; m \u003c 16 \u0026\u0026 (start + m) \u003c len; m++) {\n+\t\t\tif (buf[start + m] \u003e\u003d ' ' \u0026\u0026 buf[start + m] \u003c 127)\n+\t\t\t\t*p++ \u003d buf[start + m];\n+\t\t\telse\n+\t\t\t\t*p++ \u003d '.';\n+\t\t}\n+\t\twhile (m++ \u003c 16)\n+\t\t\t*p++ \u003d ' ';\n+\n+\t\t*p++ \u003d '\u005cn';\n+\t\t*p \u003d '\u005c0';\n+\t\t_lws_log(hexdump_level, \u0022%s\u0022, line);\n+\t\t(void)line;\n+\t}\n+\n+\t_lws_log(hexdump_level, \u0022\u005cn\u0022);\n+}\n+\n+LWS_VISIBLE void\n+lwsl_hexdump(const void *vbuf, size_t len)\n+{\n+\tlwsl_hexdump_level(LLL_DEBUG, vbuf, len);\n+}\n+\n+LWS_VISIBLE int\n+lws_is_ssl(struct lws *wsi)\n+{\n+#if defined(LWS_WITH_TLS)\n+\treturn wsi-\u003etls.use_ssl \u0026 LCCSCF_USE_SSL;\n+#else\n+\t(void)wsi;\n+\treturn 0;\n+#endif\n+}\n+\n+#if defined(LWS_WITH_TLS) \u0026\u0026 !defined(LWS_WITH_MBEDTLS)\n+LWS_VISIBLE lws_tls_conn*\n+lws_get_ssl(struct lws *wsi)\n+{\n+\treturn wsi-\u003etls.ssl;\n+}\n+#endif\n+\n+LWS_VISIBLE int\n+lws_partial_buffered(struct lws *wsi)\n+{\n+\treturn !!wsi-\u003etrunc_len;\n+}\n+\n+LWS_VISIBLE lws_fileofs_t\n+lws_get_peer_write_allowance(struct lws *wsi)\n+{\n+\treturn wsi-\u003erole_ops-\u003etx_credit(wsi);\n+}\n+\n+LWS_VISIBLE void\n+lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state,\n+\t\tstruct lws_role_ops *ops)\n+{\n+#if defined(_DEBUG)\n+\tconst char *name \u003d \u0022(unset)\u0022;\n+#endif\n+\twsi-\u003ewsistate \u003d role | state;\n+\tif (ops)\n+\t\twsi-\u003erole_ops \u003d ops;\n+#if defined(_DEBUG)\n+\tif (wsi-\u003erole_ops)\n+\t\tname \u003d wsi-\u003erole_ops-\u003ename;\n+\tlwsl_debug(\u0022%s: %p: wsistate 0x%x, ops %s\u005cn\u0022, __func__, wsi,\n+\t\t wsi-\u003ewsistate, name);\n+#endif\n+}\n+\n+LWS_VISIBLE struct lws_plat_file_ops *\n+lws_get_fops(struct lws_context *context)\n+{\n+\treturn (struct lws_plat_file_ops *)context-\u003efops;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN struct lws_context *\n+lws_get_context(const struct lws *wsi)\n+{\n+\treturn wsi-\u003econtext;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_get_count_threads(struct lws_context *context)\n+{\n+\treturn context-\u003ecount_threads;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void *\n+lws_wsi_user(struct lws *wsi)\n+{\n+\treturn wsi-\u003euser_space;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_set_wsi_user(struct lws *wsi, void *data)\n+{\n+\tif (wsi-\u003euser_space_externally_allocated)\n+\t\twsi-\u003euser_space \u003d data;\n+\telse\n+\t\tlwsl_err(\u0022%s: Cannot set internally-allocated user_space\u005cn\u0022,\n+\t\t\t __func__);\n+}\n+\n+LWS_VISIBLE LWS_EXTERN struct lws *\n+lws_get_parent(const struct lws *wsi)\n+{\n+\treturn wsi-\u003eparent;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN struct lws *\n+lws_get_child(const struct lws *wsi)\n+{\n+\treturn wsi-\u003echild_list;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_set_parent_carries_io(struct lws *wsi)\n+{\n+\twsi-\u003eparent_carries_io \u003d 1;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void *\n+lws_get_opaque_parent_data(const struct lws *wsi)\n+{\n+\treturn wsi-\u003eopaque_parent_data;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_set_opaque_parent_data(struct lws *wsi, void *data)\n+{\n+\twsi-\u003eopaque_parent_data \u003d data;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_get_child_pending_on_writable(const struct lws *wsi)\n+{\n+\treturn wsi-\u003eparent_pending_cb_on_writable;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_clear_child_pending_on_writable(struct lws *wsi)\n+{\n+\twsi-\u003eparent_pending_cb_on_writable \u003d 0;\n+}\n+\n+\n+LWS_EXTERN int\n+__lws_rx_flow_control(struct lws *wsi)\n+{\n+\tstruct lws *wsic \u003d wsi-\u003echild_list;\n+\n+\t// h2 ignores rx flow control atm\n+\tif (lwsi_role_h2(wsi) || wsi-\u003ehttp2_substream ||\n+\t lwsi_role_h2_ENCAPSULATION(wsi))\n+\t\treturn 0; // !!!\n+\n+\t/* if he has children, do those if they were changed */\n+\twhile (wsic) {\n+\t\tif (wsic-\u003erxflow_change_to \u0026 LWS_RXFLOW_PENDING_CHANGE)\n+\t\t\t__lws_rx_flow_control(wsic);\n+\n+\t\twsic \u003d wsic-\u003esibling_list;\n+\t}\n+\n+\t/* there is no pending change */\n+\tif (!(wsi-\u003erxflow_change_to \u0026 LWS_RXFLOW_PENDING_CHANGE))\n+\t\treturn 0;\n+\n+\t/* stuff is still buffered, not ready to really accept new input */\n+\tif (lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist, NULL)) {\n+\t\t/* get ourselves called back to deal with stashed buffer */\n+\t\tlws_callback_on_writable(wsi);\n+\t\treturn 0;\n+\t}\n+\n+\t/* now the pending is cleared, we can change rxflow state */\n+\n+\twsi-\u003erxflow_change_to \u0026\u003d ~LWS_RXFLOW_PENDING_CHANGE;\n+\n+\tlwsl_info(\u0022rxflow: wsi %p change_to %d\u005cn\u0022, wsi,\n+\t\t\t wsi-\u003erxflow_change_to \u0026 LWS_RXFLOW_ALLOW);\n+\n+\t/* adjust the pollfd for this wsi */\n+\n+\tif (wsi-\u003erxflow_change_to \u0026 LWS_RXFLOW_ALLOW) {\n+\t\tif (__lws_change_pollfd(wsi, 0, LWS_POLLIN)) {\n+\t\t\tlwsl_info(\u0022%s: fail\u005cn\u0022, __func__);\n+\t\t\treturn -1;\n+\t\t}\n+\t} else\n+\t\tif (__lws_change_pollfd(wsi, LWS_POLLIN, 0))\n+\t\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+LWS_EXTERN int\n+lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len)\n+{\n+\tstatic const unsigned char e0f4[] \u003d {\n+\t\t0xa0 | ((2 - 1) \u003c\u003c 2) | 1, /* e0 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e1 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e2 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e3 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e4 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e5 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e6 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e7 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e8 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e9 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ea */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* eb */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ec */\n+\t\t0x80 | ((2 - 1) \u003c\u003c 2) | 1, /* ed */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ee */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ef */\n+\t\t0x90 | ((3 - 1) \u003c\u003c 2) | 2, /* f0 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 2, /* f1 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 2, /* f2 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 2, /* f3 */\n+\t\t0x80 | ((1 - 1) \u003c\u003c 2) | 2, /* f4 */\n+\n+\t\t0,\t\t\t /* s0 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 0, /* s2 */\n+\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* s3 */\n+\t};\n+\tunsigned char s \u003d *state;\n+\n+\twhile (len--) {\n+\t\tunsigned char c \u003d *buf++;\n+\n+\t\tif (!s) {\n+\t\t\tif (c \u003e\u003d 0x80) {\n+\t\t\t\tif (c \u003c 0xc2 || c \u003e 0xf4)\n+\t\t\t\t\treturn 1;\n+\t\t\t\tif (c \u003c 0xe0)\n+\t\t\t\t\ts \u003d 0x80 | ((4 - 1) \u003c\u003c 2);\n+\t\t\t\telse\n+\t\t\t\t\ts \u003d e0f4[c - 0xe0];\n+\t\t\t}\n+\t\t} else {\n+\t\t\tif (c \u003c (s \u0026 0xf0) ||\n+\t\t\t c \u003e\u003d (s \u0026 0xf0) + 0x10 + ((s \u003c\u003c 2) \u0026 0x30))\n+\t\t\t\treturn 1;\n+\t\t\ts \u003d e0f4[21 + (s \u0026 3)];\n+\t\t}\n+\t}\n+\n+\t*state \u003d s;\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_parse_uri(char *p, const char **prot, const char **ads, int *port,\n+\t const char **path)\n+{\n+\tconst char *end;\n+\tstatic const char *slash \u003d \u0022/\u0022;\n+\n+\t/* cut up the location into address, port and path */\n+\t*prot \u003d p;\n+\twhile (*p \u0026\u0026 (*p !\u003d ':' || p[1] !\u003d '/' || p[2] !\u003d '/'))\n+\t\tp++;\n+\tif (!*p) {\n+\t\tend \u003d p;\n+\t\tp \u003d (char *)*prot;\n+\t\t*prot \u003d end;\n+\t} else {\n+\t\t*p \u003d '\u005c0';\n+\t\tp +\u003d 3;\n+\t}\n+\t*ads \u003d p;\n+\tif (!strcmp(*prot, \u0022http\u0022) || !strcmp(*prot, \u0022ws\u0022))\n+\t\t*port \u003d 80;\n+\telse if (!strcmp(*prot, \u0022https\u0022) || !strcmp(*prot, \u0022wss\u0022))\n+\t\t*port \u003d 443;\n+\n+ if (*p \u003d\u003d '[')\n+ {\n+ ++(*ads);\n+ while (*p \u0026\u0026 *p !\u003d ']')\n+ p++;\n+ if (*p)\n+ *p++ \u003d '\u005c0';\n+ }\n+ else\n+ {\n+ while (*p \u0026\u0026 *p !\u003d ':' \u0026\u0026 *p !\u003d '/')\n+ p++;\n+ }\n+\tif (*p \u003d\u003d ':') {\n+\t\t*p++ \u003d '\u005c0';\n+\t\t*port \u003d atoi(p);\n+\t\twhile (*p \u0026\u0026 *p !\u003d '/')\n+\t\t\tp++;\n+\t}\n+\t*path \u003d slash;\n+\tif (*p) {\n+\t\t*p++ \u003d '\u005c0';\n+\t\tif (*p)\n+\t\t\t*path \u003d p;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+#if defined(LWS_WITHOUT_EXTENSIONS)\n+\n+/* we need to provide dummy callbacks for internal exts\n+ * so user code runs when faced with a lib compiled with\n+ * extensions disabled.\n+ */\n+\n+LWS_VISIBLE int\n+lws_extension_callback_pm_deflate(struct lws_context *context,\n+ const struct lws_extension *ext,\n+ struct lws *wsi,\n+ enum lws_extension_callback_reasons reason,\n+ void *user, void *in, size_t len)\n+{\n+\t(void)context;\n+\t(void)ext;\n+\t(void)wsi;\n+\t(void)reason;\n+\t(void)user;\n+\t(void)in;\n+\t(void)len;\n+\n+\treturn 0;\n+}\n+\n+LWS_EXTERN int\n+lws_set_extension_option(struct lws *wsi, const char *ext_name,\n+\t\t\t const char *opt_name, const char *opt_val)\n+{\n+\treturn -1;\n+}\n+#endif\n+\n+LWS_EXTERN int\n+lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,\n+\t\tconst char *iface)\n+{\n+#ifdef LWS_WITH_UNIX_SOCK\n+\tstruct sockaddr_un serv_unix;\n+#endif\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 serv_addr6;\n+#endif\n+\tstruct sockaddr_in serv_addr4;\n+#ifndef LWS_PLAT_OPTEE\n+\tsocklen_t len \u003d sizeof(struct sockaddr_storage);\n+#endif\n+\tint n;\n+#if !defined(LWS_WITH_ESP32)\n+\tint m;\n+#endif\n+\tstruct sockaddr_storage sin;\n+\tstruct sockaddr *v;\n+\n+#ifdef LWS_WITH_UNIX_SOCK\n+\tif (LWS_UNIX_SOCK_ENABLED(vhost)) {\n+\t\tv \u003d (struct sockaddr *)\u0026serv_unix;\n+\t\tn \u003d sizeof(struct sockaddr_un);\n+\t\tbzero((char *) \u0026serv_unix, sizeof(serv_unix));\n+\t\tserv_unix.sun_family \u003d AF_UNIX;\n+\t\tif (!iface)\n+\t\t\treturn -1;\n+\t\tif (sizeof(serv_unix.sun_path) \u003c\u003d strlen(iface)) {\n+\t\t\tlwsl_err(\u0022\u005c\u0022%s\u005c\u0022 too long for UNIX domain socket\u005cn\u0022,\n+\t\t\t iface);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tstrcpy(serv_unix.sun_path, iface);\n+\t\tif (serv_unix.sun_path[0] \u003d\u003d '@')\n+\t\t\tserv_unix.sun_path[0] \u003d '\u005c0';\n+\n+\t} else\n+#endif\n+#if defined(LWS_WITH_IPV6) \u0026\u0026 !defined(LWS_WITH_ESP32)\n+\tif (LWS_IPV6_ENABLED(vhost)) {\n+\t\tv \u003d (struct sockaddr *)\u0026serv_addr6;\n+\t\tn \u003d sizeof(struct sockaddr_in6);\n+\t\tbzero((char *) \u0026serv_addr6, sizeof(serv_addr6));\n+\t\tif (iface) {\n+\t\t\tm \u003d interface_to_sa(vhost, iface,\n+\t\t\t\t (struct sockaddr_in *)v, n);\n+\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_USABLE) {\n+\t\t\t\tlwsl_info(\u0022%s: netif %s: Not usable\u005cn\u0022,\n+\t\t\t\t\t __func__, iface);\n+\t\t\t\treturn m;\n+\t\t\t}\n+\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_EXIST) {\n+\t\t\t\tlwsl_info(\u0022%s: netif %s: Does not exist\u005cn\u0022,\n+\t\t\t\t\t __func__, iface);\n+\t\t\t\treturn m;\n+\t\t\t}\n+\t\t\tserv_addr6.sin6_scope_id \u003d lws_get_addr_scope(iface);\n+\t\t}\n+\n+\t\tserv_addr6.sin6_family \u003d AF_INET6;\n+\t\tserv_addr6.sin6_port \u003d htons(port);\n+\t} else\n+#endif\n+\t{\n+\t\tv \u003d (struct sockaddr *)\u0026serv_addr4;\n+\t\tn \u003d sizeof(serv_addr4);\n+\t\tbzero((char *) \u0026serv_addr4, sizeof(serv_addr4));\n+\t\tserv_addr4.sin_addr.s_addr \u003d INADDR_ANY;\n+\t\tserv_addr4.sin_family \u003d AF_INET;\n+#if !defined(LWS_WITH_ESP32)\n+\n+\t\tif (iface) {\n+\t\t m \u003d interface_to_sa(vhost, iface,\n+\t\t\t\t (struct sockaddr_in *)v, n);\n+\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_USABLE) {\n+\t\t\t\tlwsl_info(\u0022%s: netif %s: Not usable\u005cn\u0022,\n+\t\t\t\t\t __func__, iface);\n+\t\t\t\treturn m;\n+\t\t\t}\n+\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_EXIST) {\n+\t\t\t\tlwsl_info(\u0022%s: netif %s: Does not exist\u005cn\u0022,\n+\t\t\t\t\t __func__, iface);\n+\t\t\t\treturn m;\n+\t\t\t}\n+\t\t}\n+#endif\n+\t\tserv_addr4.sin_port \u003d htons(port);\n+\t} /* ipv4 */\n+\n+\t/* just checking for the interface extant */\n+\tif (sockfd \u003d\u003d LWS_SOCK_INVALID)\n+\t\treturn 0;\n+\n+\tn \u003d bind(sockfd, v, n);\n+#ifdef LWS_WITH_UNIX_SOCK\n+\tif (n \u003c 0 \u0026\u0026 LWS_UNIX_SOCK_ENABLED(vhost)) {\n+\t\tlwsl_err(\u0022ERROR on binding fd %d to \u005c\u0022%s\u005c\u0022 (%d %d)\u005cn\u0022,\n+\t\t\t\tsockfd, iface, n, LWS_ERRNO);\n+\t\treturn -1;\n+\t} else\n+#endif\n+\tif (n \u003c 0) {\n+\t\tlwsl_err(\u0022ERROR on binding fd %d to port %d (%d %d)\u005cn\u0022,\n+\t\t\t\tsockfd, port, n, LWS_ERRNO);\n+\t\treturn -1;\n+\t}\n+\n+#ifndef LWS_PLAT_OPTEE\n+\tif (getsockname(sockfd, (struct sockaddr *)\u0026sin, \u0026len) \u003d\u003d -1)\n+\t\tlwsl_warn(\u0022getsockname: %s\u005cn\u0022, strerror(LWS_ERRNO));\n+\telse\n+#endif\n+#if defined(LWS_WITH_IPV6)\n+\t\tport \u003d (sin.ss_family \u003d\u003d AF_INET6) ?\n+\t\t\tntohs(((struct sockaddr_in6 *) \u0026sin)-\u003esin6_port) :\n+\t\t\tntohs(((struct sockaddr_in *) \u0026sin)-\u003esin_port);\n+#else\n+\t\t{\n+\t\t\tstruct sockaddr_in sain;\n+\t\t\tmemcpy(\u0026sain, \u0026sin, sizeof(sain));\n+\t\t\tport \u003d ntohs(sain.sin_port);\n+\t\t}\n+#endif\n+\n+\treturn port;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_get_vhost_listen_port(struct lws_vhost *vhost)\n+{\n+\treturn vhost-\u003elisten_port;\n+}\n+\n+#if defined(LWS_WITH_IPV6)\n+LWS_EXTERN unsigned long\n+lws_get_addr_scope(const char *ipaddr)\n+{\n+\tunsigned long scope \u003d 0;\n+\n+#ifndef WIN32\n+\tstruct ifaddrs *addrs, *addr;\n+\tchar ip[NI_MAXHOST];\n+\tunsigned int i;\n+\n+\tgetifaddrs(\u0026addrs);\n+\tfor (addr \u003d addrs; addr; addr \u003d addr-\u003eifa_next) {\n+\t\tif (!addr-\u003eifa_addr ||\n+\t\t\taddr-\u003eifa_addr-\u003esa_family !\u003d AF_INET6)\n+\t\t\tcontinue;\n+\n+\t\tgetnameinfo(addr-\u003eifa_addr,\n+\t\t\t\tsizeof(struct sockaddr_in6),\n+\t\t\t\tip, sizeof(ip),\n+\t\t\t\tNULL, 0, NI_NUMERICHOST);\n+\n+\t\ti \u003d 0;\n+\t\twhile (ip[i])\n+\t\t\tif (ip[i++] \u003d\u003d '%') {\n+\t\t\t\tip[i - 1] \u003d '\u005c0';\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\tif (!strcmp(ip, ipaddr)) {\n+\t\t\tscope \u003d if_nametoindex(addr-\u003eifa_name);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tfreeifaddrs(addrs);\n+#else\n+\tPIP_ADAPTER_ADDRESSES adapter, addrs \u003d NULL;\n+\tPIP_ADAPTER_UNICAST_ADDRESS addr;\n+\tULONG size \u003d 0;\n+\tDWORD ret;\n+\tstruct sockaddr_in6 *sockaddr;\n+\tchar ip[NI_MAXHOST];\n+\tunsigned int i;\n+\tint found \u003d 0;\n+\n+\tfor (i \u003d 0; i \u003c 5; i++)\n+\t{\n+\t\tret \u003d GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX,\n+\t\t\t\tNULL, addrs, \u0026size);\n+\t\tif ((ret \u003d\u003d NO_ERROR) || (ret \u003d\u003d ERROR_NO_DATA)) {\n+\t\t\tbreak;\n+\t\t} else if (ret \u003d\u003d ERROR_BUFFER_OVERFLOW)\n+\t\t{\n+\t\t\tif (addrs)\n+\t\t\t\tfree(addrs);\n+\t\t\taddrs \u003d (IP_ADAPTER_ADDRESSES *)malloc(size);\n+\t\t} else\n+\t\t{\n+\t\t\tif (addrs)\n+\t\t\t{\n+\t\t\t\tfree(addrs);\n+\t\t\t\taddrs \u003d NULL;\n+\t\t\t}\n+\t\t\tlwsl_err(\u0022Failed to get IPv6 address table (%d)\u0022, ret);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif ((ret \u003d\u003d NO_ERROR) \u0026\u0026 (addrs)) {\n+\t\tadapter \u003d addrs;\n+\t\twhile (adapter \u0026\u0026 !found) {\n+\t\t\taddr \u003d adapter-\u003eFirstUnicastAddress;\n+\t\t\twhile (addr \u0026\u0026 !found) {\n+\t\t\t\tif (addr-\u003eAddress.lpSockaddr-\u003esa_family \u003d\u003d\n+\t\t\t\t AF_INET6) {\n+\t\t\t\t\tsockaddr \u003d (struct sockaddr_in6 *)\n+\t\t\t\t\t\t(addr-\u003eAddress.lpSockaddr);\n+\n+\t\t\t\t\tlws_plat_inet_ntop(sockaddr-\u003esin6_family,\n+\t\t\t\t\t\t\t\u0026sockaddr-\u003esin6_addr,\n+\t\t\t\t\t\t\tip, sizeof(ip));\n+\n+\t\t\t\t\tif (!strcmp(ip, ipaddr)) {\n+\t\t\t\t\t\tscope \u003d sockaddr-\u003esin6_scope_id;\n+\t\t\t\t\t\tfound \u003d 1;\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\taddr \u003d addr-\u003eNext;\n+\t\t\t}\n+\t\t\tadapter \u003d adapter-\u003eNext;\n+\t\t}\n+\t}\n+\tif (addrs)\n+\t\tfree(addrs);\n+#endif\n+\n+\treturn scope;\n+}\n+#endif\n+\n+#if !defined(LWS_NO_SERVER)\n+\n+LWS_EXTERN struct lws *\n+lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags,\n+\t\t const char *protocol_name, struct lws *parent_wsi)\n+{\n+\tlws_sock_file_fd_type sock;\n+\tstruct addrinfo h, *r, *rp;\n+\tstruct lws *wsi \u003d NULL;\n+\tchar buf[16];\n+\tint n;\n+\n+\tmemset(\u0026h, 0, sizeof(h));\n+\th.ai_family \u003d AF_UNSPEC; /* Allow IPv4 or IPv6 */\n+\th.ai_socktype \u003d SOCK_DGRAM;\n+\th.ai_protocol \u003d IPPROTO_UDP;\n+\th.ai_flags \u003d AI_PASSIVE | AI_ADDRCONFIG;\n+\n+\tlws_snprintf(buf, sizeof(buf), \u0022%u\u0022, port);\n+\tn \u003d getaddrinfo(NULL, buf, \u0026h, \u0026r);\n+\tif (n) {\n+\t\tlwsl_info(\u0022%s: getaddrinfo error: %s\u005cn\u0022, __func__,\n+\t\t\t gai_strerror(n));\n+\t\tgoto bail;\n+\t}\n+\n+\tfor (rp \u003d r; rp; rp \u003d rp-\u003eai_next) {\n+\t\tsock.sockfd \u003d socket(rp-\u003eai_family, rp-\u003eai_socktype,\n+\t\t\t\t rp-\u003eai_protocol);\n+\t\tif (sock.sockfd \u003e\u003d 0)\n+\t\t\tbreak;\n+\t}\n+\tif (!rp) {\n+\t\tlwsl_err(\u0022%s: unable to create INET socket\u005cn\u0022, __func__);\n+\t\tgoto bail1;\n+\t}\n+\n+\tif ((flags \u0026 LWS_CAUDP_BIND) \u0026\u0026\n+\t bind(sock.sockfd, rp-\u003eai_addr, rp-\u003eai_addrlen) \u003d\u003d -1) {\n+\t\tlwsl_err(\u0022%s: bind failed\u005cn\u0022, __func__);\n+\t\tgoto bail2;\n+\t}\n+\n+\twsi \u003d lws_adopt_descriptor_vhost(vhost, LWS_ADOPT_RAW_SOCKET_UDP, sock,\n+\t\t\t\t protocol_name, parent_wsi);\n+\tif (!wsi)\n+\t\tlwsl_err(\u0022%s: udp adoption failed\u005cn\u0022, __func__);\n+\n+bail2:\n+\tif (!wsi)\n+\t\tclose((int)sock.sockfd);\n+bail1:\n+\tfreeaddrinfo(r);\n+\n+bail:\n+\treturn wsi;\n+}\n+\n+#endif\n+\n+\n+\n+static const char *hex \u003d \u00220123456789ABCDEF\u0022;\n+\n+LWS_VISIBLE LWS_EXTERN const char *\n+lws_sql_purify(char *escaped, const char *string, int len)\n+{\n+\tconst char *p \u003d string;\n+\tchar *q \u003d escaped;\n+\n+\twhile (*p \u0026\u0026 len-- \u003e 2) {\n+\t\tif (*p \u003d\u003d '\u005c'') {\n+\t\t\t*q++ \u003d '\u005c'';\n+\t\t\t*q++ \u003d '\u005c'';\n+\t\t\tlen --;\n+\t\t\tp++;\n+\t\t} else\n+\t\t\t*q++ \u003d *p++;\n+\t}\n+\t*q \u003d '\u005c0';\n+\n+\treturn escaped;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN const char *\n+lws_json_purify(char *escaped, const char *string, int len)\n+{\n+\tconst char *p \u003d string;\n+\tchar *q \u003d escaped;\n+\n+\tif (!p) {\n+\t\tescaped[0] \u003d '\u005c0';\n+\t\treturn escaped;\n+\t}\n+\n+\twhile (*p \u0026\u0026 len-- \u003e 6) {\n+\t\tif (*p \u003d\u003d '\u005c\u0022' || *p \u003d\u003d '\u005c\u005c' || *p \u003c 0x20) {\n+\t\t\t*q++ \u003d '\u005c\u005c';\n+\t\t\t*q++ \u003d 'u';\n+\t\t\t*q++ \u003d '0';\n+\t\t\t*q++ \u003d '0';\n+\t\t\t*q++ \u003d hex[((*p) \u003e\u003e 4) \u0026 15];\n+\t\t\t*q++ \u003d hex[(*p) \u0026 15];\n+\t\t\tlen -\u003d 5;\n+\t\t\tp++;\n+\t\t} else\n+\t\t\t*q++ \u003d *p++;\n+\t}\n+\t*q \u003d '\u005c0';\n+\n+\treturn escaped;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_filename_purify_inplace(char *filename)\n+{\n+\twhile (*filename) {\n+\n+\t\tif (*filename \u003d\u003d '.' \u0026\u0026 filename[1] \u003d\u003d '.') {\n+\t\t\t*filename \u003d '_';\n+\t\t\tfilename[1] \u003d '_';\n+\t\t}\n+\n+\t\tif (*filename \u003d\u003d ':' ||\n+\t\t *filename \u003d\u003d '/' ||\n+\t\t *filename \u003d\u003d '\u005c\u005c' ||\n+\t\t *filename \u003d\u003d '$' ||\n+\t\t *filename \u003d\u003d '%')\n+\t\t\t*filename \u003d '_';\n+\n+\t\tfilename++;\n+\t}\n+}\n+\n+LWS_VISIBLE LWS_EXTERN const char *\n+lws_urlencode(char *escaped, const char *string, int len)\n+{\n+\tconst char *p \u003d string;\n+\tchar *q \u003d escaped;\n+\n+\twhile (*p \u0026\u0026 len-- \u003e 3) {\n+\t\tif (*p \u003d\u003d ' ') {\n+\t\t\t*q++ \u003d '+';\n+\t\t\tp++;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif ((*p \u003e\u003d '0' \u0026\u0026 *p \u003c\u003d '9') ||\n+\t\t (*p \u003e\u003d 'A' \u0026\u0026 *p \u003c\u003d 'Z') ||\n+\t\t (*p \u003e\u003d 'a' \u0026\u0026 *p \u003c\u003d 'z')) {\n+\t\t\t*q++ \u003d *p++;\n+\t\t\tcontinue;\n+\t\t}\n+\t\t*q++ \u003d '%';\n+\t\t*q++ \u003d hex[(*p \u003e\u003e 4) \u0026 0xf];\n+\t\t*q++ \u003d hex[*p \u0026 0xf];\n+\n+\t\tlen -\u003d 2;\n+\t\tp++;\n+\t}\n+\t*q \u003d '\u005c0';\n+\n+\treturn escaped;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_urldecode(char *string, const char *escaped, int len)\n+{\n+\tint state \u003d 0, n;\n+\tchar sum \u003d 0;\n+\n+\twhile (*escaped \u0026\u0026 len) {\n+\t\tswitch (state) {\n+\t\tcase 0:\n+\t\t\tif (*escaped \u003d\u003d '%') {\n+\t\t\t\tstate++;\n+\t\t\t\tescaped++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (*escaped \u003d\u003d '+') {\n+\t\t\t\tescaped++;\n+\t\t\t\t*string++ \u003d ' ';\n+\t\t\t\tlen--;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\t*string++ \u003d *escaped++;\n+\t\t\tlen--;\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tn \u003d char_to_hex(*escaped);\n+\t\t\tif (n \u003c 0)\n+\t\t\t\treturn -1;\n+\t\t\tescaped++;\n+\t\t\tsum \u003d n \u003c\u003c 4;\n+\t\t\tstate++;\n+\t\t\tbreak;\n+\n+\t\tcase 2:\n+\t\t\tn \u003d char_to_hex(*escaped);\n+\t\t\tif (n \u003c 0)\n+\t\t\t\treturn -1;\n+\t\t\tescaped++;\n+\t\t\t*string++ \u003d sum | n;\n+\t\t\tlen--;\n+\t\t\tstate \u003d 0;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t}\n+\t*string \u003d '\u005c0';\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_finalize_startup(struct lws_context *context)\n+{\n+\tstruct lws_context_creation_info info;\n+\n+\tinfo.uid \u003d context-\u003euid;\n+\tinfo.gid \u003d context-\u003egid;\n+\n+#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n+\tmemcpy(info.caps, context-\u003ecaps, sizeof(info.caps));\n+\tinfo.count_caps \u003d context-\u003ecount_caps;\n+#endif\n+\n+\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n+\t\tlws_plat_drop_app_privileges(\u0026info);\n+\n+\treturn 0;\n+}\n+\n+int\n+lws_snprintf(char *str, size_t size, const char *format, ...)\n+{\n+\tva_list ap;\n+\tint n;\n+\n+\tif (!size)\n+\t\treturn 0;\n+\n+\tva_start(ap, format);\n+\tn \u003d vsnprintf(str, size, format, ap);\n+\tva_end(ap);\n+\n+\tif (n \u003e\u003d (int)size)\n+\t\treturn (int)size;\n+\n+\treturn n;\n+}\n+\n+char *\n+lws_strncpy(char *dest, const char *src, size_t size)\n+{\n+\tstrncpy(dest, src, size - 1);\n+\tdest[size - 1] \u003d '\u005c0';\n+\n+\treturn dest;\n+}\n+\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_is_cgi(struct lws *wsi) {\n+#ifdef LWS_WITH_CGI\n+\treturn !!wsi-\u003ehttp.cgi;\n+#else\n+\treturn 0;\n+#endif\n+}\n+\n+const struct lws_protocol_vhost_options *\n+lws_pvo_search(const struct lws_protocol_vhost_options *pvo, const char *name)\n+{\n+\twhile (pvo) {\n+\t\tif (!strcmp(pvo-\u003ename, name))\n+\t\t\tbreak;\n+\n+\t\tpvo \u003d pvo-\u003enext;\n+\t}\n+\n+\treturn pvo;\n+}\n+\n+void\n+lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs)\n+{\n+\tconst struct lws_vhost *vh \u003d ctx-\u003evhost_list;\n+\n+\twhile (vh) {\n+\n+\t\tcs-\u003erx +\u003d vh-\u003econn_stats.rx;\n+\t\tcs-\u003etx +\u003d vh-\u003econn_stats.tx;\n+\t\tcs-\u003eh1_conn +\u003d vh-\u003econn_stats.h1_conn;\n+\t\tcs-\u003eh1_trans +\u003d vh-\u003econn_stats.h1_trans;\n+\t\tcs-\u003eh2_trans +\u003d vh-\u003econn_stats.h2_trans;\n+\t\tcs-\u003ews_upg +\u003d vh-\u003econn_stats.ws_upg;\n+\t\tcs-\u003eh2_upg +\u003d vh-\u003econn_stats.h2_upg;\n+\t\tcs-\u003eh2_alpn +\u003d vh-\u003econn_stats.h2_alpn;\n+\t\tcs-\u003eh2_subs +\u003d vh-\u003econn_stats.h2_subs;\n+\t\tcs-\u003erejected +\u003d vh-\u003econn_stats.rejected;\n+\n+\t\tvh \u003d vh-\u003evhost_next;\n+\t}\n+}\n+\n+const char *\n+lws_cmdline_option(int argc, const char **argv, const char *val)\n+{\n+\tint n \u003d (int)strlen(val), c \u003d argc;\n+\n+\twhile (--c \u003e 0)\n+\t\tif (!strncmp(argv[c], val, n)) {\n+\t\t\tif (!*(argv[c] + n) \u0026\u0026 c \u003c argc - 1)\n+\t\t\t\treturn argv[c + 1];\n+\n+\t\t\treturn argv[c] + n;\n+\t\t}\n+\n+\treturn NULL;\n+}\n+\n+#ifdef LWS_WITH_SERVER_STATUS\n+\n+LWS_EXTERN int\n+lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)\n+{\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tstatic const char * const prots[] \u003d {\n+\t\t\u0022http://\u0022,\n+\t\t\u0022https://\u0022,\n+\t\t\u0022file://\u0022,\n+\t\t\u0022cgi://\u0022,\n+\t\t\u0022\u003ehttp://\u0022,\n+\t\t\u0022\u003ehttps://\u0022,\n+\t\t\u0022callback://\u0022\n+\t};\n+#endif\n+\tchar *orig \u003d buf, *end \u003d buf + len - 1, first \u003d 1;\n+\tint n \u003d 0;\n+\n+\tif (len \u003c 100)\n+\t\treturn 0;\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\u0022{\u005cn \u005c\u0022name\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022port\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022use_ssl\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022sts\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022rx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022tx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h1_conn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h1_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022ws_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022rejected\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_alpn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_subs\u005c\u0022:\u005c\u0022%lu\u005c\u0022\u0022\n+\t\t\t,\n+\t\t\tvh-\u003ename, vh-\u003elisten_port,\n+#if defined(LWS_WITH_TLS)\n+\t\t\tvh-\u003etls.use_ssl \u0026 LCCSCF_USE_SSL,\n+#else\n+\t\t\t0,\n+#endif\n+\t\t\t!!(vh-\u003eoptions \u0026 LWS_SERVER_OPTION_STS),\n+\t\t\tvh-\u003econn_stats.rx, vh-\u003econn_stats.tx,\n+\t\t\tvh-\u003econn_stats.h1_conn,\n+\t\t\tvh-\u003econn_stats.h1_trans,\n+\t\t\tvh-\u003econn_stats.h2_trans,\n+\t\t\tvh-\u003econn_stats.ws_upg,\n+\t\t\tvh-\u003econn_stats.rejected,\n+\t\t\tvh-\u003econn_stats.h2_upg,\n+\t\t\tvh-\u003econn_stats.h2_alpn,\n+\t\t\tvh-\u003econn_stats.h2_subs\n+\t);\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tif (vh-\u003ehttp.mount_list) {\n+\t\tconst struct lws_http_mount *m \u003d vh-\u003ehttp.mount_list;\n+\n+\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u005cn \u005c\u0022mounts\u005c\u0022:[\u0022);\n+\t\twhile (m) {\n+\t\t\tif (!first)\n+\t\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u0022);\n+\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\t\t\u0022\u005cn {\u005cn \u005c\u0022mountpoint\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\t\u0022 \u005c\u0022origin\u005c\u0022:\u005c\u0022%s%s\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\t\u0022 \u005c\u0022cache_max_age\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\t\u0022 \u005c\u0022cache_reuse\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\t\u0022 \u005c\u0022cache_revalidate\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\t\u0022 \u005c\u0022cache_intermediaries\u005c\u0022:\u005c\u0022%d\u005c\u0022\u005cn\u0022\n+\t\t\t\t\t,\n+\t\t\t\t\tm-\u003emountpoint,\n+\t\t\t\t\tprots[m-\u003eorigin_protocol],\n+\t\t\t\t\tm-\u003eorigin,\n+\t\t\t\t\tm-\u003ecache_max_age,\n+\t\t\t\t\tm-\u003ecache_reusable,\n+\t\t\t\t\tm-\u003ecache_revalidate,\n+\t\t\t\t\tm-\u003ecache_intermediaries);\n+\t\t\tif (m-\u003edef)\n+\t\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\t\t\t\u0022,\u005cn \u005c\u0022default\u005c\u0022:\u005c\u0022%s\u005c\u0022\u0022,\n+\t\t\t\t\t\tm-\u003edef);\n+\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn }\u0022);\n+\t\t\tfirst \u003d 0;\n+\t\t\tm \u003d m-\u003emount_next;\n+\t\t}\n+\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn ]\u0022);\n+\t}\n+#endif\n+\tif (vh-\u003eprotocols) {\n+\t\tn \u003d 0;\n+\t\tfirst \u003d 1;\n+\n+\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u005cn \u005c\u0022ws-protocols\u005c\u0022:[\u0022);\n+\t\twhile (n \u003c vh-\u003ecount_protocols) {\n+\t\t\tif (!first)\n+\t\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u0022);\n+\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\t\t\u0022\u005cn {\u005cn \u005c\u0022%s\u005c\u0022:{\u005cn\u0022\n+\t\t\t\t\t\u0022 \u005c\u0022status\u005c\u0022:\u005c\u0022ok\u005c\u0022\u005cn }\u005cn }\u0022\n+\t\t\t\t\t,\n+\t\t\t\t\tvh-\u003eprotocols[n].name);\n+\t\t\tfirst \u003d 0;\n+\t\t\tn++;\n+\t\t}\n+\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn ]\u0022);\n+\t}\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn}\u0022);\n+\n+\treturn buf - orig;\n+}\n+\n+\n+LWS_EXTERN LWS_VISIBLE int\n+lws_json_dump_context(const struct lws_context *context, char *buf, int len,\n+\t\tint hide_vhosts)\n+{\n+\tchar *orig \u003d buf, *end \u003d buf + len - 1, first \u003d 1;\n+\tconst struct lws_vhost *vh \u003d context-\u003evhost_list;\n+\tconst struct lws_context_per_thread *pt;\n+\ttime_t t \u003d time(NULL);\n+\tint n, listening \u003d 0, cgi_count \u003d 0;\n+\tstruct lws_conn_stats cs;\n+\tdouble d \u003d 0;\n+#ifdef LWS_WITH_CGI\n+\tstruct lws_cgi * const *pcgi;\n+#endif\n+\n+#ifdef LWS_WITH_LIBUV\n+\tuv_uptime(\u0026d);\n+#endif\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022{ \u0022\n+\t\t\t \u0022\u005c\u0022version\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n+\t\t\t \u0022\u005c\u0022uptime\u005c\u0022:\u005c\u0022%ld\u005c\u0022,\u005cn\u0022,\n+\t\t\t lws_get_library_version(),\n+\t\t\t (long)d);\n+\n+#ifdef LWS_HAVE_GETLOADAVG\n+\t{\n+\t\tdouble d[3];\n+\t\tint m;\n+\n+\t\tm \u003d getloadavg(d, 3);\n+\t\tfor (n \u003d 0; n \u003c m; n++) {\n+\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\t\u0022\u005c\u0022l%d\u005c\u0022:\u005c\u0022%.2f\u005c\u0022,\u005cn\u0022,\n+\t\t\t\tn + 1, d[n]);\n+\t\t}\n+\t}\n+#endif\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005c\u0022contexts\u005c\u0022:[\u005cn\u0022);\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022{ \u0022\n+\t\t\t\t\u0022\u005c\u0022context_uptime\u005c\u0022:\u005c\u0022%ld\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022\u005c\u0022cgi_spawned\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022\u005c\u0022pt_fd_max\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022\u005c\u0022ah_pool_max\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022\u005c\u0022deprecated\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022\u005c\u0022wsi_alive\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022,\n+\t\t\t\t(unsigned long)(t - context-\u003etime_up),\n+\t\t\t\tcontext-\u003ecount_cgi_spawned,\n+\t\t\t\tcontext-\u003efd_limit_per_thread,\n+\t\t\t\tcontext-\u003emax_http_header_pool,\n+\t\t\t\tcontext-\u003edeprecated,\n+\t\t\t\tcontext-\u003ecount_wsi_allocated);\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005c\u0022pt\u005c\u0022:[\u005cn \u0022);\n+\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\tpt \u003d \u0026context-\u003ept[n];\n+\t\tif (n)\n+\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u0022);\n+\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\t\u0022\u005cn {\u005cn\u0022\n+\t\t\t\t\u0022 \u005c\u0022fds_count\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022 \u005c\u0022ah_pool_inuse\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\t\u0022 \u005c\u0022ah_wait_list\u005c\u0022:\u005c\u0022%d\u005c\u0022\u005cn\u0022\n+\t\t\t\t\u0022 }\u0022,\n+\t\t\t\tpt-\u003efds_count,\n+\t\t\t\tpt-\u003ehttp.ah_count_in_use,\n+\t\t\t\tpt-\u003ehttp.ah_wait_list_length);\n+\t}\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022]\u0022);\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022, \u005c\u0022vhosts\u005c\u0022:[\u005cn \u0022);\n+\n+\tfirst \u003d 1;\n+\tvh \u003d context-\u003evhost_list;\n+\tlistening \u003d 0;\n+\tcs \u003d context-\u003econn_stats;\n+\tlws_sum_stats(context, \u0026cs);\n+\twhile (vh) {\n+\n+\t\tif (!hide_vhosts) {\n+\t\t\tif (!first)\n+\t\t\t\tif(buf !\u003d end)\n+\t\t\t\t\t*buf++ \u003d ',';\n+\t\t\tbuf +\u003d lws_json_dump_vhost(vh, buf, end - buf);\n+\t\t\tfirst \u003d 0;\n+\t\t}\n+\t\tif (vh-\u003elserv_wsi)\n+\t\t\tlistening++;\n+\t\tvh \u003d vh-\u003evhost_next;\n+\t}\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf,\n+\t\t\t\u0022],\u005cn\u005c\u0022listen_wsi\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022rx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022tx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h1_conn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h1_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022ws_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022rejected\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_alpn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_subs\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n+\t\t\t\u0022 \u005c\u0022h2_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022\u0022,\n+\t\t\tlistening, cs.rx, cs.tx,\n+\t\t\tcs.h1_conn,\n+\t\t\tcs.h1_trans,\n+\t\t\tcs.h2_trans,\n+\t\t\tcs.ws_upg,\n+\t\t\tcs.rejected,\n+\t\t\tcs.h2_alpn,\n+\t\t\tcs.h2_subs,\n+\t\t\tcs.h2_upg);\n+\n+#ifdef LWS_WITH_CGI\n+\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\tpt \u003d \u0026context-\u003ept[n];\n+\t\tpcgi \u003d \u0026pt-\u003ehttp.cgi_list;\n+\n+\t\twhile (*pcgi) {\n+\t\t\tpcgi \u003d \u0026(*pcgi)-\u003ecgi_list;\n+\n+\t\t\tcgi_count++;\n+\t\t}\n+\t}\n+#endif\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u005cn \u005c\u0022cgi_alive\u005c\u0022:\u005c\u0022%d\u005c\u0022\u005cn \u0022,\n+\t\t\tcgi_count);\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022}\u0022);\n+\n+\n+\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022]}\u005cn \u0022);\n+\n+\treturn buf - orig;\n+}\n+\n+#endif\n+\n+#if defined(LWS_WITH_STATS)\n+\n+LWS_VISIBLE LWS_EXTERN uint64_t\n+lws_stats_get(struct lws_context *context, int index)\n+{\n+\tif (index \u003e\u003d LWSSTATS_SIZE)\n+\t\treturn 0;\n+\n+\treturn context-\u003elws_stats[index];\n+}\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_stats_log_dump(struct lws_context *context)\n+{\n+\tstruct lws_vhost *v \u003d context-\u003evhost_list;\n+\tint n, m;\n+\n+\t(void)m;\n+\n+\tif (!context-\u003eupdated)\n+\t\treturn;\n+\n+\tcontext-\u003eupdated \u003d 0;\n+\n+\tlwsl_notice(\u0022\u005cn\u0022);\n+\tlwsl_notice(\u0022LWS internal statistics dump -----\u003e\u005cn\u0022);\n+\tlwsl_notice(\u0022LWSSTATS_C_CONNECTIONS: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_CONNECTIONS));\n+\tlwsl_notice(\u0022LWSSTATS_C_API_CLOSE: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_API_CLOSE));\n+\tlwsl_notice(\u0022LWSSTATS_C_API_READ: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_API_READ));\n+\tlwsl_notice(\u0022LWSSTATS_C_API_LWS_WRITE: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_API_LWS_WRITE));\n+\tlwsl_notice(\u0022LWSSTATS_C_API_WRITE: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_API_WRITE));\n+\tlwsl_notice(\u0022LWSSTATS_C_WRITE_PARTIALS: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_WRITE_PARTIALS));\n+\tlwsl_notice(\u0022LWSSTATS_C_WRITEABLE_CB_REQ: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_WRITEABLE_CB_REQ));\n+\tlwsl_notice(\u0022LWSSTATS_C_WRITEABLE_CB_EFF_REQ: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_WRITEABLE_CB_EFF_REQ));\n+\tlwsl_notice(\u0022LWSSTATS_C_WRITEABLE_CB: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_WRITEABLE_CB));\n+\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN));\n+\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNECTIONS_FAILED: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_FAILED));\n+\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_ACCEPTED));\n+\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNS_HAD_RX: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_SSL_CONNS_HAD_RX));\n+\tlwsl_notice(\u0022LWSSTATS_C_PEER_LIMIT_AH_DENIED: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_PEER_LIMIT_AH_DENIED));\n+\tlwsl_notice(\u0022LWSSTATS_C_PEER_LIMIT_WSI_DENIED: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_PEER_LIMIT_WSI_DENIED));\n+\n+\tlwsl_notice(\u0022LWSSTATS_C_TIMEOUTS: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_TIMEOUTS));\n+\tlwsl_notice(\u0022LWSSTATS_C_SERVICE_ENTRY: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_SERVICE_ENTRY));\n+\tlwsl_notice(\u0022LWSSTATS_B_READ: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context, LWSSTATS_B_READ));\n+\tlwsl_notice(\u0022LWSSTATS_B_WRITE: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context, LWSSTATS_B_WRITE));\n+\tlwsl_notice(\u0022LWSSTATS_B_PARTIALS_ACCEPTED_PARTS: %8llu\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_B_PARTIALS_ACCEPTED_PARTS));\n+\tlwsl_notice(\u0022LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY: %8llums\u005cn\u0022,\n+\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\tLWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) / 1000);\n+\tif (lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED))\n+\t\tlwsl_notice(\u0022 Avg accept delay: %8llums\u005cn\u0022,\n+\t\t\t(unsigned long long)(lws_stats_get(context,\n+\t\t\t\tLWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) /\n+\t\t\t\t\tlws_stats_get(context,\n+\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)) / 1000);\n+\tlwsl_notice(\u0022LWSSTATS_MS_SSL_RX_DELAY: %8llums\u005cn\u0022,\n+\t\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_MS_SSL_RX_DELAY) / 1000);\n+\tif (lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX))\n+\t\tlwsl_notice(\u0022 Avg accept-rx delay: %8llums\u005cn\u0022,\n+\t\t\t(unsigned long long)(lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_MS_SSL_RX_DELAY) /\n+\t\t\tlws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_C_SSL_CONNS_HAD_RX)) / 1000);\n+\n+\tlwsl_notice(\u0022LWSSTATS_MS_WRITABLE_DELAY: %8lluus\u005cn\u0022,\n+\t\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_MS_WRITABLE_DELAY));\n+\tlwsl_notice(\u0022LWSSTATS_MS_WORST_WRITABLE_DELAY: %8lluus\u005cn\u0022,\n+\t\t\t\t(unsigned long long)lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_MS_WORST_WRITABLE_DELAY));\n+\tif (lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB))\n+\t\tlwsl_notice(\u0022 Avg writable delay: %8lluus\u005cn\u0022,\n+\t\t\t(unsigned long long)(lws_stats_get(context,\n+\t\t\t\t\tLWSSTATS_MS_WRITABLE_DELAY) /\n+\t\t\tlws_stats_get(context, LWSSTATS_C_WRITEABLE_CB)));\n+\tlwsl_notice(\u0022Simultaneous SSL restriction: %8d/%d\u005cn\u0022,\n+\t\t\tcontext-\u003esimultaneous_ssl,\n+\t\t\tcontext-\u003esimultaneous_ssl_restriction);\n+\n+\tlwsl_notice(\u0022Live wsi: %8d\u005cn\u0022,\n+\t\t\tcontext-\u003ecount_wsi_allocated);\n+\n+\tcontext-\u003eupdated \u003d 1;\n+\n+\twhile (v) {\n+\t\tif (v-\u003elserv_wsi) {\n+\n+\t\t\tstruct lws_context_per_thread *pt \u003d\n+\t\t\t\t\t\u0026context-\u003ept[(int)v-\u003elserv_wsi-\u003etsi];\n+\t\t\tstruct lws_pollfd *pfd;\n+\n+\t\t\tpfd \u003d \u0026pt-\u003efds[v-\u003elserv_wsi-\u003eposition_in_fds_table];\n+\n+\t\t\tlwsl_notice(\u0022 Listen port %d actual POLLIN: %d\u005cn\u0022,\n+\t\t\t\t v-\u003elisten_port,\n+\t\t\t\t (int)pfd-\u003eevents \u0026 LWS_POLLIN);\n+\t\t}\n+\n+\t\tv \u003d v-\u003evhost_next;\n+\t}\n+\n+\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n+\t\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[n];\n+\t\tstruct lws *wl;\n+\t\tint m \u003d 0;\n+\n+\t\tlwsl_notice(\u0022PT %d\u005cn\u0022, n + 1);\n+\n+\t\tlws_pt_lock(pt, __func__);\n+\n+\t\tlwsl_notice(\u0022 AH in use / max: %d / %d\u005cn\u0022,\n+\t\t\t\tpt-\u003ehttp.ah_count_in_use,\n+\t\t\t\tcontext-\u003emax_http_header_pool);\n+\n+\t\twl \u003d pt-\u003ehttp.ah_wait_list;\n+\t\twhile (wl) {\n+\t\t\tm++;\n+\t\t\twl \u003d wl-\u003eah_wait_list;\n+\t\t}\n+\n+\t\tlwsl_notice(\u0022 AH wait list count / actual: %d / %d\u005cn\u0022,\n+\t\t\t\tpt-\u003ehttp.ah_wait_list_length, m);\n+\n+\t\tlws_pt_unlock(pt);\n+\t}\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tm \u003d 0;\n+\tfor (n \u003d 0; n \u003c (int)context-\u003epl_hash_elements; n++) {\n+\t\tlws_start_foreach_llp(struct lws_peer **, peer,\n+\t\t\t\t context-\u003epl_hash_table[n]) {\n+\t\t\tm++;\n+\t\t} lws_end_foreach_llp(peer, next);\n+\t}\n+\n+\tlwsl_notice(\u0022 Peers: total active %d\u005cn\u0022, m);\n+\tif (m \u003e 10) {\n+\t\tm \u003d 10;\n+\t\tlwsl_notice(\u0022 (showing 10 peers only)\u005cn\u0022);\n+\t}\n+\n+\tif (m) {\n+\t\tfor (n \u003d 0; n \u003c (int)context-\u003epl_hash_elements; n++) {\n+\t\t\tchar buf[72];\n+\n+\t\t\tlws_start_foreach_llp(struct lws_peer **, peer,\n+\t\t\t\t\t context-\u003epl_hash_table[n]) {\n+\t\t\t\tstruct lws_peer *df \u003d *peer;\n+\n+\t\t\t\tif (!lws_plat_inet_ntop(df-\u003eaf, df-\u003eaddr, buf,\n+\t\t\t\t\t\t\tsizeof(buf) - 1))\n+\t\t\t\t\tstrcpy(buf, \u0022unknown\u0022);\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\t\t\t\tlwsl_notice(\u0022 peer %s: count wsi: %d, count ah: %d\u005cn\u0022,\n+\t\t\t\t\t buf, df-\u003ecount_wsi, df-\u003ecount_ah);\n+#else\n+\t\t\t\tlwsl_notice(\u0022 peer %s: count wsi: %d\u005cn\u0022,\n+\t\t\t\t\t buf, df-\u003ecount_wsi);\n+#endif\n+\n+\t\t\t\tif (!--m)\n+\t\t\t\t\tbreak;\n+\t\t\t} lws_end_foreach_llp(peer, next);\n+\t\t}\n+\t}\n+#endif\n+\n+\tlwsl_notice(\u0022\u005cn\u0022);\n+}\n+\n+void\n+lws_stats_atomic_bump(struct lws_context * context,\n+\t\tstruct lws_context_per_thread *pt, int index, uint64_t bump)\n+{\n+\tlws_pt_stats_lock(pt);\n+\tcontext-\u003elws_stats[index] +\u003d bump;\n+\tif (index !\u003d LWSSTATS_C_SERVICE_ENTRY)\n+\t\tcontext-\u003eupdated \u003d 1;\n+\tlws_pt_stats_unlock(pt);\n+}\n+\n+void\n+lws_stats_atomic_max(struct lws_context * context,\n+\t\tstruct lws_context_per_thread *pt, int index, uint64_t val)\n+{\n+\tlws_pt_stats_lock(pt);\n+\tif (val \u003e context-\u003elws_stats[index]) {\n+\t\tcontext-\u003elws_stats[index] \u003d val;\n+\t\tcontext-\u003eupdated \u003d 1;\n+\t}\n+\tlws_pt_stats_unlock(pt);\n+}\n+\n+#endif\n+\ndiff --git a/lib/core/output.c b/lib/core/output.c\nnew file mode 100644\nindex 0000000..e2ff18e\n--- /dev/null\n+++ b/lib/core/output.c\n@@ -0,0 +1,308 @@\n+/*\n+ * libwebsockets - small server side websockets and web server implementation\n+ *\n+ * Copyright (C) 2010-2017 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022core/private.h\u0022\n+\n+/*\n+ * notice this returns number of bytes consumed, or -1\n+ */\n+int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)\n+{\n+\tstruct lws_context *context \u003d lws_get_context(wsi);\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tsize_t real_len \u003d len;\n+\tunsigned int n;\n+\n+\t// lwsl_hexdump_err(buf, len);\n+\n+\t/*\n+\t * Detect if we got called twice without going through the\n+\t * event loop to handle pending. This would be caused by either\n+\t * back-to-back writes in one WRITABLE (illegal) or calling lws_write()\n+\t * from outside the WRITABLE callback (illegal).\n+\t */\n+\tif (wsi-\u003ecould_have_pending) {\n+\t\tlwsl_hexdump_level(LLL_ERR, buf, len);\n+\t\tlwsl_err(\u0022** %p: vh: %s, prot: %s, role %s: \u0022\n+\t\t\t \u0022Illegal back-to-back write of %lu detected...\u005cn\u0022,\n+\t\t\t wsi, wsi-\u003evhost-\u003ename, wsi-\u003eprotocol-\u003ename,\n+\t\t\t wsi-\u003erole_ops-\u003ename,\n+\t\t\t (unsigned long)len);\n+\t\t// assert(0);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_API_WRITE, 1);\n+\n+\tif (!len)\n+\t\treturn 0;\n+\t/* just ignore sends after we cleared the truncation buffer */\n+\tif (lwsi_state(wsi) \u003d\u003d LRS_FLUSHING_BEFORE_CLOSE \u0026\u0026 !wsi-\u003etrunc_len)\n+\t\treturn (int)len;\n+\n+\tif (wsi-\u003etrunc_len \u0026\u0026 (buf \u003c wsi-\u003etrunc_alloc ||\n+\t buf \u003e (wsi-\u003etrunc_alloc + wsi-\u003etrunc_len + wsi-\u003etrunc_offset))) {\n+\t\tlwsl_hexdump_level(LLL_ERR, buf, len);\n+\t\tlwsl_err(\u0022** %p: vh: %s, prot: %s, Sending new %lu, pending truncated ...\u005cn\u0022\n+\t\t\t \u0022 It's illegal to do an lws_write outside of\u005cn\u0022\n+\t\t\t \u0022 the writable callback: fix your code\u005cn\u0022,\n+\t\t\t wsi, wsi-\u003evhost-\u003ename, wsi-\u003eprotocol-\u003ename,\n+\t\t\t (unsigned long)len);\n+\t\tassert(0);\n+\n+\t\treturn -1;\n+\t}\n+\n+\tif (!wsi-\u003ehttp2_substream \u0026\u0026 !lws_socket_is_valid(wsi-\u003edesc.sockfd))\n+\t\tlwsl_warn(\u0022** error invalid sock but expected to send\u005cn\u0022);\n+\n+\t/* limit sending */\n+\tif (wsi-\u003eprotocol-\u003etx_packet_size)\n+\t\tn \u003d (int)wsi-\u003eprotocol-\u003etx_packet_size;\n+\telse {\n+\t\tn \u003d (int)wsi-\u003eprotocol-\u003erx_buffer_size;\n+\t\tif (!n)\n+\t\t\tn \u003d context-\u003ept_serv_buf_size;\n+\t}\n+\tn +\u003d LWS_PRE + 4;\n+\tif (n \u003e len)\n+\t\tn \u003d (int)len;\n+\n+\t/* nope, send it on the socket directly */\n+\tlws_latency_pre(context, wsi);\n+\tn \u003d lws_ssl_capable_write(wsi, buf, n);\n+\tlws_latency(context, wsi, \u0022send lws_issue_raw\u0022, n, n \u003d\u003d len);\n+\n+\t/* something got written, it can have been truncated now */\n+\twsi-\u003ecould_have_pending \u003d 1;\n+\n+\tswitch (n) {\n+\tcase LWS_SSL_CAPABLE_ERROR:\n+\t\t/* we're going to close, let close know sends aren't possible */\n+\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\treturn -1;\n+\tcase LWS_SSL_CAPABLE_MORE_SERVICE:\n+\t\t/*\n+\t\t * nothing got sent, not fatal. Retry the whole thing later,\n+\t\t * ie, implying treat it was a truncated send so it gets\n+\t\t * retried\n+\t\t */\n+\t\tn \u003d 0;\n+\t\tbreak;\n+\t}\n+\n+\t/*\n+\t * we were already handling a truncated send?\n+\t */\n+\tif (wsi-\u003etrunc_len) {\n+\t\tlwsl_info(\u0022%p partial adv %d (vs %ld)\u005cn\u0022, wsi, n, (long)real_len);\n+\t\twsi-\u003etrunc_offset +\u003d n;\n+\t\twsi-\u003etrunc_len -\u003d n;\n+\n+\t\tif (!wsi-\u003etrunc_len) {\n+\t\t\tlwsl_info(\u0022** %p partial send completed\u005cn\u0022, wsi);\n+\t\t\t/* done with it, but don't free it */\n+\t\t\tn \u003d (int)real_len;\n+\t\t\tif (lwsi_state(wsi) \u003d\u003d LRS_FLUSHING_BEFORE_CLOSE) {\n+\t\t\t\tlwsl_info(\u0022** %p signalling to close now\u005cn\u0022, wsi);\n+\t\t\t\treturn -1; /* retry closing now */\n+\t\t\t}\n+\t\t}\n+\t\t/* always callback on writeable */\n+\t\tlws_callback_on_writable(wsi);\n+\n+\t\treturn n;\n+\t}\n+\n+\tif ((unsigned int)n \u003d\u003d real_len)\n+\t\t/* what we just sent went out cleanly */\n+\t\treturn n;\n+\n+\t/*\n+\t * Newly truncated send. Buffer the remainder (it will get\n+\t * first priority next time the socket is writable).\n+\t */\n+\tlwsl_debug(\u0022%p new partial sent %d from %lu total\u005cn\u0022, wsi, n,\n+\t\t (unsigned long)real_len);\n+\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_WRITE_PARTIALS, 1);\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, n);\n+\n+\t/*\n+\t * - if we still have a suitable malloc lying around, use it\n+\t * - or, if too small, reallocate it\n+\t * - or, if no buffer, create it\n+\t */\n+\tif (!wsi-\u003etrunc_alloc || real_len - n \u003e wsi-\u003etrunc_alloc_len) {\n+\t\tlws_free(wsi-\u003etrunc_alloc);\n+\n+\t\twsi-\u003etrunc_alloc_len \u003d (unsigned int)(real_len - n);\n+\t\twsi-\u003etrunc_alloc \u003d lws_malloc(real_len - n,\n+\t\t\t\t\t \u0022truncated send alloc\u0022);\n+\t\tif (!wsi-\u003etrunc_alloc) {\n+\t\t\tlwsl_err(\u0022truncated send: unable to malloc %lu\u005cn\u0022,\n+\t\t\t\t (unsigned long)(real_len - n));\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\twsi-\u003etrunc_offset \u003d 0;\n+\twsi-\u003etrunc_len \u003d (unsigned int)(real_len - n);\n+\tmemcpy(wsi-\u003etrunc_alloc, buf + n, real_len - n);\n+\n+#if !defined(LWS_WITH_ESP32)\n+\tif (lws_wsi_is_udp(wsi)) {\n+\t\t/* stash original destination for fulfilling UDP partials */\n+\t\twsi-\u003eudp-\u003esa_pending \u003d wsi-\u003eudp-\u003esa;\n+\t\twsi-\u003eudp-\u003esalen_pending \u003d wsi-\u003eudp-\u003esalen;\n+\t}\n+#endif\n+\n+\t/* since something buffered, force it to get another chance to send */\n+\tlws_callback_on_writable(wsi);\n+\n+\treturn (int)real_len;\n+}\n+\n+LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,\n+\t\t\t enum lws_write_protocol wp)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\n+\tif (wsi-\u003eparent_carries_io) {\n+\t\tstruct lws_write_passthru pas;\n+\n+\t\tpas.buf \u003d buf;\n+\t\tpas.len \u003d len;\n+\t\tpas.wp \u003d wp;\n+\t\tpas.wsi \u003d wsi;\n+\n+\t\tif (wsi-\u003eparent-\u003eprotocol-\u003ecallback(wsi-\u003eparent,\n+\t\t\t\tLWS_CALLBACK_CHILD_WRITE_VIA_PARENT,\n+\t\t\t\twsi-\u003eparent-\u003euser_space,\n+\t\t\t\t(void *)\u0026pas, 0))\n+\t\t\treturn 1;\n+\n+\t\treturn (int)len;\n+\t}\n+\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_API_LWS_WRITE, 1);\n+\n+\tif ((int)len \u003c 0) {\n+\t\tlwsl_err(\u0022%s: suspicious len int %d, ulong %lu\u005cn\u0022, __func__,\n+\t\t\t\t(int)len, (unsigned long)len);\n+\t\treturn -1;\n+\t}\n+\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_B_WRITE, len);\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+\twsi-\u003ehttp.access_log.sent +\u003d len;\n+#endif\n+\tif (wsi-\u003evhost)\n+\t\twsi-\u003evhost-\u003econn_stats.tx +\u003d len;\n+\n+\tassert(wsi-\u003erole_ops);\n+\tif (!wsi-\u003erole_ops-\u003ewrite_role_protocol)\n+\t\treturn lws_issue_raw(wsi, buf, len);\n+\n+\treturn wsi-\u003erole_ops-\u003ewrite_role_protocol(wsi, buf, len, \u0026wp);\n+}\n+\n+LWS_VISIBLE int\n+lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)\n+{\n+\tstruct lws_context *context \u003d wsi-\u003econtext;\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n+\tint n \u003d 0;\n+\n+\tlws_stats_atomic_bump(context, pt, LWSSTATS_C_API_READ, 1);\n+\n+\tif (lws_wsi_is_udp(wsi)) {\n+#if !defined(LWS_WITH_ESP32)\n+\t\twsi-\u003eudp-\u003esalen \u003d sizeof(wsi-\u003eudp-\u003esa);\n+\t\tn \u003d recvfrom(wsi-\u003edesc.sockfd, (char *)buf, len, 0,\n+\t\t\t \u0026wsi-\u003eudp-\u003esa, \u0026wsi-\u003eudp-\u003esalen);\n+#endif\n+\t} else\n+\t\tn \u003d recv(wsi-\u003edesc.sockfd, (char *)buf, len, 0);\n+\n+\tif (n \u003e\u003d 0) {\n+\t\tif (wsi-\u003evhost)\n+\t\t\twsi-\u003evhost-\u003econn_stats.rx +\u003d n;\n+\t\tlws_stats_atomic_bump(context, pt, LWSSTATS_B_READ, n);\n+\n+\t\treturn n;\n+\t}\n+\n+\tif (LWS_ERRNO \u003d\u003d LWS_EAGAIN ||\n+\t LWS_ERRNO \u003d\u003d LWS_EWOULDBLOCK ||\n+\t LWS_ERRNO \u003d\u003d LWS_EINTR)\n+\t\treturn LWS_SSL_CAPABLE_MORE_SERVICE;\n+\n+\tlwsl_notice(\u0022error on reading from skt : %d\u005cn\u0022, LWS_ERRNO);\n+\treturn LWS_SSL_CAPABLE_ERROR;\n+}\n+\n+LWS_VISIBLE int\n+lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)\n+{\n+\tint n \u003d 0;\n+\n+\tif (lws_wsi_is_udp(wsi)) {\n+#if !defined(LWS_WITH_ESP32)\n+\t\tif (wsi-\u003etrunc_len)\n+\t\t\tn \u003d sendto(wsi-\u003edesc.sockfd, buf, len, 0, \u0026wsi-\u003eudp-\u003esa_pending, wsi-\u003eudp-\u003esalen_pending);\n+\t\telse\n+\t\t\tn \u003d sendto(wsi-\u003edesc.sockfd, buf, len, 0, \u0026wsi-\u003eudp-\u003esa, wsi-\u003eudp-\u003esalen);\n+#endif\n+\t} else\n+\t\tn \u003d send(wsi-\u003edesc.sockfd, (char *)buf, len, MSG_NOSIGNAL);\n+//\tlwsl_info(\u0022%s: sent len %d result %d\u0022, __func__, len, n);\n+\tif (n \u003e\u003d 0)\n+\t\treturn n;\n+\n+\tif (LWS_ERRNO \u003d\u003d LWS_EAGAIN ||\n+\t LWS_ERRNO \u003d\u003d LWS_EWOULDBLOCK ||\n+\t LWS_ERRNO \u003d\u003d LWS_EINTR) {\n+\t\tif (LWS_ERRNO \u003d\u003d LWS_EWOULDBLOCK) {\n+\t\t\tlws_set_blocking_send(wsi);\n+\t\t}\n+\n+\t\treturn LWS_SSL_CAPABLE_MORE_SERVICE;\n+\t}\n+\n+\tlwsl_debug(\u0022ERROR writing len %d to skt fd %d err %d / errno %d\u005cn\u0022,\n+\t\t\tlen, wsi-\u003edesc.sockfd, n, LWS_ERRNO);\n+\n+\treturn LWS_SSL_CAPABLE_ERROR;\n+}\n+\n+LWS_VISIBLE int\n+lws_ssl_pending_no_ssl(struct lws *wsi)\n+{\n+\t(void)wsi;\n+#if defined(LWS_WITH_ESP32)\n+\treturn 100;\n+#else\n+\treturn 0;\n+#endif\n+}\ndiff --git a/lib/core/pollfd.c b/lib/core/pollfd.c\nnew file mode 100644\nindex 0000000..fbc6132\n--- /dev/null\n+++ b/lib/core/pollfd.c\n@@ -0,0 +1,606 @@\n+/*\n+ * libwebsockets - small server side websockets and web server implementation\n+ *\n+ * Copyright (C) 2010-2017 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022core/private.h\u0022\n+\n+int\n+_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)\n+{\n+#if !defined(LWS_WITH_LIBUV) \u0026\u0026 !defined(LWS_WITH_LIBEV) \u0026\u0026 !defined(LWS_WITH_LIBEVENT)\n+\tvolatile struct lws_context_per_thread *vpt;\n+#endif\n+\tstruct lws_context_per_thread *pt;\n+\tstruct lws_context *context;\n+\tint ret \u003d 0, pa_events \u003d 1;\n+\tstruct lws_pollfd *pfd;\n+\tint sampled_tid, tid;\n+\n+\tif (!wsi || wsi-\u003eposition_in_fds_table \u003c 0)\n+\t\treturn 0;\n+\n+\tif (((volatile struct lws *)wsi)-\u003ehandling_pollout \u0026\u0026\n+\t !_and \u0026\u0026 _or \u003d\u003d LWS_POLLOUT) {\n+\t\t/*\n+\t\t * Happening alongside service thread handling POLLOUT.\n+\t\t * The danger is when he is finished, he will disable POLLOUT,\n+\t\t * countermanding what we changed here.\n+\t\t *\n+\t\t * Instead of changing the fds, inform the service thread\n+\t\t * what happened, and ask it to leave POLLOUT active on exit\n+\t\t */\n+\t\t((volatile struct lws *)wsi)-\u003eleave_pollout_active \u003d 1;\n+\t\t/*\n+\t\t * by definition service thread is not in poll wait, so no need\n+\t\t * to cancel service\n+\t\t */\n+\n+\t\tlwsl_debug(\u0022%s: using leave_pollout_active\u005cn\u0022, __func__);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tcontext \u003d wsi-\u003econtext;\n+\tpt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n+\n+\tassert(wsi-\u003eposition_in_fds_table \u003e\u003d 0 \u0026\u0026\n+\t wsi-\u003eposition_in_fds_table \u003c (int)pt-\u003efds_count);\n+\n+#if !defined(LWS_WITH_LIBUV) \u0026\u0026 \u005c\n+ !defined(LWS_WITH_LIBEV) \u0026\u0026 \u005c\n+ !defined(LWS_WITH_LIBEVENT)\n+\t/*\n+\t * This only applies when we use the default poll() event loop.\n+\t *\n+\t * BSD can revert pa-\u003eevents at any time, when the kernel decides to\n+\t * exit from poll(). We can't protect against it using locking.\n+\t *\n+\t * Therefore we must check first if the service thread is in poll()\n+\t * wait; if so, we know we must be being called from a foreign thread,\n+\t * and we must keep a strictly ordered list of changes we made instead\n+\t * of trying to apply them, since when poll() exits, which may happen\n+\t * at any time it would revert our changes.\n+\t *\n+\t * The plat code will apply them when it leaves the poll() wait\n+\t * before doing anything else.\n+\t */\n+\n+\tvpt \u003d (volatile struct lws_context_per_thread *)pt;\n+\n+\tvpt-\u003eforeign_spinlock \u003d 1;\n+\tlws_memory_barrier();\n+\n+\tif (vpt-\u003einside_poll) {\n+\t\tstruct lws_foreign_thread_pollfd *ftp, **ftp1;\n+\t\t/*\n+\t\t * We are certainly a foreign thread trying to change events\n+\t\t * while the service thread is in the poll() wait.\n+\t\t *\n+\t\t * Create a list of changes to be applied after poll() exit,\n+\t\t * instead of trying to apply them now.\n+\t\t */\n+\t\tftp \u003d lws_malloc(sizeof(*ftp), \u0022ftp\u0022);\n+\t\tif (!ftp) {\n+\t\t\tvpt-\u003eforeign_spinlock \u003d 0;\n+\t\t\tlws_memory_barrier();\n+\t\t\tret \u003d -1;\n+\t\t\tgoto bail;\n+\t\t}\n+\n+\t\tftp-\u003e_and \u003d _and;\n+\t\tftp-\u003e_or \u003d _or;\n+\t\tftp-\u003efd_index \u003d wsi-\u003eposition_in_fds_table;\n+\t\tftp-\u003enext \u003d NULL;\n+\n+\t\t/* place at END of list to maintain order */\n+\t\tftp1 \u003d (struct lws_foreign_thread_pollfd **)\n+\t\t\t\t\t\t\u0026vpt-\u003eforeign_pfd_list;\n+\t\twhile (*ftp1)\n+\t\t\tftp1 \u003d \u0026((*ftp1)-\u003enext);\n+\n+\t\t*ftp1 \u003d ftp;\n+\t\tvpt-\u003eforeign_spinlock \u003d 0;\n+\t\tlws_memory_barrier();\n+\t\tlws_cancel_service_pt(wsi);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tvpt-\u003eforeign_spinlock \u003d 0;\n+\tlws_memory_barrier();\n+#endif\n+\n+\tpfd \u003d \u0026pt-\u003efds[wsi-\u003eposition_in_fds_table];\n+\tpa-\u003efd \u003d wsi-\u003edesc.sockfd;\n+\tlwsl_debug(\u0022%s: wsi %p: fd %d events %d -\u003e %d\u005cn\u0022, __func__, wsi, pa-\u003efd, pfd-\u003eevents, (pfd-\u003eevents \u0026 ~_and) | _or);\n+\tpa-\u003eprev_events \u003d pfd-\u003eevents;\n+\tpa-\u003eevents \u003d pfd-\u003eevents \u003d (pfd-\u003eevents \u0026 ~_and) | _or;\n+\n+\tif (wsi-\u003ehttp2_substream)\n+\t\treturn 0;\n+\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi,\n+\t\t\t \t \t LWS_CALLBACK_CHANGE_MODE_POLL_FD,\n+\t\t\t\t\t wsi-\u003euser_space, (void *)pa, 0)) {\n+\t\tret \u003d -1;\n+\t\tgoto bail;\n+\t}\n+\n+\tif (context-\u003eevent_loop_ops-\u003eio) {\n+\t\tif (_and \u0026 LWS_POLLIN)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n+\t\t\t\t\tLWS_EV_STOP | LWS_EV_READ);\n+\n+\t\tif (_or \u0026 LWS_POLLIN)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n+\t\t\t\t\tLWS_EV_START | LWS_EV_READ);\n+\n+\t\tif (_and \u0026 LWS_POLLOUT)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n+\t\t\t\t\tLWS_EV_STOP | LWS_EV_WRITE);\n+\n+\t\tif (_or \u0026 LWS_POLLOUT)\n+\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n+\t\t\t\t\tLWS_EV_START | LWS_EV_WRITE);\n+\t}\n+\n+\t/*\n+\t * if we changed something in this pollfd...\n+\t * ... and we're running in a different thread context\n+\t * than the service thread...\n+\t * ... and the service thread is waiting ...\n+\t * then cancel it to force a restart with our changed events\n+\t */\n+\tpa_events \u003d pa-\u003eprev_events !\u003d pa-\u003eevents;\n+\n+\tif (pa_events) {\n+\t\tif (lws_plat_change_pollfd(context, wsi, pfd)) {\n+\t\t\tlwsl_info(\u0022%s failed\u005cn\u0022, __func__);\n+\t\t\tret \u003d -1;\n+\t\t\tgoto bail;\n+\t\t}\n+\t\tsampled_tid \u003d context-\u003eservice_tid;\n+\t\tif (sampled_tid \u0026\u0026 wsi-\u003evhost) {\n+\t\t\ttid \u003d wsi-\u003evhost-\u003eprotocols[0].callback(wsi,\n+\t\t\t\t LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);\n+\t\t\tif (tid \u003d\u003d -1) {\n+\t\t\t\tret \u003d -1;\n+\t\t\t\tgoto bail;\n+\t\t\t}\n+\t\t\tif (tid !\u003d sampled_tid)\n+\t\t\t\tlws_cancel_service_pt(wsi);\n+\t\t}\n+\t}\n+\n+bail:\n+\treturn ret;\n+}\n+\n+#ifndef LWS_NO_SERVER\n+/*\n+ * Enable or disable listen sockets on this pt globally...\n+ * it's modulated according to the pt having space for a new accept.\n+ */\n+static void\n+lws_accept_modulation(struct lws_context *context,\n+\t\t struct lws_context_per_thread *pt, int allow)\n+{\n+\tstruct lws_vhost *vh \u003d context-\u003evhost_list;\n+\tstruct lws_pollargs pa1;\n+\n+\twhile (vh) {\n+\t\tif (vh-\u003elserv_wsi) {\n+\t\t\tif (allow)\n+\t\t\t\t_lws_change_pollfd(vh-\u003elserv_wsi,\n+\t\t\t\t\t 0, LWS_POLLIN, \u0026pa1);\n+\t\t\telse\n+\t\t\t\t_lws_change_pollfd(vh-\u003elserv_wsi,\n+\t\t\t\t\t LWS_POLLIN, 0, \u0026pa1);\n+\t\t}\n+\t\tvh \u003d vh-\u003evhost_next;\n+\t}\n+}\n+#endif\n+\n+int\n+__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)\n+{\n+\tstruct lws_pollargs pa \u003d { wsi-\u003edesc.sockfd, LWS_POLLIN, 0 };\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n+\tint ret \u003d 0;\n+\n+\n+\tlwsl_debug(\u0022%s: %p: tsi\u003d%d, sock\u003d%d, pos-in-fds\u003d%d\u005cn\u0022,\n+\t\t __func__, wsi, wsi-\u003etsi, wsi-\u003edesc.sockfd, pt-\u003efds_count);\n+\n+\tif ((unsigned int)pt-\u003efds_count \u003e\u003d context-\u003efd_limit_per_thread) {\n+\t\tlwsl_err(\u0022Too many fds (%d vs %d)\u005cn\u0022, context-\u003emax_fds,\n+\t\t\t\tcontext-\u003efd_limit_per_thread\t);\n+\t\treturn 1;\n+\t}\n+\n+#if !defined(_WIN32)\n+\tif (wsi-\u003edesc.sockfd - lws_plat_socket_offset() \u003e\u003d context-\u003emax_fds) {\n+\t\tlwsl_err(\u0022Socket fd %d is too high (%d) offset %d\u005cn\u0022,\n+\t\t\t wsi-\u003edesc.sockfd, context-\u003emax_fds, lws_plat_socket_offset());\n+\t\treturn 1;\n+\t}\n+#endif\n+\n+\tassert(wsi);\n+\tassert(wsi-\u003eevent_pipe || wsi-\u003evhost);\n+\tassert(lws_socket_is_valid(wsi-\u003edesc.sockfd));\n+\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,\n+\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 1))\n+\t\treturn -1;\n+\n+\tpt-\u003ecount_conns++;\n+\tinsert_wsi(context, wsi);\n+\twsi-\u003eposition_in_fds_table \u003d pt-\u003efds_count;\n+\n+\tpt-\u003efds[wsi-\u003eposition_in_fds_table].fd \u003d wsi-\u003edesc.sockfd;\n+\tpt-\u003efds[wsi-\u003eposition_in_fds_table].events \u003d LWS_POLLIN;\n+\tpa.events \u003d pt-\u003efds[pt-\u003efds_count].events;\n+\n+\tlws_plat_insert_socket_into_fds(context, wsi);\n+\n+\t/* external POLL support via protocol 0 */\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD,\n+\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n+\t\tret \u003d -1;\n+#ifndef LWS_NO_SERVER\n+\t/* if no more room, defeat accepts on this thread */\n+\tif ((unsigned int)pt-\u003efds_count \u003d\u003d context-\u003efd_limit_per_thread - 1)\n+\t\tlws_accept_modulation(context, pt, 0);\n+#endif\n+\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,\n+\t\t\t\t\t wsi-\u003euser_space, (void *)\u0026pa, 1))\n+\t\tret \u003d -1;\n+\n+\treturn ret;\n+}\n+\n+int\n+__remove_wsi_socket_from_fds(struct lws *wsi)\n+{\n+\tstruct lws_context *context \u003d wsi-\u003econtext;\n+\tstruct lws_pollargs pa \u003d { wsi-\u003edesc.sockfd, 0, 0 };\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n+\tstruct lws *end_wsi;\n+\tint v;\n+\tint m, ret \u003d 0;\n+\n+\tif (wsi-\u003eparent_carries_io) {\n+\t\tlws_same_vh_protocol_remove(wsi);\n+\t\treturn 0;\n+\t}\n+\n+#if !defined(_WIN32)\n+\tif (wsi-\u003edesc.sockfd - lws_plat_socket_offset() \u003e context-\u003emax_fds) {\n+\t\tlwsl_err(\u0022fd %d too high (%d)\u005cn\u0022, wsi-\u003edesc.sockfd,\n+\t\t\t context-\u003emax_fds);\n+\t\treturn 1;\n+\t}\n+#endif\n+\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,\n+\t\t\t\t\t wsi-\u003euser_space, (void *)\u0026pa, 1))\n+\t\treturn -1;\n+\n+\tlws_same_vh_protocol_remove(wsi);\n+\n+\t/* the guy who is to be deleted's slot index in pt-\u003efds */\n+\tm \u003d wsi-\u003eposition_in_fds_table;\n+\t\n+\tif (context-\u003eevent_loop_ops-\u003eio)\n+\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n+\t\t\t\t LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE |\n+\t\t\t\t LWS_EV_PREPARE_DELETION);\n+\n+\tlwsl_debug(\u0022%s: wsi\u003d%p, sock\u003d%d, fds pos\u003d%d, end guy pos\u003d%d, endfd\u003d%d\u005cn\u0022,\n+\t\t __func__, wsi, wsi-\u003edesc.sockfd, wsi-\u003eposition_in_fds_table,\n+\t\t pt-\u003efds_count, pt-\u003efds[pt-\u003efds_count].fd);\n+\n+\tif (m !\u003d LWS_SOCK_INVALID) {\n+\n+\t\t/* have the last guy take up the now vacant slot */\n+\t\tpt-\u003efds[m] \u003d pt-\u003efds[pt-\u003efds_count - 1];\n+\t\t/* this decrements pt-\u003efds_count */\n+\t\tlws_plat_delete_socket_from_fds(context, wsi, m);\n+\t\tv \u003d (int) pt-\u003efds[m].fd;\n+\t\t/* end guy's \u0022position in fds table\u0022 is now the deletion guy's old one */\n+\t\tend_wsi \u003d wsi_from_fd(context, v);\n+\t\tif (!end_wsi) {\n+\t\t\tlwsl_err(\u0022no wsi found for fd %d at pos %d, pt-\u003efds_count\u003d%d\u005cn\u0022,\n+\t\t\t\t(int)pt-\u003efds[m].fd, m, pt-\u003efds_count);\n+\t\t\tassert(0);\n+\t\t} else\n+\t\t\tend_wsi-\u003eposition_in_fds_table \u003d m;\n+\n+\t\t/* deletion guy's lws_lookup entry needs nuking */\n+\t\tdelete_from_fd(context, wsi-\u003edesc.sockfd);\n+\t\t/* removed wsi has no position any more */\n+\t\twsi-\u003eposition_in_fds_table \u003d -1;\n+\t}\n+\n+\t/* remove also from external POLL support via protocol 0 */\n+\tif (lws_socket_is_valid(wsi-\u003edesc.sockfd) \u0026\u0026 wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_DEL_POLL_FD,\n+\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n+\t\tret \u003d -1;\n+\n+#ifndef LWS_NO_SERVER\n+\tif (!context-\u003ebeing_destroyed \u0026\u0026\n+\t /* if this made some room, accept connects on this thread */\n+\t (unsigned int)pt-\u003efds_count \u003c context-\u003efd_limit_per_thread - 1)\n+\t\tlws_accept_modulation(context, pt, 1);\n+#endif\n+\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,\n+\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 1))\n+\t\tret \u003d -1;\n+\n+\treturn ret;\n+}\n+\n+int\n+__lws_change_pollfd(struct lws *wsi, int _and, int _or)\n+{\n+\tstruct lws_context *context;\n+\tstruct lws_pollargs pa;\n+\tint ret \u003d 0;\n+\n+\tif (!wsi || (!wsi-\u003eprotocol \u0026\u0026 !wsi-\u003eevent_pipe) ||\n+\t wsi-\u003eposition_in_fds_table \u003c 0)\n+\t\treturn 0;\n+\n+\tcontext \u003d lws_get_context(wsi);\n+\tif (!context)\n+\t\treturn 1;\n+\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,\n+\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n+\t\treturn -1;\n+\n+\tret \u003d _lws_change_pollfd(wsi, _and, _or, \u0026pa);\n+\tif (wsi-\u003evhost \u0026\u0026\n+\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,\n+\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n+\t\tret \u003d -1;\n+\n+\treturn ret;\n+}\n+\n+int\n+lws_change_pollfd(struct lws *wsi, int _and, int _or)\n+{\n+\tstruct lws_context_per_thread *pt;\n+\tint ret \u003d 0;\n+\n+\tpt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\n+\tlws_pt_lock(pt, __func__);\n+\tret \u003d __lws_change_pollfd(wsi, _and, _or);\n+\tlws_pt_unlock(pt);\n+\n+\treturn ret;\n+}\n+\n+LWS_VISIBLE int\n+lws_callback_on_writable(struct lws *wsi)\n+{\n+\tstruct lws_context_per_thread *pt;\n+\tint n;\n+\n+\tif (lwsi_state(wsi) \u003d\u003d LRS_SHUTDOWN)\n+\t\treturn 0;\n+\n+\tif (wsi-\u003esocket_is_permanently_unusable)\n+\t\treturn 0;\n+\n+\tpt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\n+\tif (wsi-\u003eparent_carries_io) {\n+#if defined(LWS_WITH_STATS)\n+\t\tif (!wsi-\u003eactive_writable_req_us) {\n+\t\t\twsi-\u003eactive_writable_req_us \u003d time_in_microseconds();\n+\t\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt,\n+\t\t\t\t\t LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1);\n+\t\t}\n+#endif\n+\t\tn \u003d lws_callback_on_writable(wsi-\u003eparent);\n+\t\tif (n \u003c 0)\n+\t\t\treturn n;\n+\n+\t\twsi-\u003eparent_pending_cb_on_writable \u003d 1;\n+\t\treturn 1;\n+\t}\n+\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_WRITEABLE_CB_REQ, 1);\n+#if defined(LWS_WITH_STATS)\n+\tif (!wsi-\u003eactive_writable_req_us) {\n+\t\twsi-\u003eactive_writable_req_us \u003d time_in_microseconds();\n+\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt,\n+\t\t\t\t LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1);\n+\t}\n+#endif\n+\n+\n+\tif (wsi-\u003erole_ops-\u003ecallback_on_writable) {\n+\t\tif (wsi-\u003erole_ops-\u003ecallback_on_writable(wsi))\n+\t\t\treturn 1;\n+\t\twsi \u003d lws_get_network_wsi(wsi);\n+\t}\n+\n+\tif (wsi-\u003eposition_in_fds_table \u003c 0) {\n+\t\tlwsl_debug(\u0022%s: failed to find socket %d\u005cn\u0022, __func__,\n+\t\t\t wsi-\u003edesc.sockfd);\n+\t\treturn -1;\n+\t}\n+\n+\tif (__lws_change_pollfd(wsi, 0, LWS_POLLOUT))\n+\t\treturn -1;\n+\n+\treturn 1;\n+}\n+\n+\n+/*\n+ * stitch protocol choice into the vh protocol linked list\n+ * We always insert ourselves at the start of the list\n+ *\n+ * X \u003c-\u003e B\n+ * X \u003c-\u003e pAn \u003c-\u003e pB\n+ *\n+ * Illegal to attach more than once without detach inbetween\n+ */\n+void\n+lws_same_vh_protocol_insert(struct lws *wsi, int n)\n+{\n+\tif (wsi-\u003esame_vh_protocol_prev || wsi-\u003esame_vh_protocol_next) {\n+\t\tlws_same_vh_protocol_remove(wsi);\n+\t\tlwsl_notice(\u0022Attempted to attach wsi twice to same vh prot\u005cn\u0022);\n+\t}\n+\n+\tlws_vhost_lock(wsi-\u003evhost);\n+\n+\twsi-\u003esame_vh_protocol_prev \u003d \u0026wsi-\u003evhost-\u003esame_vh_protocol_list[n];\n+\t/* old first guy is our next */\n+\twsi-\u003esame_vh_protocol_next \u003d wsi-\u003evhost-\u003esame_vh_protocol_list[n];\n+\t/* we become the new first guy */\n+\twsi-\u003evhost-\u003esame_vh_protocol_list[n] \u003d wsi;\n+\n+\tif (wsi-\u003esame_vh_protocol_next)\n+\t\t/* old first guy points back to us now */\n+\t\twsi-\u003esame_vh_protocol_next-\u003esame_vh_protocol_prev \u003d\n+\t\t\t\t\u0026wsi-\u003esame_vh_protocol_next;\n+\n+\twsi-\u003eon_same_vh_list \u003d 1;\n+\n+\tlws_vhost_unlock(wsi-\u003evhost);\n+}\n+\n+void\n+lws_same_vh_protocol_remove(struct lws *wsi)\n+{\n+\t/*\n+\t * detach ourselves from vh protocol list if we're on one\n+\t * A -\u003e B -\u003e C\n+\t * A -\u003e C , or, B -\u003e C, or A -\u003e B\n+\t *\n+\t * OK to call on already-detached wsi\n+\t */\n+\tlwsl_info(\u0022%s: removing same prot wsi %p\u005cn\u0022, __func__, wsi);\n+\n+\tif (!wsi-\u003evhost || !wsi-\u003eon_same_vh_list)\n+\t\treturn;\n+\n+\tlws_vhost_lock(wsi-\u003evhost);\n+\n+\tif (wsi-\u003esame_vh_protocol_prev) {\n+\t\tassert (*(wsi-\u003esame_vh_protocol_prev) \u003d\u003d wsi);\n+\t\tlwsl_info(\u0022have prev %p, setting him to our next %p\u005cn\u0022,\n+\t\t\t wsi-\u003esame_vh_protocol_prev,\n+\t\t\t wsi-\u003esame_vh_protocol_next);\n+\n+\t\t/* guy who pointed to us should point to our next */\n+\t\t*(wsi-\u003esame_vh_protocol_prev) \u003d wsi-\u003esame_vh_protocol_next;\n+\t}\n+\n+\t/* our next should point back to our prev */\n+\tif (wsi-\u003esame_vh_protocol_next)\n+\t\twsi-\u003esame_vh_protocol_next-\u003esame_vh_protocol_prev \u003d\n+\t\t\t\twsi-\u003esame_vh_protocol_prev;\n+\n+\twsi-\u003esame_vh_protocol_prev \u003d NULL;\n+\twsi-\u003esame_vh_protocol_next \u003d NULL;\n+\twsi-\u003eon_same_vh_list \u003d 0;\n+\n+\tlws_vhost_unlock(wsi-\u003evhost);\n+}\n+\n+\n+LWS_VISIBLE int\n+lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,\n+\t\t\t\t const struct lws_protocols *protocol)\n+{\n+\tstruct lws *wsi;\n+\n+\tif (protocol \u003c vhost-\u003eprotocols ||\n+\t protocol \u003e\u003d (vhost-\u003eprotocols + vhost-\u003ecount_protocols)) {\n+\t\tlwsl_err(\u0022%s: protocol %p is not from vhost %p (%p - %p)\u005cn\u0022,\n+\t\t\t__func__, protocol, vhost-\u003eprotocols, vhost,\n+\t\t\t(vhost-\u003eprotocols + vhost-\u003ecount_protocols));\n+\n+\t\treturn -1;\n+\t}\n+\n+\twsi \u003d vhost-\u003esame_vh_protocol_list[protocol - vhost-\u003eprotocols];\n+\twhile (wsi) {\n+\t\tassert(wsi-\u003eprotocol \u003d\u003d protocol);\n+\t\tassert(*wsi-\u003esame_vh_protocol_prev \u003d\u003d wsi);\n+\t\tif (wsi-\u003esame_vh_protocol_next)\n+\t\t\tassert(wsi-\u003esame_vh_protocol_next-\u003e\n+\t\t\t\t\tsame_vh_protocol_prev \u003d\u003d\n+\t\t\t\t\t\u0026wsi-\u003esame_vh_protocol_next);\n+\n+\t\tlws_callback_on_writable(wsi);\n+\t\twsi \u003d wsi-\u003esame_vh_protocol_next;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE int\n+lws_callback_on_writable_all_protocol(const struct lws_context *context,\n+\t\t\t\t const struct lws_protocols *protocol)\n+{\n+\tstruct lws_vhost *vhost;\n+\tint n;\n+\n+\tif (!context)\n+\t\treturn 0;\n+\n+\tvhost \u003d context-\u003evhost_list;\n+\n+\twhile (vhost) {\n+\t\tfor (n \u003d 0; n \u003c vhost-\u003ecount_protocols; n++)\n+\t\t\tif (protocol-\u003ecallback \u003d\u003d\n+\t\t\t vhost-\u003eprotocols[n].callback \u0026\u0026\n+\t\t\t !strcmp(protocol-\u003ename, vhost-\u003eprotocols[n].name))\n+\t\t\t\tbreak;\n+\t\tif (n !\u003d vhost-\u003ecount_protocols)\n+\t\t\tlws_callback_on_writable_all_protocol_vhost(\n+\t\t\t\tvhost, \u0026vhost-\u003eprotocols[n]);\n+\n+\t\tvhost \u003d vhost-\u003evhost_next;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/core/private.h b/lib/core/private.h\nnew file mode 100644\nindex 0000000..cb3ab4c\n--- /dev/null\n+++ b/lib/core/private.h\n@@ -0,0 +1,1748 @@\n+/*\n+ * libwebsockets - small server side websockets and web server implementation\n+ *\n+ * Copyright (C) 2010 - 2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022lws_config.h\u0022\n+#include \u0022lws_config_private.h\u0022\n+\n+#if defined(LWS_WITH_CGI) \u0026\u0026 defined(LWS_HAVE_VFORK)\n+ #define _GNU_SOURCE\n+#endif\n+\n+#if defined(__COVERITY__) \u0026\u0026 !defined(LWS_COVERITY_WORKAROUND)\n+ #define LWS_COVERITY_WORKAROUND\n+ typedef float _Float32;\n+ typedef float _Float64;\n+ typedef float _Float128;\n+ typedef float _Float32x;\n+ typedef float _Float64x;\n+ typedef float _Float128x;\n+#endif\n+\n+#ifdef LWS_HAVE_SYS_TYPES_H\n+ #include \u003csys/types.h\u003e\n+#endif\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstdlib.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003ctime.h\u003e\n+#include \u003cctype.h\u003e\n+#include \u003climits.h\u003e\n+#include \u003cstdarg.h\u003e\n+#include \u003cinttypes.h\u003e\n+\n+#if defined(LWS_WITH_ESP32)\n+ #define MSG_NOSIGNAL 0\n+ #define SOMAXCONN 3\n+#endif\n+\n+#define STORE_IN_ROM\n+#include \u003cassert.h\u003e\n+#if LWS_MAX_SMP \u003e 1\n+ #include \u003cpthread.h\u003e\n+#endif\n+\n+#ifdef LWS_HAVE_SYS_STAT_H\n+ #include \u003csys/stat.h\u003e\n+#endif\n+\n+#if defined(WIN32) || defined(_WIN32)\n+\n+ #ifndef WIN32_LEAN_AND_MEAN\n+ #define WIN32_LEAN_AND_MEAN\n+ #endif\n+\n+ #if (WINVER \u003c 0x0501)\n+ #undef WINVER\n+ #undef _WIN32_WINNT\n+ #define WINVER 0x0501\n+ #define _WIN32_WINNT WINVER\n+ #endif\n+\n+ #define LWS_NO_DAEMONIZE\n+ #define LWS_ERRNO WSAGetLastError()\n+ #define LWS_EAGAIN WSAEWOULDBLOCK\n+ #define LWS_EALREADY WSAEALREADY\n+ #define LWS_EINPROGRESS WSAEINPROGRESS\n+ #define LWS_EINTR WSAEINTR\n+ #define LWS_EISCONN WSAEISCONN\n+ #define LWS_EWOULDBLOCK WSAEWOULDBLOCK\n+ #define MSG_NOSIGNAL 0\n+ #define SHUT_RDWR SD_BOTH\n+ #define SOL_TCP IPPROTO_TCP\n+ #define SHUT_WR SD_SEND\n+\n+ #define compatible_close(fd) closesocket(fd)\n+ #define lws_set_blocking_send(wsi) wsi-\u003esock_send_blocking \u003d 1\n+ #define lws_socket_is_valid(x) (!!x)\n+ #define LWS_SOCK_INVALID 0\n+ #include \u003cwinsock2.h\u003e\n+ #include \u003cws2tcpip.h\u003e\n+ #include \u003cwindows.h\u003e\n+ #include \u003ctchar.h\u003e\n+ #ifdef LWS_HAVE_IN6ADDR_H\n+ #include \u003cin6addr.h\u003e\n+ #endif\n+ #include \u003cmstcpip.h\u003e\n+ #include \u003cio.h\u003e\n+\n+ #if !defined(LWS_HAVE_ATOLL)\n+ #if defined(LWS_HAVE__ATOI64)\n+ #define atoll _atoi64\n+ #else\n+ #warning No atoll or _atoi64 available, using atoi\n+ #define atoll atoi\n+ #endif\n+ #endif\n+\n+ #ifndef __func__\n+ #define __func__ __FUNCTION__\n+ #endif\n+\n+ #ifdef LWS_HAVE__VSNPRINTF\n+ #define vsnprintf _vsnprintf\n+ #endif\n+\n+ /* we don't have an implementation for this on windows... */\n+ int kill(int pid, int sig);\n+ int fork(void);\n+ #ifndef SIGINT\n+ #define SIGINT 2\n+ #endif\n+\n+#else /* not windows --\u003e */\n+\n+ #include \u003cfcntl.h\u003e\n+ #include \u003cstrings.h\u003e\n+ #include \u003cunistd.h\u003e\n+ #include \u003csys/types.h\u003e\n+\n+ #ifndef __cplusplus\n+ #include \u003cerrno.h\u003e\n+ #endif\n+ #include \u003cnetdb.h\u003e\n+ #include \u003csignal.h\u003e\n+ #include \u003csys/socket.h\u003e\n+\n+ #if defined(LWS_BUILTIN_GETIFADDRS)\n+ #include \u0022./misc/getifaddrs.h\u0022\n+ #else\n+ #if !defined(LWS_WITH_ESP32)\n+ #if defined(__HAIKU__)\n+ #define _BSD_SOURCE\n+ #endif\n+ #include \u003cifaddrs.h\u003e\n+ #endif\n+ #endif\n+ #if defined (__ANDROID__)\n+ #include \u003csyslog.h\u003e\n+ #include \u003csys/resource.h\u003e\n+ #elif defined (__sun) || defined(__HAIKU__) || defined(__QNX__)\n+ #include \u003csyslog.h\u003e\n+ #else\n+ #if !defined(LWS_WITH_ESP32)\n+ #include \u003csys/syslog.h\u003e\n+ #endif\n+ #endif\n+ #include \u003cnetdb.h\u003e\n+ #if !defined(LWS_WITH_ESP32)\n+ #include \u003csys/mman.h\u003e\n+ #include \u003csys/un.h\u003e\n+ #include \u003cnetinet/in.h\u003e\n+ #include \u003cnetinet/tcp.h\u003e\n+ #include \u003carpa/inet.h\u003e\n+ #include \u003cpoll.h\u003e\n+ #endif\n+ #ifndef LWS_NO_FORK\n+ #ifdef LWS_HAVE_SYS_PRCTL_H\n+ #include \u003csys/prctl.h\u003e\n+ #endif\n+ #endif\n+\n+ #include \u003csys/time.h\u003e\n+\n+ #define LWS_ERRNO errno\n+ #define LWS_EAGAIN EAGAIN\n+ #define LWS_EALREADY EALREADY\n+ #define LWS_EINPROGRESS EINPROGRESS\n+ #define LWS_EINTR EINTR\n+ #define LWS_EISCONN EISCONN\n+ #define LWS_EWOULDBLOCK EWOULDBLOCK\n+\n+ #define lws_set_blocking_send(wsi)\n+\n+ #define lws_socket_is_valid(x) (x \u003e\u003d 0)\n+ #define LWS_SOCK_INVALID (-1)\n+#endif /* not windows */\n+\n+#ifndef LWS_HAVE_BZERO\n+ #ifndef bzero\n+ #define bzero(b, len) (memset((b), '\u005c0', (len)), (void) 0)\n+ #endif\n+#endif\n+\n+#ifndef LWS_HAVE_STRERROR\n+ #define strerror(x) \u0022\u0022\n+#endif\n+\n+#include \u0022libwebsockets.h\u0022\n+\n+#include \u0022tls/private.h\u0022\n+\n+#if defined(WIN32) || defined(_WIN32)\n+ #include \u003cgettimeofday.h\u003e\n+\n+ #ifndef BIG_ENDIAN\n+ #define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */\n+ #endif\n+ #ifndef LITTLE_ENDIAN\n+ #define LITTLE_ENDIAN 1234\n+ #endif\n+ #ifndef BYTE_ORDER\n+ #define BYTE_ORDER LITTLE_ENDIAN\n+ #endif\n+\n+ #undef __P\n+ #ifndef __P\n+ #if __STDC__\n+ #define __P(protos) protos\n+ #else\n+ #define __P(protos) ()\n+ #endif\n+ #endif\n+\n+#else /* not windows */\n+ static inline int compatible_close(int fd) { return close(fd); }\n+\n+ #include \u003csys/stat.h\u003e\n+ #include \u003csys/time.h\u003e\n+\n+ #if defined(__APPLE__)\n+ #include \u003cmachine/endian.h\u003e\n+ #elif defined(__FreeBSD__)\n+ #include \u003csys/endian.h\u003e\n+ #elif defined(__linux__)\n+ #include \u003cendian.h\u003e\n+ #endif\n+#endif\n+\n+#ifdef __cplusplus\n+extern \u0022C\u0022 {\n+#endif\n+\n+#if defined(__QNX__)\n+\t#include \u003cgulliver.h\u003e\n+\t#if defined(__LITTLEENDIAN__)\n+\t\t#define BYTE_ORDER __LITTLEENDIAN__\n+\t\t#define LITTLE_ENDIAN __LITTLEENDIAN__\n+\t\t#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc); for suppres warning that BIG_ENDIAN is not defined. */\n+\t#endif\n+\t#if defined(__BIGENDIAN__)\n+\t\t#define BYTE_ORDER __BIGENDIAN__\n+\t\t#define LITTLE_ENDIAN 1234 /* to show byte order (taken from gcc); for suppres warning that LITTLE_ENDIAN is not defined. */\n+\t\t#define BIG_ENDIAN __BIGENDIAN__\n+\t#endif\n+#endif\n+\n+#if defined(__sun) \u0026\u0026 defined(__GNUC__)\n+\n+ #include \u003carpa/nameser_compat.h\u003e\n+\n+ #if !defined (BYTE_ORDER)\n+ #define BYTE_ORDER __BYTE_ORDER__\n+ #endif\n+\n+ #if !defined(LITTLE_ENDIAN)\n+ #define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__\n+ #endif\n+\n+ #if !defined(BIG_ENDIAN)\n+ #define BIG_ENDIAN __ORDER_BIG_ENDIAN__\n+ #endif\n+\n+#endif /* sun + GNUC */\n+\n+#if !defined(BYTE_ORDER)\n+ #define BYTE_ORDER __BYTE_ORDER\n+#endif\n+#if !defined(LITTLE_ENDIAN)\n+ #define LITTLE_ENDIAN __LITTLE_ENDIAN\n+#endif\n+#if !defined(BIG_ENDIAN)\n+ #define BIG_ENDIAN __BIG_ENDIAN\n+#endif\n+\n+\n+/*\n+ * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,\n+ * but happily have something equivalent in the SO_NOSIGPIPE flag.\n+ */\n+#ifdef __APPLE__\n+#define MSG_NOSIGNAL SO_NOSIGPIPE\n+#endif\n+\n+/*\n+ * Solaris 11.X only supports POSIX 2001, MSG_NOSIGNAL appears in\n+ * POSIX 2008.\n+ */\n+#ifdef __sun\n+ #define MSG_NOSIGNAL 0\n+#endif\n+\n+#ifdef _WIN32\n+ #ifndef FD_HASHTABLE_MODULUS\n+ #define FD_HASHTABLE_MODULUS 32\n+ #endif\n+#endif\n+\n+#ifndef LWS_DEF_HEADER_LEN\n+#define LWS_DEF_HEADER_LEN 4096\n+#endif\n+#ifndef LWS_DEF_HEADER_POOL\n+#define LWS_DEF_HEADER_POOL 4\n+#endif\n+#ifndef LWS_MAX_PROTOCOLS\n+#define LWS_MAX_PROTOCOLS 5\n+#endif\n+#ifndef LWS_MAX_EXTENSIONS_ACTIVE\n+#define LWS_MAX_EXTENSIONS_ACTIVE 1\n+#endif\n+#ifndef LWS_MAX_EXT_OFFERS\n+#define LWS_MAX_EXT_OFFERS 8\n+#endif\n+#ifndef SPEC_LATEST_SUPPORTED\n+#define SPEC_LATEST_SUPPORTED 13\n+#endif\n+#ifndef AWAITING_TIMEOUT\n+#define AWAITING_TIMEOUT 20\n+#endif\n+#ifndef CIPHERS_LIST_STRING\n+#define CIPHERS_LIST_STRING \u0022DEFAULT\u0022\n+#endif\n+#ifndef LWS_SOMAXCONN\n+#define LWS_SOMAXCONN SOMAXCONN\n+#endif\n+\n+#define MAX_WEBSOCKET_04_KEY_LEN 128\n+\n+#ifndef SYSTEM_RANDOM_FILEPATH\n+#define SYSTEM_RANDOM_FILEPATH \u0022/dev/urandom\u0022\n+#endif\n+\n+#define LWS_H2_RX_SCRATCH_SIZE 512\n+\n+\n+\n+/*\n+ * All lws_tls...() functions must return this type, converting the\n+ * native backend result and doing the extra work to determine which one\n+ * as needed.\n+ *\n+ * Native TLS backend return codes are NOT ALLOWED outside the backend.\n+ *\n+ * Non-SSL mode also uses these types.\n+ */\n+enum lws_ssl_capable_status {\n+\tLWS_SSL_CAPABLE_ERROR \u003d -1,\t\t /* it failed */\n+\tLWS_SSL_CAPABLE_DONE \u003d 0,\t\t /* it succeeded */\n+\tLWS_SSL_CAPABLE_MORE_SERVICE_READ \u003d -2,\t /* retry WANT_READ */\n+\tLWS_SSL_CAPABLE_MORE_SERVICE_WRITE \u003d -3, /* retry WANT_WRITE */\n+\tLWS_SSL_CAPABLE_MORE_SERVICE \u003d -4,\t /* general retry */\n+};\n+\n+#if defined(__clang__)\n+#define lws_memory_barrier() __sync_synchronize()\n+#elif defined(__GNUC__)\n+#define lws_memory_barrier() __sync_synchronize()\n+#else\n+#define lws_memory_barrier()\n+#endif\n+\n+/*\n+ *\n+ * ------ roles ------\n+ *\n+ */\n+\n+#include \u0022roles/private.h\u0022\n+\n+/* null-terminated array of pointers to roles lws built with */\n+extern const struct lws_role_ops *available_roles[];\n+\n+#define LWS_FOR_EVERY_AVAILABLE_ROLE_START(xx) { \u005c\n+\t\tconst struct lws_role_ops **ppxx \u003d available_roles; \u005c\n+\t\twhile (*ppxx) { \u005c\n+\t\t\tconst struct lws_role_ops *xx \u003d *ppxx++;\n+\n+#define LWS_FOR_EVERY_AVAILABLE_ROLE_END }}\n+\n+/*\n+ *\n+ * ------ event_loop ops ------\n+ *\n+ */\n+\n+#include \u0022event-libs/private.h\u0022\n+\n+/* enums of socks version */\n+enum socks_version {\n+\tSOCKS_VERSION_4 \u003d 4,\n+\tSOCKS_VERSION_5 \u003d 5\n+};\n+\n+/* enums of subnegotiation version */\n+enum socks_subnegotiation_version {\n+\tSOCKS_SUBNEGOTIATION_VERSION_1 \u003d 1,\n+};\n+\n+/* enums of socks commands */\n+enum socks_command {\n+\tSOCKS_COMMAND_CONNECT \u003d 1,\n+\tSOCKS_COMMAND_BIND \u003d 2,\n+\tSOCKS_COMMAND_UDP_ASSOCIATE \u003d 3\n+};\n+\n+/* enums of socks address type */\n+enum socks_atyp {\n+\tSOCKS_ATYP_IPV4 \u003d 1,\n+\tSOCKS_ATYP_DOMAINNAME \u003d 3,\n+\tSOCKS_ATYP_IPV6 \u003d 4\n+};\n+\n+/* enums of socks authentication methods */\n+enum socks_auth_method {\n+\tSOCKS_AUTH_NO_AUTH \u003d 0,\n+\tSOCKS_AUTH_GSSAPI \u003d 1,\n+\tSOCKS_AUTH_USERNAME_PASSWORD \u003d 2\n+};\n+\n+/* enums of subnegotiation status */\n+enum socks_subnegotiation_status {\n+\tSOCKS_SUBNEGOTIATION_STATUS_SUCCESS \u003d 0,\n+};\n+\n+/* enums of socks request reply */\n+enum socks_request_reply {\n+\tSOCKS_REQUEST_REPLY_SUCCESS \u003d 0,\n+\tSOCKS_REQUEST_REPLY_FAILURE_GENERAL \u003d 1,\n+\tSOCKS_REQUEST_REPLY_CONNECTION_NOT_ALLOWED \u003d 2,\n+\tSOCKS_REQUEST_REPLY_NETWORK_UNREACHABLE \u003d 3,\n+\tSOCKS_REQUEST_REPLY_HOST_UNREACHABLE \u003d 4,\n+\tSOCKS_REQUEST_REPLY_CONNECTION_REFUSED \u003d 5,\n+\tSOCKS_REQUEST_REPLY_TTL_EXPIRED \u003d 6,\n+\tSOCKS_REQUEST_REPLY_COMMAND_NOT_SUPPORTED \u003d 7,\n+\tSOCKS_REQUEST_REPLY_ATYP_NOT_SUPPORTED \u003d 8\n+};\n+\n+/* enums used to generate socks messages */\n+enum socks_msg_type {\n+\t/* greeting */\n+\tSOCKS_MSG_GREETING,\n+\t/* credential, user name and password */\n+\tSOCKS_MSG_USERNAME_PASSWORD,\n+\t/* connect command */\n+\tSOCKS_MSG_CONNECT\n+};\n+\n+enum {\n+\tLWS_RXFLOW_ALLOW \u003d (1 \u003c\u003c 0),\n+\tLWS_RXFLOW_PENDING_CHANGE \u003d (1 \u003c\u003c 1),\n+};\n+\n+struct lws_ring {\n+\tvoid *buf;\n+\tvoid (*destroy_element)(void *element);\n+\tuint32_t buflen;\n+\tuint32_t element_len;\n+\tuint32_t head;\n+\tuint32_t oldest_tail;\n+};\n+\n+struct lws_protocols;\n+struct lws;\n+\n+struct lws_io_watcher {\n+#ifdef LWS_WITH_LIBEV\n+\tstruct lws_io_watcher_libev ev;\n+#endif\n+#ifdef LWS_WITH_LIBUV\n+\tstruct lws_io_watcher_libuv uv;\n+#endif\n+#ifdef LWS_WITH_LIBEVENT\n+\tstruct lws_io_watcher_libevent event;\n+#endif\n+\tstruct lws_context *context;\n+\n+\tuint8_t actual_events;\n+};\n+\n+struct lws_signal_watcher {\n+#ifdef LWS_WITH_LIBEV\n+\tstruct lws_signal_watcher_libev ev;\n+#endif\n+#ifdef LWS_WITH_LIBUV\n+\tstruct lws_signal_watcher_libuv uv;\n+#endif\n+#ifdef LWS_WITH_LIBEVENT\n+\tstruct lws_signal_watcher_libevent event;\n+#endif\n+\tstruct lws_context *context;\n+};\n+\n+#ifdef _WIN32\n+#define LWS_FD_HASH(fd) ((fd ^ (fd \u003e\u003e 8) ^ (fd \u003e\u003e 16)) % FD_HASHTABLE_MODULUS)\n+struct lws_fd_hashtable {\n+\tstruct lws **wsi;\n+\tint length;\n+};\n+#endif\n+\n+struct lws_foreign_thread_pollfd {\n+\tstruct lws_foreign_thread_pollfd *next;\n+\tint fd_index;\n+\tint _and;\n+\tint _or;\n+};\n+\n+\n+#define LWS_HRTIMER_NOWAIT (0x7fffffffffffffffll)\n+\n+/*\n+ * so we can have n connections being serviced simultaneously,\n+ * these things need to be isolated per-thread.\n+ */\n+\n+struct lws_context_per_thread {\n+#if LWS_MAX_SMP \u003e 1\n+\tpthread_mutex_t lock;\n+\tpthread_mutex_t lock_stats;\n+\tpthread_t lock_owner;\n+\tconst char *last_lock_reason;\n+#endif\n+\n+\tstruct lws_context *context;\n+\n+\t/*\n+\t * usable by anything in the service code, but only if the scope\n+\t * does not last longer than the service action (since next service\n+\t * of any socket can likewise use it and overwrite)\n+\t */\n+\tunsigned char *serv_buf;\n+\n+\tstruct lws_dll_lws dll_head_timeout;\n+\tstruct lws_dll_lws dll_head_hrtimer;\n+\tstruct lws_dll_lws dll_head_buflist; /* guys with pending rxflow */\n+\n+#if defined(LWS_WITH_TLS)\n+\tstruct lws_pt_tls tls;\n+#endif\n+\n+\tstruct lws_pollfd *fds;\n+\tvolatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list;\n+#ifdef _WIN32\n+\tWSAEVENT *events;\n+#endif\n+\tlws_sockfd_type dummy_pipe_fds[2];\n+\tstruct lws *pipe_wsi;\n+\n+\t/* --- role based members --- */\n+\n+#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n+\tstruct lws_pt_role_ws ws;\n+#endif\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tstruct lws_pt_role_http http;\n+#endif\n+\n+\t/* --- event library based members --- */\n+\n+#if defined(LWS_WITH_LIBEV)\n+\tstruct lws_pt_eventlibs_libev ev;\n+#endif\n+#if defined(LWS_WITH_LIBUV)\n+\tstruct lws_pt_eventlibs_libuv uv;\n+#endif\n+#if defined(LWS_WITH_LIBEVENT)\n+\tstruct lws_pt_eventlibs_libevent event;\n+#endif\n+\n+#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT)\n+\tstruct lws_signal_watcher w_sigint;\n+#endif\n+\n+\t/* --- */\n+\n+\tunsigned long count_conns;\n+\tunsigned int fds_count;\n+\n+\tvolatile unsigned char inside_poll;\n+\tvolatile unsigned char foreign_spinlock;\n+\n+\tunsigned char tid;\n+\n+\tunsigned char lock_depth;\n+\tunsigned char inside_service:1;\n+\tunsigned char event_loop_foreign:1;\n+\tunsigned char event_loop_destroy_processing_done:1;\n+};\n+\n+struct lws_conn_stats {\n+\tunsigned long long rx, tx;\n+\tunsigned long h1_conn, h1_trans, h2_trans, ws_upg, h2_alpn, h2_subs,\n+\t\t h2_upg, rejected;\n+};\n+\n+void\n+lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs);\n+\n+struct lws_timed_vh_protocol {\n+\tstruct lws_timed_vh_protocol *next;\n+\tconst struct lws_protocols *protocol;\n+\ttime_t time;\n+\tint reason;\n+};\n+\n+/*\n+ * virtual host -related context information\n+ * vhostwide SSL context\n+ * vhostwide proxy\n+ *\n+ * hierarchy:\n+ *\n+ * context -\u003e vhost -\u003e wsi\n+ *\n+ * incoming connection non-SSL vhost binding:\n+ *\n+ * listen socket -\u003e wsi -\u003e select vhost after first headers\n+ *\n+ * incoming connection SSL vhost binding:\n+ *\n+ * SSL SNI -\u003e wsi -\u003e bind after SSL negotiation\n+ */\n+\n+\n+struct lws_vhost {\n+#if !defined(LWS_WITHOUT_CLIENT)\n+\tchar proxy_basic_auth_token[128];\n+#endif\n+#if LWS_MAX_SMP \u003e 1\n+\tpthread_mutex_t lock;\n+#endif\n+\n+#if defined(LWS_ROLE_H2)\n+\tstruct lws_vhost_role_h2 h2;\n+#endif\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tstruct lws_vhost_role_http http;\n+#endif\n+#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n+\tstruct lws_vhost_role_ws ws;\n+#endif\n+\n+#if defined(LWS_WITH_SOCKS5)\n+\tchar socks_proxy_address[128];\n+\tchar socks_user[96];\n+\tchar socks_password[96];\n+#endif\n+#if defined(LWS_WITH_LIBEV)\n+\tstruct lws_io_watcher w_accept;\n+#endif\n+\tstruct lws_conn_stats conn_stats;\n+\tstruct lws_context *context;\n+\tstruct lws_vhost *vhost_next;\n+\n+\tstruct lws *lserv_wsi;\n+\tconst char *name;\n+\tconst char *iface;\n+\n+#if !defined(LWS_WITH_ESP32) \u0026\u0026 !defined(OPTEE_TA) \u0026\u0026 !defined(WIN32)\n+\tint bind_iface;\n+#endif\n+\tconst struct lws_protocols *protocols;\n+\tvoid **protocol_vh_privs;\n+\tconst struct lws_protocol_vhost_options *pvo;\n+\tconst struct lws_protocol_vhost_options *headers;\n+\tstruct lws **same_vh_protocol_list;\n+\tstruct lws_vhost *no_listener_vhost_list;\n+#if !defined(LWS_NO_CLIENT)\n+\tstruct lws_dll_lws dll_active_client_conns;\n+#endif\n+\n+#if defined(LWS_WITH_TLS)\n+\tstruct lws_vhost_tls tls;\n+#endif\n+\n+\tstruct lws_timed_vh_protocol *timed_vh_protocol_list;\n+\tvoid *user;\n+\n+\tint listen_port;\n+\n+#if defined(LWS_WITH_SOCKS5)\n+\tunsigned int socks_proxy_port;\n+#endif\n+\tunsigned int options;\n+\tint count_protocols;\n+\tint ka_time;\n+\tint ka_probes;\n+\tint ka_interval;\n+\tint keepalive_timeout;\n+\tint timeout_secs_ah_idle;\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+\tint log_fd;\n+#endif\n+\n+\tunsigned int created_vhost_protocols:1;\n+\tunsigned int being_destroyed:1;\n+\n+\tunsigned char default_protocol_index;\n+\tunsigned char raw_protocol_index;\n+};\n+\n+struct lws_deferred_free\n+{\n+\tstruct lws_deferred_free *next;\n+\ttime_t deadline;\n+\tvoid *payload;\n+};\n+\n+typedef union {\n+#ifdef LWS_WITH_IPV6\n+\tstruct sockaddr_in6 sa6;\n+#endif\n+\tstruct sockaddr_in sa4;\n+} sockaddr46;\n+\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+struct lws_peer {\n+\tstruct lws_peer *next;\n+\tstruct lws_peer *peer_wait_list;\n+\n+\ttime_t time_created;\n+\ttime_t time_closed_all;\n+\n+\tuint8_t addr[32];\n+\tuint32_t hash;\n+\tuint32_t count_wsi;\n+\tuint32_t total_wsi;\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tstruct lws_peer_role_http http;\n+#endif\n+\n+\tuint8_t af;\n+};\n+#endif\n+\n+/*\n+ * the rest is managed per-context, that includes\n+ *\n+ * - processwide single fd -\u003e wsi lookup\n+ * - contextwide headers pool\n+ */\n+\n+struct lws_context {\n+\ttime_t last_timeout_check_s;\n+\ttime_t last_ws_ping_pong_check_s;\n+\ttime_t time_up;\n+\ttime_t time_discontiguity;\n+\ttime_t time_fixup;\n+\tconst struct lws_plat_file_ops *fops;\n+\tstruct lws_plat_file_ops fops_platform;\n+\tstruct lws_context **pcontext_finalize;\n+\n+\tconst struct lws_tls_ops *tls_ops;\n+\n+#if defined(LWS_WITH_HTTP2)\n+\tstruct http2_settings set;\n+#endif\n+#if defined(LWS_WITH_ZIP_FOPS)\n+\tstruct lws_plat_file_ops fops_zip;\n+#endif\n+\tstruct lws_context_per_thread pt[LWS_MAX_SMP];\n+\tstruct lws_conn_stats conn_stats;\n+#if LWS_MAX_SMP \u003e 1\n+\tpthread_mutex_t lock;\n+\tint lock_depth;\n+#endif\n+#ifdef _WIN32\n+/* different implementation between unix and windows */\n+\tstruct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];\n+#else\n+\tstruct lws **lws_lookup; /* fd to wsi */\n+#endif\n+\tstruct lws_vhost *vhost_list;\n+\tstruct lws_vhost *no_listener_vhost_list;\n+\tstruct lws_vhost *vhost_pending_destruction_list;\n+\tstruct lws_plugin *plugin_list;\n+\tstruct lws_deferred_free *deferred_free_list;\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tstruct lws_peer **pl_hash_table;\n+\tstruct lws_peer *peer_wait_list;\n+\ttime_t next_cull;\n+#endif\n+\n+\tvoid *external_baggage_free_on_destroy;\n+\tconst struct lws_token_limits *token_limits;\n+\tvoid *user_space;\n+\tconst struct lws_protocol_vhost_options *reject_service_keywords;\n+\tlws_reload_func deprecation_cb;\n+\tvoid (*eventlib_signal_cb)(void *event_lib_handle, int signum);\n+\n+#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n+\tcap_value_t caps[4];\n+\tchar count_caps;\n+#endif\n+\n+#if defined(LWS_WITH_LIBEV)\n+\tstruct lws_context_eventlibs_libev ev;\n+#endif\n+#if defined(LWS_WITH_LIBUV)\n+\tstruct lws_context_eventlibs_libuv uv;\n+#endif\n+#if defined(LWS_WITH_LIBEVENT)\n+\tstruct lws_context_eventlibs_libevent event;\n+#endif\n+\tstruct lws_event_loop_ops *event_loop_ops;\n+\n+\n+#if defined(LWS_WITH_TLS)\n+\tstruct lws_context_tls tls;\n+#endif\n+\n+\tchar canonical_hostname[128];\n+\tconst char *server_string;\n+\n+#ifdef LWS_LATENCY\n+\tunsigned long worst_latency;\n+\tchar worst_latency_info[256];\n+#endif\n+\n+#if defined(LWS_WITH_STATS)\n+\tuint64_t lws_stats[LWSSTATS_SIZE];\n+\tuint64_t last_dump;\n+\tint updated;\n+#endif\n+#if defined(LWS_WITH_ESP32)\n+\tunsigned long time_last_state_dump;\n+\tuint32_t last_free_heap;\n+#endif\n+\n+\tint max_fds;\n+\tint count_event_loop_static_asset_handles;\n+\tint started_with_parent;\n+\tint uid, gid;\n+\n+\tint fd_random;\n+\n+\tint count_wsi_allocated;\n+\tint count_cgi_spawned;\n+\tunsigned int options;\n+\tunsigned int fd_limit_per_thread;\n+\tunsigned int timeout_secs;\n+\tunsigned int pt_serv_buf_size;\n+\tint max_http_header_data;\n+\tint simultaneous_ssl_restriction;\n+\tint simultaneous_ssl;\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tuint32_t pl_hash_elements;\t/* protected by context-\u003elock */\n+\tuint32_t count_peers;\t\t/* protected by context-\u003elock */\n+\tunsigned short ip_limit_ah;\n+\tunsigned short ip_limit_wsi;\n+#endif\n+\tunsigned int deprecated:1;\n+\tunsigned int being_destroyed:1;\n+\tunsigned int being_destroyed1:1;\n+\tunsigned int being_destroyed2:1;\n+\tunsigned int requested_kill:1;\n+\tunsigned int protocol_init_done:1;\n+\tunsigned int doing_protocol_init:1;\n+\tunsigned int done_protocol_destroy_cb:1;\n+\tunsigned int finalize_destroy_after_internal_loops_stopped:1;\n+\t/*\n+\t * set to the Thread ID that's doing the service loop just before entry\n+\t * to poll indicates service thread likely idling in poll()\n+\t * volatile because other threads may check it as part of processing\n+\t * for pollfd event change.\n+\t */\n+\tvolatile int service_tid;\n+\tint service_tid_detected;\n+\n+\tshort max_http_header_pool;\n+\tshort count_threads;\n+\tshort plugin_protocol_count;\n+\tshort plugin_extension_count;\n+\tshort server_string_len;\n+\tunsigned short ws_ping_pong_interval;\n+\tunsigned short deprecation_pending_listen_close_count;\n+\n+\tuint8_t max_fi;\n+};\n+\n+int\n+lws_check_deferred_free(struct lws_context *context, int force);\n+\n+#define lws_get_context_protocol(ctx, x) ctx-\u003evhost_list-\u003eprotocols[x]\n+#define lws_get_vh_protocol(vh, x) vh-\u003eprotocols[x]\n+\n+LWS_EXTERN void\n+__lws_close_free_wsi_final(struct lws *wsi);\n+LWS_EXTERN void\n+lws_libuv_closehandle(struct lws *wsi);\n+LWS_EXTERN int\n+lws_libuv_check_watcher_active(struct lws *wsi);\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_plat_plugins_init(struct lws_context * context, const char * const *d);\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_plat_plugins_destroy(struct lws_context * context);\n+\n+LWS_EXTERN void\n+lws_restart_ws_ping_pong_timer(struct lws *wsi);\n+\n+struct lws *\n+lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);\n+\n+int\n+lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);\n+\n+void\n+lws_vhost_destroy1(struct lws_vhost *vh);\n+\n+enum {\n+\tLWS_EV_READ \u003d (1 \u003c\u003c 0),\n+\tLWS_EV_WRITE \u003d (1 \u003c\u003c 1),\n+\tLWS_EV_START \u003d (1 \u003c\u003c 2),\n+\tLWS_EV_STOP \u003d (1 \u003c\u003c 3),\n+\n+\tLWS_EV_PREPARE_DELETION \u003d (1 \u003c\u003c 31),\n+};\n+\n+\n+#if defined(LWS_WITH_ESP32)\n+LWS_EXTERN int\n+lws_find_string_in_file(const char *filename, const char *string, int stringlen);\n+#endif\n+\n+#ifdef LWS_WITH_IPV6\n+#define LWS_IPV6_ENABLED(vh) \u005c\n+\t(!lws_check_opt(vh-\u003econtext-\u003eoptions, LWS_SERVER_OPTION_DISABLE_IPV6) \u0026\u0026 \u005c\n+\t !lws_check_opt(vh-\u003eoptions, LWS_SERVER_OPTION_DISABLE_IPV6))\n+#else\n+#define LWS_IPV6_ENABLED(context) (0)\n+#endif\n+\n+#ifdef LWS_WITH_UNIX_SOCK\n+#define LWS_UNIX_SOCK_ENABLED(vhost) \u005c\n+\t(vhost-\u003eoptions \u0026 LWS_SERVER_OPTION_UNIX_SOCK)\n+#else\n+#define LWS_UNIX_SOCK_ENABLED(vhost) (0)\n+#endif\n+\n+enum uri_path_states {\n+\tURIPS_IDLE,\n+\tURIPS_SEEN_SLASH,\n+\tURIPS_SEEN_SLASH_DOT,\n+\tURIPS_SEEN_SLASH_DOT_DOT,\n+};\n+\n+enum uri_esc_states {\n+\tURIES_IDLE,\n+\tURIES_SEEN_PERCENT,\n+\tURIES_SEEN_PERCENT_H1,\n+};\n+\n+\n+#ifndef LWS_NO_CLIENT\n+struct client_info_stash {\n+\tchar *address;\n+\tchar *path;\n+\tchar *host;\n+\tchar *origin;\n+\tchar *protocol;\n+\tchar *method;\n+\tchar *iface;\n+\tchar *alpn;\n+};\n+#endif\n+\n+\n+signed char char_to_hex(const char c);\n+\n+\n+struct lws_buflist {\n+\tstruct lws_buflist *next;\n+\n+\tsize_t len;\n+\tsize_t pos;\n+\n+\tuint8_t buf[1]; /* true length of this is set by the oversize malloc */\n+};\n+\n+#define lws_wsi_is_udp(___wsi) (!!___wsi-\u003eudp)\n+\n+#define LWS_H2_FRAME_HEADER_LENGTH 9\n+\n+\n+struct lws {\n+\t/* structs */\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tstruct _lws_http_mode_related http;\n+#endif\n+#if defined(LWS_ROLE_H2)\n+\tstruct _lws_h2_related h2;\n+#endif\n+#if defined(LWS_ROLE_WS)\n+\tstruct _lws_websocket_related *ws; /* allocated if we upgrade to ws */\n+#endif\n+\n+\tconst struct lws_role_ops *role_ops;\n+\tlws_wsi_state_t\twsistate;\n+\tlws_wsi_state_t wsistate_pre_close;\n+\n+\t/* lifetime members */\n+\n+#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT)\n+\tstruct lws_io_watcher w_read;\n+#endif\n+#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBEVENT)\n+\tstruct lws_io_watcher w_write;\n+#endif\n+\n+\t/* pointers */\n+\n+\tstruct lws_context *context;\n+\tstruct lws_vhost *vhost;\n+\tstruct lws *parent; /* points to parent, if any */\n+\tstruct lws *child_list; /* points to first child */\n+\tstruct lws *sibling_list; /* subsequent children at same level */\n+\n+\tconst struct lws_protocols *protocol;\n+\tstruct lws **same_vh_protocol_prev, *same_vh_protocol_next;\n+\n+\tstruct lws_dll_lws dll_timeout;\n+\tstruct lws_dll_lws dll_hrtimer;\n+\tstruct lws_dll_lws dll_buflist; /* guys with pending rxflow */\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tstruct lws_peer *peer;\n+#endif\n+\n+\tstruct lws_udp *udp;\n+#ifndef LWS_NO_CLIENT\n+\tstruct client_info_stash *stash;\n+\tchar *client_hostname_copy;\n+\tstruct lws_dll_lws dll_active_client_conns;\n+\tstruct lws_dll_lws dll_client_transaction_queue_head;\n+\tstruct lws_dll_lws dll_client_transaction_queue;\n+#endif\n+\tvoid *user_space;\n+\tvoid *opaque_parent_data;\n+\n+\tstruct lws_buflist *buflist;\n+\n+\t/* truncated send handling */\n+\tunsigned char *trunc_alloc; /* non-NULL means buffering in progress */\n+\n+#if defined(LWS_WITH_TLS)\n+\tstruct lws_lws_tls tls;\n+#endif\n+\n+#ifdef LWS_LATENCY\n+\tunsigned long action_start;\n+\tunsigned long latency_start;\n+#endif\n+\n+\tlws_sock_file_fd_type desc; /* .filefd / .sockfd */\n+#if defined(LWS_WITH_STATS)\n+\tuint64_t active_writable_req_us;\n+#if defined(LWS_WITH_TLS)\n+\tuint64_t accept_start_us;\n+#endif\n+#endif\n+\n+\tlws_usec_t pending_timer; /* hrtimer fires */\n+\ttime_t pending_timeout_set; /* second-resolution timeout start */\n+\n+\t/* ints */\n+\tint position_in_fds_table;\n+\tunsigned int trunc_alloc_len; /* size of malloc */\n+\tunsigned int trunc_offset; /* where we are in terms of spilling */\n+\tunsigned int trunc_len; /* how much is buffered */\n+#ifndef LWS_NO_CLIENT\n+\tint chunk_remaining;\n+#endif\n+\tunsigned int cache_secs;\n+\n+\tunsigned int hdr_parsing_completed:1;\n+\tunsigned int http2_substream:1;\n+\tunsigned int upgraded_to_http2:1;\n+\tunsigned int h2_stream_carries_ws:1;\n+\tunsigned int seen_nonpseudoheader:1;\n+\tunsigned int listener:1;\n+\tunsigned int user_space_externally_allocated:1;\n+\tunsigned int socket_is_permanently_unusable:1;\n+\tunsigned int rxflow_change_to:2;\n+\tunsigned int conn_stat_done:1;\n+\tunsigned int cache_reuse:1;\n+\tunsigned int cache_revalidate:1;\n+\tunsigned int cache_intermediaries:1;\n+\tunsigned int favoured_pollin:1;\n+\tunsigned int sending_chunked:1;\n+\tunsigned int interpreting:1;\n+\tunsigned int already_did_cce:1;\n+\tunsigned int told_user_closed:1;\n+\tunsigned int told_event_loop_closed:1;\n+\tunsigned int waiting_to_send_close_frame:1;\n+\tunsigned int close_needs_ack:1;\n+\tunsigned int ipv6:1;\n+\tunsigned int parent_carries_io:1;\n+\tunsigned int parent_pending_cb_on_writable:1;\n+\tunsigned int cgi_stdout_zero_length:1;\n+\tunsigned int seen_zero_length_recv:1;\n+\tunsigned int rxflow_will_be_applied:1;\n+\tunsigned int event_pipe:1;\n+\tunsigned int on_same_vh_list:1;\n+\tunsigned int handling_404:1;\n+\tunsigned int protocol_bind_balance:1;\n+\n+\tunsigned int could_have_pending:1; /* detect back-to-back writes */\n+\tunsigned int outer_will_close:1;\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+\tunsigned int access_log_pending:1;\n+#endif\n+#ifndef LWS_NO_CLIENT\n+\tunsigned int do_ws:1; /* whether we are doing http or ws flow */\n+\tunsigned int chunked:1; /* if the clientside connection is chunked */\n+\tunsigned int client_rx_avail:1;\n+\tunsigned int client_http_body_pending:1;\n+\tunsigned int transaction_from_pipeline_queue:1;\n+\tunsigned int keepalive_active:1;\n+\tunsigned int keepalive_rejected:1;\n+\tunsigned int client_pipeline:1;\n+\tunsigned int client_h2_alpn:1;\n+\tunsigned int client_h2_substream:1;\n+#endif\n+\n+#ifdef _WIN32\n+\tunsigned int sock_send_blocking:1;\n+#endif\n+\n+#ifndef LWS_NO_CLIENT\n+\tunsigned short c_port;\n+#endif\n+\tunsigned short pending_timeout_limit;\n+\n+\t/* chars */\n+\n+\tchar lws_rx_parse_state; /* enum lws_rx_parse_state */\n+\tchar rx_frame_type; /* enum lws_write_protocol */\n+\tchar pending_timeout; /* enum pending_timeout */\n+\tchar tsi; /* thread service index we belong to */\n+\tchar protocol_interpret_idx;\n+\tchar redirects;\n+\tuint8_t rxflow_bitmap;\n+#ifdef LWS_WITH_CGI\n+\tchar cgi_channel; /* which of stdin/out/err */\n+\tchar hdr_state;\n+#endif\n+#ifndef LWS_NO_CLIENT\n+\tchar chunk_parser; /* enum lws_chunk_parser */\n+#endif\n+#if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT)\n+\tchar reason_bf; /* internal writeable callback reason bitfield */\n+#endif\n+#if defined(LWS_WITH_STATS) \u0026\u0026 defined(LWS_WITH_TLS)\n+\tchar seen_rx;\n+#endif\n+\tuint8_t ws_over_h2_count;\n+\t/* volatile to make sure code is aware other thread can change */\n+\tvolatile char handling_pollout;\n+\tvolatile char leave_pollout_active;\n+};\n+\n+#define lws_is_flowcontrolled(w) (!!(wsi-\u003erxflow_bitmap))\n+\n+void\n+lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);\n+\n+LWS_EXTERN int log_level;\n+\n+LWS_EXTERN int\n+lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,\n+\t\tconst char *iface);\n+\n+#if defined(LWS_WITH_IPV6)\n+LWS_EXTERN unsigned long\n+lws_get_addr_scope(const char *ipaddr);\n+#endif\n+\n+LWS_EXTERN void\n+lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);\n+LWS_EXTERN void\n+__lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);\n+\n+LWS_EXTERN void\n+__lws_free_wsi(struct lws *wsi);\n+\n+LWS_EXTERN int\n+__remove_wsi_socket_from_fds(struct lws *wsi);\n+LWS_EXTERN int\n+lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len);\n+\n+#ifndef LWS_LATENCY\n+static inline void\n+lws_latency(struct lws_context *context, struct lws *wsi, const char *action,\n+\t int ret, int completion) {\n+\tdo {\n+\t\t(void)context; (void)wsi; (void)action; (void)ret;\n+\t\t(void)completion;\n+\t} while (0);\n+}\n+static inline void\n+lws_latency_pre(struct lws_context *context, struct lws *wsi) {\n+\tdo { (void)context; (void)wsi; } while (0);\n+}\n+#else\n+#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0)\n+extern void\n+lws_latency(struct lws_context *context, struct lws *wsi, const char *action,\n+\t int ret, int completion);\n+#endif\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_ws_client_rx_sm(struct lws *wsi, unsigned char c);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_parse(struct lws *wsi, unsigned char *buf, int *len);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_parse_urldecode(struct lws *wsi, uint8_t *_c);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_http_action(struct lws *wsi);\n+\n+LWS_EXTERN int\n+lws_b64_selftest(void);\n+\n+LWS_EXTERN int\n+lws_service_flag_pending(struct lws_context *context, int tsi);\n+\n+LWS_EXTERN int\n+lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p);\n+\n+#if defined(_WIN32)\n+LWS_EXTERN struct lws *\n+wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd);\n+\n+LWS_EXTERN int\n+insert_wsi(struct lws_context *context, struct lws *wsi);\n+\n+LWS_EXTERN int\n+delete_from_fd(struct lws_context *context, lws_sockfd_type fd);\n+#else\n+#define wsi_from_fd(A,B) A-\u003elws_lookup[B - lws_plat_socket_offset()]\n+#define insert_wsi(A,B) assert(A-\u003elws_lookup[B-\u003edesc.sockfd - lws_plat_socket_offset()] \u003d\u003d 0); A-\u003elws_lookup[B-\u003edesc.sockfd - lws_plat_socket_offset()]\u003dB\n+#define delete_from_fd(A,B) A-\u003elws_lookup[B - lws_plat_socket_offset()]\u003d0\n+#endif\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);\n+\n+LWS_EXTERN void\n+lws_remove_from_timeout_list(struct lws *wsi);\n+\n+LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT\n+lws_client_connect_2(struct lws *wsi);\n+\n+LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT\n+lws_client_reset(struct lws **wsi, int ssl, const char *address, int port,\n+\t\t const char *path, const char *host);\n+\n+LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT\n+lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi);\n+\n+LWS_EXTERN char * LWS_WARN_UNUSED_RESULT\n+lws_generate_client_handshake(struct lws *wsi, char *pkt);\n+\n+LWS_EXTERN int\n+lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd);\n+\n+LWS_EXTERN struct lws *\n+lws_client_connect_via_info2(struct lws *wsi);\n+\n+\n+\n+LWS_EXTERN void\n+lws_client_stash_destroy(struct lws *wsi);\n+\n+/*\n+ * EXTENSIONS\n+ */\n+\n+#if defined(LWS_WITHOUT_EXTENSIONS)\n+#define lws_any_extension_handled(_a, _b, _c, _d) (0)\n+#define lws_ext_cb_active(_a, _b, _c, _d) (0)\n+#define lws_ext_cb_all_exts(_a, _b, _c, _d, _e) (0)\n+#define lws_issue_raw_ext_access lws_issue_raw\n+#define lws_context_init_extensions(_a, _b)\n+#endif\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_client_interpret_server_handshake(struct lws *wsi);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len);\n+\n+LWS_EXTERN void\n+lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state,\n+\t\t\tstruct lws_role_ops *ops);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+user_callback_handle_rxflow(lws_callback_function, struct lws *wsi,\n+\t\t\t enum lws_callback_reasons reason, void *user,\n+\t\t\t void *in, size_t len);\n+\n+LWS_EXTERN int\n+lws_plat_socket_offset(void);\n+\n+LWS_EXTERN int\n+lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd);\n+\n+LWS_EXTERN int\n+lws_plat_check_connection_error(struct lws *wsi);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_header_table_attach(struct lws *wsi, int autoservice);\n+\n+LWS_EXTERN int\n+lws_header_table_detach(struct lws *wsi, int autoservice);\n+LWS_EXTERN int\n+__lws_header_table_detach(struct lws *wsi, int autoservice);\n+\n+LWS_EXTERN void\n+lws_header_table_reset(struct lws *wsi, int autoservice);\n+\n+void\n+__lws_header_table_reset(struct lws *wsi, int autoservice);\n+\n+LWS_EXTERN char * LWS_WARN_UNUSED_RESULT\n+lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_ensure_user_space(struct lws *wsi);\n+\n+LWS_EXTERN int\n+lws_change_pollfd(struct lws *wsi, int _and, int _or);\n+\n+#ifndef LWS_NO_SERVER\n+ int _lws_vhost_init_server(const struct lws_context_creation_info *info,\n+\t\t\t struct lws_vhost *vhost);\n+ LWS_EXTERN struct lws_vhost *\n+ lws_select_vhost(struct lws_context *context, int port, const char *servername);\n+ LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+ lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len);\n+ LWS_EXTERN void\n+ lws_server_get_canonical_hostname(struct lws_context *context,\n+\t\t\t\t const struct lws_context_creation_info *info);\n+#else\n+ #define _lws_vhost_init_server(_a, _b) (0)\n+ #define lws_parse_ws(_a, _b, _c) (0)\n+ #define lws_server_get_canonical_hostname(_a, _b)\n+#endif\n+\n+#ifndef LWS_NO_DAEMONIZE\n+ LWS_EXTERN int get_daemonize_pid();\n+#else\n+ #define get_daemonize_pid() (0)\n+#endif\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+interface_to_sa(struct lws_vhost *vh, const char *ifname,\n+\t\tstruct sockaddr_in *addr, size_t addrlen);\n+LWS_EXTERN void lwsl_emit_stderr(int level, const char *line);\n+\n+#if !defined(LWS_WITH_TLS)\n+ #define LWS_SSL_ENABLED(context) (0)\n+ #define lws_context_init_server_ssl(_a, _b) (0)\n+ #define lws_ssl_destroy(_a)\n+ #define lws_context_init_alpn(_a)\n+ #define lws_ssl_capable_read lws_ssl_capable_read_no_ssl\n+ #define lws_ssl_capable_write lws_ssl_capable_write_no_ssl\n+ #define lws_ssl_pending lws_ssl_pending_no_ssl\n+ #define lws_server_socket_service_ssl(_b, _c) (0)\n+ #define lws_ssl_close(_a) (0)\n+ #define lws_ssl_context_destroy(_a)\n+ #define lws_ssl_SSL_CTX_destroy(_a)\n+ #define lws_ssl_remove_wsi_from_buffered_list(_a)\n+ #define __lws_ssl_remove_wsi_from_buffered_list(_a)\n+ #define lws_context_init_ssl_library(_a)\n+ #define lws_tls_check_all_cert_lifetimes(_a)\n+ #define lws_tls_acme_sni_cert_destroy(_a)\n+#endif\n+\n+\n+#if LWS_MAX_SMP \u003e 1\n+\n+static LWS_INLINE void\n+lws_pt_mutex_init(struct lws_context_per_thread *pt)\n+{\n+\tpthread_mutex_init(\u0026pt-\u003elock, NULL);\n+\tpthread_mutex_init(\u0026pt-\u003elock_stats, NULL);\n+}\n+\n+static LWS_INLINE void\n+lws_pt_mutex_destroy(struct lws_context_per_thread *pt)\n+{\n+\tpthread_mutex_destroy(\u0026pt-\u003elock_stats);\n+\tpthread_mutex_destroy(\u0026pt-\u003elock);\n+}\n+\n+static LWS_INLINE void\n+lws_pt_lock(struct lws_context_per_thread *pt, const char *reason)\n+{\n+\tif (pt-\u003elock_owner \u003d\u003d pthread_self()) {\n+\t\tpt-\u003elock_depth++;\n+\t\treturn;\n+\t}\n+\tpthread_mutex_lock(\u0026pt-\u003elock);\n+\tpt-\u003elast_lock_reason \u003d reason;\n+\tpt-\u003elock_owner \u003d pthread_self();\n+\t//lwsl_notice(\u0022tid %d: lock %s\u005cn\u0022, pt-\u003etid, reason);\n+}\n+\n+static LWS_INLINE void\n+lws_pt_unlock(struct lws_context_per_thread *pt)\n+{\n+\tif (pt-\u003elock_depth) {\n+\t\tpt-\u003elock_depth--;\n+\t\treturn;\n+\t}\n+\tpt-\u003elast_lock_reason \u003d \u0022free\u0022;\n+\tpt-\u003elock_owner \u003d 0;\n+\t//lwsl_notice(\u0022tid %d: unlock %s\u005cn\u0022, pt-\u003etid, pt-\u003elast_lock_reason);\n+\tpthread_mutex_unlock(\u0026pt-\u003elock);\n+}\n+\n+static LWS_INLINE void\n+lws_pt_stats_lock(struct lws_context_per_thread *pt)\n+{\n+\tpthread_mutex_lock(\u0026pt-\u003elock_stats);\n+}\n+\n+static LWS_INLINE void\n+lws_pt_stats_unlock(struct lws_context_per_thread *pt)\n+{\n+\tpthread_mutex_unlock(\u0026pt-\u003elock_stats);\n+}\n+\n+static LWS_INLINE void\n+lws_context_lock(struct lws_context *context)\n+{\n+\tpthread_mutex_lock(\u0026context-\u003elock);\n+}\n+\n+static LWS_INLINE void\n+lws_context_unlock(struct lws_context *context)\n+{\n+\tpthread_mutex_unlock(\u0026context-\u003elock);\n+}\n+\n+static LWS_INLINE void\n+lws_vhost_lock(struct lws_vhost *vhost)\n+{\n+\tpthread_mutex_lock(\u0026vhost-\u003elock);\n+}\n+\n+static LWS_INLINE void\n+lws_vhost_unlock(struct lws_vhost *vhost)\n+{\n+\tpthread_mutex_unlock(\u0026vhost-\u003elock);\n+}\n+\n+\n+#else\n+#define lws_pt_mutex_init(_a) (void)(_a)\n+#define lws_pt_mutex_destroy(_a) (void)(_a)\n+#define lws_pt_lock(_a, b) (void)(_a)\n+#define lws_pt_unlock(_a) (void)(_a)\n+#define lws_context_lock(_a) (void)(_a)\n+#define lws_context_unlock(_a) (void)(_a)\n+#define lws_vhost_lock(_a) (void)(_a)\n+#define lws_vhost_unlock(_a) (void)(_a)\n+#define lws_pt_stats_lock(_a) (void)(_a)\n+#define lws_pt_stats_unlock(_a) (void)(_a)\n+#endif\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_ssl_pending_no_ssl(struct lws *wsi);\n+\n+int\n+lws_tls_check_cert_lifetime(struct lws_vhost *vhost);\n+\n+int lws_jws_selftest(void);\n+\n+\n+#ifndef LWS_NO_CLIENT\n+LWS_EXTERN int lws_client_socket_service(struct lws *wsi,\n+\t\t\t\t\t struct lws_pollfd *pollfd,\n+\t\t\t\t\t struct lws *wsi_conn);\n+LWS_EXTERN struct lws *\n+lws_client_wsi_effective(struct lws *wsi);\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_http_transaction_completed_client(struct lws *wsi);\n+#if !defined(LWS_WITH_TLS)\n+\t#define lws_context_init_client_ssl(_a, _b) (0)\n+#endif\n+LWS_EXTERN void\n+lws_decode_ssl_error(void);\n+#else\n+#define lws_context_init_client_ssl(_a, _b) (0)\n+#endif\n+\n+LWS_EXTERN int\n+__lws_rx_flow_control(struct lws *wsi);\n+\n+LWS_EXTERN int\n+_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa);\n+\n+#ifndef LWS_NO_SERVER\n+LWS_EXTERN int\n+lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len);\n+#else\n+#define lws_server_socket_service(_b, _c) (0)\n+#define lws_handshake_server(_a, _b, _c) (0)\n+#endif\n+\n+#ifdef LWS_WITH_ACCESS_LOG\n+LWS_EXTERN int\n+lws_access_log(struct lws *wsi);\n+LWS_EXTERN void\n+lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int meth);\n+#else\n+#define lws_access_log(_a)\n+#endif\n+\n+LWS_EXTERN int\n+lws_cgi_kill_terminated(struct lws_context_per_thread *pt);\n+\n+LWS_EXTERN void\n+lws_cgi_remove_and_kill(struct lws *wsi);\n+\n+int\n+lws_protocol_init(struct lws_context *context);\n+\n+int\n+lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p);\n+\n+const struct lws_http_mount *\n+lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len);\n+\n+/*\n+ * custom allocator\n+ */\n+LWS_EXTERN void *\n+lws_realloc(void *ptr, size_t size, const char *reason);\n+\n+LWS_EXTERN void * LWS_WARN_UNUSED_RESULT\n+lws_zalloc(size_t size, const char *reason);\n+\n+#ifdef LWS_PLAT_OPTEE\n+void *lws_malloc(size_t size, const char *reason);\n+void lws_free(void *p);\n+#define lws_free_set_NULL(P) do { lws_free(P); (P) \u003d NULL; } while(0)\n+#else\n+#define lws_malloc(S, R)\tlws_realloc(NULL, S, R)\n+#define lws_free(P)\tlws_realloc(P, 0, \u0022lws_free\u0022)\n+#define lws_free_set_NULL(P)\tdo { lws_realloc(P, 0, \u0022free\u0022); (P) \u003d NULL; } while(0)\n+#endif\n+\n+int\n+lws_plat_pipe_create(struct lws *wsi);\n+int\n+lws_plat_pipe_signal(struct lws *wsi);\n+void\n+lws_plat_pipe_close(struct lws *wsi);\n+int\n+lws_create_event_pipes(struct lws_context *context);\n+\n+const struct lws_plat_file_ops *\n+lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,\n+\t\t const char **vpath);\n+\n+/* lws_plat_ */\n+LWS_EXTERN void\n+lws_plat_delete_socket_from_fds(struct lws_context *context,\n+\t\t\t\tstruct lws *wsi, int m);\n+LWS_EXTERN void\n+lws_plat_insert_socket_into_fds(struct lws_context *context,\n+\t\t\t\tstruct lws *wsi);\n+LWS_EXTERN void\n+lws_plat_service_periodic(struct lws_context *context);\n+\n+LWS_EXTERN int\n+lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,\n+\t\t struct lws_pollfd *pfd);\n+LWS_EXTERN void\n+lws_add_wsi_to_draining_ext_list(struct lws *wsi);\n+LWS_EXTERN void\n+lws_remove_wsi_from_draining_ext_list(struct lws *wsi);\n+LWS_EXTERN int\n+lws_plat_context_early_init(void);\n+LWS_EXTERN void\n+lws_plat_context_early_destroy(struct lws_context *context);\n+LWS_EXTERN void\n+lws_plat_context_late_destroy(struct lws_context *context);\n+LWS_EXTERN int\n+lws_poll_listen_fd(struct lws_pollfd *fd);\n+LWS_EXTERN int\n+lws_plat_service(struct lws_context *context, int timeout_ms);\n+LWS_EXTERN LWS_VISIBLE int\n+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);\n+LWS_EXTERN int\n+lws_plat_init(struct lws_context *context,\n+\t const struct lws_context_creation_info *info);\n+LWS_EXTERN void\n+lws_plat_drop_app_privileges(const struct lws_context_creation_info *info);\n+LWS_EXTERN unsigned long long\n+time_in_microseconds(void);\n+LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT\n+lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt);\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_plat_inet_pton(int af, const char *src, void *dst);\n+\n+LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n+lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);\n+LWS_EXTERN int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,\n+\t\t lws_filepos_t *amount);\n+\n+\n+LWS_EXTERN void\n+lws_same_vh_protocol_remove(struct lws *wsi);\n+LWS_EXTERN void\n+lws_same_vh_protocol_insert(struct lws *wsi, int n);\n+\n+LWS_EXTERN int\n+lws_broadcast(struct lws_context *context, int reason, void *in, size_t len);\n+\n+#if defined(LWS_WITH_STATS)\n+ void\n+ lws_stats_atomic_bump(struct lws_context * context,\n+\t\tstruct lws_context_per_thread *pt, int index, uint64_t bump);\n+ void\n+ lws_stats_atomic_max(struct lws_context * context,\n+\t\tstruct lws_context_per_thread *pt, int index, uint64_t val);\n+#else\n+ static inline uint64_t lws_stats_atomic_bump(struct lws_context * context,\n+\t\tstruct lws_context_per_thread *pt, int index, uint64_t bump) {\n+\t(void)context; (void)pt; (void)index; (void)bump; return 0; }\n+ static inline uint64_t lws_stats_atomic_max(struct lws_context * context,\n+\t\tstruct lws_context_per_thread *pt, int index, uint64_t val) {\n+\t(void)context; (void)pt; (void)index; (void)val; return 0; }\n+#endif\n+\n+/* socks */\n+void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,\n+\t\t\tssize_t *msg_len);\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+void\n+lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer);\n+int\n+lws_peer_confirm_ah_attach_ok(struct lws_context *context, struct lws_peer *peer);\n+void\n+lws_peer_track_ah_detach(struct lws_context *context, struct lws_peer *peer);\n+void\n+lws_peer_cull_peer_wait_list(struct lws_context *context);\n+struct lws_peer *\n+lws_get_or_create_peer(struct lws_vhost *vhost, lws_sockfd_type sockfd);\n+void\n+lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer,\n+\t\t struct lws *wsi);\n+void\n+lws_peer_dump_from_wsi(struct lws *wsi);\n+#endif\n+\n+\n+void\n+__lws_remove_from_timeout_list(struct lws *wsi);\n+\n+lws_usec_t\n+__lws_hrtimer_service(struct lws_context_per_thread *pt);\n+\n+void\n+__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs);\n+int\n+__lws_change_pollfd(struct lws *wsi, int _and, int _or);\n+\n+\n+int\n+lws_callback_as_writeable(struct lws *wsi);\n+int\n+lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi,\n+\t\t struct lws_tokens *ebuf);\n+int\n+lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used,\n+\t\t\t int buffered);\n+\n+\n+char *\n+lws_generate_client_ws_handshake(struct lws *wsi, char *p);\n+int\n+lws_client_ws_upgrade(struct lws *wsi, const char **cce);\n+int\n+lws_create_client_ws_object(struct lws_client_connect_info *i, struct lws *wsi);\n+int\n+lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len);\n+int\n+lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn);\n+int\n+lws_tls_server_conn_alpn(struct lws *wsi);\n+\n+int\n+lws_ws_client_rx_sm_block(struct lws *wsi, unsigned char **buf, size_t len);\n+void\n+lws_destroy_event_pipe(struct lws *wsi);\n+void\n+lws_context_destroy2(struct lws_context *context);\n+\n+#ifdef __cplusplus\n+};\n+#endif\ndiff --git a/lib/core/service.c b/lib/core/service.c\nnew file mode 100644\nindex 0000000..6523058\n--- /dev/null\n+++ b/lib/core/service.c\n@@ -0,0 +1,987 @@\n+/*\n+ * libwebsockets - small server side websockets and web server implementation\n+ *\n+ * Copyright (C) 2010-2018 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation:\n+ * version 2.1 of the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public\n+ * License along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n+ * MA 02110-1301 USA\n+ */\n+\n+#include \u0022core/private.h\u0022\n+\n+int\n+lws_callback_as_writeable(struct lws *wsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tint n, m;\n+\n+\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_WRITEABLE_CB, 1);\n+#if defined(LWS_WITH_STATS)\n+\tif (wsi-\u003eactive_writable_req_us) {\n+\t\tuint64_t ul \u003d time_in_microseconds() -\n+\t\t\t wsi-\u003eactive_writable_req_us;\n+\n+\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt,\n+\t\t\t\t LWSSTATS_MS_WRITABLE_DELAY, ul);\n+\t\tlws_stats_atomic_max(wsi-\u003econtext, pt,\n+\t\t\t\t LWSSTATS_MS_WORST_WRITABLE_DELAY, ul);\n+\t\twsi-\u003eactive_writable_req_us \u003d 0;\n+\t}\n+#endif\n+\n+\tn \u003d wsi-\u003erole_ops-\u003ewriteable_cb[lwsi_role_server(wsi)];\n+\n+\tm \u003d user_callback_handle_rxflow(wsi-\u003eprotocol-\u003ecallback,\n+\t\t\t\t\twsi, (enum lws_callback_reasons) n,\n+\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n+\n+\treturn m;\n+}\n+\n+LWS_VISIBLE int\n+lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)\n+{\n+\tvolatile struct lws *vwsi \u003d (volatile struct lws *)wsi;\n+\tint n;\n+\n+\t//lwsl_notice(\u0022%s: %p\u005cn\u0022, __func__, wsi);\n+\n+\tvwsi-\u003eleave_pollout_active \u003d 0;\n+\tvwsi-\u003ehandling_pollout \u003d 1;\n+\t/*\n+\t * if another thread wants POLLOUT on us, from here on while\n+\t * handling_pollout is set, he will only set leave_pollout_active.\n+\t * If we are going to disable POLLOUT, we will check that first.\n+\t */\n+\twsi-\u003ecould_have_pending \u003d 0; /* clear back-to-back write detection */\n+\n+\t/*\n+\t * user callback is lowest priority to get these notifications\n+\t * actually, since other pending things cannot be disordered\n+\t *\n+\t * Priority 1: pending truncated sends are incomplete ws fragments\n+\t *\t If anything else sent first the protocol would be\n+\t *\t corrupted.\n+\t */\n+\n+\tif (wsi-\u003etrunc_len) {\n+\t\t//lwsl_notice(\u0022%s: completing partial\u005cn\u0022, __func__);\n+\t\tif (lws_issue_raw(wsi, wsi-\u003etrunc_alloc + wsi-\u003etrunc_offset,\n+\t\t\t\t wsi-\u003etrunc_len) \u003c 0) {\n+\t\t\tlwsl_info(\u0022%s signalling to close\u005cn\u0022, __func__);\n+\t\t\tgoto bail_die;\n+\t\t}\n+\t\t/* leave POLLOUT active either way */\n+\t\tgoto bail_ok;\n+\t} else\n+\t\tif (lwsi_state(wsi) \u003d\u003d LRS_FLUSHING_BEFORE_CLOSE) {\n+\t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\t\tgoto bail_die; /* retry closing now */\n+\t\t}\n+\n+#ifdef LWS_WITH_CGI\n+\t/*\n+\t * A cgi master's wire protocol remains h1 or h2. He is just getting\n+\t * his data from his child cgis.\n+\t */\n+\tif (wsi-\u003ehttp.cgi) {\n+\t\t/* also one shot */\n+\t\tif (pollfd)\n+\t\t\tif (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {\n+\t\t\t\tlwsl_info(\u0022failed at set pollfd\u005cn\u0022);\n+\t\t\t\treturn 1;\n+\t\t\t}\n+\t\tgoto user_service_go_again;\n+\t}\n+#endif\n+\n+\t/* if we got here, we should have wire protocol ops set on the wsi */\n+\tassert(wsi-\u003erole_ops);\n+\n+\tif (!wsi-\u003erole_ops-\u003ehandle_POLLOUT)\n+\t\tgoto bail_ok;\n+\n+\tswitch ((wsi-\u003erole_ops-\u003ehandle_POLLOUT)(wsi)) {\n+\tcase LWS_HP_RET_BAIL_OK:\n+\t\tgoto bail_ok;\n+\tcase LWS_HP_RET_BAIL_DIE:\n+\t\tgoto bail_die;\n+\tcase LWS_HP_RET_USER_SERVICE:\n+\t\tbreak;\n+\tdefault:\n+\t\tassert(0);\n+\t}\n+\n+\t/* one shot */\n+\n+\tif (wsi-\u003eparent_carries_io) {\n+\t\tvwsi-\u003ehandling_pollout \u003d 0;\n+\t\tvwsi-\u003eleave_pollout_active \u003d 0;\n+\n+\t\treturn lws_callback_as_writeable(wsi);\n+\t}\n+\n+\tif (pollfd) {\n+\t\tint eff \u003d vwsi-\u003eleave_pollout_active;\n+\n+\t\tif (!eff) {\n+\t\t\tif (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {\n+\t\t\t\tlwsl_info(\u0022failed at set pollfd\u005cn\u0022);\n+\t\t\t\tgoto bail_die;\n+\t\t\t}\n+\t\t}\n+\n+\t\tvwsi-\u003ehandling_pollout \u003d 0;\n+\n+\t\t/* cannot get leave_pollout_active set after the above */\n+\t\tif (!eff \u0026\u0026 wsi-\u003eleave_pollout_active) {\n+\t\t\t/*\n+\t\t\t * got set inbetween sampling eff and clearing\n+\t\t\t * handling_pollout, force POLLOUT on\n+\t\t\t */\n+\t\t\tlwsl_debug(\u0022leave_pollout_active\u005cn\u0022);\n+\t\t\tif (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {\n+\t\t\t\tlwsl_info(\u0022failed at set pollfd\u005cn\u0022);\n+\t\t\t\tgoto bail_die;\n+\t\t\t}\n+\t\t}\n+\n+\t\tvwsi-\u003eleave_pollout_active \u003d 0;\n+\t}\n+\n+\tif (lwsi_role_client(wsi) \u0026\u0026\n+\t !wsi-\u003ehdr_parsing_completed \u0026\u0026\n+\t lwsi_state(wsi) !\u003d LRS_H2_WAITING_TO_SEND_HEADERS \u0026\u0026\n+\t lwsi_state(wsi) !\u003d LRS_ISSUE_HTTP_BODY\n+\t )\n+\t\tgoto bail_ok;\n+\n+\n+#ifdef LWS_WITH_CGI\n+user_service_go_again:\n+#endif\n+\n+\tif (wsi-\u003erole_ops-\u003eperform_user_POLLOUT) {\n+\t\tif (wsi-\u003erole_ops-\u003eperform_user_POLLOUT(wsi) \u003d\u003d -1)\n+\t\t\tgoto bail_die;\n+\t\telse\n+\t\t\tgoto bail_ok;\n+\t}\n+\t\n+\tlwsl_debug(\u0022%s: %p: non mux: wsistate 0x%x, ops %s\u005cn\u0022, __func__, wsi,\n+\t\t wsi-\u003ewsistate, wsi-\u003erole_ops-\u003ename);\n+\n+\tvwsi \u003d (volatile struct lws *)wsi;\n+\tvwsi-\u003eleave_pollout_active \u003d 0;\n+\n+\tn \u003d lws_callback_as_writeable(wsi);\n+\tvwsi-\u003ehandling_pollout \u003d 0;\n+\n+\tif (vwsi-\u003eleave_pollout_active)\n+\t\tlws_change_pollfd(wsi, 0, LWS_POLLOUT);\n+\n+\treturn n;\n+\n+\t/*\n+\t * since these don't disable the POLLOUT, they are always doing the\n+\t * right thing for leave_pollout_active whether it was set or not.\n+\t */\n+\n+bail_ok:\n+\tvwsi-\u003ehandling_pollout \u003d 0;\n+\tvwsi-\u003eleave_pollout_active \u003d 0;\n+\n+\treturn 0;\n+\n+bail_die:\n+\tvwsi-\u003ehandling_pollout \u003d 0;\n+\tvwsi-\u003eleave_pollout_active \u003d 0;\n+\n+\treturn -1;\n+}\n+\n+static int\n+__lws_service_timeout_check(struct lws *wsi, time_t sec)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tint n \u003d 0;\n+\n+\t(void)n;\n+\n+\t/*\n+\t * if we went beyond the allowed time, kill the\n+\t * connection\n+\t */\n+\tif (wsi-\u003edll_timeout.prev \u0026\u0026\n+\t lws_compare_time_t(wsi-\u003econtext, sec, wsi-\u003epending_timeout_set) \u003e\n+\t\t\t wsi-\u003epending_timeout_limit) {\n+\n+\t\tif (wsi-\u003edesc.sockfd !\u003d LWS_SOCK_INVALID \u0026\u0026\n+\t\t wsi-\u003eposition_in_fds_table \u003e\u003d 0)\n+\t\t\tn \u003d pt-\u003efds[wsi-\u003eposition_in_fds_table].events;\n+\n+\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_TIMEOUTS, 1);\n+\n+\t\t/* no need to log normal idle keepalive timeout */\n+\t\tif (wsi-\u003epending_timeout !\u003d PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE)\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\t\t\tlwsl_info(\u0022wsi %p: TIMEDOUT WAITING on %d \u0022\n+\t\t\t\t \u0022(did hdr %d, ah %p, wl %d, pfd \u0022\n+\t\t\t\t \u0022events %d) %llu vs %llu\u005cn\u0022,\n+\t\t\t\t (void *)wsi, wsi-\u003epending_timeout,\n+\t\t\t\t wsi-\u003ehdr_parsing_completed, wsi-\u003ehttp.ah,\n+\t\t\t\t pt-\u003ehttp.ah_wait_list_length, n,\n+\t\t\t\t (unsigned long long)sec,\n+\t\t\t\t (unsigned long long)wsi-\u003epending_timeout_limit);\n+#if defined(LWS_WITH_CGI)\n+\t\tif (wsi-\u003ehttp.cgi)\n+\t\t\tlwsl_notice(\u0022CGI timeout: %s\u005cn\u0022, wsi-\u003ehttp.cgi-\u003esummary);\n+#endif\n+#else\n+\t\tlwsl_info(\u0022wsi %p: TIMEDOUT WAITING on %d \u0022, (void *)wsi,\n+\t\t\t wsi-\u003epending_timeout);\n+#endif\n+\n+\t\t/*\n+\t\t * Since he failed a timeout, he already had a chance to do\n+\t\t * something and was unable to... that includes situations like\n+\t\t * half closed connections. So process this \u0022failed timeout\u0022\n+\t\t * close as a violent death and don't try to do protocol\n+\t\t * cleanup like flush partials.\n+\t\t */\n+\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\tif (lwsi_state(wsi) \u003d\u003d LRS_WAITING_SSL \u0026\u0026 wsi-\u003eprotocol)\n+\t\t\twsi-\u003eprotocol-\u003ecallback(wsi,\n+\t\t\t\tLWS_CALLBACK_CLIENT_CONNECTION_ERROR,\n+\t\t\t\twsi-\u003euser_space,\n+\t\t\t\t(void *)\u0022Timed out waiting SSL\u0022, 21);\n+\n+\t\t__lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, \u0022timeout\u0022);\n+\n+\t\treturn 1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tuint8_t *buffered;\n+\tsize_t blen;\n+\tint ret \u003d 0, m;\n+\n+\t/* his RX is flowcontrolled, don't send remaining now */\n+\tblen \u003d lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist, \u0026buffered);\n+\tif (blen) {\n+\t\tif (buf \u003e\u003d buffered \u0026\u0026 buf + len \u003c\u003d buffered + blen) {\n+\t\t\t/* rxflow while we were spilling prev rxflow */\n+\t\t\tlwsl_info(\u0022%s: staying in rxflow buf\u005cn\u0022, __func__);\n+\n+\t\t\treturn 1;\n+\t\t}\n+\t\tret \u003d 1;\n+\t}\n+\n+\t/* a new rxflow, buffer it and warn caller */\n+\n+\tm \u003d lws_buflist_append_segment(\u0026wsi-\u003ebuflist, buf + n, len - n);\n+\n+\tif (m \u003c 0)\n+\t\treturn -1;\n+\tif (m) {\n+\t\tlwsl_debug(\u0022%s: added %p to rxflow list\u005cn\u0022, __func__, wsi);\n+\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_buflist, \u0026pt-\u003edll_head_buflist);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/* this is used by the platform service code to stop us waiting for network\n+ * activity in poll() when we have something that already needs service\n+ */\n+\n+LWS_VISIBLE LWS_EXTERN int\n+lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n+\n+\t/* Figure out if we really want to wait in poll()\n+\t * We only need to wait if really nothing already to do and we have\n+\t * to wait for something from network\n+\t */\n+#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n+\t/* 1) if we know we are draining rx ext, do not wait in poll */\n+\tif (pt-\u003ews.rx_draining_ext_list)\n+\t\treturn 0;\n+#endif\n+\n+\t/* 2) if we know we have non-network pending data, do not wait in poll */\n+\n+\tif (pt-\u003econtext-\u003etls_ops \u0026\u0026\n+\t pt-\u003econtext-\u003etls_ops-\u003efake_POLLIN_for_buffered)\n+\t\tif (pt-\u003econtext-\u003etls_ops-\u003efake_POLLIN_for_buffered(pt))\n+\t\t\treturn 0;\n+\n+\t/* 3) If there is any wsi with rxflow buffered and in a state to process\n+\t * it, we should not wait in poll\n+\t */\n+\n+\tlws_start_foreach_dll(struct lws_dll_lws *, d, pt-\u003edll_head_buflist.next) {\n+\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_buflist);\n+\n+\t\tif (lwsi_state(wsi) !\u003d LRS_DEFERRING_ACTION)\n+\t\t\treturn 0;\n+\n+\t} lws_end_foreach_dll(d);\n+\n+\treturn timeout_ms;\n+}\n+\n+/*\n+ * POLLIN said there is something... we must read it, and either use it; or\n+ * if other material already in the buflist append it and return the buflist\n+ * head material.\n+ */\n+int\n+lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi,\n+\t\t struct lws_tokens *ebuf)\n+{\n+\tint n, prior \u003d (int)lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist, NULL);\n+\n+\tebuf-\u003etoken \u003d (char *)pt-\u003eserv_buf;\n+\tebuf-\u003elen \u003d lws_ssl_capable_read(wsi, pt-\u003eserv_buf,\n+\t\t\t\t\t wsi-\u003econtext-\u003ept_serv_buf_size);\n+\n+\tif (ebuf-\u003elen \u003d\u003d LWS_SSL_CAPABLE_MORE_SERVICE \u0026\u0026 prior)\n+\t\tgoto get_from_buflist;\n+\n+\tif (ebuf-\u003elen \u003c\u003d 0)\n+\t\treturn 0;\n+\n+\t/* nothing in buflist already? Then just use what we read */\n+\n+\tif (!prior)\n+\t\treturn 0;\n+\n+\t/* stash what we read */\n+\n+\tn \u003d lws_buflist_append_segment(\u0026wsi-\u003ebuflist, (uint8_t *)ebuf-\u003etoken,\n+\t\t\t\t ebuf-\u003elen);\n+\tif (n \u003c 0)\n+\t\treturn -1;\n+\tif (n) {\n+\t\tlwsl_debug(\u0022%s: added %p to rxflow list\u005cn\u0022, __func__, wsi);\n+\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_buflist, \u0026pt-\u003edll_head_buflist);\n+\t}\n+\n+\t/* get the first buflist guy in line */\n+\n+get_from_buflist:\n+\n+\tebuf-\u003elen \u003d (int)lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist,\n+\t\t\t\t\t\t (uint8_t **)\u0026ebuf-\u003etoken);\n+\n+\treturn 1; /* came from buflist */\n+}\n+\n+int\n+lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used,\n+\t\t\t int buffered)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tint m;\n+\n+\t/* it's in the buflist; we didn't use any */\n+\n+\tif (!used \u0026\u0026 buffered)\n+\t\treturn 0;\n+\n+\tif (used \u0026\u0026 buffered) {\n+\t\tm \u003d lws_buflist_use_segment(\u0026wsi-\u003ebuflist, used);\n+\t\tlwsl_info(\u0022%s: draining rxflow: used %d, next %d\u005cn\u0022,\n+\t\t\t __func__, used, m);\n+\t\tif (m)\n+\t\t\treturn 0;\n+\n+\t\tlwsl_info(\u0022%s: removed %p from dll_buflist\u005cn\u0022, __func__, wsi);\n+\t\tlws_dll_lws_remove(\u0026wsi-\u003edll_buflist);\n+\n+\t\treturn 0;\n+\t}\n+\n+\t/* any remainder goes on the buflist */\n+\n+\tif (used !\u003d ebuf-\u003elen) {\n+\t\tm \u003d lws_buflist_append_segment(\u0026wsi-\u003ebuflist,\n+\t\t\t\t\t (uint8_t *)ebuf-\u003etoken + used,\n+\t\t\t\t\t ebuf-\u003elen - used);\n+\t\tif (m \u003c 0)\n+\t\t\treturn 1; /* OOM */\n+\t\tif (m) {\n+\t\t\tlwsl_debug(\u0022%s: added %p to rxflow list\u005cn\u0022, __func__, wsi);\n+\t\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_buflist, \u0026pt-\u003edll_head_buflist);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt)\n+{\n+\tstruct lws_pollfd pfd;\n+\n+\tif (!pt-\u003edll_head_buflist.next)\n+\t\treturn;\n+\n+\t/*\n+\t * service all guys with pending rxflow that reached a state they can\n+\t * accept the pending data\n+\t */\n+\n+\tlws_pt_lock(pt, __func__);\n+\n+\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n+\t\t\t\t pt-\u003edll_head_buflist.next) {\n+\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_buflist);\n+\n+\t\tpfd.events \u003d LWS_POLLIN;\n+\t\tpfd.revents \u003d LWS_POLLIN;\n+\t\tpfd.fd \u003d -1;\n+\n+\t\tlwsl_debug(\u0022%s: rxflow processing: %p 0x%x\u005cn\u0022, __func__, wsi,\n+\t\t\t wsi-\u003ewsistate);\n+\n+\t\tif (!lws_is_flowcontrolled(wsi) \u0026\u0026\n+\t\t lwsi_state(wsi) !\u003d LRS_DEFERRING_ACTION \u0026\u0026\n+\t\t (wsi-\u003erole_ops-\u003ehandle_POLLIN)(pt, wsi, \u0026pfd) \u003d\u003d\n+\t\t\t\t\t\t LWS_HPI_RET_PLEASE_CLOSE_ME)\n+\t\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n+\t\t\t\t\t \u0022close_and_handled\u0022);\n+\n+\t} lws_end_foreach_dll_safe(d, d1);\n+\n+\tlws_pt_unlock(pt);\n+}\n+\n+/*\n+ * guys that need POLLIN service again without waiting for network action\n+ * can force POLLIN here if not flowcontrolled, so they will get service.\n+ *\n+ * Return nonzero if anybody got their POLLIN faked\n+ */\n+int\n+lws_service_flag_pending(struct lws_context *context, int tsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n+\n+#if defined(LWS_WITH_TLS)\n+\tstruct lws *wsi, *wsi_next;\n+#endif\n+\tint forced \u003d 0;\n+\n+\tlws_pt_lock(pt, __func__);\n+\n+\t/*\n+\t * 1) If there is any wsi with a buflist and in a state to process\n+\t * it, we should not wait in poll\n+\t */\n+\n+\tlws_start_foreach_dll(struct lws_dll_lws *, d, pt-\u003edll_head_buflist.next) {\n+\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_buflist);\n+\n+\t\tif (lwsi_state(wsi) !\u003d LRS_DEFERRING_ACTION) {\n+\t\t\tforced \u003d 1;\n+\t\t\tbreak;\n+\t\t}\n+\t} lws_end_foreach_dll(d);\n+\n+#if defined(LWS_ROLE_WS)\n+\tforced |\u003d role_ops_ws.service_flag_pending(context, tsi);\n+#endif\n+\n+#if defined(LWS_WITH_TLS)\n+\t/*\n+\t * 2) For all guys with buffered SSL read data already saved up, if they\n+\t * are not flowcontrolled, fake their POLLIN status so they'll get\n+\t * service to use up the buffered incoming data, even though their\n+\t * network socket may have nothing\n+\t */\n+\twsi \u003d pt-\u003etls.pending_read_list;\n+\twhile (wsi) {\n+\t\twsi_next \u003d wsi-\u003etls.pending_read_list_next;\n+\t\tpt-\u003efds[wsi-\u003eposition_in_fds_table].revents |\u003d\n+\t\t\tpt-\u003efds[wsi-\u003eposition_in_fds_table].events \u0026 LWS_POLLIN;\n+\t\tif (pt-\u003efds[wsi-\u003eposition_in_fds_table].revents \u0026 LWS_POLLIN) {\n+\t\t\tforced \u003d 1;\n+\t\t\t/*\n+\t\t\t * he's going to get serviced now, take him off the\n+\t\t\t * list of guys with buffered SSL. If he still has some\n+\t\t\t * at the end of the service, he'll get put back on the\n+\t\t\t * list then.\n+\t\t\t */\n+\t\t\t__lws_ssl_remove_wsi_from_buffered_list(wsi);\n+\t\t}\n+\n+\t\twsi \u003d wsi_next;\n+\t}\n+#endif\n+\n+\tlws_pt_unlock(pt);\n+\n+\treturn forced;\n+}\n+\n+static int\n+lws_service_periodic_checks(struct lws_context *context,\n+\t\t\t struct lws_pollfd *pollfd, int tsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n+\tlws_sockfd_type our_fd \u003d 0, tmp_fd;\n+\tstruct lws *wsi;\n+\tint timed_out \u003d 0;\n+\ttime_t now;\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\tstruct allocated_headers *ah;\n+\tint m;\n+#endif\n+\n+\tif (!context-\u003eprotocol_init_done)\n+\t\tif (lws_protocol_init(context))\n+\t\t\treturn -1;\n+\n+\ttime(\u0026now);\n+\n+\t/*\n+\t * handle case that system time was uninitialized when lws started\n+\t * at boot, and got initialized a little later\n+\t */\n+\tif (context-\u003etime_up \u003c 1464083026 \u0026\u0026 now \u003e 1464083026)\n+\t\tcontext-\u003etime_up \u003d now;\n+\n+\tif (context-\u003elast_timeout_check_s \u0026\u0026\n+\t now - context-\u003elast_timeout_check_s \u003e 100) {\n+\t\t/*\n+\t\t * There has been a discontiguity. Any stored time that is\n+\t\t * less than context-\u003etime_discontiguity should have context-\u003e\n+\t\t * time_fixup added to it.\n+\t\t *\n+\t\t * Some platforms with no RTC will experience this as a normal\n+\t\t * event when ntp sets their clock, but we can have started\n+\t\t * long before that with a 0-based unix time.\n+\t\t */\n+\n+\t\tcontext-\u003etime_discontiguity \u003d now;\n+\t\tcontext-\u003etime_fixup \u003d now - context-\u003elast_timeout_check_s;\n+\n+\t\tlwsl_notice(\u0022time discontiguity: at old time %llus, \u0022\n+\t\t\t \u0022new time %llus: +%llus\u005cn\u0022,\n+\t\t\t (unsigned long long)context-\u003elast_timeout_check_s,\n+\t\t\t (unsigned long long)context-\u003etime_discontiguity,\n+\t\t\t (unsigned long long)context-\u003etime_fixup);\n+\n+\t\tcontext-\u003elast_timeout_check_s \u003d now - 1;\n+\t}\n+\n+\tif (!lws_compare_time_t(context, context-\u003elast_timeout_check_s, now))\n+\t\treturn 0;\n+\n+\tcontext-\u003elast_timeout_check_s \u003d now;\n+\n+#if defined(LWS_WITH_STATS)\n+\tif (!tsi \u0026\u0026 now - context-\u003elast_dump \u003e 10) {\n+\t\tlws_stats_log_dump(context);\n+\t\tcontext-\u003elast_dump \u003d now;\n+\t}\n+#endif\n+\n+\tlws_plat_service_periodic(context);\n+\tlws_check_deferred_free(context, 0);\n+\n+#if defined(LWS_WITH_PEER_LIMITS)\n+\tlws_peer_cull_peer_wait_list(context);\n+#endif\n+\n+\t/* retire unused deprecated context */\n+#if !defined(LWS_PLAT_OPTEE) \u0026\u0026 !defined(LWS_WITH_ESP32)\n+#if !defined(_WIN32)\n+\tif (context-\u003edeprecated \u0026\u0026 !context-\u003ecount_wsi_allocated) {\n+\t\tlwsl_notice(\u0022%s: ending deprecated context\u005cn\u0022, __func__);\n+\t\tkill(getpid(), SIGINT);\n+\t\treturn 0;\n+\t}\n+#endif\n+#endif\n+\t/* global timeout check once per second */\n+\n+\tif (pollfd)\n+\t\tour_fd \u003d pollfd-\u003efd;\n+\n+\t/*\n+\t * Phase 1: check every wsi on the timeout check list\n+\t */\n+\n+\tlws_pt_lock(pt, __func__);\n+\n+\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n+\t\t\t\t context-\u003ept[tsi].dll_head_timeout.next) {\n+\t\twsi \u003d lws_container_of(d, struct lws, dll_timeout);\n+\t\ttmp_fd \u003d wsi-\u003edesc.sockfd;\n+\t\tif (__lws_service_timeout_check(wsi, now)) {\n+\t\t\t/* he did time out... */\n+\t\t\tif (tmp_fd \u003d\u003d our_fd)\n+\t\t\t\t/* it was the guy we came to service! */\n+\t\t\t\ttimed_out \u003d 1;\n+\t\t\t/* he's gone, no need to mark as handled */\n+\t\t}\n+\t} lws_end_foreach_dll_safe(d, d1);\n+\n+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n+\t/*\n+\t * Phase 2: double-check active ah timeouts independent of wsi\n+\t *\t timeout status\n+\t */\n+\n+\tah \u003d pt-\u003ehttp.ah_list;\n+\twhile (ah) {\n+\t\tint len;\n+\t\tchar buf[256];\n+\t\tconst unsigned char *c;\n+\n+\t\tif (!ah-\u003ein_use || !ah-\u003ewsi || !ah-\u003eassigned ||\n+\t\t (ah-\u003ewsi-\u003evhost \u0026\u0026\n+\t\t lws_compare_time_t(context, now, ah-\u003eassigned) \u003c\n+\t\t ah-\u003ewsi-\u003evhost-\u003etimeout_secs_ah_idle + 360)) {\n+\t\t\tah \u003d ah-\u003enext;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/*\n+\t\t * a single ah session somehow got held for\n+\t\t * an unreasonable amount of time.\n+\t\t *\n+\t\t * Dump info on the connection...\n+\t\t */\n+\t\twsi \u003d ah-\u003ewsi;\n+\t\tbuf[0] \u003d '\u005c0';\n+#if !defined(LWS_PLAT_OPTEE)\n+\t\tlws_get_peer_simple(wsi, buf, sizeof(buf));\n+#else\n+\t\tbuf[0] \u003d '\u005c0';\n+#endif\n+\t\tlwsl_notice(\u0022ah excessive hold: wsi %p\u005cn\u0022\n+\t\t\t \u0022 peer address: %s\u005cn\u0022\n+\t\t\t \u0022 ah pos %u\u005cn\u0022,\n+\t\t\t wsi, buf, ah-\u003epos);\n+\t\tbuf[0] \u003d '\u005c0';\n+\t\tm \u003d 0;\n+\t\tdo {\n+\t\t\tc \u003d lws_token_to_string(m);\n+\t\t\tif (!c)\n+\t\t\t\tbreak;\n+\t\t\tif (!(*c))\n+\t\t\t\tbreak;\n+\n+\t\t\tlen \u003d lws_hdr_total_length(wsi, m);\n+\t\t\tif (!len || len \u003e (int)sizeof(buf) - 1) {\n+\t\t\t\tm++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif (lws_hdr_copy(wsi, buf,\n+\t\t\t\t\t sizeof buf, m) \u003e 0) {\n+\t\t\t\tbuf[sizeof(buf) - 1] \u003d '\u005c0';\n+\n+\t\t\t\tlwsl_notice(\u0022 %s \u003d %s\u005cn\u0022,\n+\t\t\t\t\t (const char *)c, buf);\n+\t\t\t}\n+\t\t\tm++;\n+\t\t} while (1);\n+\n+\t\t/* explicitly detach the ah */\n+\t\tlws_header_table_detach(wsi, 0);\n+\n+\t\t/* ... and then drop the connection */\n+\n+\t\tm \u003d 0;\n+\t\tif (wsi-\u003edesc.sockfd \u003d\u003d our_fd) {\n+\t\t\tm \u003d timed_out;\n+\n+\t\t\t/* it was the guy we came to service! */\n+\t\t\ttimed_out \u003d 1;\n+\t\t}\n+\n+\t\tif (!m) /* if he didn't already timeout */\n+\t\t\t__lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n+\t\t\t\t\t \u0022excessive ah\u0022);\n+\n+\t\tah \u003d pt-\u003ehttp.ah_list;\n+\t}\n+#endif\n+\tlws_pt_unlock(pt);\n+\n+#if 0\n+\t{\n+\t\tchar s[300], *p \u003d s;\n+\n+\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++)\n+\t\t\tp +\u003d sprintf(p, \u0022 %7lu (%5d), \u0022,\n+\t\t\t\t context-\u003ept[n].count_conns,\n+\t\t\t\t context-\u003ept[n].fds_count);\n+\n+\t\tlwsl_notice(\u0022load: %s\u005cn\u0022, s);\n+\t}\n+#endif\n+\t/*\n+\t * Phase 3: vhost / protocol timer callbacks\n+\t */\n+\n+\twsi \u003d NULL;\n+\tlws_start_foreach_ll(struct lws_vhost *, v, context-\u003evhost_list) {\n+\t\tstruct lws_timed_vh_protocol *nx;\n+\t\tif (v-\u003etimed_vh_protocol_list) {\n+\t\t\tlws_start_foreach_ll(struct lws_timed_vh_protocol *,\n+\t\t\t\t\tq, v-\u003etimed_vh_protocol_list) {\n+\t\t\t\tif (now \u003e\u003d q-\u003etime) {\n+\t\t\t\t\tif (!wsi)\n+\t\t\t\t\t\twsi \u003d lws_zalloc(sizeof(*wsi), \u0022cbwsi\u0022);\n+\t\t\t\t\twsi-\u003econtext \u003d context;\n+\t\t\t\t\twsi-\u003evhost \u003d v;\n+\t\t\t\t\twsi-\u003eprotocol \u003d q-\u003eprotocol;\n+\t\t\t\t\tlwsl_debug(\u0022timed cb: vh %s, protocol %s, reason %d\u005cn\u0022, v-\u003ename, q-\u003eprotocol-\u003ename, q-\u003ereason);\n+\t\t\t\t\tq-\u003eprotocol-\u003ecallback(wsi, q-\u003ereason, NULL, NULL, 0);\n+\t\t\t\t\tnx \u003d q-\u003enext;\n+\t\t\t\t\tlws_timed_callback_remove(v, q);\n+\t\t\t\t\tq \u003d nx;\n+\t\t\t\t\tcontinue; /* we pointed ourselves to the next from the now-deleted guy */\n+\t\t\t\t}\n+\t\t\t} lws_end_foreach_ll(q, next);\n+\t\t}\n+\t} lws_end_foreach_ll(v, vhost_next);\n+\tif (wsi)\n+\t\tlws_free(wsi);\n+\n+\t/*\n+\t * Phase 4: check for unconfigured vhosts due to required\n+\t *\t interface missing before\n+\t */\n+\n+\tlws_context_lock(context);\n+\tlws_start_foreach_llp(struct lws_vhost **, pv,\n+\t\t\t context-\u003eno_listener_vhost_list) {\n+\t\tstruct lws_vhost *v \u003d *pv;\n+\t\tlwsl_debug(\u0022deferred iface: checking if on vh %s\u005cn\u0022, (*pv)-\u003ename);\n+\t\tif (_lws_vhost_init_server(NULL, *pv) \u003d\u003d 0) {\n+\t\t\t/* became happy */\n+\t\t\tlwsl_notice(\u0022vh %s: became connected\u005cn\u0022, v-\u003ename);\n+\t\t\t*pv \u003d v-\u003eno_listener_vhost_list;\n+\t\t\tv-\u003eno_listener_vhost_list \u003d NULL;\n+\t\t\tbreak;\n+\t\t}\n+\t} lws_end_foreach_llp(pv, no_listener_vhost_list);\n+\tlws_context_unlock(context);\n+\n+\t/*\n+\t * Phase 5: role periodic checks\n+\t */\n+#if defined(LWS_ROLE_WS)\n+\trole_ops_ws.periodic_checks(context, tsi, now);\n+#endif\n+#if defined(LWS_ROLE_CGI)\n+\trole_ops_cgi.periodic_checks(context, tsi, now);\n+#endif\n+\n+\t/*\n+\t * Phase 6: check the remaining cert lifetime daily\n+\t */\n+\n+\tif (context-\u003etls_ops \u0026\u0026\n+\t context-\u003etls_ops-\u003eperiodic_housekeeping)\n+\t\tcontext-\u003etls_ops-\u003eperiodic_housekeeping(context, now);\n+\n+\treturn timed_out;\n+}\n+\n+LWS_VISIBLE int\n+lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,\n+\t\t int tsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n+\tstruct lws *wsi;\n+\n+\tif (!context || context-\u003ebeing_destroyed1)\n+\t\treturn -1;\n+\n+\t/* the socket we came to service timed out, nothing to do */\n+\tif (lws_service_periodic_checks(context, pollfd, tsi) || !pollfd)\n+\t\treturn 0;\n+\n+\t/* no, here to service a socket descriptor */\n+\twsi \u003d wsi_from_fd(context, pollfd-\u003efd);\n+\tif (!wsi)\n+\t\t/* not lws connection ... leave revents alone and return */\n+\t\treturn 0;\n+\n+\t/*\n+\t * so that caller can tell we handled, past here we need to\n+\t * zero down pollfd-\u003erevents after handling\n+\t */\n+\n+\t/* handle session socket closed */\n+\n+\tif ((!(pollfd-\u003erevents \u0026 pollfd-\u003eevents \u0026 LWS_POLLIN)) \u0026\u0026\n+\t (pollfd-\u003erevents \u0026 LWS_POLLHUP)) {\n+\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\tlwsl_debug(\u0022Session Socket %p (fd\u003d%d) dead\u005cn\u0022,\n+\t\t\t (void *)wsi, pollfd-\u003efd);\n+\n+\t\tgoto close_and_handled;\n+\t}\n+\n+#ifdef _WIN32\n+\tif (pollfd-\u003erevents \u0026 LWS_POLLOUT)\n+\t\twsi-\u003esock_send_blocking \u003d FALSE;\n+#endif\n+\n+\tif ((!(pollfd-\u003erevents \u0026 pollfd-\u003eevents \u0026 LWS_POLLIN)) \u0026\u0026\n+\t (pollfd-\u003erevents \u0026 LWS_POLLHUP)) {\n+\t\tlwsl_debug(\u0022pollhup\u005cn\u0022);\n+\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n+\t\tgoto close_and_handled;\n+\t}\n+\n+#if defined(LWS_WITH_TLS)\n+\tif (lwsi_state(wsi) \u003d\u003d LRS_SHUTDOWN \u0026\u0026\n+\t lws_is_ssl(wsi) \u0026\u0026 wsi-\u003etls.ssl) {\n+\t\tswitch (__lws_tls_shutdown(wsi)) {\n+\t\tcase LWS_SSL_CAPABLE_DONE:\n+\t\tcase LWS_SSL_CAPABLE_ERROR:\n+\t\t\tgoto close_and_handled;\n+\n+\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_READ:\n+\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_WRITE:\n+\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE:\n+\t\t\tgoto handled;\n+\t\t}\n+\t}\n+#endif\n+\twsi-\u003ecould_have_pending \u003d 0; /* clear back-to-back write detection */\n+\n+\t/* okay, what we came here to do... */\n+\n+\t/* if we got here, we should have wire protocol ops set on the wsi */\n+\tassert(wsi-\u003erole_ops);\n+\n+\t// lwsl_notice(\u0022%s: %s: wsistate 0x%x\u005cn\u0022, __func__, wsi-\u003erole_ops-\u003ename,\n+\t//\t wsi-\u003ewsistate);\n+\n+\tswitch ((wsi-\u003erole_ops-\u003ehandle_POLLIN)(pt, wsi, pollfd)) {\n+\tcase LWS_HPI_RET_WSI_ALREADY_DIED:\n+\t\treturn 1;\n+\tcase LWS_HPI_RET_HANDLED:\n+\t\tbreak;\n+\tcase LWS_HPI_RET_PLEASE_CLOSE_ME:\n+close_and_handled:\n+\t\tlwsl_debug(\u0022%p: Close and handled\u005cn\u0022, wsi);\n+\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n+\t\t\t\t \u0022close_and_handled\u0022);\n+#if defined(_DEBUG) \u0026\u0026 defined(LWS_WITH_LIBUV)\n+\t\t/*\n+\t\t * confirm close has no problem being called again while\n+\t\t * it waits for libuv service to complete the first async\n+\t\t * close\n+\t\t */\n+\t\tif (context-\u003eevent_loop_ops \u003d\u003d \u0026event_loop_ops_uv)\n+\t\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n+\t\t\t\t\t \u0022close_and_handled uv repeat test\u0022);\n+#endif\n+\t\t/*\n+\t\t * pollfd may point to something else after the close\n+\t\t * due to pollfd swapping scheme on delete on some platforms\n+\t\t * we can't clear revents now because it'd be the wrong guy's\n+\t\t * revents\n+\t\t */\n+\t\treturn 1;\n+\tdefault:\n+\t\tassert(0);\n+\t}\n+#if defined(LWS_WITH_TLS)\n+handled:\n+#endif\n+\tpollfd-\u003erevents \u003d 0;\n+\n+\tlws_pt_lock(pt, __func__);\n+\t__lws_hrtimer_service(pt);\n+\tlws_pt_unlock(pt);\n+\n+\treturn 0;\n+}\n+\n+LWS_VISIBLE int\n+lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd)\n+{\n+\treturn lws_service_fd_tsi(context, pollfd, 0);\n+}\n+\n+LWS_VISIBLE int\n+lws_service(struct lws_context *context, int timeout_ms)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n+\tint n;\n+\n+\tif (!context)\n+\t\treturn 1;\n+\n+\tpt-\u003einside_service \u003d 1;\n+\n+\tif (context-\u003eevent_loop_ops-\u003erun_pt) {\n+\t\t/* we are configured for an event loop */\n+\t\tcontext-\u003eevent_loop_ops-\u003erun_pt(context, 0);\n+\n+\t\tpt-\u003einside_service \u003d 0;\n+\n+\t\treturn 1;\n+\t}\n+\tn \u003d lws_plat_service(context, timeout_ms);\n+\n+\tpt-\u003einside_service \u003d 0;\n+\n+\treturn n;\n+}\n+\n+LWS_VISIBLE int\n+lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi)\n+{\n+\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n+\tint n;\n+\n+\tpt-\u003einside_service \u003d 1;\n+\n+\tif (context-\u003eevent_loop_ops-\u003erun_pt) {\n+\t\t/* we are configured for an event loop */\n+\t\tcontext-\u003eevent_loop_ops-\u003erun_pt(context, tsi);\n+\n+\t\tpt-\u003einside_service \u003d 0;\n+\n+\t\treturn 1;\n+\t}\n+\n+\tn \u003d _lws_plat_service_tsi(context, timeout_ms, tsi);\n+\n+\tpt-\u003einside_service \u003d 0;\n+\n+\treturn n;\n+}\ndiff --git a/lib/event-libs/libev/libev.c b/lib/event-libs/libev/libev.c\nindex d60072c..3a9853d 100644\n--- a/lib/event-libs/libev/libev.c\n+++ b/lib/event-libs/libev/libev.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static void\n lws_ev_hrtimer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)\ndiff --git a/lib/event-libs/libev/private.h b/lib/event-libs/libev/private.h\nindex 52de727..9359f34 100644\n--- a/lib/event-libs/libev/private.h\n+++ b/lib/event-libs/libev/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_WITH_LIBEV\n+ * This is included from core/private.h if LWS_WITH_LIBEV\n */\n \n #include \u003cev.h\u003e\ndiff --git a/lib/event-libs/libevent/libevent.c b/lib/event-libs/libevent/libevent.c\nindex 5cb4726..f4f5cfd 100644\n--- a/lib/event-libs/libevent/libevent.c\n+++ b/lib/event-libs/libevent/libevent.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static void\n lws_event_hrtimer_cb(int fd, short event, void *p)\ndiff --git a/lib/event-libs/libevent/private.h b/lib/event-libs/libevent/private.h\nindex 1c2d360..04fbbdf 100644\n--- a/lib/event-libs/libevent/private.h\n+++ b/lib/event-libs/libevent/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_WITH_LIBEVENT\n+ * This is included from core/private.h if LWS_WITH_LIBEVENT\n */\n \n #include \u003cevent2/event.h\u003e\ndiff --git a/lib/event-libs/libuv/libuv.c b/lib/event-libs/libuv/libuv.c\nindex ee948b6..b5c8b85 100644\n--- a/lib/event-libs/libuv/libuv.c\n+++ b/lib/event-libs/libuv/libuv.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static void\n lws_uv_hrtimer_cb(uv_timer_t *timer\n@@ -666,21 +666,18 @@ static int\n elops_init_vhost_listen_wsi_uv(struct lws *wsi)\n {\n \tstruct lws_context_per_thread *pt;\n-\tstruct lws_vhost *vh \u003d wsi-\u003evhost;\n \tint n;\n \n \tif (!wsi)\n-\t\twsi \u003d vh-\u003elserv_wsi;\n-\tif (!wsi)\n \t\treturn 0;\n \tif (wsi-\u003ew_read.context)\n \t\treturn 0;\n \n-\tpt \u003d \u0026vh-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n+\tpt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n \tif (!pt-\u003euv.io_loop)\n \t\treturn 0;\n \n-\twsi-\u003ew_read.context \u003d vh-\u003econtext;\n+\twsi-\u003ew_read.context \u003d wsi-\u003econtext;\n \tn \u003d uv_poll_init_socket(pt-\u003euv.io_loop,\n \t\t\t\t\u0026wsi-\u003ew_read.uv.watcher, wsi-\u003edesc.sockfd);\n \tif (n) {\ndiff --git a/lib/event-libs/libuv/private.h b/lib/event-libs/libuv/private.h\nindex cf8f710..58a2639 100644\n--- a/lib/event-libs/libuv/private.h\n+++ b/lib/event-libs/libuv/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_WITH_LIBUV\n+ * This is included from core/private.h if LWS_WITH_LIBUV\n */\n \n #include \u003cuv.h\u003e\ndiff --git a/lib/event-libs/poll/poll.c b/lib/event-libs/poll/poll.c\nindex ad6b29b..09af5b1 100644\n--- a/lib/event-libs/poll/poll.c\n+++ b/lib/event-libs/poll/poll.c\n@@ -18,10 +18,10 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_ROLE_WS\n+ * This is included from core/private.h if LWS_ROLE_WS\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n struct lws_event_loop_ops event_loop_ops_poll \u003d {\n \t/* name */\t\t\t\u0022poll\u0022,\ndiff --git a/lib/event-libs/private.h b/lib/event-libs/private.h\nindex 59705c9..c36d39c 100644\n--- a/lib/event-libs/private.h\n+++ b/lib/event-libs/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h\n+ * This is included from core/private.h\n */\n \n struct lws_event_loop_ops {\ndiff --git a/lib/libwebsockets.c b/lib/libwebsockets.c\ndeleted file mode 100644\nindex 28bb2fe..0000000\n--- a/lib/libwebsockets.c\n+++ /dev/null\n@@ -1,3428 +0,0 @@\n-/*\n- * libwebsockets - small server side websockets and web server implementation\n- *\n- * Copyright (C) 2010-2017 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This library is free software; you can redistribute it and/or\n- * modify it under the terms of the GNU Lesser General Public\n- * License as published by the Free Software Foundation:\n- * version 2.1 of the License.\n- *\n- * This library is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * Lesser General Public License for more details.\n- *\n- * You should have received a copy of the GNU Lesser General Public\n- * License along with this library; if not, write to the Free Software\n- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n- * MA 02110-1301 USA\n- */\n-\n-#include \u0022private-libwebsockets.h\u0022\n-\n-#ifdef LWS_HAVE_SYS_TYPES_H\n-#include \u003csys/types.h\u003e\n-#endif\n-\n-#ifdef LWS_WITH_IPV6\n-#if defined(WIN32) || defined(_WIN32)\n-#include \u003cwincrypt.h\u003e\n-#include \u003cIphlpapi.h\u003e\n-#else\n-#include \u003cnet/if.h\u003e\n-#endif\n-#endif\n-\n-int log_level \u003d LLL_ERR | LLL_WARN | LLL_NOTICE;\n-static void (*lwsl_emit)(int level, const char *line)\n-#ifndef LWS_PLAT_OPTEE\n-\t\u003d lwsl_emit_stderr\n-#endif\n-\t;\n-#ifndef LWS_PLAT_OPTEE\n-static const char * const log_level_names[] \u003d {\n-\t\u0022ERR\u0022,\n-\t\u0022WARN\u0022,\n-\t\u0022NOTICE\u0022,\n-\t\u0022INFO\u0022,\n-\t\u0022DEBUG\u0022,\n-\t\u0022PARSER\u0022,\n-\t\u0022HEADER\u0022,\n-\t\u0022EXTENSION\u0022,\n-\t\u0022CLIENT\u0022,\n-\t\u0022LATENCY\u0022,\n-\t\u0022USER\u0022,\n-\t\u0022?\u0022,\n-\t\u0022?\u0022\n-};\n-#endif\n-\n-#if defined (_DEBUG)\n-void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role)\n-{\n-\twsi-\u003ewsistate \u003d (wsi-\u003ewsistate \u0026 (~LWSI_ROLE_MASK)) | role;\n-\n-\tlwsl_debug(\u0022lwsi_set_role(%p, 0x%x)\u005cn\u0022, wsi, wsi-\u003ewsistate);\n-}\n-\n-void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs)\n-{\n-\twsi-\u003ewsistate \u003d (wsi-\u003ewsistate \u0026 (~LRS_MASK)) | lrs;\n-\n-\tlwsl_debug(\u0022lwsi_set_state(%p, 0x%x)\u005cn\u0022, wsi, wsi-\u003ewsistate);\n-}\n-#endif\n-\n-signed char char_to_hex(const char c)\n-{\n-\tif (c \u003e\u003d '0' \u0026\u0026 c \u003c\u003d '9')\n-\t\treturn c - '0';\n-\n-\tif (c \u003e\u003d 'a' \u0026\u0026 c \u003c\u003d 'f')\n-\t\treturn c - 'a' + 10;\n-\n-\tif (c \u003e\u003d 'A' \u0026\u0026 c \u003c\u003d 'F')\n-\t\treturn c - 'A' + 10;\n-\n-\treturn -1;\n-}\n-\n-void\n-__lws_free_wsi(struct lws *wsi)\n-{\n-\tif (!wsi)\n-\t\treturn;\n-\n-\t/*\n-\t * Protocol user data may be allocated either internally by lws\n-\t * or by specified the user. We should only free what we allocated.\n-\t */\n-\tif (wsi-\u003eprotocol \u0026\u0026 wsi-\u003eprotocol-\u003eper_session_data_size \u0026\u0026\n-\t wsi-\u003euser_space \u0026\u0026 !wsi-\u003euser_space_externally_allocated)\n-\t\tlws_free(wsi-\u003euser_space);\n-\n-\tlws_buflist_destroy_all_segments(\u0026wsi-\u003ebuflist);\n-\tlws_free_set_NULL(wsi-\u003etrunc_alloc);\n-\tlws_free_set_NULL(wsi-\u003eudp);\n-\n-\tif (wsi-\u003evhost \u0026\u0026 wsi-\u003evhost-\u003elserv_wsi \u003d\u003d wsi)\n-\t\twsi-\u003evhost-\u003elserv_wsi \u003d NULL;\n-\n-\t// lws_peer_dump_from_wsi(wsi);\n-\n-\tif (wsi-\u003erole_ops-\u003edestroy_role)\n-\t\twsi-\u003erole_ops-\u003edestroy_role(wsi);\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tlws_peer_track_wsi_close(wsi-\u003econtext, wsi-\u003epeer);\n-\twsi-\u003epeer \u003d NULL;\n-#endif\n-\n-\t/* since we will destroy the wsi, make absolutely sure now */\n-\n-#if defined(LWS_WITH_OPENSSL)\n-\t__lws_ssl_remove_wsi_from_buffered_list(wsi);\n-#endif\n-\t__lws_remove_from_timeout_list(wsi);\n-\n-\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi)\n-\t\twsi-\u003econtext-\u003eevent_loop_ops-\u003edestroy_wsi(wsi);\n-\n-\twsi-\u003econtext-\u003ecount_wsi_allocated--;\n-\tlwsl_debug(\u0022%s: %p, remaining wsi %d\u005cn\u0022, __func__, wsi,\n-\t\t\twsi-\u003econtext-\u003ecount_wsi_allocated);\n-\n-\tlws_free(wsi);\n-}\n-\n-void\n-lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead)\n-{\n-\tif (d-\u003eprev)\n-\t\treturn;\n-\n-\t/* our next guy is current first guy */\n-\td-\u003enext \u003d phead-\u003enext;\n-\t/* if there is a next guy, set his prev ptr to our next ptr */\n-\tif (d-\u003enext)\n-\t\td-\u003enext-\u003eprev \u003d d;\n-\t/* our prev ptr is first ptr */\n-\td-\u003eprev \u003d phead;\n-\t/* set the first guy to be us */\n-\tphead-\u003enext \u003d d;\n-}\n-\n-/* situation is:\n- *\n- * HEAD: struct lws_dll * \u003d \u0026entry1\n- *\n- * Entry 1: struct lws_dll .pprev \u003d \u0026HEAD , .next \u003d Entry 2\n- * Entry 2: struct lws_dll .pprev \u003d \u0026entry1 , .next \u003d \u0026entry2\n- * Entry 3: struct lws_dll .pprev \u003d \u0026entry2 , .next \u003d NULL\n- *\n- * Delete Entry1:\n- *\n- * - HEAD \u003d \u0026entry2\n- * - Entry2: .pprev \u003d \u0026HEAD, .next \u003d \u0026entry3\n- * - Entry3: .pprev \u003d \u0026entry2, .next \u003d NULL\n- *\n- * Delete Entry2:\n- *\n- * - HEAD \u003d \u0026entry1\n- * - Entry1: .pprev \u003d \u0026HEAD, .next \u003d \u0026entry3\n- * - Entry3: .pprev \u003d \u0026entry1, .next \u003d NULL\n- *\n- * Delete Entry3:\n- *\n- * - HEAD \u003d \u0026entry1\n- * - Entry1: .pprev \u003d \u0026HEAD, .next \u003d \u0026entry2\n- * - Entry2: .pprev \u003d \u0026entry1, .next \u003d NULL\n- *\n- */\n-\n-void\n-lws_dll_remove(struct lws_dll *d)\n-{\n-\tif (!d-\u003eprev) /* ie, not part of the list */\n-\t\treturn;\n-\n-\t/*\n-\t * remove us\n-\t *\n-\t * USp \u003c-\u003e us \u003c-\u003e USn --\u003e USp \u003c-\u003e USn\n-\t */\n-\n-\t/* if we have a next guy, set his prev to our prev */\n-\tif (d-\u003enext)\n-\t\td-\u003enext-\u003eprev \u003d d-\u003eprev;\n-\n-\t/* set our prev guy to our next guy instead of us */\n-\tif (d-\u003eprev)\n-\t\td-\u003eprev-\u003enext \u003d d-\u003enext;\n-\n-\t/* we're out of the list, we should not point anywhere any more */\n-\td-\u003eprev \u003d NULL;\n-\td-\u003enext \u003d NULL;\n-}\n-\n-void\n-__lws_remove_from_timeout_list(struct lws *wsi)\n-{\n-\tlws_dll_lws_remove(\u0026wsi-\u003edll_timeout);\n-}\n-\n-void\n-lws_remove_from_timeout_list(struct lws *wsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\n-\tlws_pt_lock(pt, __func__);\n-\t__lws_remove_from_timeout_list(wsi);\n-\tlws_pt_unlock(pt);\n-}\n-\n-void\n-lws_dll_dump(struct lws_dll_lws *head, const char *title)\n-{\n-\tint n \u003d 0;\n-\n-\t(void)n;\n-\tlwsl_notice(\u0022%s: %s (head.next %p)\u005cn\u0022, __func__, title, head-\u003enext);\n-\n-\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, head-\u003enext) {\n-\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_hrtimer);\n-\n-\t\t(void)wsi;\n-\n-\t\tlwsl_notice(\u0022 %d: wsi %p: %llu\u005cn\u0022, n++, wsi,\n-\t\t\t\t(unsigned long long)wsi-\u003epending_timer);\n-\t} lws_end_foreach_dll_safe(d, d1);\n-}\n-\n-void\n-__lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tstruct lws_dll_lws *dd \u003d \u0026pt-\u003edll_head_hrtimer;\n-\tstruct timeval now;\n-\tstruct lws *wsi1;\n-\tint bef \u003d 0;\n-\n-\tlws_dll_lws_remove(\u0026wsi-\u003edll_hrtimer);\n-\n-\tif (usecs \u003d\u003d LWS_SET_TIMER_USEC_CANCEL)\n-\t\treturn;\n-\n-\tgettimeofday(\u0026now, NULL);\n-\twsi-\u003epending_timer \u003d ((now.tv_sec * 1000000ll) + now.tv_usec) + usecs;\n-\n-\t/*\n-\t * we sort the hrtimer list with the earliest timeout first\n-\t */\n-\n-\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n-\t\t\t\t pt-\u003edll_head_hrtimer.next) {\n-\t\tdd \u003d d;\n-\t\twsi1 \u003d lws_container_of(d, struct lws, dll_hrtimer);\n-\n-\t\tif (wsi1-\u003epending_timer \u003e\u003d wsi-\u003epending_timer) {\n-\t\t\t/* d, dprev's next, is \u003e\u003d our time */\n-\t\t\tbef \u003d 1;\n-\t\t\tbreak;\n-\t\t}\n-\t} lws_end_foreach_dll_safe(d, d1);\n-\n-\tif (bef) {\n-\t\t/*\n-\t\t * we go before dd\n-\t\t * DDp \u003c-\u003e DD \u003c-\u003e DDn --\u003e DDp \u003c-\u003e us \u003c-\u003e DD \u003c-\u003e DDn\n-\t\t */\n-\t\t/* we point forward to dd */\n-\t\twsi-\u003edll_hrtimer.next \u003d dd;\n-\t\t/* we point back to what dd used to point back to */\n-\t\twsi-\u003edll_hrtimer.prev \u003d dd-\u003eprev;\n-\t\t/* DDp points forward to us now */\n-\t\tdd-\u003eprev-\u003enext \u003d \u0026wsi-\u003edll_hrtimer;\n-\t\t/* DD points back to us now */\n-\t\tdd-\u003eprev \u003d \u0026wsi-\u003edll_hrtimer;\n-\t} else {\n-\t\t/*\n-\t\t * we go after dd\n-\t\t * DDp \u003c-\u003e DD \u003c-\u003e DDn --\u003e DDp \u003c-\u003e DD \u003c-\u003e us \u003c-\u003e DDn\n-\t\t */\n-\t\t/* we point forward to what dd used to point forward to */\n-\t\twsi-\u003edll_hrtimer.next \u003d dd-\u003enext;\n-\t\t/* we point back to dd */\n-\t\twsi-\u003edll_hrtimer.prev \u003d dd;\n-\t\t/* DDn points back to us */\n-\t\tif (dd-\u003enext)\n-\t\t\tdd-\u003enext-\u003eprev \u003d \u0026wsi-\u003edll_hrtimer;\n-\t\t/* DD points forward to us */\n-\t\tdd-\u003enext \u003d \u0026wsi-\u003edll_hrtimer;\n-\t}\n-\n-//\tlws_dll_dump(\u0026pt-\u003edll_head_hrtimer, \u0022after set_timer_usec\u0022);\n-}\n-\n-LWS_VISIBLE void\n-lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs)\n-{\n-\t__lws_set_timer_usecs(wsi, usecs);\n-}\n-\n-lws_usec_t\n-__lws_hrtimer_service(struct lws_context_per_thread *pt)\n-{\n-\tstruct timeval now;\n-\tstruct lws *wsi;\n-\tlws_usec_t t;\n-\n-\tgettimeofday(\u0026now, NULL);\n-\tt \u003d (now.tv_sec * 1000000ll) + now.tv_usec;\n-\n-\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n-\t\t\t\t pt-\u003edll_head_hrtimer.next) {\n-\t\twsi \u003d lws_container_of(d, struct lws, dll_hrtimer);\n-\n-\t\t/*\n-\t\t * if we met one in the future, we are done, because the list\n-\t\t * is sorted by time in the future.\n-\t\t */\n-\t\tif (wsi-\u003epending_timer \u003e t)\n-\t\t\tbreak;\n-\n-\t\tlws_set_timer_usecs(wsi, LWS_SET_TIMER_USEC_CANCEL);\n-\n-\t\t/* it's time for the timer to be serviced */\n-\n-\t\tif (wsi-\u003eprotocol \u0026\u0026\n-\t\t wsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_TIMER,\n-\t\t\t\t\t wsi-\u003euser_space, NULL, 0))\n-\t\t\t__lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n-\t\t\t\t\t \u0022timer cb errored\u0022);\n-\t} lws_end_foreach_dll_safe(d, d1);\n-\n-\t/* return an estimate how many us until next timer hit */\n-\n-\tif (!pt-\u003edll_head_hrtimer.next)\n-\t\treturn LWS_HRTIMER_NOWAIT;\n-\n-\twsi \u003d lws_container_of(pt-\u003edll_head_hrtimer.next, struct lws, dll_hrtimer);\n-\n-\tgettimeofday(\u0026now, NULL);\n-\tt \u003d (now.tv_sec * 1000000ll) + now.tv_usec;\n-\n-\tif (wsi-\u003epending_timer \u003c t)\n-\t\treturn 0;\n-\n-\treturn wsi-\u003epending_timer - t;\n-}\n-\n-void\n-__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\ttime_t now;\n-\n-\ttime(\u0026now);\n-\n-\tlwsl_debug(\u0022%s: %p: %d secs\u005cn\u0022, __func__, wsi, secs);\n-\twsi-\u003epending_timeout_limit \u003d secs;\n-\twsi-\u003epending_timeout_set \u003d now;\n-\twsi-\u003epending_timeout \u003d reason;\n-\n-\tif (!reason)\n-\t\tlws_dll_lws_remove(\u0026wsi-\u003edll_timeout);\n-\telse\n-\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_timeout, \u0026pt-\u003edll_head_timeout);\n-}\n-\n-LWS_VISIBLE void\n-lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\n-\tif (secs \u003d\u003d LWS_TO_KILL_SYNC) {\n-\t\tlws_remove_from_timeout_list(wsi);\n-\t\tlwsl_debug(\u0022synchronously killing %p\u005cn\u0022, wsi);\n-\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, \u0022to sync kill\u0022);\n-\t\treturn;\n-\t}\n-\n-\tlws_pt_lock(pt, __func__);\n-\t__lws_set_timeout(wsi, reason, secs);\n-\tlws_pt_unlock(pt);\n-}\n-\n-int\n-lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p)\n-{\n-\tlws_start_foreach_llp(struct lws_timed_vh_protocol **, pt,\n-\t\t\t vh-\u003etimed_vh_protocol_list) {\n-\t\tif (*pt \u003d\u003d p) {\n-\t\t\t*pt \u003d p-\u003enext;\n-\t\t\tlws_free(p);\n-\n-\t\t\treturn 0;\n-\t\t}\n-\t} lws_end_foreach_llp(pt, next);\n-\n-\treturn 1;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols *prot,\n-\t\t\t int reason, int secs)\n-{\n-\tstruct lws_timed_vh_protocol *p \u003d (struct lws_timed_vh_protocol *)\n-\t\t\tlws_malloc(sizeof(*p), \u0022timed_vh\u0022);\n-\n-\tif (!p)\n-\t\treturn 1;\n-\n-\tp-\u003eprotocol \u003d prot;\n-\tp-\u003ereason \u003d reason;\n-\tp-\u003etime \u003d lws_now_secs() + secs;\n-\tp-\u003enext \u003d vh-\u003etimed_vh_protocol_list;\n-\n-\tvh-\u003etimed_vh_protocol_list \u003d p;\n-\n-\treturn 0;\n-}\n-\n-static void\n-lws_remove_child_from_any_parent(struct lws *wsi)\n-{\n-\tstruct lws **pwsi;\n-\tint seen \u003d 0;\n-\n-\tif (!wsi-\u003eparent)\n-\t\treturn;\n-\n-\t/* detach ourselves from parent's child list */\n-\tpwsi \u003d \u0026wsi-\u003eparent-\u003echild_list;\n-\twhile (*pwsi) {\n-\t\tif (*pwsi \u003d\u003d wsi) {\n-\t\t\tlwsl_info(\u0022%s: detach %p from parent %p\u005cn\u0022, __func__,\n-\t\t\t\t wsi, wsi-\u003eparent);\n-\n-\t\t\tif (wsi-\u003eparent-\u003eprotocol)\n-\t\t\t\twsi-\u003eparent-\u003eprotocol-\u003ecallback(wsi,\n-\t\t\t\t\t\tLWS_CALLBACK_CHILD_CLOSING,\n-\t\t\t\t\t wsi-\u003eparent-\u003euser_space, wsi, 0);\n-\n-\t\t\t*pwsi \u003d wsi-\u003esibling_list;\n-\t\t\tseen \u003d 1;\n-\t\t\tbreak;\n-\t\t}\n-\t\tpwsi \u003d \u0026(*pwsi)-\u003esibling_list;\n-\t}\n-\tif (!seen)\n-\t\tlwsl_err(\u0022%s: failed to detach from parent\u005cn\u0022, __func__);\n-\n-\twsi-\u003eparent \u003d NULL;\n-}\n-\n-int\n-lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)\n-{\n-//\tif (wsi-\u003eprotocol \u003d\u003d p)\n-//\t\treturn 0;\n-\tconst struct lws_protocols *vp \u003d wsi-\u003evhost-\u003eprotocols, *vpo;\n-\n-\tif (wsi-\u003eprotocol \u0026\u0026 wsi-\u003eprotocol_bind_balance) {\n-\t\twsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,\n-\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n-\t\twsi-\u003eprotocol_bind_balance \u003d 0;\n-\t}\n-\tif (!wsi-\u003euser_space_externally_allocated)\n-\t\tlws_free_set_NULL(wsi-\u003euser_space);\n-\n-\tlws_same_vh_protocol_remove(wsi);\n-\n-\twsi-\u003eprotocol \u003d p;\n-\tif (!p)\n-\t\treturn 0;\n-\n-\tif (lws_ensure_user_space(wsi))\n-\t\treturn 1;\n-\n-\tif (p \u003e vp \u0026\u0026 p \u003c \u0026vp[wsi-\u003evhost-\u003ecount_protocols])\n-\t\tlws_same_vh_protocol_insert(wsi, (int)(p - vp));\n-\telse {\n-\t\tint n \u003d wsi-\u003evhost-\u003ecount_protocols;\n-\t\tint hit \u003d 0;\n-\n-\t\tvpo \u003d vp;\n-\n-\t\twhile (n--) {\n-\t\t\tif (p-\u003ename \u0026\u0026 vp-\u003ename \u0026\u0026 !strcmp(p-\u003ename, vp-\u003ename)) {\n-\t\t\t\thit \u003d 1;\n-\t\t\t\tlws_same_vh_protocol_insert(wsi, (int)(vp - vpo));\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tvp++;\n-\t\t}\n-\t\tif (!hit)\n-\t\t\tlwsl_err(\u0022%s: %p is not in vhost '%s' protocols list\u005cn\u0022,\n-\t\t\t\t __func__, p, wsi-\u003evhost-\u003ename);\n-\t}\n-\n-\tif (wsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL,\n-\t\t\t\t wsi-\u003euser_space, NULL, 0))\n-\t\treturn 1;\n-\n-\twsi-\u003eprotocol_bind_balance \u003d 1;\n-\n-\treturn 0;\n-}\n-\n-void\n-__lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller)\n-{\n-\tstruct lws_context_per_thread *pt;\n-\tstruct lws *wsi1, *wsi2;\n-\tstruct lws_context *context;\n-\tint n;\n-\n-\tlwsl_info(\u0022%s: %p: caller: %s\u005cn\u0022, __func__, wsi, caller);\n-\n-\tif (!wsi)\n-\t\treturn;\n-\n-\tlws_access_log(wsi);\n-\n-\tcontext \u003d wsi-\u003econtext;\n-\tpt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_API_CLOSE, 1);\n-\n-#if !defined(LWS_NO_CLIENT)\n-\n-\tlws_free_set_NULL(wsi-\u003eclient_hostname_copy);\n-\t/* we are no longer an active client connection that can piggyback */\n-\tlws_dll_lws_remove(\u0026wsi-\u003edll_active_client_conns);\n-\n-\t/*\n-\t * if we have wsi in our transaction queue, if we are closing we\n-\t * must go through and close all those first\n-\t */\n-\tif (wsi-\u003evhost) {\n-\t\tif ((int)reason !\u003d -1)\n-\t\t\tlws_vhost_lock(wsi-\u003evhost);\n-\t\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n-\t\t\t\t\twsi-\u003edll_client_transaction_queue_head.next) {\n-\t\t\tstruct lws *w \u003d lws_container_of(d, struct lws,\n-\t\t\t\t\t\t\t dll_client_transaction_queue);\n-\n-\t\t\t__lws_close_free_wsi(w, -1, \u0022trans q leader closing\u0022);\n-\t\t} lws_end_foreach_dll_safe(d, d1);\n-\n-\t\t/*\n-\t\t * !!! If we are closing, but we have pending pipelined transaction\n-\t\t * results we already sent headers for, that's going to destroy sync\n-\t\t * for HTTP/1 and leave H2 stream with no live swsi.\n-\t\t *\n-\t\t * However this is normal if we are being closed because the transaction\n-\t\t * queue leader is closing.\n-\t\t */\n-\t\tlws_dll_lws_remove(\u0026wsi-\u003edll_client_transaction_queue);\n-\t\tif ((int)reason !\u003d-1)\n-\t\t\tlws_vhost_unlock(wsi-\u003evhost);\n-\t}\n-#endif\n-\n-\t/* if we have children, close them first */\n-\tif (wsi-\u003echild_list) {\n-\t\twsi2 \u003d wsi-\u003echild_list;\n-\t\twhile (wsi2) {\n-\t\t\twsi1 \u003d wsi2-\u003esibling_list;\n-\t\t\twsi2-\u003eparent \u003d NULL;\n-\t\t\t/* stop it doing shutdown processing */\n-\t\t\twsi2-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\t\t__lws_close_free_wsi(wsi2, reason, \u0022general child recurse\u0022);\n-\t\t\twsi2 \u003d wsi1;\n-\t\t}\n-\t\twsi-\u003echild_list \u003d NULL;\n-\t}\n-\n-\tif (wsi-\u003erole_ops \u003d\u003d \u0026role_ops_raw_file) {\n-\t\tlws_remove_child_from_any_parent(wsi);\n-\t\t__remove_wsi_socket_from_fds(wsi);\n-\t\twsi-\u003eprotocol-\u003ecallback(wsi, wsi-\u003erole_ops-\u003eclose_cb[0],\n-\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n-\t\tgoto async_close;\n-\t}\n-\n-\twsi-\u003ewsistate_pre_close \u003d wsi-\u003ewsistate;\n-\n-#ifdef LWS_WITH_CGI\n-\tif (wsi-\u003erole_ops \u003d\u003d \u0026role_ops_cgi) {\n-\t\t/* we are not a network connection, but a handler for CGI io */\n-\t\tif (wsi-\u003eparent \u0026\u0026 wsi-\u003eparent-\u003ehttp.cgi) {\n-\n-\t\t\tif (wsi-\u003ecgi_channel \u003d\u003d LWS_STDOUT)\n-\t\t\t\tlws_cgi_remove_and_kill(wsi-\u003eparent);\n-\n-\t\t\t/* end the binding between us and master */\n-\t\t\twsi-\u003eparent-\u003ehttp.cgi-\u003estdwsi[(int)wsi-\u003ecgi_channel] \u003d NULL;\n-\t\t}\n-\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\n-\t\tgoto just_kill_connection;\n-\t}\n-\n-\tif (wsi-\u003ehttp.cgi)\n-\t\tlws_cgi_remove_and_kill(wsi);\n-#endif\n-\n-#if !defined(LWS_NO_CLIENT)\n-\tlws_client_stash_destroy(wsi);\n-#endif\n-\n-\tif (wsi-\u003erole_ops \u003d\u003d \u0026role_ops_raw_skt) {\n-\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\tgoto just_kill_connection;\n-\t}\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tif (lwsi_role_http(wsi) \u0026\u0026 lwsi_role_server(wsi) \u0026\u0026\n-\t wsi-\u003ehttp.fop_fd !\u003d NULL)\n-\t\tlws_vfs_file_close(\u0026wsi-\u003ehttp.fop_fd);\n-#endif\n-\n-\tif (lwsi_state(wsi) \u003d\u003d LRS_DEAD_SOCKET)\n-\t\treturn;\n-\n-\tif (wsi-\u003esocket_is_permanently_unusable ||\n-\t reason \u003d\u003d LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY ||\n-\t lwsi_state(wsi) \u003d\u003d LRS_SHUTDOWN)\n-\t\tgoto just_kill_connection;\n-\n-\tswitch (lwsi_state_PRE_CLOSE(wsi)) {\n-\tcase LRS_DEAD_SOCKET:\n-\t\treturn;\n-\n-\t/* we tried the polite way... */\n-\tcase LRS_WAITING_TO_SEND_CLOSE:\n-\tcase LRS_AWAITING_CLOSE_ACK:\n-\tcase LRS_RETURNED_CLOSE:\n-\t\tgoto just_kill_connection;\n-\n-\tcase LRS_FLUSHING_BEFORE_CLOSE:\n-\t\tif (wsi-\u003etrunc_len) {\n-\t\t\tlws_callback_on_writable(wsi);\n-\t\t\treturn;\n-\t\t}\n-\t\tlwsl_info(\u0022%p: end LRS_FLUSHING_BEFORE_CLOSE\u005cn\u0022, wsi);\n-\t\tgoto just_kill_connection;\n-\tdefault:\n-\t\tif (wsi-\u003etrunc_len) {\n-\t\t\tlwsl_info(\u0022%p: LRS_FLUSHING_BEFORE_CLOSE\u005cn\u0022, wsi);\n-\t\t\tlwsi_set_state(wsi, LRS_FLUSHING_BEFORE_CLOSE);\n-\t\t\t__lws_set_timeout(wsi,\n-\t\t\t\tPENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);\n-\t\t\treturn;\n-\t\t}\n-\t\tbreak;\n-\t}\n-\n-\tif (lwsi_state(wsi) \u003d\u003d LRS_WAITING_CONNECT ||\n-\t lwsi_state(wsi) \u003d\u003d LRS_H1C_ISSUE_HANDSHAKE)\n-\t\tgoto just_kill_connection;\n-\n-\tif (!wsi-\u003etold_user_closed \u0026\u0026 lwsi_role_http(wsi) \u0026\u0026\n-\t lwsi_role_server(wsi)) {\n-\t\tif (wsi-\u003euser_space \u0026\u0026 wsi-\u003eprotocol_bind_balance) {\n-\t\t\twsi-\u003evhost-\u003eprotocols-\u003ecallback(wsi,\n-\t\t\t\t\t\tLWS_CALLBACK_HTTP_DROP_PROTOCOL,\n-\t\t\t\t\t wsi-\u003euser_space, NULL, 0);\n-\t\t\twsi-\u003eprotocol_bind_balance \u003d 0;\n-\t\t}\n-\t}\n-\n-\t/*\n-\t * signal we are closing, lws_write will\n-\t * add any necessary version-specific stuff. If the write fails,\n-\t * no worries we are closing anyway. If we didn't initiate this\n-\t * close, then our state has been changed to\n-\t * LRS_RETURNED_CLOSE and we will skip this.\n-\t *\n-\t * Likewise if it's a second call to close this connection after we\n-\t * sent the close indication to the peer already, we are in state\n-\t * LRS_AWAITING_CLOSE_ACK and will skip doing this a second time.\n-\t */\n-\n-\tif (wsi-\u003erole_ops-\u003eclose_via_role_protocol \u0026\u0026\n-\t wsi-\u003erole_ops-\u003eclose_via_role_protocol(wsi, reason))\n-\t\treturn;\n-\n-just_kill_connection:\n-\n-\tif (wsi-\u003erole_ops-\u003eclose_kill_connection)\n-\t\twsi-\u003erole_ops-\u003eclose_kill_connection(wsi, reason);\n-\n-\tlws_remove_child_from_any_parent(wsi);\n-\tn \u003d 0;\n-\n-\tif (!wsi-\u003etold_user_closed \u0026\u0026 wsi-\u003euser_space \u0026\u0026\n-\t wsi-\u003eprotocol_bind_balance) {\n-\t\tlwsl_debug(\u0022%s: %p: DROP_PROTOCOL %s\u005cn\u0022, __func__, wsi,\n-\t\t wsi-\u003eprotocol-\u003ename);\n-\t\twsi-\u003eprotocol-\u003ecallback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,\n-\t\t\t\t wsi-\u003euser_space, NULL, 0);\n-\t\twsi-\u003eprotocol_bind_balance \u003d 0;\n-\t}\n-\n-\tif ((lwsi_state(wsi) \u003d\u003d LRS_WAITING_SERVER_REPLY ||\n-\t lwsi_state(wsi) \u003d\u003d LRS_WAITING_CONNECT) \u0026\u0026 !wsi-\u003ealready_did_cce)\n-\t\twsi-\u003eprotocol-\u003ecallback(wsi,\n-\t\t\t\t LWS_CALLBACK_CLIENT_CONNECTION_ERROR,\n-\t\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n-\n-\t/*\n-\t * Testing with ab shows that we have to stage the socket close when\n-\t * the system is under stress... shutdown any further TX, change the\n-\t * state to one that won't emit anything more, and wait with a timeout\n-\t * for the POLLIN to show a zero-size rx before coming back and doing\n-\t * the actual close.\n-\t */\n-\tif (wsi-\u003erole_ops !\u003d \u0026role_ops_raw_skt \u0026\u0026 !lwsi_role_client(wsi) \u0026\u0026\n-\t lwsi_state(wsi) !\u003d LRS_SHUTDOWN \u0026\u0026\n-\t lwsi_state(wsi) !\u003d LRS_UNCONNECTED \u0026\u0026\n-\t reason !\u003d LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY \u0026\u0026\n-\t !wsi-\u003esocket_is_permanently_unusable) {\n-\n-#if defined(LWS_WITH_TLS)\n-\tif (lws_is_ssl(wsi) \u0026\u0026 wsi-\u003etls.ssl) {\n-\t\tn \u003d 0;\n-\t\tswitch (__lws_tls_shutdown(wsi)) {\n-\t\tcase LWS_SSL_CAPABLE_DONE:\n-\t\tcase LWS_SSL_CAPABLE_ERROR:\n-\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_READ:\n-\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_WRITE:\n-\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE:\n-\t\t\tbreak;\n-\t\t}\n-\t} else\n-#endif\n-\t\t{\n-\t\t\tlwsl_info(\u0022%s: shutdown conn: %p (sock %d, state 0x%x)\u005cn\u0022,\n-\t\t\t\t __func__, wsi, (int)(long)wsi-\u003edesc.sockfd,\n-\t\t\t\t lwsi_state(wsi));\n-\t\t\tif (!wsi-\u003esocket_is_permanently_unusable \u0026\u0026\n-\t\t\t lws_sockfd_valid(wsi-\u003edesc.sockfd)) {\n-\t\t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\t\t\tn \u003d shutdown(wsi-\u003edesc.sockfd, SHUT_WR);\n-\t\t\t}\n-\t\t}\n-\t\tif (n)\n-\t\t\tlwsl_debug(\u0022closing: shutdown (state 0x%x) ret %d\u005cn\u0022,\n-\t\t\t\t lwsi_state(wsi), LWS_ERRNO);\n-\n-\t\t/*\n-\t\t * This causes problems on WINCE / ESP32 with disconnection\n-\t\t * when the events are half closing connection\n-\t\t */\n-#if !defined(_WIN32_WCE) \u0026\u0026 !defined(LWS_WITH_ESP32)\n-\t\t/* libuv: no event available to guarantee completion */\n-\t\tif (!wsi-\u003esocket_is_permanently_unusable \u0026\u0026\n-\t\t lws_sockfd_valid(wsi-\u003edesc.sockfd) \u0026\u0026\n-\t\t lwsi_state(wsi) !\u003d LRS_SHUTDOWN \u0026\u0026\n-\t\t context-\u003eevent_loop_ops-\u003eperiodic_events_available) {\n-\t\t\t__lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);\n-\t\t\tlwsi_set_state(wsi, LRS_SHUTDOWN);\n-\t\t\t__lws_set_timeout(wsi, PENDING_TIMEOUT_SHUTDOWN_FLUSH,\n-\t\t\t\t\t context-\u003etimeout_secs);\n-\n-\t\t\treturn;\n-\t\t}\n-#endif\n-\t}\n-\n-\tlwsl_debug(\u0022%s: real just_kill_connection: %p (sockfd %d)\u005cn\u0022, __func__,\n-\t\t wsi, wsi-\u003edesc.sockfd);\n-\t\n-#ifdef LWS_WITH_HTTP_PROXY\n-\tif (wsi-\u003ehttp.rw) {\n-\t\tlws_rewrite_destroy(wsi-\u003ehttp.rw);\n-\t\twsi-\u003ehttp.rw \u003d NULL;\n-\t}\n-#endif\n-\t/*\n-\t * we won't be servicing or receiving anything further from this guy\n-\t * delete socket from the internal poll list if still present\n-\t */\n-\t__lws_ssl_remove_wsi_from_buffered_list(wsi);\n-\t__lws_remove_from_timeout_list(wsi);\n-\tlws_dll_lws_remove(\u0026wsi-\u003edll_hrtimer);\n-\n-\t/* don't repeat event loop stuff */\n-\tif (wsi-\u003etold_event_loop_closed)\n-\t\treturn;\n-\n-\t/* checking return redundant since we anyway close */\n-\tif (wsi-\u003edesc.sockfd !\u003d LWS_SOCK_INVALID)\n-\t\t__remove_wsi_socket_from_fds(wsi);\n-\telse\n-\t\tlws_same_vh_protocol_remove(wsi);\n-\n-\tlwsi_set_state(wsi, LRS_DEAD_SOCKET);\n-\tlws_buflist_destroy_all_segments(\u0026wsi-\u003ebuflist);\n-\tlws_dll_lws_remove(\u0026wsi-\u003edll_buflist);\n-\n-\tif (wsi-\u003erole_ops-\u003eclose_role)\n-\t wsi-\u003erole_ops-\u003eclose_role(pt, wsi);\n-\n-\t/* tell the user it's all over for this guy */\n-\n-\tif (lwsi_state_est_PRE_CLOSE(wsi) \u0026\u0026 !wsi-\u003etold_user_closed \u0026\u0026\n-\t wsi-\u003erole_ops-\u003eclose_cb[lwsi_role_server(wsi)]) {\n-\t\tconst struct lws_protocols *pro \u003d wsi-\u003eprotocol;\n-\n-\t\tif (!wsi-\u003eprotocol)\n-\t\t\tpro \u003d \u0026wsi-\u003evhost-\u003eprotocols[0];\n-\n-\t\tpro-\u003ecallback(wsi,\n-\t\t\t wsi-\u003erole_ops-\u003eclose_cb[lwsi_role_server(wsi)],\n-\t\t\t wsi-\u003euser_space, NULL, 0);\n-\t\twsi-\u003etold_user_closed \u003d 1;\n-\t}\n-\n-async_close:\n-\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\n-\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close)\n-\t\tif (wsi-\u003econtext-\u003eevent_loop_ops-\u003ewsi_logical_close(wsi))\n-\t\t\treturn;\n-\n-\t__lws_close_free_wsi_final(wsi);\n-}\n-\n-void\n-__lws_close_free_wsi_final(struct lws *wsi)\n-{\n-\tint n;\n-\n-\tif (lws_socket_is_valid(wsi-\u003edesc.sockfd) \u0026\u0026 !lws_ssl_close(wsi)) {\n-\t\tn \u003d compatible_close(wsi-\u003edesc.sockfd);\n-\t\tif (n)\n-\t\t\tlwsl_debug(\u0022closing: close ret %d\u005cn\u0022, LWS_ERRNO);\n-\n-\t\twsi-\u003edesc.sockfd \u003d LWS_SOCK_INVALID;\n-\t}\n-\n-\t/* outermost destroy notification for wsi (user_space still intact) */\n-\tif (wsi-\u003evhost)\n-\t\twsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,\n-\t\t\t\t\t\t wsi-\u003euser_space, NULL, 0);\n-\n-#ifdef LWS_WITH_CGI\n-\tif (wsi-\u003ehttp.cgi) {\n-\n-\t\tfor (n \u003d 0; n \u003c 3; n++) {\n-\t\t\tif (wsi-\u003ehttp.cgi-\u003epipe_fds[n][!!(n \u003d\u003d 0)] \u003d\u003d 0)\n-\t\t\t\tlwsl_err(\u0022ZERO FD IN CGI CLOSE\u0022);\n-\n-\t\t\tif (wsi-\u003ehttp.cgi-\u003epipe_fds[n][!!(n \u003d\u003d 0)] \u003e\u003d 0)\n-\t\t\t\tclose(wsi-\u003ehttp.cgi-\u003epipe_fds[n][!!(n \u003d\u003d 0)]);\n-\t\t}\n-\n-\t\tlws_free(wsi-\u003ehttp.cgi);\n-\t}\n-#endif\n-\n-\t__lws_free_wsi(wsi);\n-}\n-\n-\n-void\n-lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\n-\tlws_pt_lock(pt, __func__);\n-\t__lws_close_free_wsi(wsi, reason, caller);\n-\tlws_pt_unlock(pt);\n-}\n-\n-/* lws_buflist */\n-\n-int\n-lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,\n-\t\t\t size_t len)\n-{\n-\tstruct lws_buflist *nbuf;\n-\tint first \u003d !*head;\n-\tvoid *p \u003d *head;\n-\tint sanity \u003d 1024;\n-\n-\tassert(buf);\n-\tassert(len);\n-\n-\t/* append at the tail */\n-\twhile (*head) {\n-\t\tif (!--sanity || head \u003d\u003d \u0026((*head)-\u003enext)) {\n-\t\t\tlwsl_err(\u0022%s: corrupt list points to self\u005cn\u0022, __func__);\n-\t\t\treturn -1;\n-\t\t}\n-\t\thead \u003d \u0026((*head)-\u003enext);\n-\t}\n-\n-\tlwsl_info(\u0022%s: len %u first %d %p\u005cn\u0022, __func__, (uint32_t)len, first, p);\n-\n-\tnbuf \u003d (struct lws_buflist *)\n-\t\t\tlws_malloc(sizeof(**head) + len, __func__);\n-\tif (!nbuf) {\n-\t\tlwsl_err(\u0022%s: OOM\u005cn\u0022, __func__);\n-\t\treturn -1;\n-\t}\n-\n-\tnbuf-\u003elen \u003d len;\n-\tnbuf-\u003epos \u003d 0;\n-\tnbuf-\u003enext \u003d NULL;\n-\n-\tp \u003d (void *)nbuf-\u003ebuf;\n-\tmemcpy(p, buf, len);\n-\n-\t*head \u003d nbuf;\n-\n-\treturn first; /* returns 1 if first segment just created */\n-}\n-\n-static int\n-lws_buflist_destroy_segment(struct lws_buflist **head)\n-{\n-\tstruct lws_buflist *old \u003d *head;\n-\n-\tassert(*head);\n-\t*head \u003d (*head)-\u003enext;\n-\told-\u003enext \u003d NULL;\n-\tlws_free(old);\n-\n-\treturn !*head; /* returns 1 if last segment just destroyed */\n-}\n-\n-void\n-lws_buflist_destroy_all_segments(struct lws_buflist **head)\n-{\n-\tstruct lws_buflist *p \u003d *head, *p1;\n-\n-\twhile (p) {\n-\t\tp1 \u003d p-\u003enext;\n-\t\tp-\u003enext \u003d NULL;\n-\t\tlws_free(p);\n-\t\tp \u003d p1;\n-\t}\n-\n-\t*head \u003d NULL;\n-}\n-\n-size_t\n-lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf)\n-{\n-\tif (!*head) {\n-\t\tif (buf)\n-\t\t\t*buf \u003d NULL;\n-\n-\t\treturn 0;\n-\t}\n-\n-\tif (!(*head)-\u003elen \u0026\u0026 (*head)-\u003enext)\n-\t\tlws_buflist_destroy_segment(head);\n-\n-\tif (!*head) {\n-\t\tif (buf)\n-\t\t\t*buf \u003d NULL;\n-\n-\t\treturn 0;\n-\t}\n-\n-\tassert((*head)-\u003epos \u003c (*head)-\u003elen);\n-\n-\tif (buf)\n-\t\t*buf \u003d (*head)-\u003ebuf + (*head)-\u003epos;\n-\n-\treturn (*head)-\u003elen - (*head)-\u003epos;\n-}\n-\n-int\n-lws_buflist_use_segment(struct lws_buflist **head, size_t len)\n-{\n-\tassert(*head);\n-\tassert(len);\n-\tassert((*head)-\u003epos + len \u003c\u003d (*head)-\u003elen);\n-\n-\t(*head)-\u003epos +\u003d len;\n-\tif ((*head)-\u003epos \u003d\u003d (*head)-\u003elen)\n-\t\tlws_buflist_destroy_segment(head);\n-\n-\tif (!*head)\n-\t\treturn 0;\n-\n-\treturn (int)((*head)-\u003elen - (*head)-\u003epos);\n-}\n-\n-void\n-lws_buflist_describe(struct lws_buflist **head, void *id)\n-{\n-\tstruct lws_buflist *old;\n-\tint n \u003d 0;\n-\n-\tif (*head \u003d\u003d NULL)\n-\t\tlwsl_notice(\u0022%p: buflist empty\u005cn\u0022, id);\n-\n-\twhile (*head) {\n-\t\tlwsl_notice(\u0022%p: %d: %llu / %llu (%llu left)\u005cn\u0022, id, n,\n-\t\t\t (unsigned long long)(*head)-\u003epos,\n-\t\t\t (unsigned long long)(*head)-\u003elen,\n-\t\t\t (unsigned long long)(*head)-\u003elen - (*head)-\u003epos);\n-\t\told \u003d *head;\n-\t\thead \u003d \u0026((*head)-\u003enext);\n-\t\tif (*head \u003d\u003d old) {\n-\t\t\tlwsl_err(\u0022%s: next points to self\u005cn\u0022, __func__);\n-\t\t\tbreak;\n-\t\t}\n-\t\tn++;\n-\t}\n-}\n-\n-/* ... */\n-\n-LWS_VISIBLE LWS_EXTERN const char *\n-lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)\n-{\n-\tint n \u003d 0, sl \u003d (int)strlen(name);\n-\n-\twhile (lws_hdr_copy_fragment(wsi, buf, len,\n-\t\t\t WSI_TOKEN_HTTP_URI_ARGS, n) \u003e\u003d 0) {\n-\n-\t\tif (!strncmp(buf, name, sl))\n-\t\t\treturn buf + sl;\n-\n-\t\tn++;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-#if !defined(LWS_WITH_ESP32)\n-LWS_VISIBLE int\n-interface_to_sa(struct lws_vhost *vh, const char *ifname,\n-\t\tstruct sockaddr_in *addr, size_t addrlen)\n-{\n-\tint ipv6 \u003d 0;\n-#ifdef LWS_WITH_IPV6\n-\tipv6 \u003d LWS_IPV6_ENABLED(vh);\n-#endif\n-\t(void)vh;\n-\n-\treturn lws_interface_to_sa(ipv6, ifname, addr, addrlen);\n-}\n-#endif\n-\n-#ifndef LWS_PLAT_OPTEE\n-static int\n-lws_get_addresses(struct lws_vhost *vh, void *ads, char *name,\n-\t\t int name_len, char *rip, int rip_len)\n-{\n-\tstruct addrinfo ai, *res;\n-\tstruct sockaddr_in addr4;\n-\n-\trip[0] \u003d '\u005c0';\n-\tname[0] \u003d '\u005c0';\n-\taddr4.sin_family \u003d AF_UNSPEC;\n-\n-#ifdef LWS_WITH_IPV6\n-\tif (LWS_IPV6_ENABLED(vh)) {\n-\t\tif (!lws_plat_inet_ntop(AF_INET6,\n-\t\t\t\t\t\u0026((struct sockaddr_in6 *)ads)-\u003esin6_addr,\n-\t\t\t\t\trip, rip_len)) {\n-\t\t\tlwsl_err(\u0022inet_ntop: %s\u0022, strerror(LWS_ERRNO));\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t// Strip off the IPv4 to IPv6 header if one exists\n-\t\tif (strncmp(rip, \u0022::ffff:\u0022, 7) \u003d\u003d 0)\n-\t\t\tmemmove(rip, rip + 7, strlen(rip) - 6);\n-\n-\t\tgetnameinfo((struct sockaddr *)ads, sizeof(struct sockaddr_in6),\n-\t\t\t name, name_len, NULL, 0, 0);\n-\n-\t\treturn 0;\n-\t} else\n-#endif\n-\t{\n-\t\tstruct addrinfo *result;\n-\n-\t\tmemset(\u0026ai, 0, sizeof ai);\n-\t\tai.ai_family \u003d PF_UNSPEC;\n-\t\tai.ai_socktype \u003d SOCK_STREAM;\n-#if !defined(LWS_WITH_ESP32)\n-\t\tif (getnameinfo((struct sockaddr *)ads,\n-\t\t\t\tsizeof(struct sockaddr_in),\n-\t\t\t\tname, name_len, NULL, 0, 0))\n-\t\t\treturn -1;\n-#endif\n-\n-\t\tif (getaddrinfo(name, NULL, \u0026ai, \u0026result))\n-\t\t\treturn -1;\n-\n-\t\tres \u003d result;\n-\t\twhile (addr4.sin_family \u003d\u003d AF_UNSPEC \u0026\u0026 res) {\n-\t\t\tswitch (res-\u003eai_family) {\n-\t\t\tcase AF_INET:\n-\t\t\t\taddr4.sin_addr \u003d\n-\t\t\t\t ((struct sockaddr_in *)res-\u003eai_addr)-\u003esin_addr;\n-\t\t\t\taddr4.sin_family \u003d AF_INET;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\n-\t\t\tres \u003d res-\u003eai_next;\n-\t\t}\n-\t\tfreeaddrinfo(result);\n-\t}\n-\n-\tif (addr4.sin_family \u003d\u003d AF_UNSPEC)\n-\t\treturn -1;\n-\n-\tif (lws_plat_inet_ntop(AF_INET, \u0026addr4.sin_addr, rip, rip_len) \u003d\u003d NULL)\n-\t\treturn -1;\n-\n-\treturn 0;\n-}\n-\n-\n-LWS_VISIBLE const char *\n-lws_get_peer_simple(struct lws *wsi, char *name, int namelen)\n-{\n-\tsocklen_t len, olen;\n-#ifdef LWS_WITH_IPV6\n-\tstruct sockaddr_in6 sin6;\n-#endif\n-\tstruct sockaddr_in sin4;\n-\tint af \u003d AF_INET;\n-\tvoid *p, *q;\n-\n-\twsi \u003d lws_get_network_wsi(wsi);\n-\n-\tif (wsi-\u003eparent_carries_io)\n-\t\twsi \u003d wsi-\u003eparent;\n-\n-#ifdef LWS_WITH_IPV6\n-\tif (LWS_IPV6_ENABLED(wsi-\u003evhost)) {\n-\t\tlen \u003d sizeof(sin6);\n-\t\tp \u003d \u0026sin6;\n-\t\taf \u003d AF_INET6;\n-\t\tq \u003d \u0026sin6.sin6_addr;\n-\t} else\n-#endif\n-\t{\n-\t\tlen \u003d sizeof(sin4);\n-\t\tp \u003d \u0026sin4;\n-\t\tq \u003d \u0026sin4.sin_addr;\n-\t}\n-\n-\tolen \u003d len;\n-\tif (getpeername(wsi-\u003edesc.sockfd, p, \u0026len) \u003c 0 || len \u003e olen) {\n-\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n-\t\treturn NULL;\n-\t}\n-\n-\treturn lws_plat_inet_ntop(af, q, name, namelen);\n-}\n-#endif\n-\n-LWS_VISIBLE void\n-lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name,\n-\t\t int name_len, char *rip, int rip_len)\n-{\n-#ifndef LWS_PLAT_OPTEE\n-\tsocklen_t len;\n-#ifdef LWS_WITH_IPV6\n-\tstruct sockaddr_in6 sin6;\n-#endif\n-\tstruct sockaddr_in sin4;\n-\tstruct lws_context *context \u003d wsi-\u003econtext;\n-\tint ret \u003d -1;\n-\tvoid *p;\n-\n-\trip[0] \u003d '\u005c0';\n-\tname[0] \u003d '\u005c0';\n-\n-\tlws_latency_pre(context, wsi);\n-\n-#ifdef LWS_WITH_IPV6\n-\tif (LWS_IPV6_ENABLED(wsi-\u003evhost)) {\n-\t\tlen \u003d sizeof(sin6);\n-\t\tp \u003d \u0026sin6;\n-\t} else\n-#endif\n-\t{\n-\t\tlen \u003d sizeof(sin4);\n-\t\tp \u003d \u0026sin4;\n-\t}\n-\n-\tif (getpeername(fd, p, \u0026len) \u003c 0) {\n-\t\tlwsl_warn(\u0022getpeername: %s\u005cn\u0022, strerror(LWS_ERRNO));\n-\t\tgoto bail;\n-\t}\n-\n-\tret \u003d lws_get_addresses(wsi-\u003evhost, p, name, name_len, rip, rip_len);\n-\n-bail:\n-\tlws_latency(context, wsi, \u0022lws_get_peer_addresses\u0022, ret, 1);\n-#endif\n-\t(void)wsi;\n-\t(void)fd;\n-\t(void)name;\n-\t(void)name_len;\n-\t(void)rip;\n-\t(void)rip_len;\n-\n-}\n-\n-LWS_EXTERN void *\n-lws_vhost_user(struct lws_vhost *vhost)\n-{\n-\treturn vhost-\u003euser;\n-}\n-\n-LWS_EXTERN void *\n-lws_context_user(struct lws_context *context)\n-{\n-\treturn context-\u003euser_space;\n-}\n-\n-LWS_VISIBLE struct lws_vhost *\n-lws_vhost_get(struct lws *wsi)\n-{\n-\treturn wsi-\u003evhost;\n-}\n-\n-LWS_VISIBLE struct lws_vhost *\n-lws_get_vhost(struct lws *wsi)\n-{\n-\treturn wsi-\u003evhost;\n-}\n-\n-LWS_VISIBLE const struct lws_protocols *\n-lws_protocol_get(struct lws *wsi)\n-{\n-\treturn wsi-\u003eprotocol;\n-}\n-\n-LWS_VISIBLE const struct lws_udp *\n-lws_get_udp(const struct lws *wsi)\n-{\n-\treturn wsi-\u003eudp;\n-}\n-\n-LWS_VISIBLE struct lws *\n-lws_get_network_wsi(struct lws *wsi)\n-{\n-\tif (!wsi)\n-\t\treturn NULL;\n-\n-#if defined(LWS_WITH_HTTP2)\n-\tif (!wsi-\u003ehttp2_substream \u0026\u0026 !wsi-\u003eclient_h2_substream)\n-\t\treturn wsi;\n-\n-\twhile (wsi-\u003eh2.parent_wsi)\n-\t\twsi \u003d wsi-\u003eh2.parent_wsi;\n-#endif\n-\n-\treturn wsi;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN const struct lws_protocols *\n-lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name)\n-{\n-\tint n;\n-\n-\tfor (n \u003d 0; n \u003c vh-\u003ecount_protocols; n++)\n-\t\tif (!strcmp(name, vh-\u003eprotocols[n].name))\n-\t\t\treturn \u0026vh-\u003eprotocols[n];\n-\n-\treturn NULL;\n-}\n-\n-LWS_VISIBLE int\n-lws_callback_all_protocol(struct lws_context *context,\n-\t\t\t const struct lws_protocols *protocol, int reason)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n-\tunsigned int n, m \u003d context-\u003ecount_threads;\n-\tstruct lws *wsi;\n-\n-\twhile (m--) {\n-\t\tfor (n \u003d 0; n \u003c pt-\u003efds_count; n++) {\n-\t\t\twsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n-\t\t\tif (!wsi)\n-\t\t\t\tcontinue;\n-\t\t\tif (wsi-\u003eprotocol \u003d\u003d protocol)\n-\t\t\t\tprotocol-\u003ecallback(wsi, reason, wsi-\u003euser_space,\n-\t\t\t\t\t\t NULL, 0);\n-\t\t}\n-\t\tpt++;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE int\n-lws_callback_all_protocol_vhost_args(struct lws_vhost *vh,\n-\t\t\t const struct lws_protocols *protocol, int reason,\n-\t\t\t void *argp, size_t len)\n-{\n-\tstruct lws_context *context \u003d vh-\u003econtext;\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n-\tunsigned int n, m \u003d context-\u003ecount_threads;\n-\tstruct lws *wsi;\n-\n-\twhile (m--) {\n-\t\tfor (n \u003d 0; n \u003c pt-\u003efds_count; n++) {\n-\t\t\twsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n-\t\t\tif (!wsi)\n-\t\t\t\tcontinue;\n-\t\t\tif (wsi-\u003evhost \u003d\u003d vh \u0026\u0026 (wsi-\u003eprotocol \u003d\u003d protocol ||\n-\t\t\t\t\t\t !protocol))\n-\t\t\t\twsi-\u003eprotocol-\u003ecallback(wsi, reason,\n-\t\t\t\t\t\twsi-\u003euser_space, argp, len);\n-\t\t}\n-\t\tpt++;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE int\n-lws_callback_all_protocol_vhost(struct lws_vhost *vh,\n-\t\t\t const struct lws_protocols *protocol, int reason)\n-{\n-\treturn lws_callback_all_protocol_vhost_args(vh, protocol, reason, NULL, 0);\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len)\n-{\n-\tint n;\n-\n-\tfor (n \u003d 0; n \u003c wsi-\u003evhost-\u003ecount_protocols; n++)\n-\t\tif (wsi-\u003evhost-\u003eprotocols[n].callback(wsi, reason, NULL, in, len))\n-\t\t\treturn 1;\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void *in,\n-\t\t\t\t size_t len)\n-{\n-\tint n;\n-\tstruct lws *wsi \u003d lws_zalloc(sizeof(*wsi), \u0022fake wsi\u0022);\n-\n-\twsi-\u003econtext \u003d vh-\u003econtext;\n-\twsi-\u003evhost \u003d vh;\n-\n-\tfor (n \u003d 0; n \u003c wsi-\u003evhost-\u003ecount_protocols; n++) {\n-\t\twsi-\u003eprotocol \u003d \u0026vh-\u003eprotocols[n];\n-\t\tif (wsi-\u003eprotocol-\u003ecallback(wsi, reason, NULL, in, len)) {\n-\t\t\tlws_free(wsi);\n-\t\t\treturn 1;\n-\t\t}\n-\t}\n-\n-\tlws_free(wsi);\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops)\n-{\n-\tcontext-\u003efops \u003d fops;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN lws_filepos_t\n-lws_vfs_tell(lws_fop_fd_t fop_fd)\n-{\n-\treturn fop_fd-\u003epos;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN lws_filepos_t\n-lws_vfs_get_length(lws_fop_fd_t fop_fd)\n-{\n-\treturn fop_fd-\u003elen;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN uint32_t\n-lws_vfs_get_mod_time(lws_fop_fd_t fop_fd)\n-{\n-\treturn fop_fd-\u003emod_time;\n-}\n-\n-LWS_VISIBLE lws_fileofs_t\n-lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset)\n-{\n-\tlws_fileofs_t ofs;\n-\n-\tofs \u003d fop_fd-\u003efops-\u003eLWS_FOP_SEEK_CUR(fop_fd, offset - fop_fd-\u003epos);\n-\n-\treturn ofs;\n-}\n-\n-\n-LWS_VISIBLE lws_fileofs_t\n-lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset)\n-{\n-\treturn fop_fd-\u003efops-\u003eLWS_FOP_SEEK_CUR(fop_fd, fop_fd-\u003elen +\n-\t\t\t\t\t fop_fd-\u003epos + offset);\n-}\n-\n-\n-const struct lws_plat_file_ops *\n-lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,\n-\t\t const char **vpath)\n-{\n-\tconst struct lws_plat_file_ops *pf;\n-\tconst char *p \u003d vfs_path;\n-\tint n;\n-\n-\t*vpath \u003d NULL;\n-\n-\t/* no non-platform fops, just use that */\n-\n-\tif (!fops-\u003enext)\n-\t\treturn fops;\n-\n-\t/*\n-\t * scan the vfs path looking for indications we are to be\n-\t * handled by a specific fops\n-\t */\n-\n-\twhile (p \u0026\u0026 *p) {\n-\t\tif (*p !\u003d '/') {\n-\t\t\tp++;\n-\t\t\tcontinue;\n-\t\t}\n-\t\t/* the first one is always platform fops, so skip */\n-\t\tpf \u003d fops-\u003enext;\n-\t\twhile (pf) {\n-\t\t\tn \u003d 0;\n-\t\t\twhile (n \u003c (int)ARRAY_SIZE(pf-\u003efi) \u0026\u0026 pf-\u003efi[n].sig) {\n-\t\t\t\tif (p \u003e\u003d vfs_path + pf-\u003efi[n].len)\n-\t\t\t\t\tif (!strncmp(p - (pf-\u003efi[n].len - 1),\n-\t\t\t\t\t\t pf-\u003efi[n].sig,\n-\t\t\t\t\t\t pf-\u003efi[n].len - 1)) {\n-\t\t\t\t\t\t*vpath \u003d p + 1;\n-\t\t\t\t\t\treturn pf;\n-\t\t\t\t\t}\n-\n-\t\t\t\tn++;\n-\t\t\t}\n-\t\t\tpf \u003d pf-\u003enext;\n-\t\t}\n-\t\tp++;\n-\t}\n-\n-\treturn fops;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT\n-lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path,\n-\t\t lws_fop_flags_t *flags)\n-{\n-\tconst char *vpath \u003d \u0022\u0022;\n-\tconst struct lws_plat_file_ops *selected;\n-\n-\tselected \u003d lws_vfs_select_fops(fops, vfs_path, \u0026vpath);\n-\n-\treturn selected-\u003eLWS_FOP_OPEN(fops, vfs_path, vpath, flags);\n-}\n-\n-\n-/**\n- * lws_now_secs() - seconds since 1970-1-1\n- *\n- */\n-LWS_VISIBLE LWS_EXTERN unsigned long\n-lws_now_secs(void)\n-{\n-\tstruct timeval tv;\n-\n-\tgettimeofday(\u0026tv, NULL);\n-\n-\treturn tv.tv_sec;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2)\n-{\n-\tif (t1 \u003c context-\u003etime_discontiguity)\n-\t\tt1 +\u003d context-\u003etime_fixup;\n-\n-\tif (t2 \u003c context-\u003etime_discontiguity)\n-\t\tt2 +\u003d context-\u003etime_fixup;\n-\n-\treturn (int)(t1 - t2);\n-}\n-\n-LWS_VISIBLE lws_sockfd_type\n-lws_get_socket_fd(struct lws *wsi)\n-{\n-\tif (!wsi)\n-\t\treturn -1;\n-\treturn wsi-\u003edesc.sockfd;\n-}\n-\n-#ifdef LWS_LATENCY\n-void\n-lws_latency(struct lws_context *context, struct lws *wsi, const char *action,\n-\t int ret, int completed)\n-{\n-\tunsigned long long u;\n-\tchar buf[256];\n-\n-\tu \u003d time_in_microseconds();\n-\n-\tif (!action) {\n-\t\twsi-\u003elatency_start \u003d u;\n-\t\tif (!wsi-\u003eaction_start)\n-\t\t\twsi-\u003eaction_start \u003d u;\n-\t\treturn;\n-\t}\n-\tif (completed) {\n-\t\tif (wsi-\u003eaction_start \u003d\u003d wsi-\u003elatency_start)\n-\t\t\tsprintf(buf,\n-\t\t\t \u0022Completion first try lat %lluus: %p: ret %d: %s\u005cn\u0022,\n-\t\t\t\t\tu - wsi-\u003elatency_start,\n-\t\t\t\t\t\t (void *)wsi, ret, action);\n-\t\telse\n-\t\t\tsprintf(buf,\n-\t\t\t \u0022Completion %lluus: lat %lluus: %p: ret %d: %s\u005cn\u0022,\n-\t\t\t\tu - wsi-\u003eaction_start,\n-\t\t\t\t\tu - wsi-\u003elatency_start,\n-\t\t\t\t\t\t (void *)wsi, ret, action);\n-\t\twsi-\u003eaction_start \u003d 0;\n-\t} else\n-\t\tsprintf(buf, \u0022lat %lluus: %p: ret %d: %s\u005cn\u0022,\n-\t\t\t u - wsi-\u003elatency_start, (void *)wsi, ret, action);\n-\n-\tif (u - wsi-\u003elatency_start \u003e context-\u003eworst_latency) {\n-\t\tcontext-\u003eworst_latency \u003d u - wsi-\u003elatency_start;\n-\t\tstrcpy(context-\u003eworst_latency_info, buf);\n-\t}\n-\tlwsl_latency(\u0022%s\u0022, buf);\n-}\n-#endif\n-\n-LWS_VISIBLE int\n-lws_rx_flow_control(struct lws *wsi, int _enable)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tint en \u003d _enable;\n-\n-\t// h2 ignores rx flow control atm\n-\tif (lwsi_role_h2(wsi) || wsi-\u003ehttp2_substream ||\n-\t lwsi_role_h2_ENCAPSULATION(wsi))\n-\t\treturn 0; // !!!\n-\n-\tlwsl_info(\u0022%s: %p 0x%x\u005cn\u0022, __func__, wsi, _enable);\n-\n-\tif (!(_enable \u0026 LWS_RXFLOW_REASON_APPLIES)) {\n-\t\t/*\n-\t\t * convert user bool style to bitmap style... in user simple\n-\t\t * bool style _enable \u003d 0 \u003d flow control it, \u003d 1 \u003d allow rx\n-\t\t */\n-\t\ten \u003d LWS_RXFLOW_REASON_APPLIES | LWS_RXFLOW_REASON_USER_BOOL;\n-\t\tif (_enable \u0026 1)\n-\t\t\ten |\u003d LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT;\n-\t}\n-\n-\tlws_pt_lock(pt, __func__);\n-\n-\t/* any bit set in rxflow_bitmap DISABLEs rxflow control */\n-\tif (en \u0026 LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT)\n-\t\twsi-\u003erxflow_bitmap \u0026\u003d ~(en \u0026 0xff);\n-\telse\n-\t\twsi-\u003erxflow_bitmap |\u003d en \u0026 0xff;\n-\n-\tif ((LWS_RXFLOW_PENDING_CHANGE | (!wsi-\u003erxflow_bitmap)) \u003d\u003d\n-\t wsi-\u003erxflow_change_to)\n-\t\tgoto skip;\n-\n-\twsi-\u003erxflow_change_to \u003d LWS_RXFLOW_PENDING_CHANGE | !wsi-\u003erxflow_bitmap;\n-\n-\tlwsl_info(\u0022%s: %p: bitmap 0x%x: en 0x%x, ch 0x%x\u005cn\u0022, __func__, wsi,\n-\t\t wsi-\u003erxflow_bitmap, en, wsi-\u003erxflow_change_to);\n-\n-\tif (_enable \u0026 LWS_RXFLOW_REASON_FLAG_PROCESS_NOW ||\n-\t !wsi-\u003erxflow_will_be_applied) {\n-\t\ten \u003d __lws_rx_flow_control(wsi);\n-\t\tlws_pt_unlock(pt);\n-\n-\t\treturn en;\n-\t}\n-\n-skip:\n-\tlws_pt_unlock(pt);\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE void\n-lws_rx_flow_allow_all_protocol(const struct lws_context *context,\n-\t\t\t const struct lws_protocols *protocol)\n-{\n-\tconst struct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n-\tstruct lws *wsi;\n-\tunsigned int n, m \u003d context-\u003ecount_threads;\n-\n-\twhile (m--) {\n-\t\tfor (n \u003d 0; n \u003c pt-\u003efds_count; n++) {\n-\t\t\twsi \u003d wsi_from_fd(context, pt-\u003efds[n].fd);\n-\t\t\tif (!wsi)\n-\t\t\t\tcontinue;\n-\t\t\tif (wsi-\u003eprotocol \u003d\u003d protocol)\n-\t\t\t\tlws_rx_flow_control(wsi, LWS_RXFLOW_ALLOW);\n-\t\t}\n-\t\tpt++;\n-\t}\n-}\n-\n-int\n-lws_broadcast(struct lws_context *context, int reason, void *in, size_t len)\n-{\n-\tstruct lws_vhost *v \u003d context-\u003evhost_list;\n-\tstruct lws wsi;\n-\tint n, ret \u003d 0;\n-\n-\tmemset(\u0026wsi, 0, sizeof(wsi));\n-\twsi.context \u003d context;\n-\n-\twhile (v) {\n-\t\tconst struct lws_protocols *p \u003d v-\u003eprotocols;\n-\t\twsi.vhost \u003d v;\n-\n-\t\tfor (n \u003d 0; n \u003c v-\u003ecount_protocols; n++) {\n-\t\t\twsi.protocol \u003d p;\n-\t\t\tif (p-\u003ecallback \u0026\u0026\n-\t\t\t p-\u003ecallback(\u0026wsi, reason, NULL, in, len))\n-\t\t\t\tret |\u003d 1;\n-\t\t\tp++;\n-\t\t}\n-\t\tv \u003d v-\u003evhost_next;\n-\t}\n-\n-\treturn ret;\n-}\n-\n-LWS_VISIBLE extern const char *\n-lws_canonical_hostname(struct lws_context *context)\n-{\n-\treturn (const char *)context-\u003ecanonical_hostname;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN const char *\n-lws_get_vhost_name(struct lws_vhost *vhost)\n-{\n-\treturn vhost-\u003ename;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_get_vhost_port(struct lws_vhost *vhost)\n-{\n-\treturn vhost-\u003elisten_port;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void *\n-lws_get_vhost_user(struct lws_vhost *vhost)\n-{\n-\treturn vhost-\u003euser;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN const char *\n-lws_get_vhost_iface(struct lws_vhost *vhost)\n-{\n-\treturn vhost-\u003eiface;\n-}\n-\n-int user_callback_handle_rxflow(lws_callback_function callback_function,\n-\t\t\t\tstruct lws *wsi,\n-\t\t\t\tenum lws_callback_reasons reason, void *user,\n-\t\t\t\tvoid *in, size_t len)\n-{\n-\tint n;\n-\n-\twsi-\u003erxflow_will_be_applied \u003d 1;\n-\tn \u003d callback_function(wsi, reason, user, in, len);\n-\twsi-\u003erxflow_will_be_applied \u003d 0;\n-\tif (!n)\n-\t\tn \u003d __lws_rx_flow_control(wsi);\n-\n-\treturn n;\n-}\n-\n-#if !defined(LWS_WITHOUT_CLIENT)\n-LWS_VISIBLE int\n-lws_set_proxy(struct lws_vhost *vhost, const char *proxy)\n-{\n-\tchar *p;\n-\tchar authstring[96];\n-\n-\tif (!proxy)\n-\t\treturn -1;\n-\n-\t/* we have to deal with a possible redundant leading http:// */\n-\tif (!strncmp(proxy, \u0022http://\u0022, 7))\n-\t\tproxy +\u003d 7;\n-\n-\tp \u003d strrchr(proxy, '@');\n-\tif (p) { /* auth is around */\n-\n-\t\tif ((unsigned int)(p - proxy) \u003e sizeof(authstring) - 1)\n-\t\t\tgoto auth_too_long;\n-\n-\t\tlws_strncpy(authstring, proxy, p - proxy + 1);\n-\t\t// null termination not needed on input\n-\t\tif (lws_b64_encode_string(authstring, lws_ptr_diff(p, proxy),\n-\t\t\t\tvhost-\u003eproxy_basic_auth_token,\n-\t\t sizeof vhost-\u003eproxy_basic_auth_token) \u003c 0)\n-\t\t\tgoto auth_too_long;\n-\n-\t\tlwsl_info(\u0022 Proxy auth in use\u005cn\u0022);\n-\n-\t\tproxy \u003d p + 1;\n-\t} else\n-\t\tvhost-\u003eproxy_basic_auth_token[0] \u003d '\u005c0';\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tlws_strncpy(vhost-\u003ehttp.http_proxy_address, proxy,\n-\t\t sizeof(vhost-\u003ehttp.http_proxy_address));\n-\n-\tp \u003d strchr(vhost-\u003ehttp.http_proxy_address, ':');\n-\tif (!p \u0026\u0026 !vhost-\u003ehttp.http_proxy_port) {\n-\t\tlwsl_err(\u0022http_proxy needs to be ads:port\u005cn\u0022);\n-\n-\t\treturn -1;\n-\t} else {\n-\t\tif (p) {\n-\t\t\t*p \u003d '\u005c0';\n-\t\t\tvhost-\u003ehttp.http_proxy_port \u003d atoi(p + 1);\n-\t\t}\n-\t}\n-\n-\tlwsl_info(\u0022 Proxy %s:%u\u005cn\u0022, vhost-\u003ehttp.http_proxy_address,\n-\t\t\tvhost-\u003ehttp.http_proxy_port);\n-#endif\n-\treturn 0;\n-\n-auth_too_long:\n-\tlwsl_err(\u0022proxy auth too long\u005cn\u0022);\n-\n-\treturn -1;\n-}\n-#endif\n-\n-#if defined(LWS_WITH_SOCKS5)\n-LWS_VISIBLE int\n-lws_set_socks(struct lws_vhost *vhost, const char *socks)\n-{\n-\tchar *p_at, *p_colon;\n-\tchar user[96];\n-\tchar password[96];\n-\n-\tif (!socks)\n-\t\treturn -1;\n-\n-\tvhost-\u003esocks_user[0] \u003d '\u005c0';\n-\tvhost-\u003esocks_password[0] \u003d '\u005c0';\n-\n-\tp_at \u003d strrchr(socks, '@');\n-\tif (p_at) { /* auth is around */\n-\t\tif ((unsigned int)(p_at - socks) \u003e (sizeof(user)\n-\t\t\t+ sizeof(password) - 2)) {\n-\t\t\tlwsl_err(\u0022Socks auth too long\u005cn\u0022);\n-\t\t\tgoto bail;\n-\t\t}\n-\n-\t\tp_colon \u003d strchr(socks, ':');\n-\t\tif (p_colon) {\n-\t\t\tif ((unsigned int)(p_colon - socks) \u003e (sizeof(user)\n-\t\t\t\t- 1) ) {\n-\t\t\t\tlwsl_err(\u0022Socks user too long\u005cn\u0022);\n-\t\t\t\tgoto bail;\n-\t\t\t}\n-\t\t\tif ((unsigned int)(p_at - p_colon) \u003e (sizeof(password)\n-\t\t\t\t- 1) ) {\n-\t\t\t\tlwsl_err(\u0022Socks password too long\u005cn\u0022);\n-\t\t\t\tgoto bail;\n-\t\t\t}\n-\n-\t\t\tlws_strncpy(vhost-\u003esocks_user, socks, p_colon - socks + 1);\n-\t\t\tlws_strncpy(vhost-\u003esocks_password, p_colon + 1,\n-\t\t\t\tp_at - (p_colon + 1) + 1);\n-\t\t}\n-\n-\t\tlwsl_info(\u0022 Socks auth, user: %s, password: %s\u005cn\u0022,\n-\t\t\tvhost-\u003esocks_user, vhost-\u003esocks_password );\n-\n-\t\tsocks \u003d p_at + 1;\n-\t}\n-\n-\tlws_strncpy(vhost-\u003esocks_proxy_address, socks,\n-\t\t sizeof(vhost-\u003esocks_proxy_address));\n-\n-\tp_colon \u003d strchr(vhost-\u003esocks_proxy_address, ':');\n-\tif (!p_colon \u0026\u0026 !vhost-\u003esocks_proxy_port) {\n-\t\tlwsl_err(\u0022socks_proxy needs to be address:port\u005cn\u0022);\n-\t\treturn -1;\n-\t} else {\n-\t\tif (p_colon) {\n-\t\t\t*p_colon \u003d '\u005c0';\n-\t\t\tvhost-\u003esocks_proxy_port \u003d atoi(p_colon + 1);\n-\t\t}\n-\t}\n-\n-\tlwsl_info(\u0022 Socks %s:%u\u005cn\u0022, vhost-\u003esocks_proxy_address,\n-\t\t\tvhost-\u003esocks_proxy_port);\n-\n-\treturn 0;\n-\n-bail:\n-\treturn -1;\n-}\n-#endif\n-\n-LWS_VISIBLE const struct lws_protocols *\n-lws_get_protocol(struct lws *wsi)\n-{\n-\treturn wsi-\u003eprotocol;\n-}\n-\n-\n-int\n-lws_ensure_user_space(struct lws *wsi)\n-{\n-\tif (!wsi-\u003eprotocol)\n-\t\treturn 0;\n-\n-\t/* allocate the per-connection user memory (if any) */\n-\n-\tif (wsi-\u003eprotocol-\u003eper_session_data_size \u0026\u0026 !wsi-\u003euser_space) {\n-\t\twsi-\u003euser_space \u003d lws_zalloc(\n-\t\t\t wsi-\u003eprotocol-\u003eper_session_data_size, \u0022user space\u0022);\n-\t\tif (wsi-\u003euser_space \u003d\u003d NULL) {\n-\t\t\tlwsl_err(\u0022%s: OOM\u005cn\u0022, __func__);\n-\t\t\treturn 1;\n-\t\t}\n-\t} else\n-\t\tlwsl_debug(\u0022%s: %p protocol pss %lu, user_space\u003d%p\u005cn\u0022, __func__,\n-\t\t\t wsi, (long)wsi-\u003eprotocol-\u003eper_session_data_size,\n-\t\t\t wsi-\u003euser_space);\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE void *\n-lws_adjust_protocol_psds(struct lws *wsi, size_t new_size)\n-{\n-\t((struct lws_protocols *)lws_get_protocol(wsi))-\u003eper_session_data_size \u003d\n-\t\tnew_size;\n-\n-\tif (lws_ensure_user_space(wsi))\n-\t\t\treturn NULL;\n-\n-\treturn wsi-\u003euser_space;\n-}\n-\n-LWS_VISIBLE int\n-lwsl_timestamp(int level, char *p, int len)\n-{\n-#ifndef LWS_PLAT_OPTEE\n-\ttime_t o_now \u003d time(NULL);\n-\tunsigned long long now;\n-\tstruct tm *ptm \u003d NULL;\n-#ifndef WIN32\n-\tstruct tm tm;\n-#endif\n-\tint n;\n-\n-#ifndef _WIN32_WCE\n-#ifdef WIN32\n-\tptm \u003d localtime(\u0026o_now);\n-#else\n-\tif (localtime_r(\u0026o_now, \u0026tm))\n-\t\tptm \u003d \u0026tm;\n-#endif\n-#endif\n-\tp[0] \u003d '\u005c0';\n-\tfor (n \u003d 0; n \u003c LLL_COUNT; n++) {\n-\t\tif (level !\u003d (1 \u003c\u003c n))\n-\t\t\tcontinue;\n-\t\tnow \u003d time_in_microseconds() / 100;\n-\t\tif (ptm)\n-\t\t\tn \u003d lws_snprintf(p, len,\n-\t\t\t\t\u0022[%04d/%02d/%02d %02d:%02d:%02d:%04d] %s: \u0022,\n-\t\t\t\tptm-\u003etm_year + 1900,\n-\t\t\t\tptm-\u003etm_mon + 1,\n-\t\t\t\tptm-\u003etm_mday,\n-\t\t\t\tptm-\u003etm_hour,\n-\t\t\t\tptm-\u003etm_min,\n-\t\t\t\tptm-\u003etm_sec,\n-\t\t\t\t(int)(now % 10000), log_level_names[n]);\n-\t\telse\n-\t\t\tn \u003d lws_snprintf(p, len, \u0022[%llu:%04d] %s: \u0022,\n-\t\t\t\t\t(unsigned long long) now / 10000,\n-\t\t\t\t\t(int)(now % 10000), log_level_names[n]);\n-\t\treturn n;\n-\t}\n-#else\n-\tp[0] \u003d '\u005c0';\n-#endif\n-\n-\treturn 0;\n-}\n-\n-#ifndef LWS_PLAT_OPTEE\n-static const char * const colours[] \u003d {\n-\t\u0022[31;1m\u0022, /* LLL_ERR */\n-\t\u0022[36;1m\u0022, /* LLL_WARN */\n-\t\u0022[35;1m\u0022, /* LLL_NOTICE */\n-\t\u0022[32;1m\u0022, /* LLL_INFO */\n-\t\u0022[34;1m\u0022, /* LLL_DEBUG */\n-\t\u0022[33;1m\u0022, /* LLL_PARSER */\n-\t\u0022[33;1m\u0022, /* LLL_HEADER */\n-\t\u0022[33;1m\u0022, /* LLL_EXT */\n-\t\u0022[33;1m\u0022, /* LLL_CLIENT */\n-\t\u0022[33;1m\u0022, /* LLL_LATENCY */\n-\t\u0022[30;1m\u0022, /* LLL_USER */\n-};\n-\n-LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)\n-{\n-\tchar buf[50];\n-\tstatic char tty \u003d 3;\n-\tint n, m \u003d ARRAY_SIZE(colours) - 1;\n-\n-\tif (!tty)\n-\t\ttty \u003d isatty(2) | 2;\n-\tlwsl_timestamp(level, buf, sizeof(buf));\n-\n-\tif (tty \u003d\u003d 3) {\n-\t\tn \u003d 1 \u003c\u003c (ARRAY_SIZE(colours) - 1);\n-\t\twhile (n) {\n-\t\t\tif (level \u0026 n)\n-\t\t\t\tbreak;\n-\t\t\tm--;\n-\t\t\tn \u003e\u003e\u003d 1;\n-\t\t}\n-\t\tfprintf(stderr, \u0022%c%s%s%s%c[0m\u0022, 27, colours[m], buf, line, 27);\n-\t} else\n-\t\tfprintf(stderr, \u0022%s%s\u0022, buf, line);\n-}\n-#endif\n-\n-LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl)\n-{\n-\tchar buf[256];\n-\tint n;\n-\n-\tif (!(log_level \u0026 filter))\n-\t\treturn;\n-\n-\tn \u003d vsnprintf(buf, sizeof(buf) - 1, format, vl);\n-\t(void)n;\n-\t/* vnsprintf returns what it would have written, even if truncated */\n-\tif (n \u003e (int)sizeof(buf) - 1)\n-\t\tn \u003d sizeof(buf) - 1;\n-\tif (n \u003e 0)\n-\t\tbuf[n] \u003d '\u005c0';\n-\n-\tlwsl_emit(filter, buf);\n-}\n-\n-LWS_VISIBLE void _lws_log(int filter, const char *format, ...)\n-{\n-\tva_list ap;\n-\n-\tva_start(ap, format);\n-\t_lws_logv(filter, format, ap);\n-\tva_end(ap);\n-}\n-\n-LWS_VISIBLE void lws_set_log_level(int level,\n-\t\t\t\t void (*func)(int level, const char *line))\n-{\n-\tlog_level \u003d level;\n-\tif (func)\n-\t\tlwsl_emit \u003d func;\n-}\n-\n-LWS_VISIBLE int lwsl_visible(int level)\n-{\n-\treturn log_level \u0026 level;\n-}\n-\n-LWS_VISIBLE void\n-lwsl_hexdump_level(int hexdump_level, const void *vbuf, size_t len)\n-{\n-\tunsigned char *buf \u003d (unsigned char *)vbuf;\n-\tunsigned int n, m, start;\n-\tchar line[80];\n-\tchar *p;\n-\n-\tif (!lwsl_visible(hexdump_level))\n-\t\treturn;\n-\n-\tif (!len)\n-\t\treturn;\n-\n-\tif (!vbuf)\n-\t\treturn;\n-\n-\t_lws_log(hexdump_level, \u0022\u005cn\u0022);\n-\n-\tfor (n \u003d 0; n \u003c len;) {\n-\t\tstart \u003d n;\n-\t\tp \u003d line;\n-\n-\t\tp +\u003d sprintf(p, \u0022%04X: \u0022, start);\n-\n-\t\tfor (m \u003d 0; m \u003c 16 \u0026\u0026 n \u003c len; m++)\n-\t\t\tp +\u003d sprintf(p, \u0022%02X \u0022, buf[n++]);\n-\t\twhile (m++ \u003c 16)\n-\t\t\tp +\u003d sprintf(p, \u0022 \u0022);\n-\n-\t\tp +\u003d sprintf(p, \u0022 \u0022);\n-\n-\t\tfor (m \u003d 0; m \u003c 16 \u0026\u0026 (start + m) \u003c len; m++) {\n-\t\t\tif (buf[start + m] \u003e\u003d ' ' \u0026\u0026 buf[start + m] \u003c 127)\n-\t\t\t\t*p++ \u003d buf[start + m];\n-\t\t\telse\n-\t\t\t\t*p++ \u003d '.';\n-\t\t}\n-\t\twhile (m++ \u003c 16)\n-\t\t\t*p++ \u003d ' ';\n-\n-\t\t*p++ \u003d '\u005cn';\n-\t\t*p \u003d '\u005c0';\n-\t\t_lws_log(hexdump_level, \u0022%s\u0022, line);\n-\t\t(void)line;\n-\t}\n-\n-\t_lws_log(hexdump_level, \u0022\u005cn\u0022);\n-}\n-\n-LWS_VISIBLE void\n-lwsl_hexdump(const void *vbuf, size_t len)\n-{\n-\tlwsl_hexdump_level(LLL_DEBUG, vbuf, len);\n-}\n-\n-LWS_VISIBLE int\n-lws_is_ssl(struct lws *wsi)\n-{\n-#if defined(LWS_WITH_TLS)\n-\treturn wsi-\u003etls.use_ssl \u0026 LCCSCF_USE_SSL;\n-#else\n-\t(void)wsi;\n-\treturn 0;\n-#endif\n-}\n-\n-#if defined(LWS_WITH_TLS) \u0026\u0026 !defined(LWS_WITH_MBEDTLS)\n-LWS_VISIBLE lws_tls_conn*\n-lws_get_ssl(struct lws *wsi)\n-{\n-\treturn wsi-\u003etls.ssl;\n-}\n-#endif\n-\n-LWS_VISIBLE int\n-lws_partial_buffered(struct lws *wsi)\n-{\n-\treturn !!wsi-\u003etrunc_len;\n-}\n-\n-LWS_VISIBLE lws_fileofs_t\n-lws_get_peer_write_allowance(struct lws *wsi)\n-{\n-\treturn wsi-\u003erole_ops-\u003etx_credit(wsi);\n-}\n-\n-LWS_VISIBLE void\n-lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state,\n-\t\tstruct lws_role_ops *ops)\n-{\n-#if defined(_DEBUG)\n-\tconst char *name \u003d \u0022(unset)\u0022;\n-#endif\n-\twsi-\u003ewsistate \u003d role | state;\n-\tif (ops)\n-\t\twsi-\u003erole_ops \u003d ops;\n-#if defined(_DEBUG)\n-\tif (wsi-\u003erole_ops)\n-\t\tname \u003d wsi-\u003erole_ops-\u003ename;\n-\tlwsl_debug(\u0022%s: %p: wsistate 0x%x, ops %s\u005cn\u0022, __func__, wsi,\n-\t\t wsi-\u003ewsistate, name);\n-#endif\n-}\n-\n-LWS_VISIBLE struct lws_plat_file_ops *\n-lws_get_fops(struct lws_context *context)\n-{\n-\treturn (struct lws_plat_file_ops *)context-\u003efops;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN struct lws_context *\n-lws_get_context(const struct lws *wsi)\n-{\n-\treturn wsi-\u003econtext;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_get_count_threads(struct lws_context *context)\n-{\n-\treturn context-\u003ecount_threads;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void *\n-lws_wsi_user(struct lws *wsi)\n-{\n-\treturn wsi-\u003euser_space;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_set_wsi_user(struct lws *wsi, void *data)\n-{\n-\tif (wsi-\u003euser_space_externally_allocated)\n-\t\twsi-\u003euser_space \u003d data;\n-\telse\n-\t\tlwsl_err(\u0022%s: Cannot set internally-allocated user_space\u005cn\u0022,\n-\t\t\t __func__);\n-}\n-\n-LWS_VISIBLE LWS_EXTERN struct lws *\n-lws_get_parent(const struct lws *wsi)\n-{\n-\treturn wsi-\u003eparent;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN struct lws *\n-lws_get_child(const struct lws *wsi)\n-{\n-\treturn wsi-\u003echild_list;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_set_parent_carries_io(struct lws *wsi)\n-{\n-\twsi-\u003eparent_carries_io \u003d 1;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void *\n-lws_get_opaque_parent_data(const struct lws *wsi)\n-{\n-\treturn wsi-\u003eopaque_parent_data;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_set_opaque_parent_data(struct lws *wsi, void *data)\n-{\n-\twsi-\u003eopaque_parent_data \u003d data;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_get_child_pending_on_writable(const struct lws *wsi)\n-{\n-\treturn wsi-\u003eparent_pending_cb_on_writable;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_clear_child_pending_on_writable(struct lws *wsi)\n-{\n-\twsi-\u003eparent_pending_cb_on_writable \u003d 0;\n-}\n-\n-\n-LWS_EXTERN int\n-__lws_rx_flow_control(struct lws *wsi)\n-{\n-\tstruct lws *wsic \u003d wsi-\u003echild_list;\n-\n-\t// h2 ignores rx flow control atm\n-\tif (lwsi_role_h2(wsi) || wsi-\u003ehttp2_substream ||\n-\t lwsi_role_h2_ENCAPSULATION(wsi))\n-\t\treturn 0; // !!!\n-\n-\t/* if he has children, do those if they were changed */\n-\twhile (wsic) {\n-\t\tif (wsic-\u003erxflow_change_to \u0026 LWS_RXFLOW_PENDING_CHANGE)\n-\t\t\t__lws_rx_flow_control(wsic);\n-\n-\t\twsic \u003d wsic-\u003esibling_list;\n-\t}\n-\n-\t/* there is no pending change */\n-\tif (!(wsi-\u003erxflow_change_to \u0026 LWS_RXFLOW_PENDING_CHANGE))\n-\t\treturn 0;\n-\n-\t/* stuff is still buffered, not ready to really accept new input */\n-\tif (lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist, NULL)) {\n-\t\t/* get ourselves called back to deal with stashed buffer */\n-\t\tlws_callback_on_writable(wsi);\n-\t\treturn 0;\n-\t}\n-\n-\t/* now the pending is cleared, we can change rxflow state */\n-\n-\twsi-\u003erxflow_change_to \u0026\u003d ~LWS_RXFLOW_PENDING_CHANGE;\n-\n-\tlwsl_info(\u0022rxflow: wsi %p change_to %d\u005cn\u0022, wsi,\n-\t\t\t wsi-\u003erxflow_change_to \u0026 LWS_RXFLOW_ALLOW);\n-\n-\t/* adjust the pollfd for this wsi */\n-\n-\tif (wsi-\u003erxflow_change_to \u0026 LWS_RXFLOW_ALLOW) {\n-\t\tif (__lws_change_pollfd(wsi, 0, LWS_POLLIN)) {\n-\t\t\tlwsl_info(\u0022%s: fail\u005cn\u0022, __func__);\n-\t\t\treturn -1;\n-\t\t}\n-\t} else\n-\t\tif (__lws_change_pollfd(wsi, LWS_POLLIN, 0))\n-\t\t\treturn -1;\n-\n-\treturn 0;\n-}\n-\n-LWS_EXTERN int\n-lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len)\n-{\n-\tstatic const unsigned char e0f4[] \u003d {\n-\t\t0xa0 | ((2 - 1) \u003c\u003c 2) | 1, /* e0 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e1 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e2 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e3 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e4 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e5 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e6 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e7 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e8 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* e9 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ea */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* eb */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ec */\n-\t\t0x80 | ((2 - 1) \u003c\u003c 2) | 1, /* ed */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ee */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* ef */\n-\t\t0x90 | ((3 - 1) \u003c\u003c 2) | 2, /* f0 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 2, /* f1 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 2, /* f2 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 2, /* f3 */\n-\t\t0x80 | ((1 - 1) \u003c\u003c 2) | 2, /* f4 */\n-\n-\t\t0,\t\t\t /* s0 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 0, /* s2 */\n-\t\t0x80 | ((4 - 1) \u003c\u003c 2) | 1, /* s3 */\n-\t};\n-\tunsigned char s \u003d *state;\n-\n-\twhile (len--) {\n-\t\tunsigned char c \u003d *buf++;\n-\n-\t\tif (!s) {\n-\t\t\tif (c \u003e\u003d 0x80) {\n-\t\t\t\tif (c \u003c 0xc2 || c \u003e 0xf4)\n-\t\t\t\t\treturn 1;\n-\t\t\t\tif (c \u003c 0xe0)\n-\t\t\t\t\ts \u003d 0x80 | ((4 - 1) \u003c\u003c 2);\n-\t\t\t\telse\n-\t\t\t\t\ts \u003d e0f4[c - 0xe0];\n-\t\t\t}\n-\t\t} else {\n-\t\t\tif (c \u003c (s \u0026 0xf0) ||\n-\t\t\t c \u003e\u003d (s \u0026 0xf0) + 0x10 + ((s \u003c\u003c 2) \u0026 0x30))\n-\t\t\t\treturn 1;\n-\t\t\ts \u003d e0f4[21 + (s \u0026 3)];\n-\t\t}\n-\t}\n-\n-\t*state \u003d s;\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_parse_uri(char *p, const char **prot, const char **ads, int *port,\n-\t const char **path)\n-{\n-\tconst char *end;\n-\tstatic const char *slash \u003d \u0022/\u0022;\n-\n-\t/* cut up the location into address, port and path */\n-\t*prot \u003d p;\n-\twhile (*p \u0026\u0026 (*p !\u003d ':' || p[1] !\u003d '/' || p[2] !\u003d '/'))\n-\t\tp++;\n-\tif (!*p) {\n-\t\tend \u003d p;\n-\t\tp \u003d (char *)*prot;\n-\t\t*prot \u003d end;\n-\t} else {\n-\t\t*p \u003d '\u005c0';\n-\t\tp +\u003d 3;\n-\t}\n-\t*ads \u003d p;\n-\tif (!strcmp(*prot, \u0022http\u0022) || !strcmp(*prot, \u0022ws\u0022))\n-\t\t*port \u003d 80;\n-\telse if (!strcmp(*prot, \u0022https\u0022) || !strcmp(*prot, \u0022wss\u0022))\n-\t\t*port \u003d 443;\n-\n- if (*p \u003d\u003d '[')\n- {\n- ++(*ads);\n- while (*p \u0026\u0026 *p !\u003d ']')\n- p++;\n- if (*p)\n- *p++ \u003d '\u005c0';\n- }\n- else\n- {\n- while (*p \u0026\u0026 *p !\u003d ':' \u0026\u0026 *p !\u003d '/')\n- p++;\n- }\n-\tif (*p \u003d\u003d ':') {\n-\t\t*p++ \u003d '\u005c0';\n-\t\t*port \u003d atoi(p);\n-\t\twhile (*p \u0026\u0026 *p !\u003d '/')\n-\t\t\tp++;\n-\t}\n-\t*path \u003d slash;\n-\tif (*p) {\n-\t\t*p++ \u003d '\u005c0';\n-\t\tif (*p)\n-\t\t\t*path \u003d p;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-#if defined(LWS_WITHOUT_EXTENSIONS)\n-\n-/* we need to provide dummy callbacks for internal exts\n- * so user code runs when faced with a lib compiled with\n- * extensions disabled.\n- */\n-\n-LWS_VISIBLE int\n-lws_extension_callback_pm_deflate(struct lws_context *context,\n- const struct lws_extension *ext,\n- struct lws *wsi,\n- enum lws_extension_callback_reasons reason,\n- void *user, void *in, size_t len)\n-{\n-\t(void)context;\n-\t(void)ext;\n-\t(void)wsi;\n-\t(void)reason;\n-\t(void)user;\n-\t(void)in;\n-\t(void)len;\n-\n-\treturn 0;\n-}\n-\n-LWS_EXTERN int\n-lws_set_extension_option(struct lws *wsi, const char *ext_name,\n-\t\t\t const char *opt_name, const char *opt_val)\n-{\n-\treturn -1;\n-}\n-#endif\n-\n-LWS_EXTERN int\n-lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,\n-\t\tconst char *iface)\n-{\n-#ifdef LWS_WITH_UNIX_SOCK\n-\tstruct sockaddr_un serv_unix;\n-#endif\n-#ifdef LWS_WITH_IPV6\n-\tstruct sockaddr_in6 serv_addr6;\n-#endif\n-\tstruct sockaddr_in serv_addr4;\n-#ifndef LWS_PLAT_OPTEE\n-\tsocklen_t len \u003d sizeof(struct sockaddr_storage);\n-#endif\n-\tint n;\n-#if !defined(LWS_WITH_ESP32)\n-\tint m;\n-#endif\n-\tstruct sockaddr_storage sin;\n-\tstruct sockaddr *v;\n-\n-#ifdef LWS_WITH_UNIX_SOCK\n-\tif (LWS_UNIX_SOCK_ENABLED(vhost)) {\n-\t\tv \u003d (struct sockaddr *)\u0026serv_unix;\n-\t\tn \u003d sizeof(struct sockaddr_un);\n-\t\tbzero((char *) \u0026serv_unix, sizeof(serv_unix));\n-\t\tserv_unix.sun_family \u003d AF_UNIX;\n-\t\tif (!iface)\n-\t\t\treturn -1;\n-\t\tif (sizeof(serv_unix.sun_path) \u003c\u003d strlen(iface)) {\n-\t\t\tlwsl_err(\u0022\u005c\u0022%s\u005c\u0022 too long for UNIX domain socket\u005cn\u0022,\n-\t\t\t iface);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tstrcpy(serv_unix.sun_path, iface);\n-\t\tif (serv_unix.sun_path[0] \u003d\u003d '@')\n-\t\t\tserv_unix.sun_path[0] \u003d '\u005c0';\n-\n-\t} else\n-#endif\n-#if defined(LWS_WITH_IPV6) \u0026\u0026 !defined(LWS_WITH_ESP32)\n-\tif (LWS_IPV6_ENABLED(vhost)) {\n-\t\tv \u003d (struct sockaddr *)\u0026serv_addr6;\n-\t\tn \u003d sizeof(struct sockaddr_in6);\n-\t\tbzero((char *) \u0026serv_addr6, sizeof(serv_addr6));\n-\t\tif (iface) {\n-\t\t\tm \u003d interface_to_sa(vhost, iface,\n-\t\t\t\t (struct sockaddr_in *)v, n);\n-\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_USABLE) {\n-\t\t\t\tlwsl_info(\u0022%s: netif %s: Not usable\u005cn\u0022,\n-\t\t\t\t\t __func__, iface);\n-\t\t\t\treturn m;\n-\t\t\t}\n-\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_EXIST) {\n-\t\t\t\tlwsl_info(\u0022%s: netif %s: Does not exist\u005cn\u0022,\n-\t\t\t\t\t __func__, iface);\n-\t\t\t\treturn m;\n-\t\t\t}\n-\t\t\tserv_addr6.sin6_scope_id \u003d lws_get_addr_scope(iface);\n-\t\t}\n-\n-\t\tserv_addr6.sin6_family \u003d AF_INET6;\n-\t\tserv_addr6.sin6_port \u003d htons(port);\n-\t} else\n-#endif\n-\t{\n-\t\tv \u003d (struct sockaddr *)\u0026serv_addr4;\n-\t\tn \u003d sizeof(serv_addr4);\n-\t\tbzero((char *) \u0026serv_addr4, sizeof(serv_addr4));\n-\t\tserv_addr4.sin_addr.s_addr \u003d INADDR_ANY;\n-\t\tserv_addr4.sin_family \u003d AF_INET;\n-#if !defined(LWS_WITH_ESP32)\n-\n-\t\tif (iface) {\n-\t\t m \u003d interface_to_sa(vhost, iface,\n-\t\t\t\t (struct sockaddr_in *)v, n);\n-\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_USABLE) {\n-\t\t\t\tlwsl_info(\u0022%s: netif %s: Not usable\u005cn\u0022,\n-\t\t\t\t\t __func__, iface);\n-\t\t\t\treturn m;\n-\t\t\t}\n-\t\t\tif (m \u003d\u003d LWS_ITOSA_NOT_EXIST) {\n-\t\t\t\tlwsl_info(\u0022%s: netif %s: Does not exist\u005cn\u0022,\n-\t\t\t\t\t __func__, iface);\n-\t\t\t\treturn m;\n-\t\t\t}\n-\t\t}\n-#endif\n-\t\tserv_addr4.sin_port \u003d htons(port);\n-\t} /* ipv4 */\n-\n-\t/* just checking for the interface extant */\n-\tif (sockfd \u003d\u003d LWS_SOCK_INVALID)\n-\t\treturn 0;\n-\n-\tn \u003d bind(sockfd, v, n);\n-#ifdef LWS_WITH_UNIX_SOCK\n-\tif (n \u003c 0 \u0026\u0026 LWS_UNIX_SOCK_ENABLED(vhost)) {\n-\t\tlwsl_err(\u0022ERROR on binding fd %d to \u005c\u0022%s\u005c\u0022 (%d %d)\u005cn\u0022,\n-\t\t\t\tsockfd, iface, n, LWS_ERRNO);\n-\t\treturn -1;\n-\t} else\n-#endif\n-\tif (n \u003c 0) {\n-\t\tlwsl_err(\u0022ERROR on binding fd %d to port %d (%d %d)\u005cn\u0022,\n-\t\t\t\tsockfd, port, n, LWS_ERRNO);\n-\t\treturn -1;\n-\t}\n-\n-#ifndef LWS_PLAT_OPTEE\n-\tif (getsockname(sockfd, (struct sockaddr *)\u0026sin, \u0026len) \u003d\u003d -1)\n-\t\tlwsl_warn(\u0022getsockname: %s\u005cn\u0022, strerror(LWS_ERRNO));\n-\telse\n-#endif\n-#if defined(LWS_WITH_IPV6)\n-\t\tport \u003d (sin.ss_family \u003d\u003d AF_INET6) ?\n-\t\t\tntohs(((struct sockaddr_in6 *) \u0026sin)-\u003esin6_port) :\n-\t\t\tntohs(((struct sockaddr_in *) \u0026sin)-\u003esin_port);\n-#else\n-\t\t{\n-\t\t\tstruct sockaddr_in sain;\n-\t\t\tmemcpy(\u0026sain, \u0026sin, sizeof(sain));\n-\t\t\tport \u003d ntohs(sain.sin_port);\n-\t\t}\n-#endif\n-\n-\treturn port;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_get_vhost_listen_port(struct lws_vhost *vhost)\n-{\n-\treturn vhost-\u003elisten_port;\n-}\n-\n-#if defined(LWS_WITH_IPV6)\n-LWS_EXTERN unsigned long\n-lws_get_addr_scope(const char *ipaddr)\n-{\n-\tunsigned long scope \u003d 0;\n-\n-#ifndef WIN32\n-\tstruct ifaddrs *addrs, *addr;\n-\tchar ip[NI_MAXHOST];\n-\tunsigned int i;\n-\n-\tgetifaddrs(\u0026addrs);\n-\tfor (addr \u003d addrs; addr; addr \u003d addr-\u003eifa_next) {\n-\t\tif (!addr-\u003eifa_addr ||\n-\t\t\taddr-\u003eifa_addr-\u003esa_family !\u003d AF_INET6)\n-\t\t\tcontinue;\n-\n-\t\tgetnameinfo(addr-\u003eifa_addr,\n-\t\t\t\tsizeof(struct sockaddr_in6),\n-\t\t\t\tip, sizeof(ip),\n-\t\t\t\tNULL, 0, NI_NUMERICHOST);\n-\n-\t\ti \u003d 0;\n-\t\twhile (ip[i])\n-\t\t\tif (ip[i++] \u003d\u003d '%') {\n-\t\t\t\tip[i - 1] \u003d '\u005c0';\n-\t\t\t\tbreak;\n-\t\t\t}\n-\n-\t\tif (!strcmp(ip, ipaddr)) {\n-\t\t\tscope \u003d if_nametoindex(addr-\u003eifa_name);\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\tfreeifaddrs(addrs);\n-#else\n-\tPIP_ADAPTER_ADDRESSES adapter, addrs \u003d NULL;\n-\tPIP_ADAPTER_UNICAST_ADDRESS addr;\n-\tULONG size \u003d 0;\n-\tDWORD ret;\n-\tstruct sockaddr_in6 *sockaddr;\n-\tchar ip[NI_MAXHOST];\n-\tunsigned int i;\n-\tint found \u003d 0;\n-\n-\tfor (i \u003d 0; i \u003c 5; i++)\n-\t{\n-\t\tret \u003d GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX,\n-\t\t\t\tNULL, addrs, \u0026size);\n-\t\tif ((ret \u003d\u003d NO_ERROR) || (ret \u003d\u003d ERROR_NO_DATA)) {\n-\t\t\tbreak;\n-\t\t} else if (ret \u003d\u003d ERROR_BUFFER_OVERFLOW)\n-\t\t{\n-\t\t\tif (addrs)\n-\t\t\t\tfree(addrs);\n-\t\t\taddrs \u003d (IP_ADAPTER_ADDRESSES *)malloc(size);\n-\t\t} else\n-\t\t{\n-\t\t\tif (addrs)\n-\t\t\t{\n-\t\t\t\tfree(addrs);\n-\t\t\t\taddrs \u003d NULL;\n-\t\t\t}\n-\t\t\tlwsl_err(\u0022Failed to get IPv6 address table (%d)\u0022, ret);\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\tif ((ret \u003d\u003d NO_ERROR) \u0026\u0026 (addrs)) {\n-\t\tadapter \u003d addrs;\n-\t\twhile (adapter \u0026\u0026 !found) {\n-\t\t\taddr \u003d adapter-\u003eFirstUnicastAddress;\n-\t\t\twhile (addr \u0026\u0026 !found) {\n-\t\t\t\tif (addr-\u003eAddress.lpSockaddr-\u003esa_family \u003d\u003d\n-\t\t\t\t AF_INET6) {\n-\t\t\t\t\tsockaddr \u003d (struct sockaddr_in6 *)\n-\t\t\t\t\t\t(addr-\u003eAddress.lpSockaddr);\n-\n-\t\t\t\t\tlws_plat_inet_ntop(sockaddr-\u003esin6_family,\n-\t\t\t\t\t\t\t\u0026sockaddr-\u003esin6_addr,\n-\t\t\t\t\t\t\tip, sizeof(ip));\n-\n-\t\t\t\t\tif (!strcmp(ip, ipaddr)) {\n-\t\t\t\t\t\tscope \u003d sockaddr-\u003esin6_scope_id;\n-\t\t\t\t\t\tfound \u003d 1;\n-\t\t\t\t\t\tbreak;\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t\taddr \u003d addr-\u003eNext;\n-\t\t\t}\n-\t\t\tadapter \u003d adapter-\u003eNext;\n-\t\t}\n-\t}\n-\tif (addrs)\n-\t\tfree(addrs);\n-#endif\n-\n-\treturn scope;\n-}\n-#endif\n-\n-#if !defined(LWS_NO_SERVER)\n-\n-LWS_EXTERN struct lws *\n-lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags,\n-\t\t const char *protocol_name, struct lws *parent_wsi)\n-{\n-\tlws_sock_file_fd_type sock;\n-\tstruct addrinfo h, *r, *rp;\n-\tstruct lws *wsi \u003d NULL;\n-\tchar buf[16];\n-\tint n;\n-\n-\tmemset(\u0026h, 0, sizeof(h));\n-\th.ai_family \u003d AF_UNSPEC; /* Allow IPv4 or IPv6 */\n-\th.ai_socktype \u003d SOCK_DGRAM;\n-\th.ai_protocol \u003d IPPROTO_UDP;\n-\th.ai_flags \u003d AI_PASSIVE | AI_ADDRCONFIG;\n-\n-\tlws_snprintf(buf, sizeof(buf), \u0022%u\u0022, port);\n-\tn \u003d getaddrinfo(NULL, buf, \u0026h, \u0026r);\n-\tif (n) {\n-\t\tlwsl_info(\u0022%s: getaddrinfo error: %s\u005cn\u0022, __func__,\n-\t\t\t gai_strerror(n));\n-\t\tgoto bail;\n-\t}\n-\n-\tfor (rp \u003d r; rp; rp \u003d rp-\u003eai_next) {\n-\t\tsock.sockfd \u003d socket(rp-\u003eai_family, rp-\u003eai_socktype,\n-\t\t\t\t rp-\u003eai_protocol);\n-\t\tif (sock.sockfd \u003e\u003d 0)\n-\t\t\tbreak;\n-\t}\n-\tif (!rp) {\n-\t\tlwsl_err(\u0022%s: unable to create INET socket\u005cn\u0022, __func__);\n-\t\tgoto bail1;\n-\t}\n-\n-\tif ((flags \u0026 LWS_CAUDP_BIND) \u0026\u0026\n-\t bind(sock.sockfd, rp-\u003eai_addr, rp-\u003eai_addrlen) \u003d\u003d -1) {\n-\t\tlwsl_err(\u0022%s: bind failed\u005cn\u0022, __func__);\n-\t\tgoto bail2;\n-\t}\n-\n-\twsi \u003d lws_adopt_descriptor_vhost(vhost, LWS_ADOPT_RAW_SOCKET_UDP, sock,\n-\t\t\t\t protocol_name, parent_wsi);\n-\tif (!wsi)\n-\t\tlwsl_err(\u0022%s: udp adoption failed\u005cn\u0022, __func__);\n-\n-bail2:\n-\tif (!wsi)\n-\t\tclose((int)sock.sockfd);\n-bail1:\n-\tfreeaddrinfo(r);\n-\n-bail:\n-\treturn wsi;\n-}\n-\n-#endif\n-\n-\n-\n-static const char *hex \u003d \u00220123456789ABCDEF\u0022;\n-\n-LWS_VISIBLE LWS_EXTERN const char *\n-lws_sql_purify(char *escaped, const char *string, int len)\n-{\n-\tconst char *p \u003d string;\n-\tchar *q \u003d escaped;\n-\n-\twhile (*p \u0026\u0026 len-- \u003e 2) {\n-\t\tif (*p \u003d\u003d '\u005c'') {\n-\t\t\t*q++ \u003d '\u005c'';\n-\t\t\t*q++ \u003d '\u005c'';\n-\t\t\tlen --;\n-\t\t\tp++;\n-\t\t} else\n-\t\t\t*q++ \u003d *p++;\n-\t}\n-\t*q \u003d '\u005c0';\n-\n-\treturn escaped;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN const char *\n-lws_json_purify(char *escaped, const char *string, int len)\n-{\n-\tconst char *p \u003d string;\n-\tchar *q \u003d escaped;\n-\n-\tif (!p) {\n-\t\tescaped[0] \u003d '\u005c0';\n-\t\treturn escaped;\n-\t}\n-\n-\twhile (*p \u0026\u0026 len-- \u003e 6) {\n-\t\tif (*p \u003d\u003d '\u005c\u0022' || *p \u003d\u003d '\u005c\u005c' || *p \u003c 0x20) {\n-\t\t\t*q++ \u003d '\u005c\u005c';\n-\t\t\t*q++ \u003d 'u';\n-\t\t\t*q++ \u003d '0';\n-\t\t\t*q++ \u003d '0';\n-\t\t\t*q++ \u003d hex[((*p) \u003e\u003e 4) \u0026 15];\n-\t\t\t*q++ \u003d hex[(*p) \u0026 15];\n-\t\t\tlen -\u003d 5;\n-\t\t\tp++;\n-\t\t} else\n-\t\t\t*q++ \u003d *p++;\n-\t}\n-\t*q \u003d '\u005c0';\n-\n-\treturn escaped;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_filename_purify_inplace(char *filename)\n-{\n-\twhile (*filename) {\n-\n-\t\tif (*filename \u003d\u003d '.' \u0026\u0026 filename[1] \u003d\u003d '.') {\n-\t\t\t*filename \u003d '_';\n-\t\t\tfilename[1] \u003d '_';\n-\t\t}\n-\n-\t\tif (*filename \u003d\u003d ':' ||\n-\t\t *filename \u003d\u003d '/' ||\n-\t\t *filename \u003d\u003d '\u005c\u005c' ||\n-\t\t *filename \u003d\u003d '$' ||\n-\t\t *filename \u003d\u003d '%')\n-\t\t\t*filename \u003d '_';\n-\n-\t\tfilename++;\n-\t}\n-}\n-\n-LWS_VISIBLE LWS_EXTERN const char *\n-lws_urlencode(char *escaped, const char *string, int len)\n-{\n-\tconst char *p \u003d string;\n-\tchar *q \u003d escaped;\n-\n-\twhile (*p \u0026\u0026 len-- \u003e 3) {\n-\t\tif (*p \u003d\u003d ' ') {\n-\t\t\t*q++ \u003d '+';\n-\t\t\tp++;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif ((*p \u003e\u003d '0' \u0026\u0026 *p \u003c\u003d '9') ||\n-\t\t (*p \u003e\u003d 'A' \u0026\u0026 *p \u003c\u003d 'Z') ||\n-\t\t (*p \u003e\u003d 'a' \u0026\u0026 *p \u003c\u003d 'z')) {\n-\t\t\t*q++ \u003d *p++;\n-\t\t\tcontinue;\n-\t\t}\n-\t\t*q++ \u003d '%';\n-\t\t*q++ \u003d hex[(*p \u003e\u003e 4) \u0026 0xf];\n-\t\t*q++ \u003d hex[*p \u0026 0xf];\n-\n-\t\tlen -\u003d 2;\n-\t\tp++;\n-\t}\n-\t*q \u003d '\u005c0';\n-\n-\treturn escaped;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_urldecode(char *string, const char *escaped, int len)\n-{\n-\tint state \u003d 0, n;\n-\tchar sum \u003d 0;\n-\n-\twhile (*escaped \u0026\u0026 len) {\n-\t\tswitch (state) {\n-\t\tcase 0:\n-\t\t\tif (*escaped \u003d\u003d '%') {\n-\t\t\t\tstate++;\n-\t\t\t\tescaped++;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (*escaped \u003d\u003d '+') {\n-\t\t\t\tescaped++;\n-\t\t\t\t*string++ \u003d ' ';\n-\t\t\t\tlen--;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t*string++ \u003d *escaped++;\n-\t\t\tlen--;\n-\t\t\tbreak;\n-\t\tcase 1:\n-\t\t\tn \u003d char_to_hex(*escaped);\n-\t\t\tif (n \u003c 0)\n-\t\t\t\treturn -1;\n-\t\t\tescaped++;\n-\t\t\tsum \u003d n \u003c\u003c 4;\n-\t\t\tstate++;\n-\t\t\tbreak;\n-\n-\t\tcase 2:\n-\t\t\tn \u003d char_to_hex(*escaped);\n-\t\t\tif (n \u003c 0)\n-\t\t\t\treturn -1;\n-\t\t\tescaped++;\n-\t\t\t*string++ \u003d sum | n;\n-\t\t\tlen--;\n-\t\t\tstate \u003d 0;\n-\t\t\tbreak;\n-\t\t}\n-\n-\t}\n-\t*string \u003d '\u005c0';\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_finalize_startup(struct lws_context *context)\n-{\n-\tstruct lws_context_creation_info info;\n-\n-\tinfo.uid \u003d context-\u003euid;\n-\tinfo.gid \u003d context-\u003egid;\n-\n-#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n-\tmemcpy(info.caps, context-\u003ecaps, sizeof(info.caps));\n-\tinfo.count_caps \u003d context-\u003ecount_caps;\n-#endif\n-\n-\tif (lws_check_opt(context-\u003eoptions, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))\n-\t\tlws_plat_drop_app_privileges(\u0026info);\n-\n-\treturn 0;\n-}\n-\n-int\n-lws_snprintf(char *str, size_t size, const char *format, ...)\n-{\n-\tva_list ap;\n-\tint n;\n-\n-\tif (!size)\n-\t\treturn 0;\n-\n-\tva_start(ap, format);\n-\tn \u003d vsnprintf(str, size, format, ap);\n-\tva_end(ap);\n-\n-\tif (n \u003e\u003d (int)size)\n-\t\treturn (int)size;\n-\n-\treturn n;\n-}\n-\n-char *\n-lws_strncpy(char *dest, const char *src, size_t size)\n-{\n-\tstrncpy(dest, src, size - 1);\n-\tdest[size - 1] \u003d '\u005c0';\n-\n-\treturn dest;\n-}\n-\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_is_cgi(struct lws *wsi) {\n-#ifdef LWS_WITH_CGI\n-\treturn !!wsi-\u003ehttp.cgi;\n-#else\n-\treturn 0;\n-#endif\n-}\n-\n-const struct lws_protocol_vhost_options *\n-lws_pvo_search(const struct lws_protocol_vhost_options *pvo, const char *name)\n-{\n-\twhile (pvo) {\n-\t\tif (!strcmp(pvo-\u003ename, name))\n-\t\t\tbreak;\n-\n-\t\tpvo \u003d pvo-\u003enext;\n-\t}\n-\n-\treturn pvo;\n-}\n-\n-void\n-lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs)\n-{\n-\tconst struct lws_vhost *vh \u003d ctx-\u003evhost_list;\n-\n-\twhile (vh) {\n-\n-\t\tcs-\u003erx +\u003d vh-\u003econn_stats.rx;\n-\t\tcs-\u003etx +\u003d vh-\u003econn_stats.tx;\n-\t\tcs-\u003eh1_conn +\u003d vh-\u003econn_stats.h1_conn;\n-\t\tcs-\u003eh1_trans +\u003d vh-\u003econn_stats.h1_trans;\n-\t\tcs-\u003eh2_trans +\u003d vh-\u003econn_stats.h2_trans;\n-\t\tcs-\u003ews_upg +\u003d vh-\u003econn_stats.ws_upg;\n-\t\tcs-\u003eh2_upg +\u003d vh-\u003econn_stats.h2_upg;\n-\t\tcs-\u003eh2_alpn +\u003d vh-\u003econn_stats.h2_alpn;\n-\t\tcs-\u003eh2_subs +\u003d vh-\u003econn_stats.h2_subs;\n-\t\tcs-\u003erejected +\u003d vh-\u003econn_stats.rejected;\n-\n-\t\tvh \u003d vh-\u003evhost_next;\n-\t}\n-}\n-\n-const char *\n-lws_cmdline_option(int argc, const char **argv, const char *val)\n-{\n-\tint n \u003d (int)strlen(val), c \u003d argc;\n-\n-\twhile (--c \u003e 0)\n-\t\tif (!strncmp(argv[c], val, n)) {\n-\t\t\tif (!*(argv[c] + n) \u0026\u0026 c !\u003d argc - 1)\n-\t\t\t\treturn argv[c + 1];\n-\n-\t\t\treturn argv[c] + n;\n-\t\t}\n-\n-\treturn NULL;\n-}\n-\n-#ifdef LWS_WITH_SERVER_STATUS\n-\n-LWS_EXTERN int\n-lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len)\n-{\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tstatic const char * const prots[] \u003d {\n-\t\t\u0022http://\u0022,\n-\t\t\u0022https://\u0022,\n-\t\t\u0022file://\u0022,\n-\t\t\u0022cgi://\u0022,\n-\t\t\u0022\u003ehttp://\u0022,\n-\t\t\u0022\u003ehttps://\u0022,\n-\t\t\u0022callback://\u0022\n-\t};\n-#endif\n-\tchar *orig \u003d buf, *end \u003d buf + len - 1, first \u003d 1;\n-\tint n \u003d 0;\n-\n-\tif (len \u003c 100)\n-\t\treturn 0;\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\u0022{\u005cn \u005c\u0022name\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022port\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022use_ssl\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022sts\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022rx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022tx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h1_conn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h1_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022ws_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022rejected\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_alpn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_subs\u005c\u0022:\u005c\u0022%lu\u005c\u0022\u0022\n-\t\t\t,\n-\t\t\tvh-\u003ename, vh-\u003elisten_port,\n-#if defined(LWS_WITH_TLS)\n-\t\t\tvh-\u003etls.use_ssl \u0026 LCCSCF_USE_SSL,\n-#else\n-\t\t\t0,\n-#endif\n-\t\t\t!!(vh-\u003eoptions \u0026 LWS_SERVER_OPTION_STS),\n-\t\t\tvh-\u003econn_stats.rx, vh-\u003econn_stats.tx,\n-\t\t\tvh-\u003econn_stats.h1_conn,\n-\t\t\tvh-\u003econn_stats.h1_trans,\n-\t\t\tvh-\u003econn_stats.h2_trans,\n-\t\t\tvh-\u003econn_stats.ws_upg,\n-\t\t\tvh-\u003econn_stats.rejected,\n-\t\t\tvh-\u003econn_stats.h2_upg,\n-\t\t\tvh-\u003econn_stats.h2_alpn,\n-\t\t\tvh-\u003econn_stats.h2_subs\n-\t);\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tif (vh-\u003ehttp.mount_list) {\n-\t\tconst struct lws_http_mount *m \u003d vh-\u003ehttp.mount_list;\n-\n-\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u005cn \u005c\u0022mounts\u005c\u0022:[\u0022);\n-\t\twhile (m) {\n-\t\t\tif (!first)\n-\t\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u0022);\n-\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\t\t\u0022\u005cn {\u005cn \u005c\u0022mountpoint\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\t\u0022 \u005c\u0022origin\u005c\u0022:\u005c\u0022%s%s\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\t\u0022 \u005c\u0022cache_max_age\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\t\u0022 \u005c\u0022cache_reuse\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\t\u0022 \u005c\u0022cache_revalidate\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\t\u0022 \u005c\u0022cache_intermediaries\u005c\u0022:\u005c\u0022%d\u005c\u0022\u005cn\u0022\n-\t\t\t\t\t,\n-\t\t\t\t\tm-\u003emountpoint,\n-\t\t\t\t\tprots[m-\u003eorigin_protocol],\n-\t\t\t\t\tm-\u003eorigin,\n-\t\t\t\t\tm-\u003ecache_max_age,\n-\t\t\t\t\tm-\u003ecache_reusable,\n-\t\t\t\t\tm-\u003ecache_revalidate,\n-\t\t\t\t\tm-\u003ecache_intermediaries);\n-\t\t\tif (m-\u003edef)\n-\t\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\t\t\t\u0022,\u005cn \u005c\u0022default\u005c\u0022:\u005c\u0022%s\u005c\u0022\u0022,\n-\t\t\t\t\t\tm-\u003edef);\n-\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn }\u0022);\n-\t\t\tfirst \u003d 0;\n-\t\t\tm \u003d m-\u003emount_next;\n-\t\t}\n-\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn ]\u0022);\n-\t}\n-#endif\n-\tif (vh-\u003eprotocols) {\n-\t\tn \u003d 0;\n-\t\tfirst \u003d 1;\n-\n-\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u005cn \u005c\u0022ws-protocols\u005c\u0022:[\u0022);\n-\t\twhile (n \u003c vh-\u003ecount_protocols) {\n-\t\t\tif (!first)\n-\t\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u0022);\n-\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\t\t\u0022\u005cn {\u005cn \u005c\u0022%s\u005c\u0022:{\u005cn\u0022\n-\t\t\t\t\t\u0022 \u005c\u0022status\u005c\u0022:\u005c\u0022ok\u005c\u0022\u005cn }\u005cn }\u0022\n-\t\t\t\t\t,\n-\t\t\t\t\tvh-\u003eprotocols[n].name);\n-\t\t\tfirst \u003d 0;\n-\t\t\tn++;\n-\t\t}\n-\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn ]\u0022);\n-\t}\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005cn}\u0022);\n-\n-\treturn buf - orig;\n-}\n-\n-\n-LWS_EXTERN LWS_VISIBLE int\n-lws_json_dump_context(const struct lws_context *context, char *buf, int len,\n-\t\tint hide_vhosts)\n-{\n-\tchar *orig \u003d buf, *end \u003d buf + len - 1, first \u003d 1;\n-\tconst struct lws_vhost *vh \u003d context-\u003evhost_list;\n-\tconst struct lws_context_per_thread *pt;\n-\ttime_t t \u003d time(NULL);\n-\tint n, listening \u003d 0, cgi_count \u003d 0;\n-\tstruct lws_conn_stats cs;\n-\tdouble d \u003d 0;\n-#ifdef LWS_WITH_CGI\n-\tstruct lws_cgi * const *pcgi;\n-#endif\n-\n-#ifdef LWS_WITH_LIBUV\n-\tuv_uptime(\u0026d);\n-#endif\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022{ \u0022\n-\t\t\t \u0022\u005c\u0022version\u005c\u0022:\u005c\u0022%s\u005c\u0022,\u005cn\u0022\n-\t\t\t \u0022\u005c\u0022uptime\u005c\u0022:\u005c\u0022%ld\u005c\u0022,\u005cn\u0022,\n-\t\t\t lws_get_library_version(),\n-\t\t\t (long)d);\n-\n-#ifdef LWS_HAVE_GETLOADAVG\n-\t{\n-\t\tdouble d[3];\n-\t\tint m;\n-\n-\t\tm \u003d getloadavg(d, 3);\n-\t\tfor (n \u003d 0; n \u003c m; n++) {\n-\t\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\t\u0022\u005c\u0022l%d\u005c\u0022:\u005c\u0022%.2f\u005c\u0022,\u005cn\u0022,\n-\t\t\t\tn + 1, d[n]);\n-\t\t}\n-\t}\n-#endif\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005c\u0022contexts\u005c\u0022:[\u005cn\u0022);\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022{ \u0022\n-\t\t\t\t\u0022\u005c\u0022context_uptime\u005c\u0022:\u005c\u0022%ld\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022\u005c\u0022cgi_spawned\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022\u005c\u0022pt_fd_max\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022\u005c\u0022ah_pool_max\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022\u005c\u0022deprecated\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022\u005c\u0022wsi_alive\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022,\n-\t\t\t\t(unsigned long)(t - context-\u003etime_up),\n-\t\t\t\tcontext-\u003ecount_cgi_spawned,\n-\t\t\t\tcontext-\u003efd_limit_per_thread,\n-\t\t\t\tcontext-\u003emax_http_header_pool,\n-\t\t\t\tcontext-\u003edeprecated,\n-\t\t\t\tcontext-\u003ecount_wsi_allocated);\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022\u005c\u0022pt\u005c\u0022:[\u005cn \u0022);\n-\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\tpt \u003d \u0026context-\u003ept[n];\n-\t\tif (n)\n-\t\t\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u0022);\n-\t\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\t\u0022\u005cn {\u005cn\u0022\n-\t\t\t\t\u0022 \u005c\u0022fds_count\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022 \u005c\u0022ah_pool_inuse\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\t\u0022 \u005c\u0022ah_wait_list\u005c\u0022:\u005c\u0022%d\u005c\u0022\u005cn\u0022\n-\t\t\t\t\u0022 }\u0022,\n-\t\t\t\tpt-\u003efds_count,\n-\t\t\t\tpt-\u003ehttp.ah_count_in_use,\n-\t\t\t\tpt-\u003ehttp.ah_wait_list_length);\n-\t}\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022]\u0022);\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022, \u005c\u0022vhosts\u005c\u0022:[\u005cn \u0022);\n-\n-\tfirst \u003d 1;\n-\tvh \u003d context-\u003evhost_list;\n-\tlistening \u003d 0;\n-\tcs \u003d context-\u003econn_stats;\n-\tlws_sum_stats(context, \u0026cs);\n-\twhile (vh) {\n-\n-\t\tif (!hide_vhosts) {\n-\t\t\tif (!first)\n-\t\t\t\tif(buf !\u003d end)\n-\t\t\t\t\t*buf++ \u003d ',';\n-\t\t\tbuf +\u003d lws_json_dump_vhost(vh, buf, end - buf);\n-\t\t\tfirst \u003d 0;\n-\t\t}\n-\t\tif (vh-\u003elserv_wsi)\n-\t\t\tlistening++;\n-\t\tvh \u003d vh-\u003evhost_next;\n-\t}\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf,\n-\t\t\t\u0022],\u005cn\u005c\u0022listen_wsi\u005c\u0022:\u005c\u0022%d\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022rx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022tx\u005c\u0022:\u005c\u0022%llu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h1_conn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h1_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_trans\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022ws_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022rejected\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_alpn\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_subs\u005c\u0022:\u005c\u0022%lu\u005c\u0022,\u005cn\u0022\n-\t\t\t\u0022 \u005c\u0022h2_upg\u005c\u0022:\u005c\u0022%lu\u005c\u0022\u0022,\n-\t\t\tlistening, cs.rx, cs.tx,\n-\t\t\tcs.h1_conn,\n-\t\t\tcs.h1_trans,\n-\t\t\tcs.h2_trans,\n-\t\t\tcs.ws_upg,\n-\t\t\tcs.rejected,\n-\t\t\tcs.h2_alpn,\n-\t\t\tcs.h2_subs,\n-\t\t\tcs.h2_upg);\n-\n-#ifdef LWS_WITH_CGI\n-\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\tpt \u003d \u0026context-\u003ept[n];\n-\t\tpcgi \u003d \u0026pt-\u003ehttp.cgi_list;\n-\n-\t\twhile (*pcgi) {\n-\t\t\tpcgi \u003d \u0026(*pcgi)-\u003ecgi_list;\n-\n-\t\t\tcgi_count++;\n-\t\t}\n-\t}\n-#endif\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022,\u005cn \u005c\u0022cgi_alive\u005c\u0022:\u005c\u0022%d\u005c\u0022\u005cn \u0022,\n-\t\t\tcgi_count);\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022}\u0022);\n-\n-\n-\tbuf +\u003d lws_snprintf(buf, end - buf, \u0022]}\u005cn \u0022);\n-\n-\treturn buf - orig;\n-}\n-\n-#endif\n-\n-#if defined(LWS_WITH_STATS)\n-\n-LWS_VISIBLE LWS_EXTERN uint64_t\n-lws_stats_get(struct lws_context *context, int index)\n-{\n-\tif (index \u003e\u003d LWSSTATS_SIZE)\n-\t\treturn 0;\n-\n-\treturn context-\u003elws_stats[index];\n-}\n-\n-LWS_VISIBLE LWS_EXTERN void\n-lws_stats_log_dump(struct lws_context *context)\n-{\n-\tstruct lws_vhost *v \u003d context-\u003evhost_list;\n-\tint n, m;\n-\n-\t(void)m;\n-\n-\tif (!context-\u003eupdated)\n-\t\treturn;\n-\n-\tcontext-\u003eupdated \u003d 0;\n-\n-\tlwsl_notice(\u0022\u005cn\u0022);\n-\tlwsl_notice(\u0022LWS internal statistics dump -----\u003e\u005cn\u0022);\n-\tlwsl_notice(\u0022LWSSTATS_C_CONNECTIONS: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_CONNECTIONS));\n-\tlwsl_notice(\u0022LWSSTATS_C_API_CLOSE: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_API_CLOSE));\n-\tlwsl_notice(\u0022LWSSTATS_C_API_READ: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_API_READ));\n-\tlwsl_notice(\u0022LWSSTATS_C_API_LWS_WRITE: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_API_LWS_WRITE));\n-\tlwsl_notice(\u0022LWSSTATS_C_API_WRITE: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_API_WRITE));\n-\tlwsl_notice(\u0022LWSSTATS_C_WRITE_PARTIALS: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_WRITE_PARTIALS));\n-\tlwsl_notice(\u0022LWSSTATS_C_WRITEABLE_CB_REQ: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_WRITEABLE_CB_REQ));\n-\tlwsl_notice(\u0022LWSSTATS_C_WRITEABLE_CB_EFF_REQ: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_WRITEABLE_CB_EFF_REQ));\n-\tlwsl_notice(\u0022LWSSTATS_C_WRITEABLE_CB: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_WRITEABLE_CB));\n-\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN));\n-\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNECTIONS_FAILED: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_FAILED));\n-\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_ACCEPTED));\n-\tlwsl_notice(\u0022LWSSTATS_C_SSL_CONNS_HAD_RX: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_SSL_CONNS_HAD_RX));\n-\tlwsl_notice(\u0022LWSSTATS_C_PEER_LIMIT_AH_DENIED: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_PEER_LIMIT_AH_DENIED));\n-\tlwsl_notice(\u0022LWSSTATS_C_PEER_LIMIT_WSI_DENIED: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_PEER_LIMIT_WSI_DENIED));\n-\n-\tlwsl_notice(\u0022LWSSTATS_C_TIMEOUTS: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_TIMEOUTS));\n-\tlwsl_notice(\u0022LWSSTATS_C_SERVICE_ENTRY: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_SERVICE_ENTRY));\n-\tlwsl_notice(\u0022LWSSTATS_B_READ: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context, LWSSTATS_B_READ));\n-\tlwsl_notice(\u0022LWSSTATS_B_WRITE: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context, LWSSTATS_B_WRITE));\n-\tlwsl_notice(\u0022LWSSTATS_B_PARTIALS_ACCEPTED_PARTS: %8llu\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_B_PARTIALS_ACCEPTED_PARTS));\n-\tlwsl_notice(\u0022LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY: %8llums\u005cn\u0022,\n-\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\tLWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) / 1000);\n-\tif (lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED))\n-\t\tlwsl_notice(\u0022 Avg accept delay: %8llums\u005cn\u0022,\n-\t\t\t(unsigned long long)(lws_stats_get(context,\n-\t\t\t\tLWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) /\n-\t\t\t\t\tlws_stats_get(context,\n-\t\t\t\tLWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)) / 1000);\n-\tlwsl_notice(\u0022LWSSTATS_MS_SSL_RX_DELAY: %8llums\u005cn\u0022,\n-\t\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_MS_SSL_RX_DELAY) / 1000);\n-\tif (lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX))\n-\t\tlwsl_notice(\u0022 Avg accept-rx delay: %8llums\u005cn\u0022,\n-\t\t\t(unsigned long long)(lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_MS_SSL_RX_DELAY) /\n-\t\t\tlws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_C_SSL_CONNS_HAD_RX)) / 1000);\n-\n-\tlwsl_notice(\u0022LWSSTATS_MS_WRITABLE_DELAY: %8lluus\u005cn\u0022,\n-\t\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_MS_WRITABLE_DELAY));\n-\tlwsl_notice(\u0022LWSSTATS_MS_WORST_WRITABLE_DELAY: %8lluus\u005cn\u0022,\n-\t\t\t\t(unsigned long long)lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_MS_WORST_WRITABLE_DELAY));\n-\tif (lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB))\n-\t\tlwsl_notice(\u0022 Avg writable delay: %8lluus\u005cn\u0022,\n-\t\t\t(unsigned long long)(lws_stats_get(context,\n-\t\t\t\t\tLWSSTATS_MS_WRITABLE_DELAY) /\n-\t\t\tlws_stats_get(context, LWSSTATS_C_WRITEABLE_CB)));\n-\tlwsl_notice(\u0022Simultaneous SSL restriction: %8d/%d\u005cn\u0022,\n-\t\t\tcontext-\u003esimultaneous_ssl,\n-\t\t\tcontext-\u003esimultaneous_ssl_restriction);\n-\n-\tlwsl_notice(\u0022Live wsi: %8d\u005cn\u0022,\n-\t\t\tcontext-\u003ecount_wsi_allocated);\n-\n-\tcontext-\u003eupdated \u003d 1;\n-\n-\twhile (v) {\n-\t\tif (v-\u003elserv_wsi) {\n-\n-\t\t\tstruct lws_context_per_thread *pt \u003d\n-\t\t\t\t\t\u0026context-\u003ept[(int)v-\u003elserv_wsi-\u003etsi];\n-\t\t\tstruct lws_pollfd *pfd;\n-\n-\t\t\tpfd \u003d \u0026pt-\u003efds[v-\u003elserv_wsi-\u003eposition_in_fds_table];\n-\n-\t\t\tlwsl_notice(\u0022 Listen port %d actual POLLIN: %d\u005cn\u0022,\n-\t\t\t\t v-\u003elisten_port,\n-\t\t\t\t (int)pfd-\u003eevents \u0026 LWS_POLLIN);\n-\t\t}\n-\n-\t\tv \u003d v-\u003evhost_next;\n-\t}\n-\n-\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++) {\n-\t\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[n];\n-\t\tstruct lws *wl;\n-\t\tint m \u003d 0;\n-\n-\t\tlwsl_notice(\u0022PT %d\u005cn\u0022, n + 1);\n-\n-\t\tlws_pt_lock(pt, __func__);\n-\n-\t\tlwsl_notice(\u0022 AH in use / max: %d / %d\u005cn\u0022,\n-\t\t\t\tpt-\u003ehttp.ah_count_in_use,\n-\t\t\t\tcontext-\u003emax_http_header_pool);\n-\n-\t\twl \u003d pt-\u003ehttp.ah_wait_list;\n-\t\twhile (wl) {\n-\t\t\tm++;\n-\t\t\twl \u003d wl-\u003eah_wait_list;\n-\t\t}\n-\n-\t\tlwsl_notice(\u0022 AH wait list count / actual: %d / %d\u005cn\u0022,\n-\t\t\t\tpt-\u003ehttp.ah_wait_list_length, m);\n-\n-\t\tlws_pt_unlock(pt);\n-\t}\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tm \u003d 0;\n-\tfor (n \u003d 0; n \u003c (int)context-\u003epl_hash_elements; n++) {\n-\t\tlws_start_foreach_llp(struct lws_peer **, peer,\n-\t\t\t\t context-\u003epl_hash_table[n]) {\n-\t\t\tm++;\n-\t\t} lws_end_foreach_llp(peer, next);\n-\t}\n-\n-\tlwsl_notice(\u0022 Peers: total active %d\u005cn\u0022, m);\n-\tif (m \u003e 10) {\n-\t\tm \u003d 10;\n-\t\tlwsl_notice(\u0022 (showing 10 peers only)\u005cn\u0022);\n-\t}\n-\n-\tif (m) {\n-\t\tfor (n \u003d 0; n \u003c (int)context-\u003epl_hash_elements; n++) {\n-\t\t\tchar buf[72];\n-\n-\t\t\tlws_start_foreach_llp(struct lws_peer **, peer,\n-\t\t\t\t\t context-\u003epl_hash_table[n]) {\n-\t\t\t\tstruct lws_peer *df \u003d *peer;\n-\n-\t\t\t\tif (!lws_plat_inet_ntop(df-\u003eaf, df-\u003eaddr, buf,\n-\t\t\t\t\t\t\tsizeof(buf) - 1))\n-\t\t\t\t\tstrcpy(buf, \u0022unknown\u0022);\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\t\t\t\tlwsl_notice(\u0022 peer %s: count wsi: %d, count ah: %d\u005cn\u0022,\n-\t\t\t\t\t buf, df-\u003ecount_wsi, df-\u003ecount_ah);\n-#else\n-\t\t\t\tlwsl_notice(\u0022 peer %s: count wsi: %d\u005cn\u0022,\n-\t\t\t\t\t buf, df-\u003ecount_wsi);\n-#endif\n-\n-\t\t\t\tif (!--m)\n-\t\t\t\t\tbreak;\n-\t\t\t} lws_end_foreach_llp(peer, next);\n-\t\t}\n-\t}\n-#endif\n-\n-\tlwsl_notice(\u0022\u005cn\u0022);\n-}\n-\n-void\n-lws_stats_atomic_bump(struct lws_context * context,\n-\t\tstruct lws_context_per_thread *pt, int index, uint64_t bump)\n-{\n-\tlws_pt_stats_lock(pt);\n-\tcontext-\u003elws_stats[index] +\u003d bump;\n-\tif (index !\u003d LWSSTATS_C_SERVICE_ENTRY)\n-\t\tcontext-\u003eupdated \u003d 1;\n-\tlws_pt_stats_unlock(pt);\n-}\n-\n-void\n-lws_stats_atomic_max(struct lws_context * context,\n-\t\tstruct lws_context_per_thread *pt, int index, uint64_t val)\n-{\n-\tlws_pt_stats_lock(pt);\n-\tif (val \u003e context-\u003elws_stats[index]) {\n-\t\tcontext-\u003elws_stats[index] \u003d val;\n-\t\tcontext-\u003eupdated \u003d 1;\n-\t}\n-\tlws_pt_stats_unlock(pt);\n-}\n-\n-#endif\n-\ndiff --git a/lib/libwebsockets.h b/lib/libwebsockets.h\nindex 14c65ac..c4f8bcb 100644\n--- a/lib/libwebsockets.h\n+++ b/lib/libwebsockets.h\n@@ -27,7 +27,7 @@\n #ifdef __cplusplus\n #include \u003ccstddef\u003e\n #include \u003ccstdarg\u003e\n-#\n+\n extern \u0022C\u0022 {\n #else\n #include \u003cstdarg.h\u003e\ndiff --git a/lib/misc/base64-decode.c b/lib/misc/base64-decode.c\nindex 27db51f..64b84d7 100644\n--- a/lib/misc/base64-decode.c\n+++ b/lib/misc/base64-decode.c\n@@ -40,7 +40,7 @@\n \n #include \u003cstdio.h\u003e\n #include \u003cstring.h\u003e\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static const char encode_orig[] \u003d \u0022ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0022\n \t\t\t \u0022abcdefghijklmnopqrstuvwxyz0123456789+/\u0022;\ndiff --git a/lib/misc/daemonize.c b/lib/misc/daemonize.c\nindex eb92821..457f290 100644\n--- a/lib/misc/daemonize.c\n+++ b/lib/misc/daemonize.c\n@@ -22,7 +22,7 @@\n #include \u003cunistd.h\u003e\n #include \u003cerrno.h\u003e\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n int pid_daemon;\n static char *lock_path;\ndiff --git a/lib/misc/getifaddrs.c b/lib/misc/getifaddrs.c\nindex 4f42ab4..735b899 100644\n--- a/lib/misc/getifaddrs.c\n+++ b/lib/misc/getifaddrs.c\n@@ -43,7 +43,7 @@\n #include \u003cstring.h\u003e\n #include \u003csys/ioctl.h\u003e\n #include \u003cunistd.h\u003e\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #ifdef LWS_HAVE_SYS_SOCKIO_H\n #include \u003csys/sockio.h\u003e\ndiff --git a/lib/misc/jws/jwk.c b/lib/misc/jws/jwk.c\nindex 000da84..2337d5e 100644\n--- a/lib/misc/jws/jwk.c\n+++ b/lib/misc/jws/jwk.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #include \u003cfcntl.h\u003e\n #include \u003cunistd.h\u003e\ndiff --git a/lib/misc/jws/jws.c b/lib/misc/jws/jws.c\nindex feacfe0..23a863c 100644\n--- a/lib/misc/jws/jws.c\n+++ b/lib/misc/jws/jws.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * JSON Web Signature is defined in RFC7515\ndiff --git a/lib/misc/lws-ring.c b/lib/misc/lws-ring.c\nindex d1079ca..bbd4df9 100644\n--- a/lib/misc/lws-ring.c\n+++ b/lib/misc/lws-ring.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n LWS_VISIBLE LWS_EXTERN struct lws_ring *\n lws_ring_create(size_t element_len, size_t count,\ndiff --git a/lib/misc/peer-limits.c b/lib/misc/peer-limits.c\nindex 373ec54..66deef4 100644\n--- a/lib/misc/peer-limits.c\n+++ b/lib/misc/peer-limits.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /* requires context-\u003elock */\n static void\ndiff --git a/lib/misc/sha-1.c b/lib/misc/sha-1.c\nindex 50205a0..2e4db52 100644\n--- a/lib/misc/sha-1.c\n+++ b/lib/misc/sha-1.c\n@@ -32,7 +32,7 @@\n * implemented by Jun-ichiro itojun Itoh \u003citojun@itojun.org\u003e\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #ifdef LWS_HAVE_SYS_TYPES_H\n #include \u003csys/types.h\u003e\ndiff --git a/lib/misc/smtp.c b/lib/misc/smtp.c\nindex dc76360..290499c 100644\n--- a/lib/misc/smtp.c\n+++ b/lib/misc/smtp.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static unsigned int\n lwsgs_now_secs(void)\ndiff --git a/lib/output.c b/lib/output.c\ndeleted file mode 100644\nindex 7d1a748..0000000\n--- a/lib/output.c\n+++ /dev/null\n@@ -1,308 +0,0 @@\n-/*\n- * libwebsockets - small server side websockets and web server implementation\n- *\n- * Copyright (C) 2010-2017 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This library is free software; you can redistribute it and/or\n- * modify it under the terms of the GNU Lesser General Public\n- * License as published by the Free Software Foundation:\n- * version 2.1 of the License.\n- *\n- * This library is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * Lesser General Public License for more details.\n- *\n- * You should have received a copy of the GNU Lesser General Public\n- * License along with this library; if not, write to the Free Software\n- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n- * MA 02110-1301 USA\n- */\n-\n-#include \u0022private-libwebsockets.h\u0022\n-\n-/*\n- * notice this returns number of bytes consumed, or -1\n- */\n-int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)\n-{\n-\tstruct lws_context *context \u003d lws_get_context(wsi);\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tsize_t real_len \u003d len;\n-\tunsigned int n;\n-\n-\t// lwsl_hexdump_err(buf, len);\n-\n-\t/*\n-\t * Detect if we got called twice without going through the\n-\t * event loop to handle pending. This would be caused by either\n-\t * back-to-back writes in one WRITABLE (illegal) or calling lws_write()\n-\t * from outside the WRITABLE callback (illegal).\n-\t */\n-\tif (wsi-\u003ecould_have_pending) {\n-\t\tlwsl_hexdump_level(LLL_ERR, buf, len);\n-\t\tlwsl_err(\u0022** %p: vh: %s, prot: %s, role %s: \u0022\n-\t\t\t \u0022Illegal back-to-back write of %lu detected...\u005cn\u0022,\n-\t\t\t wsi, wsi-\u003evhost-\u003ename, wsi-\u003eprotocol-\u003ename,\n-\t\t\t wsi-\u003erole_ops-\u003ename,\n-\t\t\t (unsigned long)len);\n-\t\t// assert(0);\n-\n-\t\treturn -1;\n-\t}\n-\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_API_WRITE, 1);\n-\n-\tif (!len)\n-\t\treturn 0;\n-\t/* just ignore sends after we cleared the truncation buffer */\n-\tif (lwsi_state(wsi) \u003d\u003d LRS_FLUSHING_BEFORE_CLOSE \u0026\u0026 !wsi-\u003etrunc_len)\n-\t\treturn (int)len;\n-\n-\tif (wsi-\u003etrunc_len \u0026\u0026 (buf \u003c wsi-\u003etrunc_alloc ||\n-\t buf \u003e (wsi-\u003etrunc_alloc + wsi-\u003etrunc_len + wsi-\u003etrunc_offset))) {\n-\t\tlwsl_hexdump_level(LLL_ERR, buf, len);\n-\t\tlwsl_err(\u0022** %p: vh: %s, prot: %s, Sending new %lu, pending truncated ...\u005cn\u0022\n-\t\t\t \u0022 It's illegal to do an lws_write outside of\u005cn\u0022\n-\t\t\t \u0022 the writable callback: fix your code\u005cn\u0022,\n-\t\t\t wsi, wsi-\u003evhost-\u003ename, wsi-\u003eprotocol-\u003ename,\n-\t\t\t (unsigned long)len);\n-\t\tassert(0);\n-\n-\t\treturn -1;\n-\t}\n-\n-\tif (!wsi-\u003ehttp2_substream \u0026\u0026 !lws_socket_is_valid(wsi-\u003edesc.sockfd))\n-\t\tlwsl_warn(\u0022** error invalid sock but expected to send\u005cn\u0022);\n-\n-\t/* limit sending */\n-\tif (wsi-\u003eprotocol-\u003etx_packet_size)\n-\t\tn \u003d (int)wsi-\u003eprotocol-\u003etx_packet_size;\n-\telse {\n-\t\tn \u003d (int)wsi-\u003eprotocol-\u003erx_buffer_size;\n-\t\tif (!n)\n-\t\t\tn \u003d context-\u003ept_serv_buf_size;\n-\t}\n-\tn +\u003d LWS_PRE + 4;\n-\tif (n \u003e len)\n-\t\tn \u003d (int)len;\n-\n-\t/* nope, send it on the socket directly */\n-\tlws_latency_pre(context, wsi);\n-\tn \u003d lws_ssl_capable_write(wsi, buf, n);\n-\tlws_latency(context, wsi, \u0022send lws_issue_raw\u0022, n, n \u003d\u003d len);\n-\n-\t/* something got written, it can have been truncated now */\n-\twsi-\u003ecould_have_pending \u003d 1;\n-\n-\tswitch (n) {\n-\tcase LWS_SSL_CAPABLE_ERROR:\n-\t\t/* we're going to close, let close know sends aren't possible */\n-\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\treturn -1;\n-\tcase LWS_SSL_CAPABLE_MORE_SERVICE:\n-\t\t/*\n-\t\t * nothing got sent, not fatal. Retry the whole thing later,\n-\t\t * ie, implying treat it was a truncated send so it gets\n-\t\t * retried\n-\t\t */\n-\t\tn \u003d 0;\n-\t\tbreak;\n-\t}\n-\n-\t/*\n-\t * we were already handling a truncated send?\n-\t */\n-\tif (wsi-\u003etrunc_len) {\n-\t\tlwsl_info(\u0022%p partial adv %d (vs %ld)\u005cn\u0022, wsi, n, (long)real_len);\n-\t\twsi-\u003etrunc_offset +\u003d n;\n-\t\twsi-\u003etrunc_len -\u003d n;\n-\n-\t\tif (!wsi-\u003etrunc_len) {\n-\t\t\tlwsl_info(\u0022** %p partial send completed\u005cn\u0022, wsi);\n-\t\t\t/* done with it, but don't free it */\n-\t\t\tn \u003d (int)real_len;\n-\t\t\tif (lwsi_state(wsi) \u003d\u003d LRS_FLUSHING_BEFORE_CLOSE) {\n-\t\t\t\tlwsl_info(\u0022** %p signalling to close now\u005cn\u0022, wsi);\n-\t\t\t\treturn -1; /* retry closing now */\n-\t\t\t}\n-\t\t}\n-\t\t/* always callback on writeable */\n-\t\tlws_callback_on_writable(wsi);\n-\n-\t\treturn n;\n-\t}\n-\n-\tif ((unsigned int)n \u003d\u003d real_len)\n-\t\t/* what we just sent went out cleanly */\n-\t\treturn n;\n-\n-\t/*\n-\t * Newly truncated send. Buffer the remainder (it will get\n-\t * first priority next time the socket is writable).\n-\t */\n-\tlwsl_debug(\u0022%p new partial sent %d from %lu total\u005cn\u0022, wsi, n,\n-\t\t (unsigned long)real_len);\n-\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_WRITE_PARTIALS, 1);\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, n);\n-\n-\t/*\n-\t * - if we still have a suitable malloc lying around, use it\n-\t * - or, if too small, reallocate it\n-\t * - or, if no buffer, create it\n-\t */\n-\tif (!wsi-\u003etrunc_alloc || real_len - n \u003e wsi-\u003etrunc_alloc_len) {\n-\t\tlws_free(wsi-\u003etrunc_alloc);\n-\n-\t\twsi-\u003etrunc_alloc_len \u003d (unsigned int)(real_len - n);\n-\t\twsi-\u003etrunc_alloc \u003d lws_malloc(real_len - n,\n-\t\t\t\t\t \u0022truncated send alloc\u0022);\n-\t\tif (!wsi-\u003etrunc_alloc) {\n-\t\t\tlwsl_err(\u0022truncated send: unable to malloc %lu\u005cn\u0022,\n-\t\t\t\t (unsigned long)(real_len - n));\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\twsi-\u003etrunc_offset \u003d 0;\n-\twsi-\u003etrunc_len \u003d (unsigned int)(real_len - n);\n-\tmemcpy(wsi-\u003etrunc_alloc, buf + n, real_len - n);\n-\n-#if !defined(LWS_WITH_ESP32)\n-\tif (lws_wsi_is_udp(wsi)) {\n-\t\t/* stash original destination for fulfilling UDP partials */\n-\t\twsi-\u003eudp-\u003esa_pending \u003d wsi-\u003eudp-\u003esa;\n-\t\twsi-\u003eudp-\u003esalen_pending \u003d wsi-\u003eudp-\u003esalen;\n-\t}\n-#endif\n-\n-\t/* since something buffered, force it to get another chance to send */\n-\tlws_callback_on_writable(wsi);\n-\n-\treturn (int)real_len;\n-}\n-\n-LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,\n-\t\t\t enum lws_write_protocol wp)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\n-\tif (wsi-\u003eparent_carries_io) {\n-\t\tstruct lws_write_passthru pas;\n-\n-\t\tpas.buf \u003d buf;\n-\t\tpas.len \u003d len;\n-\t\tpas.wp \u003d wp;\n-\t\tpas.wsi \u003d wsi;\n-\n-\t\tif (wsi-\u003eparent-\u003eprotocol-\u003ecallback(wsi-\u003eparent,\n-\t\t\t\tLWS_CALLBACK_CHILD_WRITE_VIA_PARENT,\n-\t\t\t\twsi-\u003eparent-\u003euser_space,\n-\t\t\t\t(void *)\u0026pas, 0))\n-\t\t\treturn 1;\n-\n-\t\treturn (int)len;\n-\t}\n-\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_API_LWS_WRITE, 1);\n-\n-\tif ((int)len \u003c 0) {\n-\t\tlwsl_err(\u0022%s: suspicious len int %d, ulong %lu\u005cn\u0022, __func__,\n-\t\t\t\t(int)len, (unsigned long)len);\n-\t\treturn -1;\n-\t}\n-\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_B_WRITE, len);\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-\twsi-\u003ehttp.access_log.sent +\u003d len;\n-#endif\n-\tif (wsi-\u003evhost)\n-\t\twsi-\u003evhost-\u003econn_stats.tx +\u003d len;\n-\n-\tassert(wsi-\u003erole_ops);\n-\tif (!wsi-\u003erole_ops-\u003ewrite_role_protocol)\n-\t\treturn lws_issue_raw(wsi, buf, len);\n-\n-\treturn wsi-\u003erole_ops-\u003ewrite_role_protocol(wsi, buf, len, \u0026wp);\n-}\n-\n-LWS_VISIBLE int\n-lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)\n-{\n-\tstruct lws_context *context \u003d wsi-\u003econtext;\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n-\tint n \u003d 0;\n-\n-\tlws_stats_atomic_bump(context, pt, LWSSTATS_C_API_READ, 1);\n-\n-\tif (lws_wsi_is_udp(wsi)) {\n-#if !defined(LWS_WITH_ESP32)\n-\t\twsi-\u003eudp-\u003esalen \u003d sizeof(wsi-\u003eudp-\u003esa);\n-\t\tn \u003d recvfrom(wsi-\u003edesc.sockfd, (char *)buf, len, 0,\n-\t\t\t \u0026wsi-\u003eudp-\u003esa, \u0026wsi-\u003eudp-\u003esalen);\n-#endif\n-\t} else\n-\t\tn \u003d recv(wsi-\u003edesc.sockfd, (char *)buf, len, 0);\n-\n-\tif (n \u003e\u003d 0) {\n-\t\tif (wsi-\u003evhost)\n-\t\t\twsi-\u003evhost-\u003econn_stats.rx +\u003d n;\n-\t\tlws_stats_atomic_bump(context, pt, LWSSTATS_B_READ, n);\n-\n-\t\treturn n;\n-\t}\n-\n-\tif (LWS_ERRNO \u003d\u003d LWS_EAGAIN ||\n-\t LWS_ERRNO \u003d\u003d LWS_EWOULDBLOCK ||\n-\t LWS_ERRNO \u003d\u003d LWS_EINTR)\n-\t\treturn LWS_SSL_CAPABLE_MORE_SERVICE;\n-\n-\tlwsl_notice(\u0022error on reading from skt : %d\u005cn\u0022, LWS_ERRNO);\n-\treturn LWS_SSL_CAPABLE_ERROR;\n-}\n-\n-LWS_VISIBLE int\n-lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)\n-{\n-\tint n \u003d 0;\n-\n-\tif (lws_wsi_is_udp(wsi)) {\n-#if !defined(LWS_WITH_ESP32)\n-\t\tif (wsi-\u003etrunc_len)\n-\t\t\tn \u003d sendto(wsi-\u003edesc.sockfd, buf, len, 0, \u0026wsi-\u003eudp-\u003esa_pending, wsi-\u003eudp-\u003esalen_pending);\n-\t\telse\n-\t\t\tn \u003d sendto(wsi-\u003edesc.sockfd, buf, len, 0, \u0026wsi-\u003eudp-\u003esa, wsi-\u003eudp-\u003esalen);\n-#endif\n-\t} else\n-\t\tn \u003d send(wsi-\u003edesc.sockfd, (char *)buf, len, MSG_NOSIGNAL);\n-//\tlwsl_info(\u0022%s: sent len %d result %d\u0022, __func__, len, n);\n-\tif (n \u003e\u003d 0)\n-\t\treturn n;\n-\n-\tif (LWS_ERRNO \u003d\u003d LWS_EAGAIN ||\n-\t LWS_ERRNO \u003d\u003d LWS_EWOULDBLOCK ||\n-\t LWS_ERRNO \u003d\u003d LWS_EINTR) {\n-\t\tif (LWS_ERRNO \u003d\u003d LWS_EWOULDBLOCK) {\n-\t\t\tlws_set_blocking_send(wsi);\n-\t\t}\n-\n-\t\treturn LWS_SSL_CAPABLE_MORE_SERVICE;\n-\t}\n-\n-\tlwsl_debug(\u0022ERROR writing len %d to skt fd %d err %d / errno %d\u005cn\u0022,\n-\t\t\tlen, wsi-\u003edesc.sockfd, n, LWS_ERRNO);\n-\n-\treturn LWS_SSL_CAPABLE_ERROR;\n-}\n-\n-LWS_VISIBLE int\n-lws_ssl_pending_no_ssl(struct lws *wsi)\n-{\n-\t(void)wsi;\n-#if defined(LWS_WITH_ESP32)\n-\treturn 100;\n-#else\n-\treturn 0;\n-#endif\n-}\ndiff --git a/lib/plat/lws-plat-esp32.c b/lib/plat/lws-plat-esp32.c\nindex 89f1fb6..ff53e13 100644\n--- a/lib/plat/lws-plat-esp32.c\n+++ b/lib/plat/lws-plat-esp32.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n #include \u0022freertos/timers.h\u0022\n #include \u003cesp_attr.h\u003e\n #include \u003cesp_system.h\u003e\ndiff --git a/lib/plat/lws-plat-optee.c b/lib/plat/lws-plat-optee.c\nindex ab04f84..ec649cd 100644\n--- a/lib/plat/lws-plat-optee.c\n+++ b/lib/plat/lws-plat-optee.c\n@@ -1,4 +1,4 @@\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * included from libwebsockets.c for OPTEE builds\ndiff --git a/lib/plat/lws-plat-unix.c b/lib/plat/lws-plat-unix.c\nindex 2c103bb..5b59f20 100644\n--- a/lib/plat/lws-plat-unix.c\n+++ b/lib/plat/lws-plat-unix.c\n@@ -20,7 +20,7 @@\n */\n \n #define _GNU_SOURCE\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #include \u003cpwd.h\u003e\n #include \u003cgrp.h\u003e\ndiff --git a/lib/plat/lws-plat-win.c b/lib/plat/lws-plat-win.c\nindex 287e144..b7f28de 100644\n--- a/lib/plat/lws-plat-win.c\n+++ b/lib/plat/lws-plat-win.c\n@@ -1,7 +1,7 @@\n #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS\n #define _WINSOCK_DEPRECATED_NO_WARNINGS\n #endif\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n int\n lws_plat_socket_offset(void)\ndiff --git a/lib/pollfd.c b/lib/pollfd.c\ndeleted file mode 100644\nindex 6a06d51..0000000\n--- a/lib/pollfd.c\n+++ /dev/null\n@@ -1,606 +0,0 @@\n-/*\n- * libwebsockets - small server side websockets and web server implementation\n- *\n- * Copyright (C) 2010-2017 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This library is free software; you can redistribute it and/or\n- * modify it under the terms of the GNU Lesser General Public\n- * License as published by the Free Software Foundation:\n- * version 2.1 of the License.\n- *\n- * This library is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * Lesser General Public License for more details.\n- *\n- * You should have received a copy of the GNU Lesser General Public\n- * License along with this library; if not, write to the Free Software\n- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n- * MA 02110-1301 USA\n- */\n-\n-#include \u0022private-libwebsockets.h\u0022\n-\n-int\n-_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)\n-{\n-#if !defined(LWS_WITH_LIBUV) \u0026\u0026 !defined(LWS_WITH_LIBEV) \u0026\u0026 !defined(LWS_WITH_LIBEVENT)\n-\tvolatile struct lws_context_per_thread *vpt;\n-#endif\n-\tstruct lws_context_per_thread *pt;\n-\tstruct lws_context *context;\n-\tint ret \u003d 0, pa_events \u003d 1;\n-\tstruct lws_pollfd *pfd;\n-\tint sampled_tid, tid;\n-\n-\tif (!wsi || wsi-\u003eposition_in_fds_table \u003c 0)\n-\t\treturn 0;\n-\n-\tif (((volatile struct lws *)wsi)-\u003ehandling_pollout \u0026\u0026\n-\t !_and \u0026\u0026 _or \u003d\u003d LWS_POLLOUT) {\n-\t\t/*\n-\t\t * Happening alongside service thread handling POLLOUT.\n-\t\t * The danger is when he is finished, he will disable POLLOUT,\n-\t\t * countermanding what we changed here.\n-\t\t *\n-\t\t * Instead of changing the fds, inform the service thread\n-\t\t * what happened, and ask it to leave POLLOUT active on exit\n-\t\t */\n-\t\t((volatile struct lws *)wsi)-\u003eleave_pollout_active \u003d 1;\n-\t\t/*\n-\t\t * by definition service thread is not in poll wait, so no need\n-\t\t * to cancel service\n-\t\t */\n-\n-\t\tlwsl_debug(\u0022%s: using leave_pollout_active\u005cn\u0022, __func__);\n-\n-\t\treturn 0;\n-\t}\n-\n-\tcontext \u003d wsi-\u003econtext;\n-\tpt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n-\n-\tassert(wsi-\u003eposition_in_fds_table \u003e\u003d 0 \u0026\u0026\n-\t wsi-\u003eposition_in_fds_table \u003c (int)pt-\u003efds_count);\n-\n-#if !defined(LWS_WITH_LIBUV) \u0026\u0026 \u005c\n- !defined(LWS_WITH_LIBEV) \u0026\u0026 \u005c\n- !defined(LWS_WITH_LIBEVENT)\n-\t/*\n-\t * This only applies when we use the default poll() event loop.\n-\t *\n-\t * BSD can revert pa-\u003eevents at any time, when the kernel decides to\n-\t * exit from poll(). We can't protect against it using locking.\n-\t *\n-\t * Therefore we must check first if the service thread is in poll()\n-\t * wait; if so, we know we must be being called from a foreign thread,\n-\t * and we must keep a strictly ordered list of changes we made instead\n-\t * of trying to apply them, since when poll() exits, which may happen\n-\t * at any time it would revert our changes.\n-\t *\n-\t * The plat code will apply them when it leaves the poll() wait\n-\t * before doing anything else.\n-\t */\n-\n-\tvpt \u003d (volatile struct lws_context_per_thread *)pt;\n-\n-\tvpt-\u003eforeign_spinlock \u003d 1;\n-\tlws_memory_barrier();\n-\n-\tif (vpt-\u003einside_poll) {\n-\t\tstruct lws_foreign_thread_pollfd *ftp, **ftp1;\n-\t\t/*\n-\t\t * We are certainly a foreign thread trying to change events\n-\t\t * while the service thread is in the poll() wait.\n-\t\t *\n-\t\t * Create a list of changes to be applied after poll() exit,\n-\t\t * instead of trying to apply them now.\n-\t\t */\n-\t\tftp \u003d lws_malloc(sizeof(*ftp), \u0022ftp\u0022);\n-\t\tif (!ftp) {\n-\t\t\tvpt-\u003eforeign_spinlock \u003d 0;\n-\t\t\tlws_memory_barrier();\n-\t\t\tret \u003d -1;\n-\t\t\tgoto bail;\n-\t\t}\n-\n-\t\tftp-\u003e_and \u003d _and;\n-\t\tftp-\u003e_or \u003d _or;\n-\t\tftp-\u003efd_index \u003d wsi-\u003eposition_in_fds_table;\n-\t\tftp-\u003enext \u003d NULL;\n-\n-\t\t/* place at END of list to maintain order */\n-\t\tftp1 \u003d (struct lws_foreign_thread_pollfd **)\n-\t\t\t\t\t\t\u0026vpt-\u003eforeign_pfd_list;\n-\t\twhile (*ftp1)\n-\t\t\tftp1 \u003d \u0026((*ftp1)-\u003enext);\n-\n-\t\t*ftp1 \u003d ftp;\n-\t\tvpt-\u003eforeign_spinlock \u003d 0;\n-\t\tlws_memory_barrier();\n-\t\tlws_cancel_service_pt(wsi);\n-\n-\t\treturn 0;\n-\t}\n-\n-\tvpt-\u003eforeign_spinlock \u003d 0;\n-\tlws_memory_barrier();\n-#endif\n-\n-\tpfd \u003d \u0026pt-\u003efds[wsi-\u003eposition_in_fds_table];\n-\tpa-\u003efd \u003d wsi-\u003edesc.sockfd;\n-\tlwsl_debug(\u0022%s: wsi %p: fd %d events %d -\u003e %d\u005cn\u0022, __func__, wsi, pa-\u003efd, pfd-\u003eevents, (pfd-\u003eevents \u0026 ~_and) | _or);\n-\tpa-\u003eprev_events \u003d pfd-\u003eevents;\n-\tpa-\u003eevents \u003d pfd-\u003eevents \u003d (pfd-\u003eevents \u0026 ~_and) | _or;\n-\n-\tif (wsi-\u003ehttp2_substream)\n-\t\treturn 0;\n-\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi,\n-\t\t\t \t \t LWS_CALLBACK_CHANGE_MODE_POLL_FD,\n-\t\t\t\t\t wsi-\u003euser_space, (void *)pa, 0)) {\n-\t\tret \u003d -1;\n-\t\tgoto bail;\n-\t}\n-\n-\tif (context-\u003eevent_loop_ops-\u003eio) {\n-\t\tif (_and \u0026 LWS_POLLIN)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n-\t\t\t\t\tLWS_EV_STOP | LWS_EV_READ);\n-\n-\t\tif (_or \u0026 LWS_POLLIN)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n-\t\t\t\t\tLWS_EV_START | LWS_EV_READ);\n-\n-\t\tif (_and \u0026 LWS_POLLOUT)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n-\t\t\t\t\tLWS_EV_STOP | LWS_EV_WRITE);\n-\n-\t\tif (_or \u0026 LWS_POLLOUT)\n-\t\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n-\t\t\t\t\tLWS_EV_START | LWS_EV_WRITE);\n-\t}\n-\n-\t/*\n-\t * if we changed something in this pollfd...\n-\t * ... and we're running in a different thread context\n-\t * than the service thread...\n-\t * ... and the service thread is waiting ...\n-\t * then cancel it to force a restart with our changed events\n-\t */\n-\tpa_events \u003d pa-\u003eprev_events !\u003d pa-\u003eevents;\n-\n-\tif (pa_events) {\n-\t\tif (lws_plat_change_pollfd(context, wsi, pfd)) {\n-\t\t\tlwsl_info(\u0022%s failed\u005cn\u0022, __func__);\n-\t\t\tret \u003d -1;\n-\t\t\tgoto bail;\n-\t\t}\n-\t\tsampled_tid \u003d context-\u003eservice_tid;\n-\t\tif (sampled_tid \u0026\u0026 wsi-\u003evhost) {\n-\t\t\ttid \u003d wsi-\u003evhost-\u003eprotocols[0].callback(wsi,\n-\t\t\t\t LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);\n-\t\t\tif (tid \u003d\u003d -1) {\n-\t\t\t\tret \u003d -1;\n-\t\t\t\tgoto bail;\n-\t\t\t}\n-\t\t\tif (tid !\u003d sampled_tid)\n-\t\t\t\tlws_cancel_service_pt(wsi);\n-\t\t}\n-\t}\n-\n-bail:\n-\treturn ret;\n-}\n-\n-#ifndef LWS_NO_SERVER\n-/*\n- * Enable or disable listen sockets on this pt globally...\n- * it's modulated according to the pt having space for a new accept.\n- */\n-static void\n-lws_accept_modulation(struct lws_context *context,\n-\t\t struct lws_context_per_thread *pt, int allow)\n-{\n-\tstruct lws_vhost *vh \u003d context-\u003evhost_list;\n-\tstruct lws_pollargs pa1;\n-\n-\twhile (vh) {\n-\t\tif (vh-\u003elserv_wsi) {\n-\t\t\tif (allow)\n-\t\t\t\t_lws_change_pollfd(vh-\u003elserv_wsi,\n-\t\t\t\t\t 0, LWS_POLLIN, \u0026pa1);\n-\t\t\telse\n-\t\t\t\t_lws_change_pollfd(vh-\u003elserv_wsi,\n-\t\t\t\t\t LWS_POLLIN, 0, \u0026pa1);\n-\t\t}\n-\t\tvh \u003d vh-\u003evhost_next;\n-\t}\n-}\n-#endif\n-\n-int\n-__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)\n-{\n-\tstruct lws_pollargs pa \u003d { wsi-\u003edesc.sockfd, LWS_POLLIN, 0 };\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n-\tint ret \u003d 0;\n-\n-\n-\tlwsl_debug(\u0022%s: %p: tsi\u003d%d, sock\u003d%d, pos-in-fds\u003d%d\u005cn\u0022,\n-\t\t __func__, wsi, wsi-\u003etsi, wsi-\u003edesc.sockfd, pt-\u003efds_count);\n-\n-\tif ((unsigned int)pt-\u003efds_count \u003e\u003d context-\u003efd_limit_per_thread) {\n-\t\tlwsl_err(\u0022Too many fds (%d vs %d)\u005cn\u0022, context-\u003emax_fds,\n-\t\t\t\tcontext-\u003efd_limit_per_thread\t);\n-\t\treturn 1;\n-\t}\n-\n-#if !defined(_WIN32)\n-\tif (wsi-\u003edesc.sockfd - lws_plat_socket_offset() \u003e\u003d context-\u003emax_fds) {\n-\t\tlwsl_err(\u0022Socket fd %d is too high (%d) offset %d\u005cn\u0022,\n-\t\t\t wsi-\u003edesc.sockfd, context-\u003emax_fds, lws_plat_socket_offset());\n-\t\treturn 1;\n-\t}\n-#endif\n-\n-\tassert(wsi);\n-\tassert(wsi-\u003eevent_pipe || wsi-\u003evhost);\n-\tassert(lws_socket_is_valid(wsi-\u003edesc.sockfd));\n-\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,\n-\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 1))\n-\t\treturn -1;\n-\n-\tpt-\u003ecount_conns++;\n-\tinsert_wsi(context, wsi);\n-\twsi-\u003eposition_in_fds_table \u003d pt-\u003efds_count;\n-\n-\tpt-\u003efds[wsi-\u003eposition_in_fds_table].fd \u003d wsi-\u003edesc.sockfd;\n-\tpt-\u003efds[wsi-\u003eposition_in_fds_table].events \u003d LWS_POLLIN;\n-\tpa.events \u003d pt-\u003efds[pt-\u003efds_count].events;\n-\n-\tlws_plat_insert_socket_into_fds(context, wsi);\n-\n-\t/* external POLL support via protocol 0 */\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD,\n-\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n-\t\tret \u003d -1;\n-#ifndef LWS_NO_SERVER\n-\t/* if no more room, defeat accepts on this thread */\n-\tif ((unsigned int)pt-\u003efds_count \u003d\u003d context-\u003efd_limit_per_thread - 1)\n-\t\tlws_accept_modulation(context, pt, 0);\n-#endif\n-\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,\n-\t\t\t\t\t wsi-\u003euser_space, (void *)\u0026pa, 1))\n-\t\tret \u003d -1;\n-\n-\treturn ret;\n-}\n-\n-int\n-__remove_wsi_socket_from_fds(struct lws *wsi)\n-{\n-\tstruct lws_context *context \u003d wsi-\u003econtext;\n-\tstruct lws_pollargs pa \u003d { wsi-\u003edesc.sockfd, 0, 0 };\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[(int)wsi-\u003etsi];\n-\tstruct lws *end_wsi;\n-\tint v;\n-\tint m, ret \u003d 0;\n-\n-\tif (wsi-\u003eparent_carries_io) {\n-\t\tlws_same_vh_protocol_remove(wsi);\n-\t\treturn 0;\n-\t}\n-\n-#if !defined(_WIN32)\n-\tif (wsi-\u003edesc.sockfd - lws_plat_socket_offset() \u003e context-\u003emax_fds) {\n-\t\tlwsl_err(\u0022fd %d too high (%d)\u005cn\u0022, wsi-\u003edesc.sockfd,\n-\t\t\t context-\u003emax_fds);\n-\t\treturn 1;\n-\t}\n-#endif\n-\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,\n-\t\t\t\t\t wsi-\u003euser_space, (void *)\u0026pa, 1))\n-\t\treturn -1;\n-\n-\tlws_same_vh_protocol_remove(wsi);\n-\n-\t/* the guy who is to be deleted's slot index in pt-\u003efds */\n-\tm \u003d wsi-\u003eposition_in_fds_table;\n-\t\n-\tif (context-\u003eevent_loop_ops-\u003eio)\n-\t\tcontext-\u003eevent_loop_ops-\u003eio(wsi,\n-\t\t\t\t LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE |\n-\t\t\t\t LWS_EV_PREPARE_DELETION);\n-\n-\tlwsl_debug(\u0022%s: wsi\u003d%p, sock\u003d%d, fds pos\u003d%d, end guy pos\u003d%d, endfd\u003d%d\u005cn\u0022,\n-\t\t __func__, wsi, wsi-\u003edesc.sockfd, wsi-\u003eposition_in_fds_table,\n-\t\t pt-\u003efds_count, pt-\u003efds[pt-\u003efds_count].fd);\n-\n-\tif (m !\u003d LWS_SOCK_INVALID) {\n-\n-\t\t/* have the last guy take up the now vacant slot */\n-\t\tpt-\u003efds[m] \u003d pt-\u003efds[pt-\u003efds_count - 1];\n-\t\t/* this decrements pt-\u003efds_count */\n-\t\tlws_plat_delete_socket_from_fds(context, wsi, m);\n-\t\tv \u003d (int) pt-\u003efds[m].fd;\n-\t\t/* end guy's \u0022position in fds table\u0022 is now the deletion guy's old one */\n-\t\tend_wsi \u003d wsi_from_fd(context, v);\n-\t\tif (!end_wsi) {\n-\t\t\tlwsl_err(\u0022no wsi found for fd %d at pos %d, pt-\u003efds_count\u003d%d\u005cn\u0022,\n-\t\t\t\t(int)pt-\u003efds[m].fd, m, pt-\u003efds_count);\n-\t\t\tassert(0);\n-\t\t} else\n-\t\t\tend_wsi-\u003eposition_in_fds_table \u003d m;\n-\n-\t\t/* deletion guy's lws_lookup entry needs nuking */\n-\t\tdelete_from_fd(context, wsi-\u003edesc.sockfd);\n-\t\t/* removed wsi has no position any more */\n-\t\twsi-\u003eposition_in_fds_table \u003d -1;\n-\t}\n-\n-\t/* remove also from external POLL support via protocol 0 */\n-\tif (lws_socket_is_valid(wsi-\u003edesc.sockfd) \u0026\u0026 wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_DEL_POLL_FD,\n-\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n-\t\tret \u003d -1;\n-\n-#ifndef LWS_NO_SERVER\n-\tif (!context-\u003ebeing_destroyed \u0026\u0026\n-\t /* if this made some room, accept connects on this thread */\n-\t (unsigned int)pt-\u003efds_count \u003c context-\u003efd_limit_per_thread - 1)\n-\t\tlws_accept_modulation(context, pt, 1);\n-#endif\n-\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,\n-\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 1))\n-\t\tret \u003d -1;\n-\n-\treturn ret;\n-}\n-\n-int\n-__lws_change_pollfd(struct lws *wsi, int _and, int _or)\n-{\n-\tstruct lws_context *context;\n-\tstruct lws_pollargs pa;\n-\tint ret \u003d 0;\n-\n-\tif (!wsi || (!wsi-\u003eprotocol \u0026\u0026 !wsi-\u003eevent_pipe) ||\n-\t wsi-\u003eposition_in_fds_table \u003c 0)\n-\t\treturn 0;\n-\n-\tcontext \u003d lws_get_context(wsi);\n-\tif (!context)\n-\t\treturn 1;\n-\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,\n-\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n-\t\treturn -1;\n-\n-\tret \u003d _lws_change_pollfd(wsi, _and, _or, \u0026pa);\n-\tif (wsi-\u003evhost \u0026\u0026\n-\t wsi-\u003evhost-\u003eprotocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,\n-\t\t\t\t\t wsi-\u003euser_space, (void *) \u0026pa, 0))\n-\t\tret \u003d -1;\n-\n-\treturn ret;\n-}\n-\n-int\n-lws_change_pollfd(struct lws *wsi, int _and, int _or)\n-{\n-\tstruct lws_context_per_thread *pt;\n-\tint ret \u003d 0;\n-\n-\tpt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\n-\tlws_pt_lock(pt, __func__);\n-\tret \u003d __lws_change_pollfd(wsi, _and, _or);\n-\tlws_pt_unlock(pt);\n-\n-\treturn ret;\n-}\n-\n-LWS_VISIBLE int\n-lws_callback_on_writable(struct lws *wsi)\n-{\n-\tstruct lws_context_per_thread *pt;\n-\tint n;\n-\n-\tif (lwsi_state(wsi) \u003d\u003d LRS_SHUTDOWN)\n-\t\treturn 0;\n-\n-\tif (wsi-\u003esocket_is_permanently_unusable)\n-\t\treturn 0;\n-\n-\tpt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\n-\tif (wsi-\u003eparent_carries_io) {\n-#if defined(LWS_WITH_STATS)\n-\t\tif (!wsi-\u003eactive_writable_req_us) {\n-\t\t\twsi-\u003eactive_writable_req_us \u003d time_in_microseconds();\n-\t\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt,\n-\t\t\t\t\t LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1);\n-\t\t}\n-#endif\n-\t\tn \u003d lws_callback_on_writable(wsi-\u003eparent);\n-\t\tif (n \u003c 0)\n-\t\t\treturn n;\n-\n-\t\twsi-\u003eparent_pending_cb_on_writable \u003d 1;\n-\t\treturn 1;\n-\t}\n-\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_WRITEABLE_CB_REQ, 1);\n-#if defined(LWS_WITH_STATS)\n-\tif (!wsi-\u003eactive_writable_req_us) {\n-\t\twsi-\u003eactive_writable_req_us \u003d time_in_microseconds();\n-\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt,\n-\t\t\t\t LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1);\n-\t}\n-#endif\n-\n-\n-\tif (wsi-\u003erole_ops-\u003ecallback_on_writable) {\n-\t\tif (wsi-\u003erole_ops-\u003ecallback_on_writable(wsi))\n-\t\t\treturn 1;\n-\t\twsi \u003d lws_get_network_wsi(wsi);\n-\t}\n-\n-\tif (wsi-\u003eposition_in_fds_table \u003c 0) {\n-\t\tlwsl_debug(\u0022%s: failed to find socket %d\u005cn\u0022, __func__,\n-\t\t\t wsi-\u003edesc.sockfd);\n-\t\treturn -1;\n-\t}\n-\n-\tif (__lws_change_pollfd(wsi, 0, LWS_POLLOUT))\n-\t\treturn -1;\n-\n-\treturn 1;\n-}\n-\n-\n-/*\n- * stitch protocol choice into the vh protocol linked list\n- * We always insert ourselves at the start of the list\n- *\n- * X \u003c-\u003e B\n- * X \u003c-\u003e pAn \u003c-\u003e pB\n- *\n- * Illegal to attach more than once without detach inbetween\n- */\n-void\n-lws_same_vh_protocol_insert(struct lws *wsi, int n)\n-{\n-\tif (wsi-\u003esame_vh_protocol_prev || wsi-\u003esame_vh_protocol_next) {\n-\t\tlws_same_vh_protocol_remove(wsi);\n-\t\tlwsl_notice(\u0022Attempted to attach wsi twice to same vh prot\u005cn\u0022);\n-\t}\n-\n-\tlws_vhost_lock(wsi-\u003evhost);\n-\n-\twsi-\u003esame_vh_protocol_prev \u003d \u0026wsi-\u003evhost-\u003esame_vh_protocol_list[n];\n-\t/* old first guy is our next */\n-\twsi-\u003esame_vh_protocol_next \u003d wsi-\u003evhost-\u003esame_vh_protocol_list[n];\n-\t/* we become the new first guy */\n-\twsi-\u003evhost-\u003esame_vh_protocol_list[n] \u003d wsi;\n-\n-\tif (wsi-\u003esame_vh_protocol_next)\n-\t\t/* old first guy points back to us now */\n-\t\twsi-\u003esame_vh_protocol_next-\u003esame_vh_protocol_prev \u003d\n-\t\t\t\t\u0026wsi-\u003esame_vh_protocol_next;\n-\n-\twsi-\u003eon_same_vh_list \u003d 1;\n-\n-\tlws_vhost_unlock(wsi-\u003evhost);\n-}\n-\n-void\n-lws_same_vh_protocol_remove(struct lws *wsi)\n-{\n-\t/*\n-\t * detach ourselves from vh protocol list if we're on one\n-\t * A -\u003e B -\u003e C\n-\t * A -\u003e C , or, B -\u003e C, or A -\u003e B\n-\t *\n-\t * OK to call on already-detached wsi\n-\t */\n-\tlwsl_info(\u0022%s: removing same prot wsi %p\u005cn\u0022, __func__, wsi);\n-\n-\tif (!wsi-\u003evhost || !wsi-\u003eon_same_vh_list)\n-\t\treturn;\n-\n-\tlws_vhost_lock(wsi-\u003evhost);\n-\n-\tif (wsi-\u003esame_vh_protocol_prev) {\n-\t\tassert (*(wsi-\u003esame_vh_protocol_prev) \u003d\u003d wsi);\n-\t\tlwsl_info(\u0022have prev %p, setting him to our next %p\u005cn\u0022,\n-\t\t\t wsi-\u003esame_vh_protocol_prev,\n-\t\t\t wsi-\u003esame_vh_protocol_next);\n-\n-\t\t/* guy who pointed to us should point to our next */\n-\t\t*(wsi-\u003esame_vh_protocol_prev) \u003d wsi-\u003esame_vh_protocol_next;\n-\t}\n-\n-\t/* our next should point back to our prev */\n-\tif (wsi-\u003esame_vh_protocol_next)\n-\t\twsi-\u003esame_vh_protocol_next-\u003esame_vh_protocol_prev \u003d\n-\t\t\t\twsi-\u003esame_vh_protocol_prev;\n-\n-\twsi-\u003esame_vh_protocol_prev \u003d NULL;\n-\twsi-\u003esame_vh_protocol_next \u003d NULL;\n-\twsi-\u003eon_same_vh_list \u003d 0;\n-\n-\tlws_vhost_unlock(wsi-\u003evhost);\n-}\n-\n-\n-LWS_VISIBLE int\n-lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,\n-\t\t\t\t const struct lws_protocols *protocol)\n-{\n-\tstruct lws *wsi;\n-\n-\tif (protocol \u003c vhost-\u003eprotocols ||\n-\t protocol \u003e\u003d (vhost-\u003eprotocols + vhost-\u003ecount_protocols)) {\n-\t\tlwsl_err(\u0022%s: protocol %p is not from vhost %p (%p - %p)\u005cn\u0022,\n-\t\t\t__func__, protocol, vhost-\u003eprotocols, vhost,\n-\t\t\t(vhost-\u003eprotocols + vhost-\u003ecount_protocols));\n-\n-\t\treturn -1;\n-\t}\n-\n-\twsi \u003d vhost-\u003esame_vh_protocol_list[protocol - vhost-\u003eprotocols];\n-\twhile (wsi) {\n-\t\tassert(wsi-\u003eprotocol \u003d\u003d protocol);\n-\t\tassert(*wsi-\u003esame_vh_protocol_prev \u003d\u003d wsi);\n-\t\tif (wsi-\u003esame_vh_protocol_next)\n-\t\t\tassert(wsi-\u003esame_vh_protocol_next-\u003e\n-\t\t\t\t\tsame_vh_protocol_prev \u003d\u003d\n-\t\t\t\t\t\u0026wsi-\u003esame_vh_protocol_next);\n-\n-\t\tlws_callback_on_writable(wsi);\n-\t\twsi \u003d wsi-\u003esame_vh_protocol_next;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE int\n-lws_callback_on_writable_all_protocol(const struct lws_context *context,\n-\t\t\t\t const struct lws_protocols *protocol)\n-{\n-\tstruct lws_vhost *vhost;\n-\tint n;\n-\n-\tif (!context)\n-\t\treturn 0;\n-\n-\tvhost \u003d context-\u003evhost_list;\n-\n-\twhile (vhost) {\n-\t\tfor (n \u003d 0; n \u003c vhost-\u003ecount_protocols; n++)\n-\t\t\tif (protocol-\u003ecallback \u003d\u003d\n-\t\t\t vhost-\u003eprotocols[n].callback \u0026\u0026\n-\t\t\t !strcmp(protocol-\u003ename, vhost-\u003eprotocols[n].name))\n-\t\t\t\tbreak;\n-\t\tif (n !\u003d vhost-\u003ecount_protocols)\n-\t\t\tlws_callback_on_writable_all_protocol_vhost(\n-\t\t\t\tvhost, \u0026vhost-\u003eprotocols[n]);\n-\n-\t\tvhost \u003d vhost-\u003evhost_next;\n-\t}\n-\n-\treturn 0;\n-}\ndiff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h\ndeleted file mode 100644\nindex 9f60bd6..0000000\n--- a/lib/private-libwebsockets.h\n+++ /dev/null\n@@ -1,1742 +0,0 @@\n-/*\n- * libwebsockets - small server side websockets and web server implementation\n- *\n- * Copyright (C) 2010 - 2018 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This library is free software; you can redistribute it and/or\n- * modify it under the terms of the GNU Lesser General Public\n- * License as published by the Free Software Foundation:\n- * version 2.1 of the License.\n- *\n- * This library is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * Lesser General Public License for more details.\n- *\n- * You should have received a copy of the GNU Lesser General Public\n- * License along with this library; if not, write to the Free Software\n- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n- * MA 02110-1301 USA\n- */\n-\n-#include \u0022lws_config.h\u0022\n-#include \u0022lws_config_private.h\u0022\n-\n-#if defined(LWS_WITH_CGI) \u0026\u0026 defined(LWS_HAVE_VFORK)\n- #define _GNU_SOURCE\n-#endif\n-\n-#if defined(__COVERITY__)\n- typedef struct { long double x, y; } _Float128;\n-#endif\n-\n-#ifdef LWS_HAVE_SYS_TYPES_H\n- #include \u003csys/types.h\u003e\n-#endif\n-\n-#include \u003cstdio.h\u003e\n-#include \u003cstdlib.h\u003e\n-#include \u003cstring.h\u003e\n-#include \u003ctime.h\u003e\n-#include \u003cctype.h\u003e\n-#include \u003climits.h\u003e\n-#include \u003cstdarg.h\u003e\n-#include \u003cinttypes.h\u003e\n-\n-#if defined(LWS_WITH_ESP32)\n- #define MSG_NOSIGNAL 0\n- #define SOMAXCONN 3\n-#endif\n-\n-#define STORE_IN_ROM\n-#include \u003cassert.h\u003e\n-#if LWS_MAX_SMP \u003e 1\n- #include \u003cpthread.h\u003e\n-#endif\n-\n-#ifdef LWS_HAVE_SYS_STAT_H\n- #include \u003csys/stat.h\u003e\n-#endif\n-\n-#if defined(WIN32) || defined(_WIN32)\n-\n- #ifndef WIN32_LEAN_AND_MEAN\n- #define WIN32_LEAN_AND_MEAN\n- #endif\n-\n- #if (WINVER \u003c 0x0501)\n- #undef WINVER\n- #undef _WIN32_WINNT\n- #define WINVER 0x0501\n- #define _WIN32_WINNT WINVER\n- #endif\n-\n- #define LWS_NO_DAEMONIZE\n- #define LWS_ERRNO WSAGetLastError()\n- #define LWS_EAGAIN WSAEWOULDBLOCK\n- #define LWS_EALREADY WSAEALREADY\n- #define LWS_EINPROGRESS WSAEINPROGRESS\n- #define LWS_EINTR WSAEINTR\n- #define LWS_EISCONN WSAEISCONN\n- #define LWS_EWOULDBLOCK WSAEWOULDBLOCK\n- #define MSG_NOSIGNAL 0\n- #define SHUT_RDWR SD_BOTH\n- #define SOL_TCP IPPROTO_TCP\n- #define SHUT_WR SD_SEND\n-\n- #define compatible_close(fd) closesocket(fd)\n- #define lws_set_blocking_send(wsi) wsi-\u003esock_send_blocking \u003d 1\n- #define lws_socket_is_valid(x) (!!x)\n- #define LWS_SOCK_INVALID 0\n- #include \u003cwinsock2.h\u003e\n- #include \u003cws2tcpip.h\u003e\n- #include \u003cwindows.h\u003e\n- #include \u003ctchar.h\u003e\n- #ifdef LWS_HAVE_IN6ADDR_H\n- #include \u003cin6addr.h\u003e\n- #endif\n- #include \u003cmstcpip.h\u003e\n- #include \u003cio.h\u003e\n-\n- #if !defined(LWS_HAVE_ATOLL)\n- #if defined(LWS_HAVE__ATOI64)\n- #define atoll _atoi64\n- #else\n- #warning No atoll or _atoi64 available, using atoi\n- #define atoll atoi\n- #endif\n- #endif\n-\n- #ifndef __func__\n- #define __func__ __FUNCTION__\n- #endif\n-\n- #ifdef LWS_HAVE__VSNPRINTF\n- #define vsnprintf _vsnprintf\n- #endif\n-\n- /* we don't have an implementation for this on windows... */\n- int kill(int pid, int sig);\n- int fork(void);\n- #ifndef SIGINT\n- #define SIGINT 2\n- #endif\n-\n-#else /* not windows --\u003e */\n-\n- #include \u003cfcntl.h\u003e\n- #include \u003cstrings.h\u003e\n- #include \u003cunistd.h\u003e\n- #include \u003csys/types.h\u003e\n-\n- #ifndef __cplusplus\n- #include \u003cerrno.h\u003e\n- #endif\n- #include \u003cnetdb.h\u003e\n- #include \u003csignal.h\u003e\n- #include \u003csys/socket.h\u003e\n-\n- #if defined(LWS_BUILTIN_GETIFADDRS)\n- #include \u0022./misc/getifaddrs.h\u0022\n- #else\n- #if !defined(LWS_WITH_ESP32)\n- #if defined(__HAIKU__)\n- #define _BSD_SOURCE\n- #endif\n- #include \u003cifaddrs.h\u003e\n- #endif\n- #endif\n- #if defined (__ANDROID__)\n- #include \u003csyslog.h\u003e\n- #include \u003csys/resource.h\u003e\n- #elif defined (__sun) || defined(__HAIKU__) || defined(__QNX__)\n- #include \u003csyslog.h\u003e\n- #else\n- #if !defined(LWS_WITH_ESP32)\n- #include \u003csys/syslog.h\u003e\n- #endif\n- #endif\n- #include \u003cnetdb.h\u003e\n- #if !defined(LWS_WITH_ESP32)\n- #include \u003csys/mman.h\u003e\n- #include \u003csys/un.h\u003e\n- #include \u003cnetinet/in.h\u003e\n- #include \u003cnetinet/tcp.h\u003e\n- #include \u003carpa/inet.h\u003e\n- #include \u003cpoll.h\u003e\n- #endif\n- #ifndef LWS_NO_FORK\n- #ifdef LWS_HAVE_SYS_PRCTL_H\n- #include \u003csys/prctl.h\u003e\n- #endif\n- #endif\n-\n- #include \u003csys/time.h\u003e\n-\n- #define LWS_ERRNO errno\n- #define LWS_EAGAIN EAGAIN\n- #define LWS_EALREADY EALREADY\n- #define LWS_EINPROGRESS EINPROGRESS\n- #define LWS_EINTR EINTR\n- #define LWS_EISCONN EISCONN\n- #define LWS_EWOULDBLOCK EWOULDBLOCK\n-\n- #define lws_set_blocking_send(wsi)\n-\n- #define lws_socket_is_valid(x) (x \u003e\u003d 0)\n- #define LWS_SOCK_INVALID (-1)\n-#endif /* not windows */\n-\n-#ifndef LWS_HAVE_BZERO\n- #ifndef bzero\n- #define bzero(b, len) (memset((b), '\u005c0', (len)), (void) 0)\n- #endif\n-#endif\n-\n-#ifndef LWS_HAVE_STRERROR\n- #define strerror(x) \u0022\u0022\n-#endif\n-\n-#include \u0022libwebsockets.h\u0022\n-\n-#include \u0022tls/private.h\u0022\n-\n-#if defined(WIN32) || defined(_WIN32)\n- #include \u003cgettimeofday.h\u003e\n-\n- #ifndef BIG_ENDIAN\n- #define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */\n- #endif\n- #ifndef LITTLE_ENDIAN\n- #define LITTLE_ENDIAN 1234\n- #endif\n- #ifndef BYTE_ORDER\n- #define BYTE_ORDER LITTLE_ENDIAN\n- #endif\n-\n- #undef __P\n- #ifndef __P\n- #if __STDC__\n- #define __P(protos) protos\n- #else\n- #define __P(protos) ()\n- #endif\n- #endif\n-\n-#else /* not windows */\n- static inline int compatible_close(int fd) { return close(fd); }\n-\n- #include \u003csys/stat.h\u003e\n- #include \u003csys/time.h\u003e\n-\n- #if defined(__APPLE__)\n- #include \u003cmachine/endian.h\u003e\n- #elif defined(__FreeBSD__)\n- #include \u003csys/endian.h\u003e\n- #elif defined(__linux__)\n- #include \u003cendian.h\u003e\n- #endif\n-#endif\n-\n-#ifdef __cplusplus\n-extern \u0022C\u0022 {\n-#endif\n-\n-#if defined(__QNX__)\n-\t#include \u003cgulliver.h\u003e\n-\t#if defined(__LITTLEENDIAN__)\n-\t\t#define BYTE_ORDER __LITTLEENDIAN__\n-\t\t#define LITTLE_ENDIAN __LITTLEENDIAN__\n-\t\t#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc); for suppres warning that BIG_ENDIAN is not defined. */\n-\t#endif\n-\t#if defined(__BIGENDIAN__)\n-\t\t#define BYTE_ORDER __BIGENDIAN__\n-\t\t#define LITTLE_ENDIAN 1234 /* to show byte order (taken from gcc); for suppres warning that LITTLE_ENDIAN is not defined. */\n-\t\t#define BIG_ENDIAN __BIGENDIAN__\n-\t#endif\n-#endif\n-\n-#if defined(__sun) \u0026\u0026 defined(__GNUC__)\n-\n- #include \u003carpa/nameser_compat.h\u003e\n-\n- #if !defined (BYTE_ORDER)\n- #define BYTE_ORDER __BYTE_ORDER__\n- #endif\n-\n- #if !defined(LITTLE_ENDIAN)\n- #define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__\n- #endif\n-\n- #if !defined(BIG_ENDIAN)\n- #define BIG_ENDIAN __ORDER_BIG_ENDIAN__\n- #endif\n-\n-#endif /* sun + GNUC */\n-\n-#if !defined(BYTE_ORDER)\n- #define BYTE_ORDER __BYTE_ORDER\n-#endif\n-#if !defined(LITTLE_ENDIAN)\n- #define LITTLE_ENDIAN __LITTLE_ENDIAN\n-#endif\n-#if !defined(BIG_ENDIAN)\n- #define BIG_ENDIAN __BIG_ENDIAN\n-#endif\n-\n-\n-/*\n- * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,\n- * but happily have something equivalent in the SO_NOSIGPIPE flag.\n- */\n-#ifdef __APPLE__\n-#define MSG_NOSIGNAL SO_NOSIGPIPE\n-#endif\n-\n-/*\n- * Solaris 11.X only supports POSIX 2001, MSG_NOSIGNAL appears in\n- * POSIX 2008.\n- */\n-#ifdef __sun\n- #define MSG_NOSIGNAL 0\n-#endif\n-\n-#ifdef _WIN32\n- #ifndef FD_HASHTABLE_MODULUS\n- #define FD_HASHTABLE_MODULUS 32\n- #endif\n-#endif\n-\n-#ifndef LWS_DEF_HEADER_LEN\n-#define LWS_DEF_HEADER_LEN 4096\n-#endif\n-#ifndef LWS_DEF_HEADER_POOL\n-#define LWS_DEF_HEADER_POOL 4\n-#endif\n-#ifndef LWS_MAX_PROTOCOLS\n-#define LWS_MAX_PROTOCOLS 5\n-#endif\n-#ifndef LWS_MAX_EXTENSIONS_ACTIVE\n-#define LWS_MAX_EXTENSIONS_ACTIVE 1\n-#endif\n-#ifndef LWS_MAX_EXT_OFFERS\n-#define LWS_MAX_EXT_OFFERS 8\n-#endif\n-#ifndef SPEC_LATEST_SUPPORTED\n-#define SPEC_LATEST_SUPPORTED 13\n-#endif\n-#ifndef AWAITING_TIMEOUT\n-#define AWAITING_TIMEOUT 20\n-#endif\n-#ifndef CIPHERS_LIST_STRING\n-#define CIPHERS_LIST_STRING \u0022DEFAULT\u0022\n-#endif\n-#ifndef LWS_SOMAXCONN\n-#define LWS_SOMAXCONN SOMAXCONN\n-#endif\n-\n-#define MAX_WEBSOCKET_04_KEY_LEN 128\n-\n-#ifndef SYSTEM_RANDOM_FILEPATH\n-#define SYSTEM_RANDOM_FILEPATH \u0022/dev/urandom\u0022\n-#endif\n-\n-#define LWS_H2_RX_SCRATCH_SIZE 512\n-\n-\n-\n-/*\n- * All lws_tls...() functions must return this type, converting the\n- * native backend result and doing the extra work to determine which one\n- * as needed.\n- *\n- * Native TLS backend return codes are NOT ALLOWED outside the backend.\n- *\n- * Non-SSL mode also uses these types.\n- */\n-enum lws_ssl_capable_status {\n-\tLWS_SSL_CAPABLE_ERROR \u003d -1,\t\t /* it failed */\n-\tLWS_SSL_CAPABLE_DONE \u003d 0,\t\t /* it succeeded */\n-\tLWS_SSL_CAPABLE_MORE_SERVICE_READ \u003d -2,\t /* retry WANT_READ */\n-\tLWS_SSL_CAPABLE_MORE_SERVICE_WRITE \u003d -3, /* retry WANT_WRITE */\n-\tLWS_SSL_CAPABLE_MORE_SERVICE \u003d -4,\t /* general retry */\n-};\n-\n-#if defined(__clang__)\n-#define lws_memory_barrier() __sync_synchronize()\n-#elif defined(__GNUC__)\n-#define lws_memory_barrier() __sync_synchronize()\n-#else\n-#define lws_memory_barrier()\n-#endif\n-\n-/*\n- *\n- * ------ roles ------\n- *\n- */\n-\n-#include \u0022roles/private.h\u0022\n-\n-/* null-terminated array of pointers to roles lws built with */\n-extern const struct lws_role_ops *available_roles[];\n-\n-#define LWS_FOR_EVERY_AVAILABLE_ROLE_START(xx) { \u005c\n-\t\tconst struct lws_role_ops **ppxx \u003d available_roles; \u005c\n-\t\twhile (*ppxx) { \u005c\n-\t\t\tconst struct lws_role_ops *xx \u003d *ppxx++;\n-\n-#define LWS_FOR_EVERY_AVAILABLE_ROLE_END }}\n-\n-/*\n- *\n- * ------ event_loop ops ------\n- *\n- */\n-\n-#include \u0022event-libs/private.h\u0022\n-\n-/* enums of socks version */\n-enum socks_version {\n-\tSOCKS_VERSION_4 \u003d 4,\n-\tSOCKS_VERSION_5 \u003d 5\n-};\n-\n-/* enums of subnegotiation version */\n-enum socks_subnegotiation_version {\n-\tSOCKS_SUBNEGOTIATION_VERSION_1 \u003d 1,\n-};\n-\n-/* enums of socks commands */\n-enum socks_command {\n-\tSOCKS_COMMAND_CONNECT \u003d 1,\n-\tSOCKS_COMMAND_BIND \u003d 2,\n-\tSOCKS_COMMAND_UDP_ASSOCIATE \u003d 3\n-};\n-\n-/* enums of socks address type */\n-enum socks_atyp {\n-\tSOCKS_ATYP_IPV4 \u003d 1,\n-\tSOCKS_ATYP_DOMAINNAME \u003d 3,\n-\tSOCKS_ATYP_IPV6 \u003d 4\n-};\n-\n-/* enums of socks authentication methods */\n-enum socks_auth_method {\n-\tSOCKS_AUTH_NO_AUTH \u003d 0,\n-\tSOCKS_AUTH_GSSAPI \u003d 1,\n-\tSOCKS_AUTH_USERNAME_PASSWORD \u003d 2\n-};\n-\n-/* enums of subnegotiation status */\n-enum socks_subnegotiation_status {\n-\tSOCKS_SUBNEGOTIATION_STATUS_SUCCESS \u003d 0,\n-};\n-\n-/* enums of socks request reply */\n-enum socks_request_reply {\n-\tSOCKS_REQUEST_REPLY_SUCCESS \u003d 0,\n-\tSOCKS_REQUEST_REPLY_FAILURE_GENERAL \u003d 1,\n-\tSOCKS_REQUEST_REPLY_CONNECTION_NOT_ALLOWED \u003d 2,\n-\tSOCKS_REQUEST_REPLY_NETWORK_UNREACHABLE \u003d 3,\n-\tSOCKS_REQUEST_REPLY_HOST_UNREACHABLE \u003d 4,\n-\tSOCKS_REQUEST_REPLY_CONNECTION_REFUSED \u003d 5,\n-\tSOCKS_REQUEST_REPLY_TTL_EXPIRED \u003d 6,\n-\tSOCKS_REQUEST_REPLY_COMMAND_NOT_SUPPORTED \u003d 7,\n-\tSOCKS_REQUEST_REPLY_ATYP_NOT_SUPPORTED \u003d 8\n-};\n-\n-/* enums used to generate socks messages */\n-enum socks_msg_type {\n-\t/* greeting */\n-\tSOCKS_MSG_GREETING,\n-\t/* credential, user name and password */\n-\tSOCKS_MSG_USERNAME_PASSWORD,\n-\t/* connect command */\n-\tSOCKS_MSG_CONNECT\n-};\n-\n-enum {\n-\tLWS_RXFLOW_ALLOW \u003d (1 \u003c\u003c 0),\n-\tLWS_RXFLOW_PENDING_CHANGE \u003d (1 \u003c\u003c 1),\n-};\n-\n-struct lws_ring {\n-\tvoid *buf;\n-\tvoid (*destroy_element)(void *element);\n-\tuint32_t buflen;\n-\tuint32_t element_len;\n-\tuint32_t head;\n-\tuint32_t oldest_tail;\n-};\n-\n-struct lws_protocols;\n-struct lws;\n-\n-struct lws_io_watcher {\n-#ifdef LWS_WITH_LIBEV\n-\tstruct lws_io_watcher_libev ev;\n-#endif\n-#ifdef LWS_WITH_LIBUV\n-\tstruct lws_io_watcher_libuv uv;\n-#endif\n-#ifdef LWS_WITH_LIBEVENT\n-\tstruct lws_io_watcher_libevent event;\n-#endif\n-\tstruct lws_context *context;\n-\n-\tuint8_t actual_events;\n-};\n-\n-struct lws_signal_watcher {\n-#ifdef LWS_WITH_LIBEV\n-\tstruct lws_signal_watcher_libev ev;\n-#endif\n-#ifdef LWS_WITH_LIBUV\n-\tstruct lws_signal_watcher_libuv uv;\n-#endif\n-#ifdef LWS_WITH_LIBEVENT\n-\tstruct lws_signal_watcher_libevent event;\n-#endif\n-\tstruct lws_context *context;\n-};\n-\n-#ifdef _WIN32\n-#define LWS_FD_HASH(fd) ((fd ^ (fd \u003e\u003e 8) ^ (fd \u003e\u003e 16)) % FD_HASHTABLE_MODULUS)\n-struct lws_fd_hashtable {\n-\tstruct lws **wsi;\n-\tint length;\n-};\n-#endif\n-\n-struct lws_foreign_thread_pollfd {\n-\tstruct lws_foreign_thread_pollfd *next;\n-\tint fd_index;\n-\tint _and;\n-\tint _or;\n-};\n-\n-\n-#define LWS_HRTIMER_NOWAIT (0x7fffffffffffffffll)\n-\n-/*\n- * so we can have n connections being serviced simultaneously,\n- * these things need to be isolated per-thread.\n- */\n-\n-struct lws_context_per_thread {\n-#if LWS_MAX_SMP \u003e 1\n-\tpthread_mutex_t lock;\n-\tpthread_mutex_t lock_stats;\n-\tpthread_t lock_owner;\n-\tconst char *last_lock_reason;\n-#endif\n-\n-\tstruct lws_context *context;\n-\n-\t/*\n-\t * usable by anything in the service code, but only if the scope\n-\t * does not last longer than the service action (since next service\n-\t * of any socket can likewise use it and overwrite)\n-\t */\n-\tunsigned char *serv_buf;\n-\n-\tstruct lws_dll_lws dll_head_timeout;\n-\tstruct lws_dll_lws dll_head_hrtimer;\n-\tstruct lws_dll_lws dll_head_buflist; /* guys with pending rxflow */\n-\n-#if defined(LWS_WITH_TLS)\n-\tstruct lws_pt_tls tls;\n-#endif\n-\n-\tstruct lws_pollfd *fds;\n-\tvolatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list;\n-#ifdef _WIN32\n-\tWSAEVENT *events;\n-#endif\n-\tlws_sockfd_type dummy_pipe_fds[2];\n-\tstruct lws *pipe_wsi;\n-\n-\t/* --- role based members --- */\n-\n-#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n-\tstruct lws_pt_role_ws ws;\n-#endif\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tstruct lws_pt_role_http http;\n-#endif\n-\n-\t/* --- event library based members --- */\n-\n-#if defined(LWS_WITH_LIBEV)\n-\tstruct lws_pt_eventlibs_libev ev;\n-#endif\n-#if defined(LWS_WITH_LIBUV)\n-\tstruct lws_pt_eventlibs_libuv uv;\n-#endif\n-#if defined(LWS_WITH_LIBEVENT)\n-\tstruct lws_pt_eventlibs_libevent event;\n-#endif\n-\n-#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT)\n-\tstruct lws_signal_watcher w_sigint;\n-#endif\n-\n-\t/* --- */\n-\n-\tunsigned long count_conns;\n-\tunsigned int fds_count;\n-\n-\tvolatile unsigned char inside_poll;\n-\tvolatile unsigned char foreign_spinlock;\n-\n-\tunsigned char tid;\n-\n-\tunsigned char lock_depth;\n-\tunsigned char inside_service:1;\n-\tunsigned char event_loop_foreign:1;\n-\tunsigned char event_loop_destroy_processing_done:1;\n-};\n-\n-struct lws_conn_stats {\n-\tunsigned long long rx, tx;\n-\tunsigned long h1_conn, h1_trans, h2_trans, ws_upg, h2_alpn, h2_subs,\n-\t\t h2_upg, rejected;\n-};\n-\n-void\n-lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs);\n-\n-struct lws_timed_vh_protocol {\n-\tstruct lws_timed_vh_protocol *next;\n-\tconst struct lws_protocols *protocol;\n-\ttime_t time;\n-\tint reason;\n-};\n-\n-/*\n- * virtual host -related context information\n- * vhostwide SSL context\n- * vhostwide proxy\n- *\n- * hierarchy:\n- *\n- * context -\u003e vhost -\u003e wsi\n- *\n- * incoming connection non-SSL vhost binding:\n- *\n- * listen socket -\u003e wsi -\u003e select vhost after first headers\n- *\n- * incoming connection SSL vhost binding:\n- *\n- * SSL SNI -\u003e wsi -\u003e bind after SSL negotiation\n- */\n-\n-\n-struct lws_vhost {\n-#if !defined(LWS_WITHOUT_CLIENT)\n-\tchar proxy_basic_auth_token[128];\n-#endif\n-#if LWS_MAX_SMP \u003e 1\n-\tpthread_mutex_t lock;\n-#endif\n-\n-#if defined(LWS_ROLE_H2)\n-\tstruct lws_vhost_role_h2 h2;\n-#endif\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tstruct lws_vhost_role_http http;\n-#endif\n-#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n-\tstruct lws_vhost_role_ws ws;\n-#endif\n-\n-#if defined(LWS_WITH_SOCKS5)\n-\tchar socks_proxy_address[128];\n-\tchar socks_user[96];\n-\tchar socks_password[96];\n-#endif\n-#if defined(LWS_WITH_LIBEV)\n-\tstruct lws_io_watcher w_accept;\n-#endif\n-\tstruct lws_conn_stats conn_stats;\n-\tstruct lws_context *context;\n-\tstruct lws_vhost *vhost_next;\n-\n-\tstruct lws *lserv_wsi;\n-\tconst char *name;\n-\tconst char *iface;\n-\n-#if !defined(LWS_WITH_ESP32) \u0026\u0026 !defined(OPTEE_TA) \u0026\u0026 !defined(WIN32)\n-\tint bind_iface;\n-#endif\n-\tconst struct lws_protocols *protocols;\n-\tvoid **protocol_vh_privs;\n-\tconst struct lws_protocol_vhost_options *pvo;\n-\tconst struct lws_protocol_vhost_options *headers;\n-\tstruct lws **same_vh_protocol_list;\n-\tstruct lws_vhost *no_listener_vhost_list;\n-#if !defined(LWS_NO_CLIENT)\n-\tstruct lws_dll_lws dll_active_client_conns;\n-#endif\n-\n-#if defined(LWS_WITH_TLS)\n-\tstruct lws_vhost_tls tls;\n-#endif\n-\n-\tstruct lws_timed_vh_protocol *timed_vh_protocol_list;\n-\tvoid *user;\n-\n-\tint listen_port;\n-\n-#if defined(LWS_WITH_SOCKS5)\n-\tunsigned int socks_proxy_port;\n-#endif\n-\tunsigned int options;\n-\tint count_protocols;\n-\tint ka_time;\n-\tint ka_probes;\n-\tint ka_interval;\n-\tint keepalive_timeout;\n-\tint timeout_secs_ah_idle;\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-\tint log_fd;\n-#endif\n-\n-\tunsigned int created_vhost_protocols:1;\n-\tunsigned int being_destroyed:1;\n-\n-\tunsigned char default_protocol_index;\n-\tunsigned char raw_protocol_index;\n-};\n-\n-struct lws_deferred_free\n-{\n-\tstruct lws_deferred_free *next;\n-\ttime_t deadline;\n-\tvoid *payload;\n-};\n-\n-typedef union {\n-#ifdef LWS_WITH_IPV6\n-\tstruct sockaddr_in6 sa6;\n-#endif\n-\tstruct sockaddr_in sa4;\n-} sockaddr46;\n-\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-struct lws_peer {\n-\tstruct lws_peer *next;\n-\tstruct lws_peer *peer_wait_list;\n-\n-\ttime_t time_created;\n-\ttime_t time_closed_all;\n-\n-\tuint8_t addr[32];\n-\tuint32_t hash;\n-\tuint32_t count_wsi;\n-\tuint32_t total_wsi;\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tstruct lws_peer_role_http http;\n-#endif\n-\n-\tuint8_t af;\n-};\n-#endif\n-\n-/*\n- * the rest is managed per-context, that includes\n- *\n- * - processwide single fd -\u003e wsi lookup\n- * - contextwide headers pool\n- */\n-\n-struct lws_context {\n-\ttime_t last_timeout_check_s;\n-\ttime_t last_ws_ping_pong_check_s;\n-\ttime_t time_up;\n-\ttime_t time_discontiguity;\n-\ttime_t time_fixup;\n-\tconst struct lws_plat_file_ops *fops;\n-\tstruct lws_plat_file_ops fops_platform;\n-\tstruct lws_context **pcontext_finalize;\n-\n-\tconst struct lws_tls_ops *tls_ops;\n-\n-#if defined(LWS_WITH_HTTP2)\n-\tstruct http2_settings set;\n-#endif\n-#if defined(LWS_WITH_ZIP_FOPS)\n-\tstruct lws_plat_file_ops fops_zip;\n-#endif\n-\tstruct lws_context_per_thread pt[LWS_MAX_SMP];\n-\tstruct lws_conn_stats conn_stats;\n-#if LWS_MAX_SMP \u003e 1\n-\tpthread_mutex_t lock;\n-\tint lock_depth;\n-#endif\n-#ifdef _WIN32\n-/* different implementation between unix and windows */\n-\tstruct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];\n-#else\n-\tstruct lws **lws_lookup; /* fd to wsi */\n-#endif\n-\tstruct lws_vhost *vhost_list;\n-\tstruct lws_vhost *no_listener_vhost_list;\n-\tstruct lws_vhost *vhost_pending_destruction_list;\n-\tstruct lws_plugin *plugin_list;\n-\tstruct lws_deferred_free *deferred_free_list;\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tstruct lws_peer **pl_hash_table;\n-\tstruct lws_peer *peer_wait_list;\n-\ttime_t next_cull;\n-#endif\n-\n-\tvoid *external_baggage_free_on_destroy;\n-\tconst struct lws_token_limits *token_limits;\n-\tvoid *user_space;\n-\tconst struct lws_protocol_vhost_options *reject_service_keywords;\n-\tlws_reload_func deprecation_cb;\n-\tvoid (*eventlib_signal_cb)(void *event_lib_handle, int signum);\n-\n-#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n-\tcap_value_t caps[4];\n-\tchar count_caps;\n-#endif\n-\n-#if defined(LWS_WITH_LIBEV)\n-\tstruct lws_context_eventlibs_libev ev;\n-#endif\n-#if defined(LWS_WITH_LIBUV)\n-\tstruct lws_context_eventlibs_libuv uv;\n-#endif\n-#if defined(LWS_WITH_LIBEVENT)\n-\tstruct lws_context_eventlibs_libevent event;\n-#endif\n-\tstruct lws_event_loop_ops *event_loop_ops;\n-\n-\n-#if defined(LWS_WITH_TLS)\n-\tstruct lws_context_tls tls;\n-#endif\n-\n-\tchar canonical_hostname[128];\n-\tconst char *server_string;\n-\n-#ifdef LWS_LATENCY\n-\tunsigned long worst_latency;\n-\tchar worst_latency_info[256];\n-#endif\n-\n-#if defined(LWS_WITH_STATS)\n-\tuint64_t lws_stats[LWSSTATS_SIZE];\n-\tuint64_t last_dump;\n-\tint updated;\n-#endif\n-#if defined(LWS_WITH_ESP32)\n-\tunsigned long time_last_state_dump;\n-\tuint32_t last_free_heap;\n-#endif\n-\n-\tint max_fds;\n-\tint count_event_loop_static_asset_handles;\n-\tint started_with_parent;\n-\tint uid, gid;\n-\n-\tint fd_random;\n-\n-\tint count_wsi_allocated;\n-\tint count_cgi_spawned;\n-\tunsigned int options;\n-\tunsigned int fd_limit_per_thread;\n-\tunsigned int timeout_secs;\n-\tunsigned int pt_serv_buf_size;\n-\tint max_http_header_data;\n-\tint simultaneous_ssl_restriction;\n-\tint simultaneous_ssl;\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tuint32_t pl_hash_elements;\t/* protected by context-\u003elock */\n-\tuint32_t count_peers;\t\t/* protected by context-\u003elock */\n-\tunsigned short ip_limit_ah;\n-\tunsigned short ip_limit_wsi;\n-#endif\n-\tunsigned int deprecated:1;\n-\tunsigned int being_destroyed:1;\n-\tunsigned int being_destroyed1:1;\n-\tunsigned int being_destroyed2:1;\n-\tunsigned int requested_kill:1;\n-\tunsigned int protocol_init_done:1;\n-\tunsigned int doing_protocol_init:1;\n-\tunsigned int done_protocol_destroy_cb:1;\n-\tunsigned int finalize_destroy_after_internal_loops_stopped:1;\n-\t/*\n-\t * set to the Thread ID that's doing the service loop just before entry\n-\t * to poll indicates service thread likely idling in poll()\n-\t * volatile because other threads may check it as part of processing\n-\t * for pollfd event change.\n-\t */\n-\tvolatile int service_tid;\n-\tint service_tid_detected;\n-\n-\tshort max_http_header_pool;\n-\tshort count_threads;\n-\tshort plugin_protocol_count;\n-\tshort plugin_extension_count;\n-\tshort server_string_len;\n-\tunsigned short ws_ping_pong_interval;\n-\tunsigned short deprecation_pending_listen_close_count;\n-\n-\tuint8_t max_fi;\n-};\n-\n-int\n-lws_check_deferred_free(struct lws_context *context, int force);\n-\n-#define lws_get_context_protocol(ctx, x) ctx-\u003evhost_list-\u003eprotocols[x]\n-#define lws_get_vh_protocol(vh, x) vh-\u003eprotocols[x]\n-\n-LWS_EXTERN void\n-__lws_close_free_wsi_final(struct lws *wsi);\n-LWS_EXTERN void\n-lws_libuv_closehandle(struct lws *wsi);\n-LWS_EXTERN int\n-lws_libuv_check_watcher_active(struct lws *wsi);\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_plat_plugins_init(struct lws_context * context, const char * const *d);\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_plat_plugins_destroy(struct lws_context * context);\n-\n-LWS_EXTERN void\n-lws_restart_ws_ping_pong_timer(struct lws *wsi);\n-\n-struct lws *\n-lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);\n-\n-int\n-lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);\n-\n-void\n-lws_vhost_destroy1(struct lws_vhost *vh);\n-\n-enum {\n-\tLWS_EV_READ \u003d (1 \u003c\u003c 0),\n-\tLWS_EV_WRITE \u003d (1 \u003c\u003c 1),\n-\tLWS_EV_START \u003d (1 \u003c\u003c 2),\n-\tLWS_EV_STOP \u003d (1 \u003c\u003c 3),\n-\n-\tLWS_EV_PREPARE_DELETION \u003d (1 \u003c\u003c 31),\n-};\n-\n-\n-#if defined(LWS_WITH_ESP32)\n-LWS_EXTERN int\n-lws_find_string_in_file(const char *filename, const char *string, int stringlen);\n-#endif\n-\n-#ifdef LWS_WITH_IPV6\n-#define LWS_IPV6_ENABLED(vh) \u005c\n-\t(!lws_check_opt(vh-\u003econtext-\u003eoptions, LWS_SERVER_OPTION_DISABLE_IPV6) \u0026\u0026 \u005c\n-\t !lws_check_opt(vh-\u003eoptions, LWS_SERVER_OPTION_DISABLE_IPV6))\n-#else\n-#define LWS_IPV6_ENABLED(context) (0)\n-#endif\n-\n-#ifdef LWS_WITH_UNIX_SOCK\n-#define LWS_UNIX_SOCK_ENABLED(vhost) \u005c\n-\t(vhost-\u003eoptions \u0026 LWS_SERVER_OPTION_UNIX_SOCK)\n-#else\n-#define LWS_UNIX_SOCK_ENABLED(vhost) (0)\n-#endif\n-\n-enum uri_path_states {\n-\tURIPS_IDLE,\n-\tURIPS_SEEN_SLASH,\n-\tURIPS_SEEN_SLASH_DOT,\n-\tURIPS_SEEN_SLASH_DOT_DOT,\n-};\n-\n-enum uri_esc_states {\n-\tURIES_IDLE,\n-\tURIES_SEEN_PERCENT,\n-\tURIES_SEEN_PERCENT_H1,\n-};\n-\n-\n-#ifndef LWS_NO_CLIENT\n-struct client_info_stash {\n-\tchar *address;\n-\tchar *path;\n-\tchar *host;\n-\tchar *origin;\n-\tchar *protocol;\n-\tchar *method;\n-\tchar *iface;\n-\tchar *alpn;\n-};\n-#endif\n-\n-\n-signed char char_to_hex(const char c);\n-\n-\n-struct lws_buflist {\n-\tstruct lws_buflist *next;\n-\n-\tsize_t len;\n-\tsize_t pos;\n-\n-\tuint8_t buf[1]; /* true length of this is set by the oversize malloc */\n-};\n-\n-#define lws_wsi_is_udp(___wsi) (!!___wsi-\u003eudp)\n-\n-#define LWS_H2_FRAME_HEADER_LENGTH 9\n-\n-\n-struct lws {\n-\t/* structs */\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tstruct _lws_http_mode_related http;\n-#endif\n-#if defined(LWS_ROLE_H2)\n-\tstruct _lws_h2_related h2;\n-#endif\n-#if defined(LWS_ROLE_WS)\n-\tstruct _lws_websocket_related *ws; /* allocated if we upgrade to ws */\n-#endif\n-\n-\tconst struct lws_role_ops *role_ops;\n-\tlws_wsi_state_t\twsistate;\n-\tlws_wsi_state_t wsistate_pre_close;\n-\n-\t/* lifetime members */\n-\n-#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT)\n-\tstruct lws_io_watcher w_read;\n-#endif\n-#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBEVENT)\n-\tstruct lws_io_watcher w_write;\n-#endif\n-\n-\t/* pointers */\n-\n-\tstruct lws_context *context;\n-\tstruct lws_vhost *vhost;\n-\tstruct lws *parent; /* points to parent, if any */\n-\tstruct lws *child_list; /* points to first child */\n-\tstruct lws *sibling_list; /* subsequent children at same level */\n-\n-\tconst struct lws_protocols *protocol;\n-\tstruct lws **same_vh_protocol_prev, *same_vh_protocol_next;\n-\n-\tstruct lws_dll_lws dll_timeout;\n-\tstruct lws_dll_lws dll_hrtimer;\n-\tstruct lws_dll_lws dll_buflist; /* guys with pending rxflow */\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tstruct lws_peer *peer;\n-#endif\n-\n-\tstruct lws_udp *udp;\n-#ifndef LWS_NO_CLIENT\n-\tstruct client_info_stash *stash;\n-\tchar *client_hostname_copy;\n-\tstruct lws_dll_lws dll_active_client_conns;\n-\tstruct lws_dll_lws dll_client_transaction_queue_head;\n-\tstruct lws_dll_lws dll_client_transaction_queue;\n-#endif\n-\tvoid *user_space;\n-\tvoid *opaque_parent_data;\n-\n-\tstruct lws_buflist *buflist;\n-\n-\t/* truncated send handling */\n-\tunsigned char *trunc_alloc; /* non-NULL means buffering in progress */\n-\n-#if defined(LWS_WITH_TLS)\n-\tstruct lws_lws_tls tls;\n-#endif\n-\n-#ifdef LWS_LATENCY\n-\tunsigned long action_start;\n-\tunsigned long latency_start;\n-#endif\n-\n-\tlws_sock_file_fd_type desc; /* .filefd / .sockfd */\n-#if defined(LWS_WITH_STATS)\n-\tuint64_t active_writable_req_us;\n-#if defined(LWS_WITH_TLS)\n-\tuint64_t accept_start_us;\n-#endif\n-#endif\n-\n-\tlws_usec_t pending_timer;\n-\ttime_t pending_timeout_set;\n-\n-\t/* ints */\n-\tint position_in_fds_table;\n-\tunsigned int trunc_alloc_len; /* size of malloc */\n-\tunsigned int trunc_offset; /* where we are in terms of spilling */\n-\tunsigned int trunc_len; /* how much is buffered */\n-#ifndef LWS_NO_CLIENT\n-\tint chunk_remaining;\n-#endif\n-\tunsigned int cache_secs;\n-\n-\tunsigned int hdr_parsing_completed:1;\n-\tunsigned int http2_substream:1;\n-\tunsigned int upgraded_to_http2:1;\n-\tunsigned int h2_stream_carries_ws:1;\n-\tunsigned int seen_nonpseudoheader:1;\n-\tunsigned int listener:1;\n-\tunsigned int user_space_externally_allocated:1;\n-\tunsigned int socket_is_permanently_unusable:1;\n-\tunsigned int rxflow_change_to:2;\n-\tunsigned int conn_stat_done:1;\n-\tunsigned int cache_reuse:1;\n-\tunsigned int cache_revalidate:1;\n-\tunsigned int cache_intermediaries:1;\n-\tunsigned int favoured_pollin:1;\n-\tunsigned int sending_chunked:1;\n-\tunsigned int interpreting:1;\n-\tunsigned int already_did_cce:1;\n-\tunsigned int told_user_closed:1;\n-\tunsigned int told_event_loop_closed:1;\n-\tunsigned int waiting_to_send_close_frame:1;\n-\tunsigned int close_needs_ack:1;\n-\tunsigned int ipv6:1;\n-\tunsigned int parent_carries_io:1;\n-\tunsigned int parent_pending_cb_on_writable:1;\n-\tunsigned int cgi_stdout_zero_length:1;\n-\tunsigned int seen_zero_length_recv:1;\n-\tunsigned int rxflow_will_be_applied:1;\n-\tunsigned int event_pipe:1;\n-\tunsigned int on_same_vh_list:1;\n-\tunsigned int handling_404:1;\n-\tunsigned int protocol_bind_balance:1;\n-\n-\tunsigned int could_have_pending:1; /* detect back-to-back writes */\n-\tunsigned int outer_will_close:1;\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-\tunsigned int access_log_pending:1;\n-#endif\n-#ifndef LWS_NO_CLIENT\n-\tunsigned int do_ws:1; /* whether we are doing http or ws flow */\n-\tunsigned int chunked:1; /* if the clientside connection is chunked */\n-\tunsigned int client_rx_avail:1;\n-\tunsigned int client_http_body_pending:1;\n-\tunsigned int transaction_from_pipeline_queue:1;\n-\tunsigned int keepalive_active:1;\n-\tunsigned int keepalive_rejected:1;\n-\tunsigned int client_pipeline:1;\n-\tunsigned int client_h2_alpn:1;\n-\tunsigned int client_h2_substream:1;\n-#endif\n-\n-#ifdef _WIN32\n-\tunsigned int sock_send_blocking:1;\n-#endif\n-\n-#ifndef LWS_NO_CLIENT\n-\tunsigned short c_port;\n-#endif\n-\tunsigned short pending_timeout_limit;\n-\n-\t/* chars */\n-\n-\tchar lws_rx_parse_state; /* enum lws_rx_parse_state */\n-\tchar rx_frame_type; /* enum lws_write_protocol */\n-\tchar pending_timeout; /* enum pending_timeout */\n-\tchar tsi; /* thread service index we belong to */\n-\tchar protocol_interpret_idx;\n-\tchar redirects;\n-\tuint8_t rxflow_bitmap;\n-#ifdef LWS_WITH_CGI\n-\tchar cgi_channel; /* which of stdin/out/err */\n-\tchar hdr_state;\n-#endif\n-#ifndef LWS_NO_CLIENT\n-\tchar chunk_parser; /* enum lws_chunk_parser */\n-#endif\n-#if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT)\n-\tchar reason_bf; /* internal writeable callback reason bitfield */\n-#endif\n-#if defined(LWS_WITH_STATS) \u0026\u0026 defined(LWS_WITH_TLS)\n-\tchar seen_rx;\n-#endif\n-\tuint8_t ws_over_h2_count;\n-\t/* volatile to make sure code is aware other thread can change */\n-\tvolatile char handling_pollout;\n-\tvolatile char leave_pollout_active;\n-};\n-\n-#define lws_is_flowcontrolled(w) (!!(wsi-\u003erxflow_bitmap))\n-\n-void\n-lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);\n-\n-LWS_EXTERN int log_level;\n-\n-LWS_EXTERN int\n-lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,\n-\t\tconst char *iface);\n-\n-#if defined(LWS_WITH_IPV6)\n-LWS_EXTERN unsigned long\n-lws_get_addr_scope(const char *ipaddr);\n-#endif\n-\n-LWS_EXTERN void\n-lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);\n-LWS_EXTERN void\n-__lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);\n-\n-LWS_EXTERN void\n-__lws_free_wsi(struct lws *wsi);\n-\n-LWS_EXTERN int\n-__remove_wsi_socket_from_fds(struct lws *wsi);\n-LWS_EXTERN int\n-lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len);\n-\n-#ifndef LWS_LATENCY\n-static inline void\n-lws_latency(struct lws_context *context, struct lws *wsi, const char *action,\n-\t int ret, int completion) {\n-\tdo {\n-\t\t(void)context; (void)wsi; (void)action; (void)ret;\n-\t\t(void)completion;\n-\t} while (0);\n-}\n-static inline void\n-lws_latency_pre(struct lws_context *context, struct lws *wsi) {\n-\tdo { (void)context; (void)wsi; } while (0);\n-}\n-#else\n-#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0)\n-extern void\n-lws_latency(struct lws_context *context, struct lws *wsi, const char *action,\n-\t int ret, int completion);\n-#endif\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_ws_client_rx_sm(struct lws *wsi, unsigned char c);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_parse(struct lws *wsi, unsigned char *buf, int *len);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_parse_urldecode(struct lws *wsi, uint8_t *_c);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_http_action(struct lws *wsi);\n-\n-LWS_EXTERN int\n-lws_b64_selftest(void);\n-\n-LWS_EXTERN int\n-lws_service_flag_pending(struct lws_context *context, int tsi);\n-\n-LWS_EXTERN int\n-lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p);\n-\n-#if defined(_WIN32)\n-LWS_EXTERN struct lws *\n-wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd);\n-\n-LWS_EXTERN int\n-insert_wsi(struct lws_context *context, struct lws *wsi);\n-\n-LWS_EXTERN int\n-delete_from_fd(struct lws_context *context, lws_sockfd_type fd);\n-#else\n-#define wsi_from_fd(A,B) A-\u003elws_lookup[B - lws_plat_socket_offset()]\n-#define insert_wsi(A,B) assert(A-\u003elws_lookup[B-\u003edesc.sockfd - lws_plat_socket_offset()] \u003d\u003d 0); A-\u003elws_lookup[B-\u003edesc.sockfd - lws_plat_socket_offset()]\u003dB\n-#define delete_from_fd(A,B) A-\u003elws_lookup[B - lws_plat_socket_offset()]\u003d0\n-#endif\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);\n-\n-LWS_EXTERN void\n-lws_remove_from_timeout_list(struct lws *wsi);\n-\n-LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT\n-lws_client_connect_2(struct lws *wsi);\n-\n-LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT\n-lws_client_reset(struct lws **wsi, int ssl, const char *address, int port,\n-\t\t const char *path, const char *host);\n-\n-LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT\n-lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi);\n-\n-LWS_EXTERN char * LWS_WARN_UNUSED_RESULT\n-lws_generate_client_handshake(struct lws *wsi, char *pkt);\n-\n-LWS_EXTERN int\n-lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd);\n-\n-LWS_EXTERN struct lws *\n-lws_client_connect_via_info2(struct lws *wsi);\n-\n-\n-\n-LWS_EXTERN void\n-lws_client_stash_destroy(struct lws *wsi);\n-\n-/*\n- * EXTENSIONS\n- */\n-\n-#if defined(LWS_WITHOUT_EXTENSIONS)\n-#define lws_any_extension_handled(_a, _b, _c, _d) (0)\n-#define lws_ext_cb_active(_a, _b, _c, _d) (0)\n-#define lws_ext_cb_all_exts(_a, _b, _c, _d, _e) (0)\n-#define lws_issue_raw_ext_access lws_issue_raw\n-#define lws_context_init_extensions(_a, _b)\n-#endif\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_client_interpret_server_handshake(struct lws *wsi);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len);\n-\n-LWS_EXTERN void\n-lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state,\n-\t\t\tstruct lws_role_ops *ops);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-user_callback_handle_rxflow(lws_callback_function, struct lws *wsi,\n-\t\t\t enum lws_callback_reasons reason, void *user,\n-\t\t\t void *in, size_t len);\n-\n-LWS_EXTERN int\n-lws_plat_socket_offset(void);\n-\n-LWS_EXTERN int\n-lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd);\n-\n-LWS_EXTERN int\n-lws_plat_check_connection_error(struct lws *wsi);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_header_table_attach(struct lws *wsi, int autoservice);\n-\n-LWS_EXTERN int\n-lws_header_table_detach(struct lws *wsi, int autoservice);\n-LWS_EXTERN int\n-__lws_header_table_detach(struct lws *wsi, int autoservice);\n-\n-LWS_EXTERN void\n-lws_header_table_reset(struct lws *wsi, int autoservice);\n-\n-void\n-__lws_header_table_reset(struct lws *wsi, int autoservice);\n-\n-LWS_EXTERN char * LWS_WARN_UNUSED_RESULT\n-lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_ensure_user_space(struct lws *wsi);\n-\n-LWS_EXTERN int\n-lws_change_pollfd(struct lws *wsi, int _and, int _or);\n-\n-#ifndef LWS_NO_SERVER\n- int _lws_vhost_init_server(const struct lws_context_creation_info *info,\n-\t\t\t struct lws_vhost *vhost);\n- LWS_EXTERN struct lws_vhost *\n- lws_select_vhost(struct lws_context *context, int port, const char *servername);\n- LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n- lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len);\n- LWS_EXTERN void\n- lws_server_get_canonical_hostname(struct lws_context *context,\n-\t\t\t\t const struct lws_context_creation_info *info);\n-#else\n- #define _lws_vhost_init_server(_a, _b) (0)\n- #define lws_parse_ws(_a, _b, _c) (0)\n- #define lws_server_get_canonical_hostname(_a, _b)\n-#endif\n-\n-#ifndef LWS_NO_DAEMONIZE\n- LWS_EXTERN int get_daemonize_pid();\n-#else\n- #define get_daemonize_pid() (0)\n-#endif\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-interface_to_sa(struct lws_vhost *vh, const char *ifname,\n-\t\tstruct sockaddr_in *addr, size_t addrlen);\n-LWS_EXTERN void lwsl_emit_stderr(int level, const char *line);\n-\n-#if !defined(LWS_WITH_TLS)\n- #define LWS_SSL_ENABLED(context) (0)\n- #define lws_context_init_server_ssl(_a, _b) (0)\n- #define lws_ssl_destroy(_a)\n- #define lws_context_init_alpn(_a)\n- #define lws_ssl_capable_read lws_ssl_capable_read_no_ssl\n- #define lws_ssl_capable_write lws_ssl_capable_write_no_ssl\n- #define lws_ssl_pending lws_ssl_pending_no_ssl\n- #define lws_server_socket_service_ssl(_b, _c) (0)\n- #define lws_ssl_close(_a) (0)\n- #define lws_ssl_context_destroy(_a)\n- #define lws_ssl_SSL_CTX_destroy(_a)\n- #define lws_ssl_remove_wsi_from_buffered_list(_a)\n- #define __lws_ssl_remove_wsi_from_buffered_list(_a)\n- #define lws_context_init_ssl_library(_a)\n- #define lws_tls_check_all_cert_lifetimes(_a)\n- #define lws_tls_acme_sni_cert_destroy(_a)\n-#endif\n-\n-\n-#if LWS_MAX_SMP \u003e 1\n-\n-static LWS_INLINE void\n-lws_pt_mutex_init(struct lws_context_per_thread *pt)\n-{\n-\tpthread_mutex_init(\u0026pt-\u003elock, NULL);\n-\tpthread_mutex_init(\u0026pt-\u003elock_stats, NULL);\n-}\n-\n-static LWS_INLINE void\n-lws_pt_mutex_destroy(struct lws_context_per_thread *pt)\n-{\n-\tpthread_mutex_destroy(\u0026pt-\u003elock_stats);\n-\tpthread_mutex_destroy(\u0026pt-\u003elock);\n-}\n-\n-static LWS_INLINE void\n-lws_pt_lock(struct lws_context_per_thread *pt, const char *reason)\n-{\n-\tif (pt-\u003elock_owner \u003d\u003d pthread_self()) {\n-\t\tpt-\u003elock_depth++;\n-\t\treturn;\n-\t}\n-\tpthread_mutex_lock(\u0026pt-\u003elock);\n-\tpt-\u003elast_lock_reason \u003d reason;\n-\tpt-\u003elock_owner \u003d pthread_self();\n-\t//lwsl_notice(\u0022tid %d: lock %s\u005cn\u0022, pt-\u003etid, reason);\n-}\n-\n-static LWS_INLINE void\n-lws_pt_unlock(struct lws_context_per_thread *pt)\n-{\n-\tif (pt-\u003elock_depth) {\n-\t\tpt-\u003elock_depth--;\n-\t\treturn;\n-\t}\n-\tpt-\u003elast_lock_reason \u003d\u0022free\u0022;\n-\tpt-\u003elock_owner \u003d 0;\n-\t//lwsl_notice(\u0022tid %d: unlock %s\u005cn\u0022, pt-\u003etid, pt-\u003elast_lock_reason);\n-\tpthread_mutex_unlock(\u0026pt-\u003elock);\n-}\n-\n-static LWS_INLINE void\n-lws_pt_stats_lock(struct lws_context_per_thread *pt)\n-{\n-\tpthread_mutex_lock(\u0026pt-\u003elock_stats);\n-}\n-\n-static LWS_INLINE void\n-lws_pt_stats_unlock(struct lws_context_per_thread *pt)\n-{\n-\tpthread_mutex_unlock(\u0026pt-\u003elock_stats);\n-}\n-\n-static LWS_INLINE void\n-lws_context_lock(struct lws_context *context)\n-{\n-\tpthread_mutex_lock(\u0026context-\u003elock);\n-}\n-\n-static LWS_INLINE void\n-lws_context_unlock(struct lws_context *context)\n-{\n-\tpthread_mutex_unlock(\u0026context-\u003elock);\n-}\n-\n-static LWS_INLINE void\n-lws_vhost_lock(struct lws_vhost *vhost)\n-{\n-\tpthread_mutex_lock(\u0026vhost-\u003elock);\n-}\n-\n-static LWS_INLINE void\n-lws_vhost_unlock(struct lws_vhost *vhost)\n-{\n-\tpthread_mutex_unlock(\u0026vhost-\u003elock);\n-}\n-\n-\n-#else\n-#define lws_pt_mutex_init(_a) (void)(_a)\n-#define lws_pt_mutex_destroy(_a) (void)(_a)\n-#define lws_pt_lock(_a, b) (void)(_a)\n-#define lws_pt_unlock(_a) (void)(_a)\n-#define lws_context_lock(_a) (void)(_a)\n-#define lws_context_unlock(_a) (void)(_a)\n-#define lws_vhost_lock(_a) (void)(_a)\n-#define lws_vhost_unlock(_a) (void)(_a)\n-#define lws_pt_stats_lock(_a) (void)(_a)\n-#define lws_pt_stats_unlock(_a) (void)(_a)\n-#endif\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_ssl_pending_no_ssl(struct lws *wsi);\n-\n-int\n-lws_tls_check_cert_lifetime(struct lws_vhost *vhost);\n-\n-int lws_jws_selftest(void);\n-\n-\n-#ifndef LWS_NO_CLIENT\n-LWS_EXTERN int lws_client_socket_service(struct lws *wsi,\n-\t\t\t\t\t struct lws_pollfd *pollfd,\n-\t\t\t\t\t struct lws *wsi_conn);\n-LWS_EXTERN struct lws *\n-lws_client_wsi_effective(struct lws *wsi);\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_http_transaction_completed_client(struct lws *wsi);\n-#if !defined(LWS_WITH_TLS)\n-\t#define lws_context_init_client_ssl(_a, _b) (0)\n-#endif\n-LWS_EXTERN void\n-lws_decode_ssl_error(void);\n-#else\n-#define lws_context_init_client_ssl(_a, _b) (0)\n-#endif\n-\n-LWS_EXTERN int\n-__lws_rx_flow_control(struct lws *wsi);\n-\n-LWS_EXTERN int\n-_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa);\n-\n-#ifndef LWS_NO_SERVER\n-LWS_EXTERN int\n-lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len);\n-#else\n-#define lws_server_socket_service(_b, _c) (0)\n-#define lws_handshake_server(_a, _b, _c) (0)\n-#endif\n-\n-#ifdef LWS_WITH_ACCESS_LOG\n-LWS_EXTERN int\n-lws_access_log(struct lws *wsi);\n-LWS_EXTERN void\n-lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int meth);\n-#else\n-#define lws_access_log(_a)\n-#endif\n-\n-LWS_EXTERN int\n-lws_cgi_kill_terminated(struct lws_context_per_thread *pt);\n-\n-LWS_EXTERN void\n-lws_cgi_remove_and_kill(struct lws *wsi);\n-\n-int\n-lws_protocol_init(struct lws_context *context);\n-\n-int\n-lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p);\n-\n-const struct lws_http_mount *\n-lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len);\n-\n-/*\n- * custom allocator\n- */\n-LWS_EXTERN void *\n-lws_realloc(void *ptr, size_t size, const char *reason);\n-\n-LWS_EXTERN void * LWS_WARN_UNUSED_RESULT\n-lws_zalloc(size_t size, const char *reason);\n-\n-#ifdef LWS_PLAT_OPTEE\n-void *lws_malloc(size_t size, const char *reason);\n-void lws_free(void *p);\n-#define lws_free_set_NULL(P) do { lws_free(P); (P) \u003d NULL; } while(0)\n-#else\n-#define lws_malloc(S, R)\tlws_realloc(NULL, S, R)\n-#define lws_free(P)\tlws_realloc(P, 0, \u0022lws_free\u0022)\n-#define lws_free_set_NULL(P)\tdo { lws_realloc(P, 0, \u0022free\u0022); (P) \u003d NULL; } while(0)\n-#endif\n-\n-int\n-lws_plat_pipe_create(struct lws *wsi);\n-int\n-lws_plat_pipe_signal(struct lws *wsi);\n-void\n-lws_plat_pipe_close(struct lws *wsi);\n-int\n-lws_create_event_pipes(struct lws_context *context);\n-\n-const struct lws_plat_file_ops *\n-lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,\n-\t\t const char **vpath);\n-\n-/* lws_plat_ */\n-LWS_EXTERN void\n-lws_plat_delete_socket_from_fds(struct lws_context *context,\n-\t\t\t\tstruct lws *wsi, int m);\n-LWS_EXTERN void\n-lws_plat_insert_socket_into_fds(struct lws_context *context,\n-\t\t\t\tstruct lws *wsi);\n-LWS_EXTERN void\n-lws_plat_service_periodic(struct lws_context *context);\n-\n-LWS_EXTERN int\n-lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,\n-\t\t struct lws_pollfd *pfd);\n-LWS_EXTERN void\n-lws_add_wsi_to_draining_ext_list(struct lws *wsi);\n-LWS_EXTERN void\n-lws_remove_wsi_from_draining_ext_list(struct lws *wsi);\n-LWS_EXTERN int\n-lws_plat_context_early_init(void);\n-LWS_EXTERN void\n-lws_plat_context_early_destroy(struct lws_context *context);\n-LWS_EXTERN void\n-lws_plat_context_late_destroy(struct lws_context *context);\n-LWS_EXTERN int\n-lws_poll_listen_fd(struct lws_pollfd *fd);\n-LWS_EXTERN int\n-lws_plat_service(struct lws_context *context, int timeout_ms);\n-LWS_EXTERN LWS_VISIBLE int\n-_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);\n-LWS_EXTERN int\n-lws_plat_init(struct lws_context *context,\n-\t const struct lws_context_creation_info *info);\n-LWS_EXTERN void\n-lws_plat_drop_app_privileges(const struct lws_context_creation_info *info);\n-LWS_EXTERN unsigned long long\n-time_in_microseconds(void);\n-LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT\n-lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt);\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_plat_inet_pton(int af, const char *src, void *dst);\n-\n-LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);\n-LWS_EXTERN int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,\n-\t\t lws_filepos_t *amount);\n-\n-\n-LWS_EXTERN void\n-lws_same_vh_protocol_remove(struct lws *wsi);\n-LWS_EXTERN void\n-lws_same_vh_protocol_insert(struct lws *wsi, int n);\n-\n-LWS_EXTERN int\n-lws_broadcast(struct lws_context *context, int reason, void *in, size_t len);\n-\n-#if defined(LWS_WITH_STATS)\n- void\n- lws_stats_atomic_bump(struct lws_context * context,\n-\t\tstruct lws_context_per_thread *pt, int index, uint64_t bump);\n- void\n- lws_stats_atomic_max(struct lws_context * context,\n-\t\tstruct lws_context_per_thread *pt, int index, uint64_t val);\n-#else\n- static inline uint64_t lws_stats_atomic_bump(struct lws_context * context,\n-\t\tstruct lws_context_per_thread *pt, int index, uint64_t bump) {\n-\t(void)context; (void)pt; (void)index; (void)bump; return 0; }\n- static inline uint64_t lws_stats_atomic_max(struct lws_context * context,\n-\t\tstruct lws_context_per_thread *pt, int index, uint64_t val) {\n-\t(void)context; (void)pt; (void)index; (void)val; return 0; }\n-#endif\n-\n-/* socks */\n-void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,\n-\t\t\tssize_t *msg_len);\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-void\n-lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer);\n-int\n-lws_peer_confirm_ah_attach_ok(struct lws_context *context, struct lws_peer *peer);\n-void\n-lws_peer_track_ah_detach(struct lws_context *context, struct lws_peer *peer);\n-void\n-lws_peer_cull_peer_wait_list(struct lws_context *context);\n-struct lws_peer *\n-lws_get_or_create_peer(struct lws_vhost *vhost, lws_sockfd_type sockfd);\n-void\n-lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer,\n-\t\t struct lws *wsi);\n-void\n-lws_peer_dump_from_wsi(struct lws *wsi);\n-#endif\n-\n-\n-void\n-__lws_remove_from_timeout_list(struct lws *wsi);\n-\n-lws_usec_t\n-__lws_hrtimer_service(struct lws_context_per_thread *pt);\n-\n-void\n-__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs);\n-int\n-__lws_change_pollfd(struct lws *wsi, int _and, int _or);\n-\n-\n-int\n-lws_callback_as_writeable(struct lws *wsi);\n-int\n-lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi,\n-\t\t struct lws_tokens *ebuf);\n-int\n-lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used,\n-\t\t\t int buffered);\n-\n-\n-char *\n-lws_generate_client_ws_handshake(struct lws *wsi, char *p);\n-int\n-lws_client_ws_upgrade(struct lws *wsi, const char **cce);\n-int\n-lws_create_client_ws_object(struct lws_client_connect_info *i, struct lws *wsi);\n-int\n-lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len);\n-int\n-lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn);\n-int\n-lws_tls_server_conn_alpn(struct lws *wsi);\n-\n-int\n-lws_ws_client_rx_sm_block(struct lws *wsi, unsigned char **buf, size_t len);\n-void\n-lws_destroy_event_pipe(struct lws *wsi);\n-void\n-lws_context_destroy2(struct lws_context *context);\n-\n-#ifdef __cplusplus\n-};\n-#endif\ndiff --git a/lib/roles/cgi/cgi-server.c b/lib/roles/cgi/cgi-server.c\nindex 4fc8305..e5a466a 100644\n--- a/lib/roles/cgi/cgi-server.c\n+++ b/lib/roles/cgi/cgi-server.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #if defined(WIN32) || defined(_WIN32)\n #else\ndiff --git a/lib/roles/cgi/ops-cgi.c b/lib/roles/cgi/ops-cgi.c\nindex bc42c10..8555f7b 100644\n--- a/lib/roles/cgi/ops-cgi.c\n+++ b/lib/roles/cgi/ops-cgi.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n static int\n rops_handle_POLLIN_cgi(struct lws_context_per_thread *pt, struct lws *wsi,\ndiff --git a/lib/roles/cgi/private.h b/lib/roles/cgi/private.h\nindex 868dba0..b964ce0 100644\n--- a/lib/roles/cgi/private.h\n+++ b/lib/roles/cgi/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_ROLE_WS\n+ * This is included from core/private.h if LWS_ROLE_WS\n */\n \n extern struct lws_role_ops role_ops_cgi;\ndiff --git a/lib/roles/h1/ops-h1.c b/lib/roles/h1/ops-h1.c\nindex 172b8d8..8afd626 100644\n--- a/lib/roles/h1/ops-h1.c\n+++ b/lib/roles/h1/ops-h1.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n #ifndef min\n #define min(a, b) ((a) \u003c (b) ? (a) : (b))\ndiff --git a/lib/roles/h1/private.h b/lib/roles/h1/private.h\nindex 17e7a90..3f53954 100644\n--- a/lib/roles/h1/private.h\n+++ b/lib/roles/h1/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_ROLE_H1\n+ * This is included from core/private.h if LWS_ROLE_H1\n *\n * Most of the h1 business is defined in the h1 / h2 common roles/http dir\n */\ndiff --git a/lib/roles/h2/hpack.c b/lib/roles/h2/hpack.c\nindex 6e80276..d25849d 100644\n--- a/lib/roles/h2/hpack.c\n+++ b/lib/roles/h2/hpack.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * Official static header table for HPACK\ndiff --git a/lib/roles/h2/http2.c b/lib/roles/h2/http2.c\nindex c61eb84..d630872 100644\n--- a/lib/roles/h2/http2.c\n+++ b/lib/roles/h2/http2.c\n@@ -20,7 +20,7 @@\n */\n \n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * bitmap of control messages that are valid to receive for each http2 state\ndiff --git a/lib/roles/h2/ops-h2.c b/lib/roles/h2/ops-h2.c\nindex abd7e12..0e0afee 100644\n--- a/lib/roles/h2/ops-h2.c\n+++ b/lib/roles/h2/ops-h2.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n /*\n * These are the standardized defaults.\ndiff --git a/lib/roles/h2/private.h b/lib/roles/h2/private.h\nindex 0341b4a..664c509 100644\n--- a/lib/roles/h2/private.h\n+++ b/lib/roles/h2/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_ROLE_H2\n+ * This is included from core/private.h if LWS_ROLE_H2\n */\n \n extern struct lws_role_ops role_ops_h2;\ndiff --git a/lib/roles/http/client/client-handshake.c b/lib/roles/http/client/client-handshake.c\nindex a28d7fe..337ccea 100644\n--- a/lib/roles/http/client/client-handshake.c\n+++ b/lib/roles/http/client/client-handshake.c\n@@ -1,4 +1,4 @@\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static int\n lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result)\n@@ -78,7 +78,9 @@ lws_client_connect_2(struct lws *wsi)\n \t */\n \n \tadsin \u003d lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);\n-\tlws_vhost_lock(wsi-\u003evhost);\n+\n+\tlws_vhost_lock(wsi-\u003evhost); /* ----------------------------------- { */\n+\n \tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n \t\t\t\t wsi-\u003evhost-\u003edll_active_client_conns.next) {\n \t\tstruct lws *w \u003d lws_container_of(d, struct lws,\n@@ -101,6 +103,7 @@ lws_client_connect_2(struct lws *wsi)\n \t\t\tif (w-\u003ekeepalive_rejected) {\n \t\t\t\tlwsl_info(\u0022defeating pipelining due to no \u0022\n \t\t\t\t\t \u0022keepalive on server\u005cn\u0022);\n+\t\t\t\tlws_vhost_unlock(wsi-\u003evhost); /* } ---------- */\n \t\t\t\tgoto create_new_conn;\n \t\t\t}\n #if defined (LWS_WITH_HTTP2)\n@@ -117,7 +120,7 @@ lws_client_connect_2(struct lws *wsi)\n \n \t\t\t\twsi-\u003eclient_h2_alpn \u003d 1;\n \t\t\t\tlws_wsi_h2_adopt(w, wsi);\n-\t\t\t\tlws_vhost_unlock(wsi-\u003evhost);\n+\t\t\t\tlws_vhost_unlock(wsi-\u003evhost); /* } ---------- */\n \n \t\t\t\treturn wsi;\n \t\t\t}\n@@ -140,12 +143,13 @@ lws_client_connect_2(struct lws *wsi)\n \n \t\t\twsi_piggyback \u003d w;\n \n-\t\t\tlws_vhost_unlock(wsi-\u003evhost);\n+\t\t\tlws_vhost_unlock(wsi-\u003evhost); /* } ---------- */\n \t\t\tgoto send_hs;\n \t\t}\n \n \t} lws_end_foreach_dll_safe(d, d1);\n-\tlws_vhost_unlock(wsi-\u003evhost);\n+\n+\tlws_vhost_unlock(wsi-\u003evhost); /* } ---------------------------------- */\n \n create_new_conn:\n #endif\ndiff --git a/lib/roles/http/client/client.c b/lib/roles/http/client/client.c\nindex e035dba..ce42dc6 100644\n--- a/lib/roles/http/client/client.c\n+++ b/lib/roles/http/client/client.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n LWS_VISIBLE LWS_EXTERN void\n lws_client_http_body_pending(struct lws *wsi, int something_left_to_send)\ndiff --git a/lib/roles/http/header.c b/lib/roles/http/header.c\nindex eef5fde..99e56f7 100644\n--- a/lib/roles/http/header.c\n+++ b/lib/roles/http/header.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n #include \u0022lextable-strings.h\u0022\n \n \ndiff --git a/lib/roles/http/private.h b/lib/roles/http/private.h\nindex 2411ec8..2aa7a92 100644\n--- a/lib/roles/http/private.h\n+++ b/lib/roles/http/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if either H1 or H2 roles are\n+ * This is included from core/private.h if either H1 or H2 roles are\n * enabled\n */\n \ndiff --git a/lib/roles/http/server/access-log.c b/lib/roles/http/server/access-log.c\nindex c07e557..0e75309 100644\n--- a/lib/roles/http/server/access-log.c\n+++ b/lib/roles/http/server/access-log.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * Produce Apache-compatible log string for wsi, like this:\ndiff --git a/lib/roles/http/server/fops-zip.c b/lib/roles/http/server/fops-zip.c\nindex f8ede1f..4db83ce 100644\n--- a/lib/roles/http/server/fops-zip.c\n+++ b/lib/roles/http/server/fops-zip.c\n@@ -51,7 +51,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #include \u003czlib.h\u003e\n \ndiff --git a/lib/roles/http/server/lejp-conf.c b/lib/roles/http/server/lejp-conf.c\nindex b41779d..e9ce854 100644\n--- a/lib/roles/http/server/lejp-conf.c\n+++ b/lib/roles/http/server/lejp-conf.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #ifndef _WIN32\n /* this is needed for Travis CI */\ndiff --git a/lib/roles/http/server/lws-spa.c b/lib/roles/http/server/lws-spa.c\nindex b3ed050..88675ef 100644\n--- a/lib/roles/http/server/lws-spa.c\n+++ b/lib/roles/http/server/lws-spa.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #define LWS_MAX_ELEM_NAME 32\n \ndiff --git a/lib/roles/http/server/parsers.c b/lib/roles/http/server/parsers.c\nindex 21d44db..5754f90 100644\n--- a/lib/roles/http/server/parsers.c\n+++ b/lib/roles/http/server/parsers.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static const unsigned char lextable[] \u003d {\n \t#include \u0022../lextable.h\u0022\ndiff --git a/lib/roles/http/server/ranges.c b/lib/roles/http/server/ranges.c\nindex bc1578d..f69c33c 100644\n--- a/lib/roles/http/server/ranges.c\n+++ b/lib/roles/http/server/ranges.c\n@@ -21,7 +21,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * RFC7233 examples\ndiff --git a/lib/roles/http/server/rewrite.c b/lib/roles/http/server/rewrite.c\nindex 2f9b0c4..61bb613 100644\n--- a/lib/roles/http/server/rewrite.c\n+++ b/lib/roles/http/server/rewrite.c\n@@ -1,4 +1,4 @@\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n \n LWS_EXTERN struct lws_rewrite *\ndiff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c\nindex 83f5de8..a308683 100644\n--- a/lib/roles/http/server/server.c\n+++ b/lib/roles/http/server/server.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n const char * const method_names[] \u003d {\n \t\u0022GET\u0022, \u0022POST\u0022, \u0022OPTIONS\u0022, \u0022PUT\u0022, \u0022PATCH\u0022, \u0022DELETE\u0022, \u0022CONNECT\u0022, \u0022HEAD\u0022,\ndiff --git a/lib/roles/listen/ops-listen.c b/lib/roles/listen/ops-listen.c\nindex 02f028a..0e46323 100644\n--- a/lib/roles/listen/ops-listen.c\n+++ b/lib/roles/listen/ops-listen.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n static int\n rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,\ndiff --git a/lib/roles/pipe/ops-pipe.c b/lib/roles/pipe/ops-pipe.c\nindex 4fd4902..b9348d5 100644\n--- a/lib/roles/pipe/ops-pipe.c\n+++ b/lib/roles/pipe/ops-pipe.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n static int\n rops_handle_POLLIN_pipe(struct lws_context_per_thread *pt, struct lws *wsi,\ndiff --git a/lib/roles/private.h b/lib/roles/private.h\nindex f13e14a..4e0b312 100644\n--- a/lib/roles/private.h\n+++ b/lib/roles/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h\n+ * This is included from core/private.h\n */\n \n typedef uint32_t lws_wsi_state_t;\ndiff --git a/lib/roles/raw/ops-raw.c b/lib/roles/raw/ops-raw.c\nindex e94af04..68b52bd 100644\n--- a/lib/roles/raw/ops-raw.c\n+++ b/lib/roles/raw/ops-raw.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n static int\n rops_handle_POLLIN_raw_skt(struct lws_context_per_thread *pt, struct lws *wsi,\ndiff --git a/lib/roles/ws/client-parser-ws.c b/lib/roles/ws/client-parser-ws.c\nindex 8e74a6d..aa561ce 100644\n--- a/lib/roles/ws/client-parser-ws.c\n+++ b/lib/roles/ws/client-parser-ws.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * parsers.c: lws_ws_rx_sm() needs to be roughly kept in\n@@ -29,10 +29,13 @@\n int lws_ws_client_rx_sm(struct lws *wsi, unsigned char c)\n {\n \tint callback_action \u003d LWS_CALLBACK_CLIENT_RECEIVE;\n-\tint handled, n, m, rx_draining_ext \u003d 0;\n+\tint handled, m;\n \tunsigned short close_code;\n \tstruct lws_tokens ebuf;\n \tunsigned char *pp;\n+#if !defined(LWS_WITHOUT_EXTENSIONS)\n+\tint rx_draining_ext \u003d 0, n;\n+#endif\n \n \tebuf.token \u003d NULL;\n \tebuf.len \u003d 0;\n@@ -498,12 +501,14 @@ drain_extension:\n \t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n \t\t\treturn -1;\n \t\t}\n-#else\n-\t\tn \u003d 0;\n #endif\n \t\tlwsl_debug(\u0022post inflate ebuf len %d\u005cn\u0022, ebuf.len);\n \n-\t\tif (rx_draining_ext \u0026\u0026 !ebuf.len) {\n+\t\tif (\n+#if !defined(LWS_WITHOUT_EXTENSIONS)\n+\t\t rx_draining_ext \u0026\u0026\n+#endif\n+\t\t !ebuf.len) {\n \t\t\tlwsl_debug(\u0022 --- ending drain on 0 read result\u005cn\u0022);\n \t\t\tgoto already_done;\n \t\t}\n@@ -520,7 +525,11 @@ drain_extension:\n \n \t\t\t/* we are ending partway through utf-8 character? */\n \t\t\tif (!wsi-\u003ews-\u003erx_packet_length \u0026\u0026 wsi-\u003ews-\u003efinal \u0026\u0026\n-\t\t\t wsi-\u003ews-\u003eutf8 \u0026\u0026 !n) {\n+\t\t\t wsi-\u003ews-\u003eutf8\n+#if !defined(LWS_WITHOUT_EXTENSIONS)\n+\t\t\t \u0026\u0026 !n\n+#endif\n+\t\t\t ) {\n \t\t\t\tlwsl_info(\u0022FINAL utf8 error\u005cn\u0022);\n \t\t\t\tlws_close_reason(wsi,\n \t\t\t\t\tLWS_CLOSE_STATUS_INVALID_PAYLOAD,\n@@ -550,9 +559,9 @@ utf8_fail:\n \n \t\tif (\n \t\t\t\t/* coverity says dead code otherwise */\n-//#if !defined(LWS_WITHOUT_EXTENSIONS)\n+#if !defined(LWS_WITHOUT_EXTENSIONS)\n \t\t\t\tn \u0026\u0026\n-//#endif\n+#endif\n \t\t\t\tebuf.len)\n \t\t\t/* extension had more... main loop will come back\n \t\t\t * we want callback to be done with this set, if so,\ndiff --git a/lib/roles/ws/client-ws.c b/lib/roles/ws/client-ws.c\nindex 10b69f0..fd6cf42 100644\n--- a/lib/roles/ws/client-ws.c\n+++ b/lib/roles/ws/client-ws.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n /*\n * In-place str to lower case\ndiff --git a/lib/roles/ws/ext/extension-permessage-deflate.c b/lib/roles/ws/ext/extension-permessage-deflate.c\nindex e23d80d..728aa5c 100644\n--- a/lib/roles/ws/ext/extension-permessage-deflate.c\n+++ b/lib/roles/ws/ext/extension-permessage-deflate.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n #include \u0022extension-permessage-deflate.h\u0022\n #include \u003cstdio.h\u003e\n #include \u003cstring.h\u003e\ndiff --git a/lib/roles/ws/ext/extension.c b/lib/roles/ws/ext/extension.c\nindex d20c956..a45f3ba 100644\n--- a/lib/roles/ws/ext/extension.c\n+++ b/lib/roles/ws/ext/extension.c\n@@ -1,4 +1,4 @@\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #include \u0022extension-permessage-deflate.h\u0022\n \ndiff --git a/lib/roles/ws/ops-ws.c b/lib/roles/ws/ops-ws.c\nindex 9e2a52f..fd036c3 100644\n--- a/lib/roles/ws/ops-ws.c\n+++ b/lib/roles/ws/ops-ws.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n #define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr +\u003d strlen(str); }\n \n@@ -32,12 +32,13 @@ int\n lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c)\n {\n \tint callback_action \u003d LWS_CALLBACK_RECEIVE;\n-\tint ret \u003d 0, rx_draining_ext \u003d 0;\n+\tint ret \u003d 0;\n \tunsigned short close_code;\n \tstruct lws_tokens ebuf;\n \tunsigned char *pp;\n \tint n \u003d 0;\n #if !defined(LWS_WITHOUT_EXTENSIONS)\n+\tint rx_draining_ext \u003d 0;\n \tint lin;\n #endif\n \n@@ -586,7 +587,11 @@ drain_extension:\n \t\t\treturn -1;\n \t\t}\n #endif\n-\t\tif (rx_draining_ext \u0026\u0026 ebuf.len \u003d\u003d 0)\n+\t\tif (\n+#if !defined(LWS_WITHOUT_EXTENSIONS)\n+\t\t rx_draining_ext \u0026\u0026\n+#endif\n+\t\t ebuf.len \u003d\u003d 0)\n \t\t\tgoto already_done;\n \n \t\tif (\ndiff --git a/lib/roles/ws/private.h b/lib/roles/ws/private.h\nindex 82eb84b..71ffcae 100644\n--- a/lib/roles/ws/private.h\n+++ b/lib/roles/ws/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_ROLE_WS\n+ * This is included from core/private.h if LWS_ROLE_WS\n */\n \n extern struct lws_role_ops role_ops_ws;\ndiff --git a/lib/roles/ws/server-ws.c b/lib/roles/ws/server-ws.c\nindex 0d8a0b9..62bcd85 100644\n--- a/lib/roles/ws/server-ws.c\n+++ b/lib/roles/ws/server-ws.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u003cprivate-libwebsockets.h\u003e\n+#include \u003ccore/private.h\u003e\n \n #define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr +\u003d strlen(str); }\n \ndiff --git a/lib/service.c b/lib/service.c\ndeleted file mode 100644\nindex a08506f..0000000\n--- a/lib/service.c\n+++ /dev/null\n@@ -1,987 +0,0 @@\n-/*\n- * libwebsockets - small server side websockets and web server implementation\n- *\n- * Copyright (C) 2010-2018 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This library is free software; you can redistribute it and/or\n- * modify it under the terms of the GNU Lesser General Public\n- * License as published by the Free Software Foundation:\n- * version 2.1 of the License.\n- *\n- * This library is distributed in the hope that it will be useful,\n- * but WITHOUT ANY WARRANTY; without even the implied warranty of\n- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n- * Lesser General Public License for more details.\n- *\n- * You should have received a copy of the GNU Lesser General Public\n- * License along with this library; if not, write to the Free Software\n- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n- * MA 02110-1301 USA\n- */\n-\n-#include \u0022private-libwebsockets.h\u0022\n-\n-int\n-lws_callback_as_writeable(struct lws *wsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tint n, m;\n-\n-\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_WRITEABLE_CB, 1);\n-#if defined(LWS_WITH_STATS)\n-\tif (wsi-\u003eactive_writable_req_us) {\n-\t\tuint64_t ul \u003d time_in_microseconds() -\n-\t\t\t wsi-\u003eactive_writable_req_us;\n-\n-\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt,\n-\t\t\t\t LWSSTATS_MS_WRITABLE_DELAY, ul);\n-\t\tlws_stats_atomic_max(wsi-\u003econtext, pt,\n-\t\t\t\t LWSSTATS_MS_WORST_WRITABLE_DELAY, ul);\n-\t\twsi-\u003eactive_writable_req_us \u003d 0;\n-\t}\n-#endif\n-\n-\tn \u003d wsi-\u003erole_ops-\u003ewriteable_cb[lwsi_role_server(wsi)];\n-\n-\tm \u003d user_callback_handle_rxflow(wsi-\u003eprotocol-\u003ecallback,\n-\t\t\t\t\twsi, (enum lws_callback_reasons) n,\n-\t\t\t\t\twsi-\u003euser_space, NULL, 0);\n-\n-\treturn m;\n-}\n-\n-LWS_VISIBLE int\n-lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)\n-{\n-\tvolatile struct lws *vwsi \u003d (volatile struct lws *)wsi;\n-\tint n;\n-\n-\t//lwsl_notice(\u0022%s: %p\u005cn\u0022, __func__, wsi);\n-\n-\tvwsi-\u003eleave_pollout_active \u003d 0;\n-\tvwsi-\u003ehandling_pollout \u003d 1;\n-\t/*\n-\t * if another thread wants POLLOUT on us, from here on while\n-\t * handling_pollout is set, he will only set leave_pollout_active.\n-\t * If we are going to disable POLLOUT, we will check that first.\n-\t */\n-\twsi-\u003ecould_have_pending \u003d 0; /* clear back-to-back write detection */\n-\n-\t/*\n-\t * user callback is lowest priority to get these notifications\n-\t * actually, since other pending things cannot be disordered\n-\t *\n-\t * Priority 1: pending truncated sends are incomplete ws fragments\n-\t *\t If anything else sent first the protocol would be\n-\t *\t corrupted.\n-\t */\n-\n-\tif (wsi-\u003etrunc_len) {\n-\t\t//lwsl_notice(\u0022%s: completing partial\u005cn\u0022, __func__);\n-\t\tif (lws_issue_raw(wsi, wsi-\u003etrunc_alloc + wsi-\u003etrunc_offset,\n-\t\t\t\t wsi-\u003etrunc_len) \u003c 0) {\n-\t\t\tlwsl_info(\u0022%s signalling to close\u005cn\u0022, __func__);\n-\t\t\tgoto bail_die;\n-\t\t}\n-\t\t/* leave POLLOUT active either way */\n-\t\tgoto bail_ok;\n-\t} else\n-\t\tif (lwsi_state(wsi) \u003d\u003d LRS_FLUSHING_BEFORE_CLOSE) {\n-\t\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\t\tgoto bail_die; /* retry closing now */\n-\t\t}\n-\n-#ifdef LWS_WITH_CGI\n-\t/*\n-\t * A cgi master's wire protocol remains h1 or h2. He is just getting\n-\t * his data from his child cgis.\n-\t */\n-\tif (wsi-\u003ehttp.cgi) {\n-\t\t/* also one shot */\n-\t\tif (pollfd)\n-\t\t\tif (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {\n-\t\t\t\tlwsl_info(\u0022failed at set pollfd\u005cn\u0022);\n-\t\t\t\treturn 1;\n-\t\t\t}\n-\t\tgoto user_service_go_again;\n-\t}\n-#endif\n-\n-\t/* if we got here, we should have wire protocol ops set on the wsi */\n-\tassert(wsi-\u003erole_ops);\n-\n-\tif (!wsi-\u003erole_ops-\u003ehandle_POLLOUT)\n-\t\tgoto bail_ok;\n-\n-\tswitch ((wsi-\u003erole_ops-\u003ehandle_POLLOUT)(wsi)) {\n-\tcase LWS_HP_RET_BAIL_OK:\n-\t\tgoto bail_ok;\n-\tcase LWS_HP_RET_BAIL_DIE:\n-\t\tgoto bail_die;\n-\tcase LWS_HP_RET_USER_SERVICE:\n-\t\tbreak;\n-\tdefault:\n-\t\tassert(0);\n-\t}\n-\n-\t/* one shot */\n-\n-\tif (wsi-\u003eparent_carries_io) {\n-\t\tvwsi-\u003ehandling_pollout \u003d 0;\n-\t\tvwsi-\u003eleave_pollout_active \u003d 0;\n-\n-\t\treturn lws_callback_as_writeable(wsi);\n-\t}\n-\n-\tif (pollfd) {\n-\t\tint eff \u003d vwsi-\u003eleave_pollout_active;\n-\n-\t\tif (!eff) {\n-\t\t\tif (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {\n-\t\t\t\tlwsl_info(\u0022failed at set pollfd\u005cn\u0022);\n-\t\t\t\tgoto bail_die;\n-\t\t\t}\n-\t\t}\n-\n-\t\tvwsi-\u003ehandling_pollout \u003d 0;\n-\n-\t\t/* cannot get leave_pollout_active set after the above */\n-\t\tif (!eff \u0026\u0026 wsi-\u003eleave_pollout_active) {\n-\t\t\t/*\n-\t\t\t * got set inbetween sampling eff and clearing\n-\t\t\t * handling_pollout, force POLLOUT on\n-\t\t\t */\n-\t\t\tlwsl_debug(\u0022leave_pollout_active\u005cn\u0022);\n-\t\t\tif (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {\n-\t\t\t\tlwsl_info(\u0022failed at set pollfd\u005cn\u0022);\n-\t\t\t\tgoto bail_die;\n-\t\t\t}\n-\t\t}\n-\n-\t\tvwsi-\u003eleave_pollout_active \u003d 0;\n-\t}\n-\n-\tif (lwsi_role_client(wsi) \u0026\u0026\n-\t !wsi-\u003ehdr_parsing_completed \u0026\u0026\n-\t lwsi_state(wsi) !\u003d LRS_H2_WAITING_TO_SEND_HEADERS \u0026\u0026\n-\t lwsi_state(wsi) !\u003d LRS_ISSUE_HTTP_BODY\n-\t )\n-\t\tgoto bail_ok;\n-\n-\n-#ifdef LWS_WITH_CGI\n-user_service_go_again:\n-#endif\n-\n-\tif (wsi-\u003erole_ops-\u003eperform_user_POLLOUT) {\n-\t\tif (wsi-\u003erole_ops-\u003eperform_user_POLLOUT(wsi) \u003d\u003d -1)\n-\t\t\tgoto bail_die;\n-\t\telse\n-\t\t\tgoto bail_ok;\n-\t}\n-\t\n-\tlwsl_debug(\u0022%s: %p: non mux: wsistate 0x%x, ops %s\u005cn\u0022, __func__, wsi,\n-\t\t wsi-\u003ewsistate, wsi-\u003erole_ops-\u003ename);\n-\n-\tvwsi \u003d (volatile struct lws *)wsi;\n-\tvwsi-\u003eleave_pollout_active \u003d 0;\n-\n-\tn \u003d lws_callback_as_writeable(wsi);\n-\tvwsi-\u003ehandling_pollout \u003d 0;\n-\n-\tif (vwsi-\u003eleave_pollout_active)\n-\t\tlws_change_pollfd(wsi, 0, LWS_POLLOUT);\n-\n-\treturn n;\n-\n-\t/*\n-\t * since these don't disable the POLLOUT, they are always doing the\n-\t * right thing for leave_pollout_active whether it was set or not.\n-\t */\n-\n-bail_ok:\n-\tvwsi-\u003ehandling_pollout \u003d 0;\n-\tvwsi-\u003eleave_pollout_active \u003d 0;\n-\n-\treturn 0;\n-\n-bail_die:\n-\tvwsi-\u003ehandling_pollout \u003d 0;\n-\tvwsi-\u003eleave_pollout_active \u003d 0;\n-\n-\treturn -1;\n-}\n-\n-static int\n-__lws_service_timeout_check(struct lws *wsi, time_t sec)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tint n \u003d 0;\n-\n-\t(void)n;\n-\n-\t/*\n-\t * if we went beyond the allowed time, kill the\n-\t * connection\n-\t */\n-\tif (wsi-\u003edll_timeout.prev \u0026\u0026\n-\t lws_compare_time_t(wsi-\u003econtext, sec, wsi-\u003epending_timeout_set) \u003e\n-\t\t\t wsi-\u003epending_timeout_limit) {\n-\n-\t\tif (wsi-\u003edesc.sockfd !\u003d LWS_SOCK_INVALID \u0026\u0026\n-\t\t wsi-\u003eposition_in_fds_table \u003e\u003d 0)\n-\t\t\tn \u003d pt-\u003efds[wsi-\u003eposition_in_fds_table].events;\n-\n-\t\tlws_stats_atomic_bump(wsi-\u003econtext, pt, LWSSTATS_C_TIMEOUTS, 1);\n-\n-\t\t/* no need to log normal idle keepalive timeout */\n-\t\tif (wsi-\u003epending_timeout !\u003d PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE)\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\t\t\tlwsl_info(\u0022wsi %p: TIMEDOUT WAITING on %d \u0022\n-\t\t\t\t \u0022(did hdr %d, ah %p, wl %d, pfd \u0022\n-\t\t\t\t \u0022events %d) %llu vs %llu\u005cn\u0022,\n-\t\t\t\t (void *)wsi, wsi-\u003epending_timeout,\n-\t\t\t\t wsi-\u003ehdr_parsing_completed, wsi-\u003ehttp.ah,\n-\t\t\t\t pt-\u003ehttp.ah_wait_list_length, n,\n-\t\t\t\t (unsigned long long)sec,\n-\t\t\t\t (unsigned long long)wsi-\u003epending_timeout_limit);\n-#if defined(LWS_WITH_CGI)\n-\t\tif (wsi-\u003ehttp.cgi)\n-\t\t\tlwsl_notice(\u0022CGI timeout: %s\u005cn\u0022, wsi-\u003ehttp.cgi-\u003esummary);\n-#endif\n-#else\n-\t\tlwsl_info(\u0022wsi %p: TIMEDOUT WAITING on %d \u0022, (void *)wsi,\n-\t\t\t wsi-\u003epending_timeout);\n-#endif\n-\n-\t\t/*\n-\t\t * Since he failed a timeout, he already had a chance to do\n-\t\t * something and was unable to... that includes situations like\n-\t\t * half closed connections. So process this \u0022failed timeout\u0022\n-\t\t * close as a violent death and don't try to do protocol\n-\t\t * cleanup like flush partials.\n-\t\t */\n-\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\tif (lwsi_state(wsi) \u003d\u003d LRS_WAITING_SSL \u0026\u0026 wsi-\u003eprotocol)\n-\t\t\twsi-\u003eprotocol-\u003ecallback(wsi,\n-\t\t\t\tLWS_CALLBACK_CLIENT_CONNECTION_ERROR,\n-\t\t\t\twsi-\u003euser_space,\n-\t\t\t\t(void *)\u0022Timed out waiting SSL\u0022, 21);\n-\n-\t\t__lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, \u0022timeout\u0022);\n-\n-\t\treturn 1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-int lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tuint8_t *buffered;\n-\tsize_t blen;\n-\tint ret \u003d 0, m;\n-\n-\t/* his RX is flowcontrolled, don't send remaining now */\n-\tblen \u003d lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist, \u0026buffered);\n-\tif (blen) {\n-\t\tif (buf \u003e\u003d buffered \u0026\u0026 buf + len \u003c\u003d buffered + blen) {\n-\t\t\t/* rxflow while we were spilling prev rxflow */\n-\t\t\tlwsl_info(\u0022%s: staying in rxflow buf\u005cn\u0022, __func__);\n-\n-\t\t\treturn 1;\n-\t\t}\n-\t\tret \u003d 1;\n-\t}\n-\n-\t/* a new rxflow, buffer it and warn caller */\n-\n-\tm \u003d lws_buflist_append_segment(\u0026wsi-\u003ebuflist, buf + n, len - n);\n-\n-\tif (m \u003c 0)\n-\t\treturn -1;\n-\tif (m) {\n-\t\tlwsl_debug(\u0022%s: added %p to rxflow list\u005cn\u0022, __func__, wsi);\n-\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_buflist, \u0026pt-\u003edll_head_buflist);\n-\t}\n-\n-\treturn ret;\n-}\n-\n-/* this is used by the platform service code to stop us waiting for network\n- * activity in poll() when we have something that already needs service\n- */\n-\n-LWS_VISIBLE LWS_EXTERN int\n-lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n-\n-\t/* Figure out if we really want to wait in poll()\n-\t * We only need to wait if really nothing already to do and we have\n-\t * to wait for something from network\n-\t */\n-#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n-\t/* 1) if we know we are draining rx ext, do not wait in poll */\n-\tif (pt-\u003ews.rx_draining_ext_list)\n-\t\treturn 0;\n-#endif\n-\n-\t/* 2) if we know we have non-network pending data, do not wait in poll */\n-\n-\tif (pt-\u003econtext-\u003etls_ops \u0026\u0026\n-\t pt-\u003econtext-\u003etls_ops-\u003efake_POLLIN_for_buffered)\n-\t\tif (pt-\u003econtext-\u003etls_ops-\u003efake_POLLIN_for_buffered(pt))\n-\t\t\treturn 0;\n-\n-\t/* 3) If there is any wsi with rxflow buffered and in a state to process\n-\t * it, we should not wait in poll\n-\t */\n-\n-\tlws_start_foreach_dll(struct lws_dll_lws *, d, pt-\u003edll_head_buflist.next) {\n-\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_buflist);\n-\n-\t\tif (lwsi_state(wsi) !\u003d LRS_DEFERRING_ACTION)\n-\t\t\treturn 0;\n-\n-\t} lws_end_foreach_dll(d);\n-\n-\treturn timeout_ms;\n-}\n-\n-/*\n- * POLLIN said there is something... we must read it, and either use it; or\n- * if other material already in the buflist append it and return the buflist\n- * head material.\n- */\n-int\n-lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi,\n-\t\t struct lws_tokens *ebuf)\n-{\n-\tint n, prior \u003d (int)lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist, NULL);\n-\n-\tebuf-\u003etoken \u003d (char *)pt-\u003eserv_buf;\n-\tebuf-\u003elen \u003d lws_ssl_capable_read(wsi, pt-\u003eserv_buf,\n-\t\t\t\t\t wsi-\u003econtext-\u003ept_serv_buf_size);\n-\n-\tif (ebuf-\u003elen \u003d\u003d LWS_SSL_CAPABLE_MORE_SERVICE \u0026\u0026 prior)\n-\t\tgoto get_from_buflist;\n-\n-\tif (ebuf-\u003elen \u003c\u003d 0)\n-\t\treturn 0;\n-\n-\t/* nothing in buflist already? Then just use what we read */\n-\n-\tif (!prior)\n-\t\treturn 0;\n-\n-\t/* stash what we read */\n-\n-\tn \u003d lws_buflist_append_segment(\u0026wsi-\u003ebuflist, (uint8_t *)ebuf-\u003etoken,\n-\t\t\t\t ebuf-\u003elen);\n-\tif (n \u003c 0)\n-\t\treturn -1;\n-\tif (n) {\n-\t\tlwsl_debug(\u0022%s: added %p to rxflow list\u005cn\u0022, __func__, wsi);\n-\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_buflist, \u0026pt-\u003edll_head_buflist);\n-\t}\n-\n-\t/* get the first buflist guy in line */\n-\n-get_from_buflist:\n-\n-\tebuf-\u003elen \u003d (int)lws_buflist_next_segment_len(\u0026wsi-\u003ebuflist,\n-\t\t\t\t\t\t (uint8_t **)\u0026ebuf-\u003etoken);\n-\n-\treturn 1; /* came from buflist */\n-}\n-\n-int\n-lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used,\n-\t\t\t int buffered)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n-\tint m;\n-\n-\t/* it's in the buflist; we didn't use any */\n-\n-\tif (!used \u0026\u0026 buffered)\n-\t\treturn 0;\n-\n-\tif (used \u0026\u0026 buffered) {\n-\t\tm \u003d lws_buflist_use_segment(\u0026wsi-\u003ebuflist, used);\n-\t\tlwsl_info(\u0022%s: draining rxflow: used %d, next %d\u005cn\u0022,\n-\t\t\t __func__, used, m);\n-\t\tif (m)\n-\t\t\treturn 0;\n-\n-\t\tlwsl_info(\u0022%s: removed %p from dll_buflist\u005cn\u0022, __func__, wsi);\n-\t\tlws_dll_lws_remove(\u0026wsi-\u003edll_buflist);\n-\n-\t\treturn 0;\n-\t}\n-\n-\t/* any remainder goes on the buflist */\n-\n-\tif (used !\u003d ebuf-\u003elen) {\n-\t\tm \u003d lws_buflist_append_segment(\u0026wsi-\u003ebuflist,\n-\t\t\t\t\t (uint8_t *)ebuf-\u003etoken + used,\n-\t\t\t\t\t ebuf-\u003elen - used);\n-\t\tif (m \u003c 0)\n-\t\t\treturn 1; /* OOM */\n-\t\tif (m) {\n-\t\t\tlwsl_debug(\u0022%s: added %p to rxflow list\u005cn\u0022, __func__, wsi);\n-\t\t\tlws_dll_lws_add_front(\u0026wsi-\u003edll_buflist, \u0026pt-\u003edll_head_buflist);\n-\t\t}\n-\t}\n-\n-\treturn 0;\n-}\n-\n-void\n-lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt)\n-{\n-\tstruct lws_pollfd pfd;\n-\n-\tif (!pt-\u003edll_head_buflist.next)\n-\t\treturn;\n-\n-\t/*\n-\t * service all guys with pending rxflow that reached a state they can\n-\t * accept the pending data\n-\t */\n-\n-\tlws_pt_lock(pt, __func__);\n-\n-\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n-\t\t\t\t pt-\u003edll_head_buflist.next) {\n-\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_buflist);\n-\n-\t\tpfd.events \u003d LWS_POLLIN;\n-\t\tpfd.revents \u003d LWS_POLLIN;\n-\t\tpfd.fd \u003d -1;\n-\n-\t\tlwsl_debug(\u0022%s: rxflow processing: %p 0x%x\u005cn\u0022, __func__, wsi,\n-\t\t\t wsi-\u003ewsistate);\n-\n-\t\tif (!lws_is_flowcontrolled(wsi) \u0026\u0026\n-\t\t lwsi_state(wsi) !\u003d LRS_DEFERRING_ACTION \u0026\u0026\n-\t\t (wsi-\u003erole_ops-\u003ehandle_POLLIN)(pt, wsi, \u0026pfd) \u003d\u003d\n-\t\t\t\t\t\t LWS_HPI_RET_PLEASE_CLOSE_ME)\n-\t\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n-\t\t\t\t\t \u0022close_and_handled\u0022);\n-\n-\t} lws_end_foreach_dll_safe(d, d1);\n-\n-\tlws_pt_unlock(pt);\n-}\n-\n-/*\n- * guys that need POLLIN service again without waiting for network action\n- * can force POLLIN here if not flowcontrolled, so they will get service.\n- *\n- * Return nonzero if anybody got their POLLIN faked\n- */\n-int\n-lws_service_flag_pending(struct lws_context *context, int tsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n-\n-#if defined(LWS_WITH_TLS)\n-\tstruct lws *wsi, *wsi_next;\n-#endif\n-\tint forced \u003d 0;\n-\n-\tlws_pt_lock(pt, __func__);\n-\n-\t/*\n-\t * 1) If there is any wsi with a buflist and in a state to process\n-\t * it, we should not wait in poll\n-\t */\n-\n-\tlws_start_foreach_dll(struct lws_dll_lws *, d, pt-\u003edll_head_buflist.next) {\n-\t\tstruct lws *wsi \u003d lws_container_of(d, struct lws, dll_buflist);\n-\n-\t\tif (lwsi_state(wsi) !\u003d LRS_DEFERRING_ACTION) {\n-\t\t\tforced \u003d 1;\n-\t\t\tbreak;\n-\t\t}\n-\t} lws_end_foreach_dll(d);\n-\n-#if defined(LWS_ROLE_WS)\n-\tforced |\u003d role_ops_ws.service_flag_pending(context, tsi);\n-#endif\n-\n-#if defined(LWS_WITH_TLS)\n-\t/*\n-\t * 2) For all guys with buffered SSL read data already saved up, if they\n-\t * are not flowcontrolled, fake their POLLIN status so they'll get\n-\t * service to use up the buffered incoming data, even though their\n-\t * network socket may have nothing\n-\t */\n-\twsi \u003d pt-\u003etls.pending_read_list;\n-\twhile (wsi) {\n-\t\twsi_next \u003d wsi-\u003etls.pending_read_list_next;\n-\t\tpt-\u003efds[wsi-\u003eposition_in_fds_table].revents |\u003d\n-\t\t\tpt-\u003efds[wsi-\u003eposition_in_fds_table].events \u0026 LWS_POLLIN;\n-\t\tif (pt-\u003efds[wsi-\u003eposition_in_fds_table].revents \u0026 LWS_POLLIN) {\n-\t\t\tforced \u003d 1;\n-\t\t\t/*\n-\t\t\t * he's going to get serviced now, take him off the\n-\t\t\t * list of guys with buffered SSL. If he still has some\n-\t\t\t * at the end of the service, he'll get put back on the\n-\t\t\t * list then.\n-\t\t\t */\n-\t\t\t__lws_ssl_remove_wsi_from_buffered_list(wsi);\n-\t\t}\n-\n-\t\twsi \u003d wsi_next;\n-\t}\n-#endif\n-\n-\tlws_pt_unlock(pt);\n-\n-\treturn forced;\n-}\n-\n-static int\n-lws_service_periodic_checks(struct lws_context *context,\n-\t\t\t struct lws_pollfd *pollfd, int tsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n-\tlws_sockfd_type our_fd \u003d 0, tmp_fd;\n-\tstruct lws *wsi;\n-\tint timed_out \u003d 0;\n-\ttime_t now;\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\tstruct allocated_headers *ah;\n-\tint m;\n-#endif\n-\n-\tif (!context-\u003eprotocol_init_done)\n-\t\tif (lws_protocol_init(context))\n-\t\t\treturn -1;\n-\n-\ttime(\u0026now);\n-\n-\t/*\n-\t * handle case that system time was uninitialized when lws started\n-\t * at boot, and got initialized a little later\n-\t */\n-\tif (context-\u003etime_up \u003c 1464083026 \u0026\u0026 now \u003e 1464083026)\n-\t\tcontext-\u003etime_up \u003d now;\n-\n-\tif (context-\u003elast_timeout_check_s \u0026\u0026\n-\t now - context-\u003elast_timeout_check_s \u003e 100) {\n-\t\t/*\n-\t\t * There has been a discontiguity. Any stored time that is\n-\t\t * less than context-\u003etime_discontiguity should have context-\u003e\n-\t\t * time_fixup added to it.\n-\t\t *\n-\t\t * Some platforms with no RTC will experience this as a normal\n-\t\t * event when ntp sets their clock, but we can have started\n-\t\t * long before that with a 0-based unix time.\n-\t\t */\n-\n-\t\tcontext-\u003etime_discontiguity \u003d now;\n-\t\tcontext-\u003etime_fixup \u003d now - context-\u003elast_timeout_check_s;\n-\n-\t\tlwsl_notice(\u0022time discontiguity: at old time %llus, \u0022\n-\t\t\t \u0022new time %llus: +%llus\u005cn\u0022,\n-\t\t\t (unsigned long long)context-\u003elast_timeout_check_s,\n-\t\t\t (unsigned long long)context-\u003etime_discontiguity,\n-\t\t\t (unsigned long long)context-\u003etime_fixup);\n-\n-\t\tcontext-\u003elast_timeout_check_s \u003d now - 1;\n-\t}\n-\n-\tif (!lws_compare_time_t(context, context-\u003elast_timeout_check_s, now))\n-\t\treturn 0;\n-\n-\tcontext-\u003elast_timeout_check_s \u003d now;\n-\n-#if defined(LWS_WITH_STATS)\n-\tif (!tsi \u0026\u0026 now - context-\u003elast_dump \u003e 10) {\n-\t\tlws_stats_log_dump(context);\n-\t\tcontext-\u003elast_dump \u003d now;\n-\t}\n-#endif\n-\n-\tlws_plat_service_periodic(context);\n-\tlws_check_deferred_free(context, 0);\n-\n-#if defined(LWS_WITH_PEER_LIMITS)\n-\tlws_peer_cull_peer_wait_list(context);\n-#endif\n-\n-\t/* retire unused deprecated context */\n-#if !defined(LWS_PLAT_OPTEE) \u0026\u0026 !defined(LWS_WITH_ESP32)\n-#if !defined(_WIN32)\n-\tif (context-\u003edeprecated \u0026\u0026 !context-\u003ecount_wsi_allocated) {\n-\t\tlwsl_notice(\u0022%s: ending deprecated context\u005cn\u0022, __func__);\n-\t\tkill(getpid(), SIGINT);\n-\t\treturn 0;\n-\t}\n-#endif\n-#endif\n-\t/* global timeout check once per second */\n-\n-\tif (pollfd)\n-\t\tour_fd \u003d pollfd-\u003efd;\n-\n-\t/*\n-\t * Phase 1: check every wsi on the timeout check list\n-\t */\n-\n-\tlws_pt_lock(pt, __func__);\n-\n-\tlws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1,\n-\t\t\t\t context-\u003ept[tsi].dll_head_timeout.next) {\n-\t\twsi \u003d lws_container_of(d, struct lws, dll_timeout);\n-\t\ttmp_fd \u003d wsi-\u003edesc.sockfd;\n-\t\tif (__lws_service_timeout_check(wsi, now)) {\n-\t\t\t/* he did time out... */\n-\t\t\tif (tmp_fd \u003d\u003d our_fd)\n-\t\t\t\t/* it was the guy we came to service! */\n-\t\t\t\ttimed_out \u003d 1;\n-\t\t\t/* he's gone, no need to mark as handled */\n-\t\t}\n-\t} lws_end_foreach_dll_safe(d, d1);\n-\n-#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)\n-\t/*\n-\t * Phase 2: double-check active ah timeouts independent of wsi\n-\t *\t timeout status\n-\t */\n-\n-\tah \u003d pt-\u003ehttp.ah_list;\n-\twhile (ah) {\n-\t\tint len;\n-\t\tchar buf[256];\n-\t\tconst unsigned char *c;\n-\n-\t\tif (!ah-\u003ein_use || !ah-\u003ewsi || !ah-\u003eassigned ||\n-\t\t (ah-\u003ewsi-\u003evhost \u0026\u0026\n-\t\t lws_compare_time_t(context, now, ah-\u003eassigned) \u003c\n-\t\t ah-\u003ewsi-\u003evhost-\u003etimeout_secs_ah_idle + 360)) {\n-\t\t\tah \u003d ah-\u003enext;\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\t/*\n-\t\t * a single ah session somehow got held for\n-\t\t * an unreasonable amount of time.\n-\t\t *\n-\t\t * Dump info on the connection...\n-\t\t */\n-\t\twsi \u003d ah-\u003ewsi;\n-\t\tbuf[0] \u003d '\u005c0';\n-#if !defined(LWS_PLAT_OPTEE)\n-\t\tlws_get_peer_simple(wsi, buf, sizeof(buf));\n-#else\n-\t\tbuf[0] \u003d '\u005c0';\n-#endif\n-\t\tlwsl_notice(\u0022ah excessive hold: wsi %p\u005cn\u0022\n-\t\t\t \u0022 peer address: %s\u005cn\u0022\n-\t\t\t \u0022 ah pos %u\u005cn\u0022,\n-\t\t\t wsi, buf, ah-\u003epos);\n-\t\tbuf[0] \u003d '\u005c0';\n-\t\tm \u003d 0;\n-\t\tdo {\n-\t\t\tc \u003d lws_token_to_string(m);\n-\t\t\tif (!c)\n-\t\t\t\tbreak;\n-\t\t\tif (!(*c))\n-\t\t\t\tbreak;\n-\n-\t\t\tlen \u003d lws_hdr_total_length(wsi, m);\n-\t\t\tif (!len || len \u003e (int)sizeof(buf) - 1) {\n-\t\t\t\tm++;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\n-\t\t\tif (lws_hdr_copy(wsi, buf,\n-\t\t\t\t\t sizeof buf, m) \u003e 0) {\n-\t\t\t\tbuf[sizeof(buf) - 1] \u003d '\u005c0';\n-\n-\t\t\t\tlwsl_notice(\u0022 %s \u003d %s\u005cn\u0022,\n-\t\t\t\t\t (const char *)c, buf);\n-\t\t\t}\n-\t\t\tm++;\n-\t\t} while (1);\n-\n-\t\t/* explicitly detach the ah */\n-\t\tlws_header_table_detach(wsi, 0);\n-\n-\t\t/* ... and then drop the connection */\n-\n-\t\tm \u003d 0;\n-\t\tif (wsi-\u003edesc.sockfd \u003d\u003d our_fd) {\n-\t\t\tm \u003d timed_out;\n-\n-\t\t\t/* it was the guy we came to service! */\n-\t\t\ttimed_out \u003d 1;\n-\t\t}\n-\n-\t\tif (!m) /* if he didn't already timeout */\n-\t\t\t__lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n-\t\t\t\t\t \u0022excessive ah\u0022);\n-\n-\t\tah \u003d pt-\u003ehttp.ah_list;\n-\t}\n-#endif\n-\tlws_pt_unlock(pt);\n-\n-#if 0\n-\t{\n-\t\tchar s[300], *p \u003d s;\n-\n-\t\tfor (n \u003d 0; n \u003c context-\u003ecount_threads; n++)\n-\t\t\tp +\u003d sprintf(p, \u0022 %7lu (%5d), \u0022,\n-\t\t\t\t context-\u003ept[n].count_conns,\n-\t\t\t\t context-\u003ept[n].fds_count);\n-\n-\t\tlwsl_notice(\u0022load: %s\u005cn\u0022, s);\n-\t}\n-#endif\n-\t/*\n-\t * Phase 3: vhost / protocol timer callbacks\n-\t */\n-\n-\twsi \u003d NULL;\n-\tlws_start_foreach_ll(struct lws_vhost *, v, context-\u003evhost_list) {\n-\t\tstruct lws_timed_vh_protocol *nx;\n-\t\tif (v-\u003etimed_vh_protocol_list) {\n-\t\t\tlws_start_foreach_ll(struct lws_timed_vh_protocol *,\n-\t\t\t\t\tq, v-\u003etimed_vh_protocol_list) {\n-\t\t\t\tif (now \u003e\u003d q-\u003etime) {\n-\t\t\t\t\tif (!wsi)\n-\t\t\t\t\t\twsi \u003d lws_zalloc(sizeof(*wsi), \u0022cbwsi\u0022);\n-\t\t\t\t\twsi-\u003econtext \u003d context;\n-\t\t\t\t\twsi-\u003evhost \u003d v;\n-\t\t\t\t\twsi-\u003eprotocol \u003d q-\u003eprotocol;\n-\t\t\t\t\tlwsl_debug(\u0022timed cb: vh %s, protocol %s, reason %d\u005cn\u0022, v-\u003ename, q-\u003eprotocol-\u003ename, q-\u003ereason);\n-\t\t\t\t\tq-\u003eprotocol-\u003ecallback(wsi, q-\u003ereason, NULL, NULL, 0);\n-\t\t\t\t\tnx \u003d q-\u003enext;\n-\t\t\t\t\tlws_timed_callback_remove(v, q);\n-\t\t\t\t\tq \u003d nx;\n-\t\t\t\t\tcontinue; /* we pointed ourselves to the next from the now-deleted guy */\n-\t\t\t\t}\n-\t\t\t} lws_end_foreach_ll(q, next);\n-\t\t}\n-\t} lws_end_foreach_ll(v, vhost_next);\n-\tif (wsi)\n-\t\tlws_free(wsi);\n-\n-\t/*\n-\t * Phase 4: check for unconfigured vhosts due to required\n-\t *\t interface missing before\n-\t */\n-\n-\tlws_context_lock(context);\n-\tlws_start_foreach_llp(struct lws_vhost **, pv,\n-\t\t\t context-\u003eno_listener_vhost_list) {\n-\t\tstruct lws_vhost *v \u003d *pv;\n-\t\tlwsl_debug(\u0022deferred iface: checking if on vh %s\u005cn\u0022, (*pv)-\u003ename);\n-\t\tif (_lws_vhost_init_server(NULL, *pv) \u003d\u003d 0) {\n-\t\t\t/* became happy */\n-\t\t\tlwsl_notice(\u0022vh %s: became connected\u005cn\u0022, v-\u003ename);\n-\t\t\t*pv \u003d v-\u003eno_listener_vhost_list;\n-\t\t\tv-\u003eno_listener_vhost_list \u003d NULL;\n-\t\t\tbreak;\n-\t\t}\n-\t} lws_end_foreach_llp(pv, no_listener_vhost_list);\n-\tlws_context_unlock(context);\n-\n-\t/*\n-\t * Phase 5: role periodic checks\n-\t */\n-#if defined(LWS_ROLE_WS)\n-\trole_ops_ws.periodic_checks(context, tsi, now);\n-#endif\n-#if defined(LWS_ROLE_CGI)\n-\trole_ops_cgi.periodic_checks(context, tsi, now);\n-#endif\n-\n-\t/*\n-\t * Phase 6: check the remaining cert lifetime daily\n-\t */\n-\n-\tif (context-\u003etls_ops \u0026\u0026\n-\t context-\u003etls_ops-\u003eperiodic_housekeeping)\n-\t\tcontext-\u003etls_ops-\u003eperiodic_housekeeping(context, now);\n-\n-\treturn timed_out;\n-}\n-\n-LWS_VISIBLE int\n-lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,\n-\t\t int tsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n-\tstruct lws *wsi;\n-\n-\tif (!context || context-\u003ebeing_destroyed1)\n-\t\treturn -1;\n-\n-\t/* the socket we came to service timed out, nothing to do */\n-\tif (lws_service_periodic_checks(context, pollfd, tsi) || !pollfd)\n-\t\treturn 0;\n-\n-\t/* no, here to service a socket descriptor */\n-\twsi \u003d wsi_from_fd(context, pollfd-\u003efd);\n-\tif (!wsi)\n-\t\t/* not lws connection ... leave revents alone and return */\n-\t\treturn 0;\n-\n-\t/*\n-\t * so that caller can tell we handled, past here we need to\n-\t * zero down pollfd-\u003erevents after handling\n-\t */\n-\n-\t/* handle session socket closed */\n-\n-\tif ((!(pollfd-\u003erevents \u0026 pollfd-\u003eevents \u0026 LWS_POLLIN)) \u0026\u0026\n-\t (pollfd-\u003erevents \u0026 LWS_POLLHUP)) {\n-\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\tlwsl_debug(\u0022Session Socket %p (fd\u003d%d) dead\u005cn\u0022,\n-\t\t\t (void *)wsi, pollfd-\u003efd);\n-\n-\t\tgoto close_and_handled;\n-\t}\n-\n-#ifdef _WIN32\n-\tif (pollfd-\u003erevents \u0026 LWS_POLLOUT)\n-\t\twsi-\u003esock_send_blocking \u003d FALSE;\n-#endif\n-\n-\tif ((!(pollfd-\u003erevents \u0026 pollfd-\u003eevents \u0026 LWS_POLLIN)) \u0026\u0026\n-\t (pollfd-\u003erevents \u0026 LWS_POLLHUP)) {\n-\t\tlwsl_debug(\u0022pollhup\u005cn\u0022);\n-\t\twsi-\u003esocket_is_permanently_unusable \u003d 1;\n-\t\tgoto close_and_handled;\n-\t}\n-\n-#if defined(LWS_WITH_TLS)\n-\tif (lwsi_state(wsi) \u003d\u003d LRS_SHUTDOWN \u0026\u0026\n-\t lws_is_ssl(wsi) \u0026\u0026 wsi-\u003etls.ssl) {\n-\t\tswitch (__lws_tls_shutdown(wsi)) {\n-\t\tcase LWS_SSL_CAPABLE_DONE:\n-\t\tcase LWS_SSL_CAPABLE_ERROR:\n-\t\t\tgoto close_and_handled;\n-\n-\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_READ:\n-\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE_WRITE:\n-\t\tcase LWS_SSL_CAPABLE_MORE_SERVICE:\n-\t\t\tgoto handled;\n-\t\t}\n-\t}\n-#endif\n-\twsi-\u003ecould_have_pending \u003d 0; /* clear back-to-back write detection */\n-\n-\t/* okay, what we came here to do... */\n-\n-\t/* if we got here, we should have wire protocol ops set on the wsi */\n-\tassert(wsi-\u003erole_ops);\n-\n-\t// lwsl_notice(\u0022%s: %s: wsistate 0x%x\u005cn\u0022, __func__, wsi-\u003erole_ops-\u003ename,\n-\t//\t wsi-\u003ewsistate);\n-\n-\tswitch ((wsi-\u003erole_ops-\u003ehandle_POLLIN)(pt, wsi, pollfd)) {\n-\tcase LWS_HPI_RET_WSI_ALREADY_DIED:\n-\t\treturn 1;\n-\tcase LWS_HPI_RET_HANDLED:\n-\t\tbreak;\n-\tcase LWS_HPI_RET_PLEASE_CLOSE_ME:\n-close_and_handled:\n-\t\tlwsl_debug(\u0022%p: Close and handled\u005cn\u0022, wsi);\n-\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n-\t\t\t\t \u0022close_and_handled\u0022);\n-#if defined(_DEBUG) \u0026\u0026 defined(LWS_WITH_LIBUV)\n-\t\t/*\n-\t\t * confirm close has no problem being called again while\n-\t\t * it waits for libuv service to complete the first async\n-\t\t * close\n-\t\t */\n-\t\tif (context-\u003eevent_loop_ops \u003d\u003d \u0026event_loop_ops_uv)\n-\t\t\tlws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,\n-\t\t\t\t\t \u0022close_and_handled uv repeat test\u0022);\n-#endif\n-\t\t/*\n-\t\t * pollfd may point to something else after the close\n-\t\t * due to pollfd swapping scheme on delete on some platforms\n-\t\t * we can't clear revents now because it'd be the wrong guy's\n-\t\t * revents\n-\t\t */\n-\t\treturn 1;\n-\tdefault:\n-\t\tassert(0);\n-\t}\n-#if defined(LWS_WITH_TLS)\n-handled:\n-#endif\n-\tpollfd-\u003erevents \u003d 0;\n-\n-\tlws_pt_lock(pt, __func__);\n-\t__lws_hrtimer_service(pt);\n-\tlws_pt_unlock(pt);\n-\n-\treturn 0;\n-}\n-\n-LWS_VISIBLE int\n-lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd)\n-{\n-\treturn lws_service_fd_tsi(context, pollfd, 0);\n-}\n-\n-LWS_VISIBLE int\n-lws_service(struct lws_context *context, int timeout_ms)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[0];\n-\tint n;\n-\n-\tif (!context)\n-\t\treturn 1;\n-\n-\tpt-\u003einside_service \u003d 1;\n-\n-\tif (context-\u003eevent_loop_ops-\u003erun_pt) {\n-\t\t/* we are configured for an event loop */\n-\t\tcontext-\u003eevent_loop_ops-\u003erun_pt(context, 0);\n-\n-\t\tpt-\u003einside_service \u003d 0;\n-\n-\t\treturn 1;\n-\t}\n-\tn \u003d lws_plat_service(context, timeout_ms);\n-\n-\tpt-\u003einside_service \u003d 0;\n-\n-\treturn n;\n-}\n-\n-LWS_VISIBLE int\n-lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi)\n-{\n-\tstruct lws_context_per_thread *pt \u003d \u0026context-\u003ept[tsi];\n-\tint n;\n-\n-\tpt-\u003einside_service \u003d 1;\n-\n-\tif (context-\u003eevent_loop_ops-\u003erun_pt) {\n-\t\t/* we are configured for an event loop */\n-\t\tcontext-\u003eevent_loop_ops-\u003erun_pt(context, tsi);\n-\n-\t\tpt-\u003einside_service \u003d 0;\n-\n-\t\treturn 1;\n-\t}\n-\n-\tn \u003d _lws_plat_service_tsi(context, timeout_ms, tsi);\n-\n-\tpt-\u003einside_service \u003d 0;\n-\n-\treturn n;\n-}\ndiff --git a/lib/tls/mbedtls/lws-genrsa.c b/lib/tls/mbedtls/lws-genrsa.c\nindex ba5f6d5..70a9fcf 100644\n--- a/lib/tls/mbedtls/lws-genrsa.c\n+++ b/lib/tls/mbedtls/lws-genrsa.c\n@@ -21,7 +21,7 @@\n * lws_genhash provides a hash / hmac abstraction api in lws that works the\n * same whether you are using openssl or mbedtls hash functions underneath.\n */\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n LWS_VISIBLE void\n lws_jwk_destroy_genrsa_elements(struct lws_genrsa_elements *el)\ndiff --git a/lib/tls/mbedtls/mbedtls-client.c b/lib/tls/mbedtls/mbedtls-client.c\nindex fd9957b..a7864ab 100644\n--- a/lib/tls/mbedtls/mbedtls-client.c\n+++ b/lib/tls/mbedtls/mbedtls-client.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n static int\n OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)\ndiff --git a/lib/tls/mbedtls/mbedtls-server.c b/lib/tls/mbedtls/mbedtls-server.c\nindex 2a93468..12829a3 100644\n--- a/lib/tls/mbedtls/mbedtls-server.c\n+++ b/lib/tls/mbedtls/mbedtls-server.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n #include \u003cmbedtls/x509_csr.h\u003e\n \n int\ndiff --git a/lib/tls/mbedtls/ssl.c b/lib/tls/mbedtls/ssl.c\nindex b024dfa..6ae9d25 100644\n--- a/lib/tls/mbedtls/ssl.c\n+++ b/lib/tls/mbedtls/ssl.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n #include \u003cmbedtls/oid.h\u003e\n \n void\ndiff --git a/lib/tls/openssl/lws-genrsa.c b/lib/tls/openssl/lws-genrsa.c\nindex 3eabe4c..d04aea8 100644\n--- a/lib/tls/openssl/lws-genrsa.c\n+++ b/lib/tls/openssl/lws-genrsa.c\n@@ -21,7 +21,7 @@\n * lws_genhash provides a hash / hmac abstraction api in lws that works the\n * same whether you are using openssl or mbedtls hash functions underneath.\n */\n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n LWS_VISIBLE void\n lws_jwk_destroy_genrsa_elements(struct lws_genrsa_elements *el)\ndiff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c\nindex e1602ed..bff3d40 100644\n--- a/lib/tls/openssl/openssl-client.c\n+++ b/lib/tls/openssl/openssl-client.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n extern int openssl_websocket_private_data_index,\n openssl_SSL_CTX_private_data_index;\ndiff --git a/lib/tls/openssl/openssl-server.c b/lib/tls/openssl/openssl-server.c\nindex 8a6bf14..a87c920 100644\n--- a/lib/tls/openssl/openssl-server.c\n+++ b/lib/tls/openssl/openssl-server.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n extern int openssl_websocket_private_data_index,\n \t openssl_SSL_CTX_private_data_index;\ndiff --git a/lib/tls/openssl/ssl.c b/lib/tls/openssl/ssl.c\nindex ec43770..0ec5542 100644\n--- a/lib/tls/openssl/ssl.c\n+++ b/lib/tls/openssl/ssl.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n #include \u003cerrno.h\u003e\n \n int openssl_websocket_private_data_index,\ndiff --git a/lib/tls/private.h b/lib/tls/private.h\nindex 5c6beeb..606e257 100644\n--- a/lib/tls/private.h\n+++ b/lib/tls/private.h\n@@ -18,7 +18,7 @@\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n * MA 02110-1301 USA\n *\n- * This is included from private-libwebsockets.h if LWS_WITH_TLS\n+ * This is included from core/private.h if LWS_WITH_TLS\n */\n \n #if defined(LWS_WITH_TLS)\ndiff --git a/lib/tls/tls-client.c b/lib/tls/tls-client.c\nindex a122155..70eb6f6 100644\n--- a/lib/tls/tls-client.c\n+++ b/lib/tls/tls-client.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n int\n lws_ssl_client_connect1(struct lws *wsi)\ndiff --git a/lib/tls/tls-server.c b/lib/tls/tls-server.c\nindex 19549a5..440e790 100644\n--- a/lib/tls/tls-server.c\n+++ b/lib/tls/tls-server.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n #if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) \u0026\u0026 \u005c\n \t\t\t\t OPENSSL_VERSION_NUMBER \u003e\u003d 0x10002000L)\ndiff --git a/lib/tls/tls.c b/lib/tls/tls.c\nindex 916b99f..c865c89 100644\n--- a/lib/tls/tls.c\n+++ b/lib/tls/tls.c\n@@ -19,7 +19,7 @@\n * MA 02110-1301 USA\n */\n \n-#include \u0022private-libwebsockets.h\u0022\n+#include \u0022core/private.h\u0022\n \n /*\n * fakes POLLIN on all tls guys with buffered rx\ndiff --git a/minimal-examples/http-server/minimal-http-server-sse-ring/minimal-http-server-sse-ring.c b/minimal-examples/http-server/minimal-http-server-sse-ring/minimal-http-server-sse-ring.c\nindex 8027982..616300c 100644\n--- a/minimal-examples/http-server/minimal-http-server-sse-ring/minimal-http-server-sse-ring.c\n+++ b/minimal-examples/http-server/minimal-http-server-sse-ring/minimal-http-server-sse-ring.c\n@@ -120,7 +120,8 @@ wait_unlock:\n \t\tpthread_mutex_unlock(\u0026vhd-\u003elock_ring); /* } ring lock ------- */\n \n wait:\n-\t\tusleep(100000 + (rand() \u0026 0xfffff));\n+\t\t/* rand() would make more sense but coverity shrieks */\n+\t\tusleep(100000 + (time(NULL) \u0026 0xffff));\n \n \t} while (!vhd-\u003efinished);\n \ndiff --git a/test-apps/test-server-libev.c b/test-apps/test-server-libev.c\ndeleted file mode 100644\nindex 42eca94..0000000\n--- a/test-apps/test-server-libev.c\n+++ /dev/null\n@@ -1,349 +0,0 @@\n-/*\n- * libwebsockets-test-server - libwebsockets test implementation\n- *\n- * Copyright (C) 2011-2018 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This file is made available under the Creative Commons CC0 1.0\n- * Universal Public Domain Dedication.\n- *\n- * The person who associated a work with this deed has dedicated\n- * the work to the public domain by waiving all of his or her rights\n- * to the work worldwide under copyright law, including all related\n- * and neighboring rights, to the extent allowed by law. You can copy,\n- * modify, distribute and perform the work, even for commercial purposes,\n- * all without asking permission.\n- *\n- * The test apps are intended to be adapted for use in your code, which\n- * may be proprietary. So unlike the library itself, they are licensed\n- * Public Domain.\n- */\n-#include \u003clibwebsockets.h\u003e\n-#include \u003cstdio.h\u003e\n-#include \u003cstdlib.h\u003e\n-#include \u003cgetopt.h\u003e\n-\n-int close_testing;\n-int max_poll_elements;\n-int debug_level \u003d 7;\n-volatile int force_exit \u003d 0;\n-struct lws_context *context;\n-struct lws_plat_file_ops fops_plat;\n-\n-/* http server gets files from this path */\n-#define LOCAL_RESOURCE_PATH INSTALL_DATADIR\u0022/libwebsockets-test-server\u0022\n-char *resource_path \u003d LOCAL_RESOURCE_PATH;\n-\n-#if defined(LWS_WITH_TLS) \u0026\u0026 defined(LWS_HAVE_SSL_CTX_set1_param)\n-char crl_path[1024] \u003d \u0022\u0022;\n-#endif\n-\n-#define LWS_PLUGIN_STATIC\n-#include \u0022../plugins/protocol_dumb_increment.c\u0022\n-#include \u0022../plugins/protocol_lws_mirror.c\u0022\n-#include \u0022../plugins/protocol_lws_status.c\u0022\n-#include \u0022../plugins/protocol_post_demo.c\u0022\n-\n-/* list of supported protocols and callbacks */\n-\n-static struct lws_protocols protocols[] \u003d {\n-\t/* first protocol must always be HTTP handler */\n-\t{ \u0022http-only\u0022, lws_callback_http_dummy, 0, 0, },\n-\tLWS_PLUGIN_PROTOCOL_DUMB_INCREMENT,\n-\tLWS_PLUGIN_PROTOCOL_MIRROR,\n-\tLWS_PLUGIN_PROTOCOL_LWS_STATUS,\n-\tLWS_PLUGIN_PROTOCOL_POST_DEMO,\n-\t{ NULL, NULL, 0, 0 } /* terminator */\n-};\n-\n-static const struct lws_extension exts[] \u003d {\n-\t{\n-\t\t\u0022permessage-deflate\u0022,\n-\t\tlws_extension_callback_pm_deflate,\n-\t\t\u0022permessage-deflate; client_no_context_takeover; client_max_window_bits\u0022\n-\t},\n-\t{ NULL, NULL, NULL /* terminator */ }\n-};\n-\n-/*\n- * mount handlers for sections of the URL space\n- */\n-\n-static const struct lws_http_mount mount_ziptest \u003d {\n-\tNULL,\t\t\t/* linked-list pointer to next*/\n-\t\u0022/ziptest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n-\tLOCAL_RESOURCE_PATH\u0022/candide.zip\u0022,\t/* handler */\n-\tNULL,\t/* default filename if none given */\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\tLWSMPRO_FILE,\t/* origin points to a callback */\n-\t8,\t\t\t/* strlen(\u0022/ziptest\u0022), ie length of the mountpoint */\n-\tNULL,\n-\n-\t{ NULL, NULL } // sentinel\n-};\n-\n-static const struct lws_http_mount mount_post \u003d {\n-\t(struct lws_http_mount *)\u0026mount_ziptest, /* linked-list pointer to next*/\n-\t\u0022/formtest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n-\t\u0022protocol-post-demo\u0022,\t/* handler */\n-\tNULL,\t/* default filename if none given */\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\tLWSMPRO_CALLBACK,\t/* origin points to a callback */\n-\t9,\t\t\t/* strlen(\u0022/formtest\u0022), ie length of the mountpoint */\n-\tNULL,\n-\n-\t{ NULL, NULL } // sentinel\n-};\n-\n-/*\n- * mount a filesystem directory into the URL space at /\n- * point it to our /usr/share directory with our assets in\n- * stuff from here is autoserved by the library\n- */\n-\n-static const struct lws_http_mount mount \u003d {\n-\t(struct lws_http_mount *)\u0026mount_post,\t/* linked-list pointer to next*/\n-\t\u0022/\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n-\tLOCAL_RESOURCE_PATH, /* where to go on the filesystem for that */\n-\t\u0022test.html\u0022,\t/* default filename if none given */\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\tLWSMPRO_FILE,\t/* mount type is a directory in a filesystem */\n-\t1,\t\t/* strlen(\u0022/\u0022), ie length of the mountpoint */\n-\tNULL,\n-\n-\t{ NULL, NULL } // sentinel\n-};\n-\n-/* this shows how to override the lws file operations. You don't need\n- * to do any of this unless you have a reason (eg, want to serve\n- * compressed files without decompressing the whole archive)\n- */\n-static lws_fop_fd_t\n-test_server_fops_open(const struct lws_plat_file_ops *fops,\n-\t\t const char *vfs_path, const char *vpath,\n-\t\t lws_fop_flags_t *flags)\n-{\n-\tlws_fop_fd_t n;\n-\n-\t/* call through to original platform implementation */\n-\tn \u003d fops_plat.open(fops, vfs_path, vpath, flags);\n-\n-\tlwsl_debug(\u0022%s: opening %s, ret %p\u005cn\u0022, __func__, vfs_path, n);\n-\n-\treturn n;\n-}\n-\n-void signal_cb(struct ev_loop *loop, struct ev_signal* watcher, int revents)\n-{\n-\tlwsl_notice(\u0022Signal caught, exiting...\u005cn\u0022);\n-\tforce_exit \u003d 1;\n-\tswitch (watcher-\u003esignum) {\n-\tcase SIGTERM:\n-\tcase SIGINT:\n-\t\tev_break(loop, EVBREAK_ALL);\n-\t\tbreak;\n-\tdefault:\n-\t\tsignal(SIGABRT, SIG_DFL);\n-\t\tabort();\n-\t\tbreak;\n-\t}\n-}\n-\n-static struct option options[] \u003d {\n-\t{ \u0022help\u0022,\tno_argument,\t\tNULL, 'h' },\n-\t{ \u0022debug\u0022,\trequired_argument,\tNULL, 'd' },\n-\t{ \u0022port\u0022,\trequired_argument,\tNULL, 'p' },\n-\t{ \u0022ssl\u0022,\tno_argument,\t\tNULL, 's' },\n-\t{ \u0022allow-non-ssl\u0022,\tno_argument,\tNULL, 'a' },\n-\t{ \u0022interface\u0022, required_argument,\tNULL, 'i' },\n-\t{ \u0022closetest\u0022, no_argument,\t\tNULL, 'c' },\n-#ifndef LWS_NO_DAEMONIZE\n-\t{ \u0022daemonize\u0022, \tno_argument,\t\tNULL, 'D' },\n-#endif\n-\t{ \u0022resource_path\u0022, required_argument,\tNULL, 'r' },\n-\t{ NULL, 0, 0, 0 }\n-};\n-\n-int main(int argc, char **argv)\n-{\n-\tint sigs[] \u003d { SIGINT, SIGKILL, SIGTERM, SIGSEGV, SIGFPE };\n-\tstruct ev_signal signals[ARRAY_SIZE(sigs)];\n-\tstruct ev_loop *loop \u003d ev_default_loop(0);\n-\tstruct lws_context_creation_info info;\n-\tchar interface_name[128] \u003d \u0022\u0022;\n-\tconst char *iface \u003d NULL;\n-\tvoid *foreign_loops[1];\n-\tchar cert_path[1024];\n-\tchar key_path[1024];\n-\tint use_ssl \u003d 0;\n-\tint opts \u003d 0;\n-\tint n \u003d 0;\n-#ifndef LWS_NO_DAEMONIZE\n-\tint daemonize \u003d 0;\n-#endif\n-\n-\t/*\n-\t * take care to zero down the info struct, he contains random garbaage\n-\t * from the stack otherwise\n-\t */\n-\tmemset(\u0026info, 0, sizeof info);\n-\tinfo.port \u003d 7681;\n-\n-\twhile (n \u003e\u003d 0) {\n-\t\tn \u003d getopt_long(argc, argv, \u0022ci:hsap:d:Dr:\u0022, options, NULL);\n-\t\tif (n \u003c 0)\n-\t\t\tcontinue;\n-\t\tswitch (n) {\n-#ifndef LWS_NO_DAEMONIZE\n-\t\tcase 'D':\n-\t\t\tdaemonize \u003d 1;\n-\t\t\t#ifndef _WIN32\n-\t\t\tsyslog_options \u0026\u003d ~LOG_PERROR;\n-\t\t\t#endif\n-\t\t\tbreak;\n-#endif\n-\t\tcase 'd':\n-\t\t\tdebug_level \u003d atoi(optarg);\n-\t\t\tbreak;\n-\t\tcase 's':\n-\t\t\tuse_ssl \u003d 1;\n-\t\t\tbreak;\n-\t\tcase 'a':\n-\t\t\topts |\u003d LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;\n-\t\t\tbreak;\n-\t\tcase 'p':\n-\t\t\tinfo.port \u003d atoi(optarg);\n-\t\t\tbreak;\n-\t\tcase 'i':\n-\t\t\tlws_strncpy(interface_name, optarg, sizeof interface_name);\n-\t\t\tiface \u003d interface_name;\n-\t\t\tbreak;\n-\t\tcase 'c':\n-\t\t\tclose_testing \u003d 1;\n-\t\t\tfprintf(stderr, \u0022 Close testing mode -- closes on \u0022\n-\t\t\t\t\t \u0022client after 50 dumb increments\u0022\n-\t\t\t\t\t \u0022and suppresses lws_mirror spam\u005cn\u0022);\n-\t\t\tbreak;\n-\t\tcase 'r':\n-\t\t\tresource_path \u003d optarg;\n-\t\t\tprintf(\u0022Setting resource path to \u005c\u0022%s\u005c\u0022\u005cn\u0022, resource_path);\n-\t\t\tbreak;\n-\t\tcase 'h':\n-\t\t\tfprintf(stderr, \u0022Usage: test-server \u0022\n-\t\t\t\t\t\u0022[--port\u003d\u003cp\u003e] [--ssl] \u0022\n-\t\t\t\t\t\u0022[-d \u003clog bitfield\u003e] \u0022\n-\t\t\t\t\t\u0022[--resource_path \u003cpath\u003e]\u005cn\u0022);\n-\t\t\texit(1);\n-\t\t}\n-\t}\n-\n-#if !defined(LWS_NO_DAEMONIZE) \u0026\u0026 !defined(WIN32)\n-\t/*\n-\t * normally lock path would be /var/lock/lwsts or similar, to\n-\t * simplify getting started without having to take care about\n-\t * permissions or running as root, set to /tmp/.lwsts-lock\n-\t */\n-\tif (daemonize \u0026\u0026 lws_daemonize(\u0022/tmp/.lwsts-lock\u0022)) {\n-\t\tfprintf(stderr, \u0022Failed to daemonize\u005cn\u0022);\n-\t\treturn 1;\n-\t}\n-#endif\n-\n-\tfor (n \u003d 0; n \u003c (int)ARRAY_SIZE(sigs); n++) {\n-\t\tev_init(\u0026signals[n], signal_cb);\n-\t\tev_signal_set(\u0026signals[n], sigs[n]);\n-\t\tev_signal_start(loop, \u0026signals[n]);\n-\t}\n-\n-\t/* tell the library what debug level to emit and to send it to stderr */\n-\tlws_set_log_level(debug_level, NULL);\n-\n-\tlwsl_notice(\u0022libwebsockets test server libev - license LGPL2.1+SLE\u005cn\u0022);\n-\tlwsl_notice(\u0022(C) Copyright 2010-2018 Andy Green \u003candy@warmcat.com\u003e\u005cn\u0022);\n-\n-\tprintf(\u0022Using resource path \u005c\u0022%s\u005c\u0022\u005cn\u0022, resource_path);\n-\n-\tinfo.iface \u003d iface;\n-\tinfo.protocols \u003d protocols;\n-\tinfo.extensions \u003d exts;\n-\tinfo.mounts \u003d \u0026mount;\n-\n-\tinfo.ssl_cert_filepath \u003d NULL;\n-\tinfo.ssl_private_key_filepath \u003d NULL;\n-\n-\tif (use_ssl) {\n-\t\tif (strlen(resource_path) \u003e sizeof(cert_path) - 32) {\n-\t\t\tlwsl_err(\u0022resource path too long\u005cn\u0022);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tsprintf(cert_path, \u0022%s/libwebsockets-test-server.pem\u0022,\n-\t\t\t\t\t\t\t\tresource_path);\n-\t\tif (strlen(resource_path) \u003e sizeof(key_path) - 32) {\n-\t\t\tlwsl_err(\u0022resource path too long\u005cn\u0022);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tsprintf(key_path, \u0022%s/libwebsockets-test-server.key.pem\u0022,\n-\t\t\t\t\t\t\t\tresource_path);\n-\n-\t\tinfo.ssl_cert_filepath \u003d cert_path;\n-\t\tinfo.ssl_private_key_filepath \u003d key_path;\n-\n-\t\topts |\u003d LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;\n-\t}\n-\tinfo.gid \u003d -1;\n-\tinfo.uid \u003d -1;\n-\tinfo.options \u003d opts | LWS_SERVER_OPTION_LIBEV;\n-\n-\tforeign_loops[0] \u003d \u0026loop;\n-\tinfo.foreign_loops \u003d foreign_loops;\n-\n-\tcontext \u003d lws_create_context(\u0026info);\n-\tif (context \u003d\u003d NULL) {\n-\t\tlwsl_err(\u0022libwebsocket init failed\u005cn\u0022);\n-\t\treturn -1;\n-\t}\n-\n-\t/*\n-\t * this shows how to override the lws file operations. You don't need\n-\t * to do any of this unless you have a reason (eg, want to serve\n-\t * compressed files without decompressing the whole archive)\n-\t */\n-\t/* stash original platform fops */\n-\tfops_plat \u003d *(lws_get_fops(context));\n-\t/* override the active fops */\n-\tlws_get_fops(context)-\u003eopen \u003d test_server_fops_open;\n-\n-\tlws_service(context, 0);\n-\n-\tlws_context_destroy(context);\n-\n-\tlwsl_notice(\u0022libwebsockets-test-server exited cleanly\u005cn\u0022);\n-\n-\treturn 0;\n-}\ndiff --git a/test-apps/test-server-libevent.c b/test-apps/test-server-libevent.c\ndeleted file mode 100644\nindex bc47f99..0000000\n--- a/test-apps/test-server-libevent.c\n+++ /dev/null\n@@ -1,351 +0,0 @@\n-/*\n- * libwebsockets-test-server - libwebsockets test implementation\n- *\n- * Copyright (C) 2011-2017 Andy Green \u003candy@warmcat.com\u003e\n- *\n- * This file is made available under the Creative Commons CC0 1.0\n- * Universal Public Domain Dedication.\n- *\n- * The person who associated a work with this deed has dedicated\n- * the work to the public domain by waiving all of his or her rights\n- * to the work worldwide under copyright law, including all related\n- * and neighboring rights, to the extent allowed by law. You can copy,\n- * modify, distribute and perform the work, even for commercial purposes,\n- * all without asking permission.\n- *\n- * The test apps are intended to be adapted for use in your code, which\n- * may be proprietary. So unlike the library itself, they are licensed\n- * Public Domain.\n- */\n-#include \u003clibwebsockets.h\u003e\n-#include \u003cstdio.h\u003e\n-#include \u003cstdlib.h\u003e\n-#include \u003cgetopt.h\u003e\n-\n-int close_testing;\n-int max_poll_elements;\n-int debug_level \u003d 7;\n-volatile int force_exit \u003d 0;\n-struct lws_context *context;\n-struct lws_plat_file_ops fops_plat;\n-\n-/* http server gets files from this path */\n-#define LOCAL_RESOURCE_PATH INSTALL_DATADIR\u0022/libwebsockets-test-server\u0022\n-char *resource_path \u003d LOCAL_RESOURCE_PATH;\n-\n-#if defined(LWS_WITH_TLS) \u0026\u0026 defined(LWS_HAVE_SSL_CTX_set1_param)\n-char crl_path[1024] \u003d \u0022\u0022;\n-#endif\n-\n-#define LWS_PLUGIN_STATIC\n-#include \u0022../plugins/protocol_dumb_increment.c\u0022\n-#include \u0022../plugins/protocol_lws_mirror.c\u0022\n-#include \u0022../plugins/protocol_lws_status.c\u0022\n-#include \u0022../plugins/protocol_post_demo.c\u0022\n-\n-/* list of supported protocols and callbacks */\n-\n-static struct lws_protocols protocols[] \u003d {\n-\t/* first protocol must always be HTTP handler */\n-\t{ \u0022http-only\u0022, lws_callback_http_dummy, 0, 0, },\n-\tLWS_PLUGIN_PROTOCOL_DUMB_INCREMENT,\n-\tLWS_PLUGIN_PROTOCOL_MIRROR,\n-\tLWS_PLUGIN_PROTOCOL_LWS_STATUS,\n-\tLWS_PLUGIN_PROTOCOL_POST_DEMO,\n-\t{ NULL, NULL, 0, 0 } /* terminator */\n-};\n-\n-static const struct lws_extension exts[] \u003d {\n-\t{\n-\t\t\u0022permessage-deflate\u0022,\n-\t\tlws_extension_callback_pm_deflate,\n-\t\t\u0022permessage-deflate; client_no_context_takeover; client_max_window_bits\u0022\n-\t},\n-\t{ NULL, NULL, NULL /* terminator */ }\n-};\n-\n-/* this shows how to override the lws file operations. You don't need\n- * to do any of this unless you have a reason (eg, want to serve\n- * compressed files without decompressing the whole archive)\n- */\n-static lws_fop_fd_t\n-test_server_fops_open(const struct lws_plat_file_ops *fops,\n-\t\tconst char *vfs_path, const char *vpath,\n-\t\tlws_fop_flags_t *flags)\n-{\n-\tlws_fop_fd_t n;\n-\n-\t/* call through to original platform implementation */\n-\tn \u003d fops_plat.open(fops, vfs_path, vpath, flags);\n-\n-\tlwsl_notice(\u0022%s: opening %s, ret %p\u005cn\u0022, __func__, vfs_path, n);\n-\n-\treturn n;\n-}\n-\n-void signal_cb(evutil_socket_t sock_fd, short events, void *ctx)\n-{\n-\tstruct event_base *event_base_loop \u003d ctx;\n-\n-\tlwsl_notice(\u0022Signal caught, exiting...\u005cn\u0022);\n-\tforce_exit \u003d 1;\n-\tif (events \u0026 EV_SIGNAL)\n-\t\tevent_base_loopbreak(event_base_loop);\n-}\n-\n-/*\n- * mount handlers for sections of the URL space\n- */\n-\n-static const struct lws_http_mount mount_ziptest \u003d {\n-\tNULL,\t\t\t/* linked-list pointer to next*/\n-\t\u0022/ziptest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n-\tLOCAL_RESOURCE_PATH\u0022/candide.zip\u0022,\t/* handler */\n-\tNULL,\t/* default filename if none given */\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\tLWSMPRO_FILE,\t/* origin points to a callback */\n-\t8,\t\t\t/* strlen(\u0022/ziptest\u0022), ie length of the mountpoint */\n-\tNULL,\n-\n-\t{ NULL, NULL } // sentinel\n-};\n-\n-static const struct lws_http_mount mount_post \u003d {\n-\t(struct lws_http_mount *)\u0026mount_ziptest, /* linked-list pointer to next*/\n-\t\u0022/formtest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n-\t\u0022protocol-post-demo\u0022,\t/* handler */\n-\tNULL,\t/* default filename if none given */\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\tLWSMPRO_CALLBACK,\t/* origin points to a callback */\n-\t9,\t\t\t/* strlen(\u0022/formtest\u0022), ie length of the mountpoint */\n-\tNULL,\n-\n-\t{ NULL, NULL } // sentinel\n-};\n-\n-/*\n- * mount a filesystem directory into the URL space at /\n- * point it to our /usr/share directory with our assets in\n- * stuff from here is autoserved by the library\n- */\n-\n-static const struct lws_http_mount mount \u003d {\n-\t(struct lws_http_mount *)\u0026mount_post,\t/* linked-list pointer to next*/\n-\t\u0022/\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n-\tLOCAL_RESOURCE_PATH, /* where to go on the filesystem for that */\n-\t\u0022test.html\u0022,\t/* default filename if none given */\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\tNULL,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\t0,\n-\tLWSMPRO_FILE,\t/* mount type is a directory in a filesystem */\n-\t1,\t\t/* strlen(\u0022/\u0022), ie length of the mountpoint */\n-\tNULL,\n-\n-\t{ NULL, NULL } // sentinel\n-};\n-\n-static struct option options[] \u003d {\n-\t\t{ \u0022help\u0022, no_argument, NULL, 'h' },\n-\t\t{ \u0022debug\u0022, required_argument, NULL, 'd' },\n-\t\t{ \u0022port\u0022, required_argument, NULL, 'p' },\n-\t\t{ \u0022ssl\u0022, no_argument, NULL, 's' },\n-\t\t{ \u0022allow-non-ssl\u0022, no_argument, NULL, 'a' },\n-\t\t{ \u0022interface\u0022, required_argument, NULL, 'i' },\n-\t\t{ \u0022closetest\u0022, no_argument, NULL, 'c' },\n-\t\t{ \u0022libevent\u0022, no_argument, NULL, 'e' },\n-#ifndef LWS_NO_DAEMONIZE\n-\t\t{ \u0022daemonize\u0022, no_argument, NULL, 'D' },\n-#endif\n-\t\t{ \u0022resource_path\u0022, required_argument, NULL, 'r' },\n-\t\t{ NULL, 0, 0, 0 }\n-};\n-\n-int main(int argc, char **argv)\n-{\n-\tint sigs[] \u003d { SIGINT, SIGKILL, SIGTERM, SIGSEGV, SIGFPE };\n-\tstruct event *signals[ARRAY_SIZE(sigs)];\n-\tstruct event_base *event_base_loop \u003d event_base_new();\n-\tstruct lws_context_creation_info info;\n-\tchar interface_name[128] \u003d \u0022\u0022;\n-\tvoid *foreign_loops[1];\n-\tconst char *iface \u003d NULL;\n-\tchar cert_path[1024];\n-\tchar key_path[1024];\n-\tint use_ssl \u003d 0;\n-\tint opts \u003d 0;\n-\tint n \u003d 0;\n-#ifndef LWS_NO_DAEMONIZE\n-\tint daemonize \u003d 0;\n-#endif\n-\n-\t/*\n-\t * take care to zero down the info struct, he contains random garbaage\n-\t * from the stack otherwise\n-\t */\n-\tmemset(\u0026info, 0, sizeof info);\n-\tinfo.port \u003d 7681;\n-\n-\twhile (n \u003e\u003d 0) {\n-\t\tn \u003d getopt_long(argc, argv, \u0022eci:hsap:d:Dr:\u0022, options, NULL);\n-\t\tif (n \u003c 0)\n-\t\t\tcontinue;\n-\t\tswitch (n) {\n-\t\tcase 'e':\n-\t\t\topts |\u003d LWS_SERVER_OPTION_LIBEVENT;\n-\t\t\tbreak;\n-#ifndef LWS_NO_DAEMONIZE\n-\t\tcase 'D':\n-\t\t\tdaemonize \u003d 1;\n-#ifndef _WIN32\n-\t\t\tsyslog_options \u0026\u003d ~LOG_PERROR;\n-#endif\n-\t\t\tbreak;\n-#endif\n-\t\tcase 'd':\n-\t\t\tdebug_level \u003d atoi(optarg);\n-\t\t\tbreak;\n-\t\tcase 's':\n-\t\t\tuse_ssl \u003d 1;\n-\t\t\tbreak;\n-\t\tcase 'a':\n-\t\t\topts |\u003d LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;\n-\t\t\tbreak;\n-\t\tcase 'p':\n-\t\t\tinfo.port \u003d atoi(optarg);\n-\t\t\tbreak;\n-\t\tcase 'i':\n-\t\t\tlws_strncpy(interface_name, optarg, sizeof interface_name);\n-\t\t\tiface \u003d interface_name;\n-\t\t\tbreak;\n-\t\tcase 'c':\n-\t\t\tclose_testing \u003d 1;\n-\t\t\tfprintf(stderr, \u0022 Close testing mode -- closes on \u0022\n-\t\t\t\t\t\u0022client after 50 dumb increments\u0022\n-\t\t\t\t\t\u0022and suppresses lws_mirror spam\u005cn\u0022);\n-\t\t\tbreak;\n-\t\tcase 'r':\n-\t\t\tresource_path \u003d optarg;\n-\t\t\tprintf(\u0022Setting resource path to \u005c\u0022%s\u005c\u0022\u005cn\u0022, resource_path);\n-\t\t\tbreak;\n-\t\tcase 'h':\n-\t\t\tfprintf(stderr, \u0022Usage: test-server \u0022\n-\t\t\t\t\t\u0022[--port\u003d\u003cp\u003e] [--ssl] \u0022\n-\t\t\t\t\t\u0022[-d \u003clog bitfield\u003e] \u0022\n-\t\t\t\t\t\u0022[--resource_path \u003cpath\u003e]\u005cn\u0022);\n-\t\t\texit(1);\n-\t\t}\n-\t}\n-\n-#if !defined(LWS_NO_DAEMONIZE) \u0026\u0026 !defined(WIN32)\n-\t/*\n-\t * normally lock path would be /var/lock/lwsts or similar, to\n-\t * simplify getting started without having to take care about\n-\t * permissions or running as root, set to /tmp/.lwsts-lock\n-\t */\n-\tif (daemonize \u0026\u0026 lws_daemonize(\u0022/tmp/.lwsts-lock\u0022)) {\n-\t\tfprintf(stderr, \u0022Failed to daemonize\u005cn\u0022);\n-\t\treturn 1;\n-\t}\n-#endif\n-\n-\tfor (n \u003d 0; n \u003c (int)ARRAY_SIZE(sigs); n++) {\n-\t\tsignals[n] \u003d evsignal_new(event_base_loop, sigs[n], signal_cb,\n-\t\t\t\t\t event_base_loop);\n-\n-\t\tevsignal_add(signals[n], NULL);\n-\t}\n-\n-\t/* tell the library what debug level to emit and to send it to stderr */\n-\tlws_set_log_level(debug_level, NULL);\n-\n-\tlwsl_notice(\u0022libwebsockets test server libevent - license LGPL2.1+SLE\u005cn\u0022);\n-\tlwsl_notice(\u0022(C) Copyright 2010-2018 Andy Green \u003candy@warmcat.com\u003e\u005cn\u0022);\n-\n-\tprintf(\u0022Using resource path \u005c\u0022%s\u005c\u0022\u005cn\u0022, resource_path);\n-\n-\tinfo.iface \u003d iface;\n-\tinfo.protocols \u003d protocols;\n-\tinfo.extensions \u003d exts;\n-\tinfo.mounts \u003d \u0026mount;\n-\n-\tinfo.ssl_cert_filepath \u003d NULL;\n-\tinfo.ssl_private_key_filepath \u003d NULL;\n-\n-\tif (use_ssl) {\n-\t\tif (strlen(resource_path) \u003e sizeof(cert_path) - 32) {\n-\t\t\tlwsl_err(\u0022resource path too long\u005cn\u0022);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tsprintf(cert_path, \u0022%s/libwebsockets-test-server.pem\u0022,\n-\t\t\t\tresource_path);\n-\t\tif (strlen(resource_path) \u003e sizeof(key_path) - 32) {\n-\t\t\tlwsl_err(\u0022resource path too long\u005cn\u0022);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tsprintf(key_path, \u0022%s/libwebsockets-test-server.key.pem\u0022,\n-\t\t\t\tresource_path);\n-\n-\t\tinfo.ssl_cert_filepath \u003d cert_path;\n-\t\tinfo.ssl_private_key_filepath \u003d key_path;\n-\n-\t\topts |\u003d LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;\n-\t}\n-\tinfo.gid \u003d -1;\n-\tinfo.uid \u003d -1;\n-\tinfo.options \u003d opts | LWS_SERVER_OPTION_LIBEVENT;\n-\n-\tforeign_loops[0] \u003d event_base_loop;\n-\tinfo.foreign_loops \u003d foreign_loops;\n-\n-\tcontext \u003d lws_create_context(\u0026info);\n-\tif (context \u003d\u003d NULL) {\n-\t\tlwsl_err(\u0022libwebsocket init failed\u005cn\u0022);\n-\t\treturn -1;\n-\t}\n-\n-\t/*\n-\t * this shows how to override the lws file operations. You don't need\n-\t * to do any of this unless you have a reason (eg, want to serve\n-\t * compressed files without decompressing the whole archive)\n-\t */\n-\t/* stash original platform fops */\n-\tfops_plat \u003d *(lws_get_fops(context));\n-\t/* override the active fops */\n-\tlws_get_fops(context)-\u003eopen \u003d test_server_fops_open;\n-\n-\tevent_base_dispatch(event_base_loop);\n-\n-\tfor (n \u003d 0; n \u003c (int)ARRAY_SIZE(sigs); n++)\n-\t\tevent_free(signals[n]);\n-\n-\tlws_context_destroy(context);\n-\n-\tlwsl_notice(\u0022libwebsockets-test-server exited cleanly\u005cn\u0022);\n-\n-\treturn 0;\n-}\n","s":{"c":1750739108,"u": 67676}}
],"g": 301971,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}