valgrind: avoid complaints from plugin loading
[platform/upstream/libwebsockets.git] / lib / private-libwebsockets.h
index 5044707..1968722 100644 (file)
 #include <ctype.h>
 #include <limits.h>
 #include <stdarg.h>
+
+#if defined(LWS_WITH_ESP32)
+#define MSG_NOSIGNAL 0
+#define SOMAXCONN 3
+#endif
+
 #if defined(LWS_WITH_ESP8266)
 #include <user_interface.h>
 #define assert(n)
@@ -128,20 +134,28 @@ char *ets_strchr(const char *s, int c);
 #include <mstcpip.h>
 #include <io.h>
 
+#if !defined(LWS_HAVE_ATOLL)
+#if defined(LWS_HAVE__ATOI64)
+#define atoll _atoi64
+#else
+#warning No atoll or _atoi64 available, using atoi
+#define atoll atoi
+#endif
+#endif
+
 #ifndef __func__
 #define __func__ __FUNCTION__
 #endif
 
-#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE)
-#define vsnprintf _vsnprintf
-#else
 #ifdef LWS_HAVE__VSNPRINTF
 #define vsnprintf _vsnprintf
 #endif
-#endif
 
-#ifdef LWS_HAVE__SNPRINTF
-#define lws_snprintf _snprintf
+/* we don't have an implementation for this on windows... */
+int kill(int pid, int sig);
+int fork(void);
+#ifndef SIGINT
+#define SIGINT 2
 #endif
 
 #else /* not windows --> */
@@ -150,7 +164,7 @@ char *ets_strchr(const char *s, int c);
 #include <strings.h>
 #include <unistd.h>
 #include <sys/types.h>
-#ifndef MBED_OPERATORS
+
 #ifndef __cplusplus
 #include <errno.h>
 #endif
@@ -161,6 +175,9 @@ char *ets_strchr(const char *s, int c);
 #define vsnprintf ets_vsnprintf
 #define snprintf ets_snprintf
 #define sprintf ets_sprintf
+
+int kill(int pid, int sig);
+
 #else
 #include <sys/socket.h>
 #endif
@@ -171,7 +188,7 @@ char *ets_strchr(const char *s, int c);
 #if defined(LWS_BUILTIN_GETIFADDRS)
  #include <getifaddrs.h>
 #else
- #if !defined(LWS_WITH_ESP8266)
+ #if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32)
  #include <ifaddrs.h>
  #endif
 #endif
@@ -181,12 +198,12 @@ char *ets_strchr(const char *s, int c);
 #elif defined (__sun)
 #include <syslog.h>
 #else
-#if !defined(LWS_WITH_ESP8266)
+#if !defined(LWS_WITH_ESP8266)  && !defined(LWS_WITH_ESP32)
 #include <sys/syslog.h>
 #endif
 #endif
 #include <netdb.h>
-#if !defined(LWS_WITH_ESP8266)
+#if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32)
 #include <sys/mman.h>
 #include <sys/un.h>
 #include <netinet/in.h>
@@ -200,8 +217,9 @@ char *ets_strchr(const char *s, int c);
 #ifdef LWS_USE_LIBUV
 #include <uv.h>
 #endif
-
-#endif /* MBED */
+#ifdef LWS_USE_LIBEVENT
+#include <event2/event.h>
+#endif
 
 #ifndef LWS_NO_FORK
 #ifdef LWS_HAVE_SYS_PRCTL_H
@@ -221,7 +239,7 @@ char *ets_strchr(const char *s, int c);
 
 #define lws_set_blocking_send(wsi)
 
-#if defined(MBED_OPERATORS) || defined(LWS_WITH_ESP8266)
+#if defined(LWS_WITH_ESP8266)
 #define lws_socket_is_valid(x) ((x) != NULL)
 #define LWS_SOCK_INVALID (NULL)
 struct lws;
@@ -252,26 +270,11 @@ lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen);
 #else
 #include <wolfssl/openssl/ssl.h>
 #include <wolfssl/error-ssl.h>
+#define OPENSSL_NO_TLSEXT
 #endif /* not USE_OLD_CYASSL */
 #else
-#if defined(LWS_USE_POLARSSL)
-#include <polarssl/ssl.h>
-#include <polarssl/error.h>
-#include <polarssl/md5.h>
-#include <polarssl/sha1.h>
-#include <polarssl/ecdh.h>
-#define SSL_ERROR_WANT_READ POLARSSL_ERR_NET_WANT_READ
-#define SSL_ERROR_WANT_WRITE POLARSSL_ERR_NET_WANT_WRITE
-#define OPENSSL_VERSION_NUMBER  0x10002000L
-#else
-#if defined(LWS_USE_MBEDTLS)
-#include <mbedtls/ssl.h>
-#include <mbedtls/error.h>
-#include <mbedtls/md5.h>
-#include <mbedtls/sha1.h>
-#include <mbedtls/ecdh.h>
-#else
 #include <openssl/ssl.h>
+#if !defined(LWS_WITH_ESP32)
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/md5.h>
@@ -280,8 +283,14 @@ lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen);
 #include <openssl/ecdh.h>
 #endif
 #include <openssl/x509v3.h>
-#endif /* not USE_MBEDTLS */
-#endif /* not USE_POLARSSL */
+#endif
+#if (OPENSSL_VERSION_NUMBER < 0x0009080afL)
+/* later openssl defines this to negate the presence of tlsext... but it was only
+ * introduced at 0.9.8j.  Earlier versions don't know it exists so don't
+ * define it... making it look like the feature exists...
+ */
+#define OPENSSL_NO_TLSEXT
+#endif
 #endif /* not USE_WOLFSSL */
 #endif
 
@@ -291,18 +300,8 @@ lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen);
 static inline int compatible_close(int fd) { return close(fd); }
 #endif
 
-#if defined(MBED_OPERATORS)
-#undef compatible_close
-#define compatible_close(fd) mbed3_delete_tcp_stream_socket(fd)
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN    4321  /* to show byte order (taken from gcc) */
-#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
+#if defined(WIN32) || defined(_WIN32)
+#include <gettimeofday.h>
 #endif
 
 #if defined(LWS_WITH_ESP8266)
@@ -380,11 +379,23 @@ extern "C" {
 #endif
 
 #if defined(__sun) && defined(__GNUC__)
+
+#include <arpa/nameser_compat.h>
+
+#if !defined (BYTE_ORDER)
 # define BYTE_ORDER __BYTE_ORDER__
+#endif
+
+#if !defined(LITTLE_ENDIAN)
 # define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
+#endif
+
+#if !defined(BIG_ENDIAN)
 # define BIG_ENDIAN __ORDER_BIG_ENDIAN__
 #endif
 
+#endif /* sun + GNUC */
+
 #if !defined(BYTE_ORDER)
 # define BYTE_ORDER __BYTE_ORDER
 #endif
@@ -550,10 +561,15 @@ enum connection_mode {
        /* transient, ssl delay hiding */
        LWSCM_SSL_ACK_PENDING,
        LWSCM_SSL_INIT,
+       /* as above, but complete into LWSCM_RAW */
+       LWSCM_SSL_ACK_PENDING_RAW,
+       LWSCM_SSL_INIT_RAW,
 
        /* special internal types */
        LWSCM_SERVER_LISTENER,
        LWSCM_CGI, /* stdin, stdout, stderr for another cgi master wsi */
+       LWSCM_RAW, /* raw with bulk handling */
+       LWSCM_RAW_FILEDESC, /* raw without bulk handling */
 
        /* HTTP Client related */
        LWSCM_HTTP_CLIENT = LWSCM_FLAG_IMPLIES_CALLBACK_CLOSED_CLIENT_HTTP,
@@ -567,12 +583,75 @@ enum connection_mode {
        LWSCM_WSCL_WAITING_SERVER_REPLY,
        LWSCM_WSCL_WAITING_EXTENSION_CONNECT,
        LWSCM_WSCL_PENDING_CANDIDATE_CHILD,
+       LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY,
+       LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY,
+       LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY,
 
        /****** add new things just above ---^ ******/
 
 
 };
 
+/* enums of socks version */
+enum socks_version {
+       SOCKS_VERSION_4 = 4,
+       SOCKS_VERSION_5 = 5
+};
+
+/* enums of subnegotiation version */
+enum socks_subnegotiation_version {
+       SOCKS_SUBNEGOTIATION_VERSION_1 = 1,
+};
+
+/* enums of socks commands */
+enum socks_command {
+       SOCKS_COMMAND_CONNECT = 1,
+       SOCKS_COMMAND_BIND = 2,
+       SOCKS_COMMAND_UDP_ASSOCIATE = 3
+};
+
+/* enums of socks address type */
+enum socks_atyp {
+       SOCKS_ATYP_IPV4 = 1,
+       SOCKS_ATYP_DOMAINNAME = 3,
+       SOCKS_ATYP_IPV6 = 4
+};
+
+/* enums of socks authentication methods */
+enum socks_auth_method {
+       SOCKS_AUTH_NO_AUTH = 0,
+       SOCKS_AUTH_GSSAPI = 1,
+       SOCKS_AUTH_USERNAME_PASSWORD = 2
+};
+
+/* enums of subnegotiation status */
+enum socks_subnegotiation_status {
+       SOCKS_SUBNEGOTIATION_STATUS_SUCCESS = 0,
+};
+
+/* enums of socks request reply */
+enum socks_request_reply {
+       SOCKS_REQUEST_REPLY_SUCCESS = 0,
+       SOCKS_REQUEST_REPLY_FAILURE_GENERAL = 1,
+       SOCKS_REQUEST_REPLY_CONNECTION_NOT_ALLOWED = 2,
+       SOCKS_REQUEST_REPLY_NETWORK_UNREACHABLE = 3,
+       SOCKS_REQUEST_REPLY_HOST_UNREACHABLE = 4,
+       SOCKS_REQUEST_REPLY_CONNECTION_REFUSED = 5,
+       SOCKS_REQUEST_REPLY_TTL_EXPIRED = 6,
+       SOCKS_REQUEST_REPLY_COMMAND_NOT_SUPPORTED = 7,
+       SOCKS_REQUEST_REPLY_ATYP_NOT_SUPPORTED = 8
+};
+
+/* enums used to generate socks messages */
+enum socks_msg_type {
+       /* greeting */
+       SOCKS_MSG_GREETING,
+       /* credential, user name and password */
+       SOCKS_MSG_USERNAME_PASSWORD,
+       /* connect command */
+       SOCKS_MSG_CONNECT
+};
+
 enum {
        LWS_RXFLOW_ALLOW = (1 << 0),
        LWS_RXFLOW_PENDING_CHANGE = (1 << 1),
@@ -584,7 +663,7 @@ enum {
 struct lws_protocols;
 struct lws;
 
-#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV)
+#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV) || defined(LWS_USE_LIBEVENT)
 
 struct lws_io_watcher {
 #ifdef LWS_USE_LIBEV
@@ -593,6 +672,9 @@ struct lws_io_watcher {
 #ifdef LWS_USE_LIBUV
        uv_poll_t uv_watcher;
 #endif
+#ifdef LWS_USE_LIBEVENT
+       struct event *event_watcher;
+#endif
        struct lws_context *context;
 };
 
@@ -603,6 +685,9 @@ struct lws_signal_watcher {
 #ifdef LWS_USE_LIBUV
        uv_signal_t uv_watcher;
 #endif
+#ifdef LWS_USE_LIBEVENT
+       struct event *event_watcher;
+#endif
        struct lws_context *context;
 };
 #endif
@@ -648,10 +733,13 @@ struct allocated_headers {
         */
        unsigned char frag_index[WSI_TOKEN_COUNT];
        unsigned char rx[2048];
+
        unsigned int rxpos;
        unsigned int rxlen;
        unsigned int pos;
 
+       unsigned int http_response;
+
 #ifndef LWS_NO_CLIENT
        char initial_handshake_hash_base64[30];
 #endif
@@ -676,7 +764,7 @@ struct lws_context_per_thread {
        struct lws *rx_draining_ext_list;
        struct lws *tx_draining_ext_list;
        struct lws *timeout_list;
-#ifdef LWS_USE_LIBUV
+#if defined(LWS_USE_LIBUV) || defined(LWS_USE_LIBEVENT)
        struct lws_context *context;
 #endif
 #ifdef LWS_WITH_CGI
@@ -689,9 +777,6 @@ struct lws_context_per_thread {
 #ifdef LWS_OPENSSL_SUPPORT
        struct lws *pending_read_list; /* linked list */
 #endif
-#ifndef LWS_NO_SERVER
-       struct lws *wsi_listening;
-#endif
 #if defined(LWS_USE_LIBEV)
        struct ev_loop *io_loop_ev;
 #endif
@@ -701,10 +786,13 @@ struct lws_context_per_thread {
        uv_timer_t uv_timeout_watcher;
        uv_idle_t uv_idle;
 #endif
+#if defined(LWS_USE_LIBEVENT)
+       struct event_base *io_loop_event_base;
+#endif
 #if defined(LWS_USE_LIBEV)
        struct lws_io_watcher w_accept;
 #endif
-#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV)
+#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV) || defined(LWS_USE_LIBEVENT)
        struct lws_signal_watcher w_sigint;
        unsigned char ev_loop_foreign:1;
 #endif
@@ -728,6 +816,14 @@ struct lws_context_per_thread {
        unsigned char lock_depth;
 };
 
+struct lws_conn_stats {
+       unsigned long long rx, tx;
+       unsigned long conn, trans, ws_upg, http2_upg, rejected;
+};
+
+void
+lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs);
+
 /*
  * virtual host -related context information
  *   vhostwide SSL context
@@ -750,17 +846,26 @@ struct lws_vhost {
 #if !defined(LWS_WITH_ESP8266)
        char http_proxy_address[128];
        char proxy_basic_auth_token[128];
+#if defined(LWS_WITH_SOCKS5)
+       char socks_proxy_address[128];
+       char socks_user[96];
+       char socks_password[96];
+#endif
 #endif
 #if defined(LWS_WITH_ESP8266)
        /* listen sockets need a place to hang their hat */
        esp_tcp tcp;
 #endif
+       struct lws_conn_stats conn_stats;
        struct lws_context *context;
        struct lws_vhost *vhost_next;
        const struct lws_http_mount *mount_list;
        struct lws *lserv_wsi;
        const char *name;
        const char *iface;
+#if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32) && !defined(OPTEE_TA) && !defined(WIN32)
+       int bind_iface;
+#endif
        const struct lws_protocols *protocols;
        void **protocol_vh_privs;
        const struct lws_protocol_vhost_options *pvo;
@@ -773,17 +878,19 @@ struct lws_vhost {
 #ifndef LWS_NO_EXTENSIONS
        const struct lws_extension *extensions;
 #endif
-       unsigned long long rx, tx;
-       unsigned long conn, trans, ws_upgrades, http2_upgrades;
 
        int listen_port;
        unsigned int http_proxy_port;
+#if defined(LWS_WITH_SOCKS5)
+       unsigned int socks_proxy_port;
+#endif
        unsigned int options;
        int count_protocols;
        int ka_time;
        int ka_probes;
        int ka_interval;
        int keepalive_timeout;
+       int ssl_info_event_mask;
 #ifdef LWS_WITH_ACCESS_LOG
        int log_fd;
 #endif
@@ -794,7 +901,10 @@ struct lws_vhost {
        unsigned int user_supplied_ssl_ctx:1;
 #endif
 
+       unsigned int created_vhost_protocols:1;
+
        unsigned char default_protocol_index;
+       unsigned char raw_protocol_index;
 };
 
 /*
@@ -808,8 +918,13 @@ struct lws_context {
        time_t last_timeout_check_s;
        time_t last_ws_ping_pong_check_s;
        time_t time_up;
-       struct lws_plat_file_ops fops;
+       const struct lws_plat_file_ops *fops;
+       struct lws_plat_file_ops fops_platform;
+#if defined(LWS_WITH_ZIP_FOPS)
+       struct lws_plat_file_ops fops_zip;
+#endif
        struct lws_context_per_thread pt[LWS_MAX_SMP];
+       struct lws_conn_stats conn_stats;
 #ifdef _WIN32
 /* different implementation between unix and windows */
        struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
@@ -825,16 +940,28 @@ struct lws_context {
 #endif
        struct lws_vhost *vhost_list;
        struct lws_plugin *plugin_list;
+
+       void *external_baggage_free_on_destroy;
        const struct lws_token_limits *token_limits;
        void *user_space;
        const char *server_string;
        const struct lws_protocol_vhost_options *reject_service_keywords;
+       lws_reload_func deprecation_cb;
+
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+       cap_value_t caps[4];
+       char count_caps;
+#endif
 
 #if defined(LWS_USE_LIBEV)
        lws_ev_signal_cb_t * lws_ev_sigint_cb;
 #endif
 #if defined(LWS_USE_LIBUV)
        uv_signal_cb lws_uv_sigint_cb;
+       uv_loop_t pu_loop;
+#endif
+#if defined(LWS_USE_LIBEVENT)
+       lws_event_signal_cb_t * lws_event_sigint_cb;
 #endif
        char canonical_hostname[128];
 #ifdef LWS_LATENCY
@@ -842,8 +969,14 @@ struct lws_context {
        char worst_latency_info[256];
 #endif
 
+#if defined(LWS_WITH_STATS)
+       uint64_t lws_stats[LWSSTATS_SIZE];
+       uint64_t last_dump;
+       int updated;
+#endif
+
        int max_fds;
-#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV)
+#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV) || defined(LWS_USE_LIBEVENT)
        int use_ev_sigint;
 #endif
        int started_with_parent;
@@ -868,7 +1001,15 @@ struct lws_context {
        unsigned int timeout_secs;
        unsigned int pt_serv_buf_size;
        int max_http_header_data;
+       int simultaneous_ssl_restriction;
+       int simultaneous_ssl;
 
+       unsigned int deprecated:1;
+       unsigned int being_destroyed:1;
+       unsigned int being_destroyed1:1;
+       unsigned int requested_kill:1;
+       unsigned int protocol_init_done:1;
+       unsigned int ssl_gate_accepts:1;
        /*
         * set to the Thread ID that's doing the service loop just before entry
         * to poll indicates service thread likely idling in poll()
@@ -884,10 +1025,8 @@ struct lws_context {
        short plugin_extension_count;
        short server_string_len;
        unsigned short ws_ping_pong_interval;
-
-       unsigned int being_destroyed:1;
-       unsigned int requested_kill:1;
-       unsigned int protocol_init_done:1;
+       unsigned short deprecation_pending_listen_close_count;
+       uint8_t max_fi;
 };
 
 #define lws_get_context_protocol(ctx, x) ctx->vhost_list->protocols[x]
@@ -897,6 +1036,10 @@ LWS_EXTERN void
 lws_close_free_wsi_final(struct lws *wsi);
 LWS_EXTERN void
 lws_libuv_closehandle(struct lws *wsi);
+LWS_EXTERN void
+lws_libuv_closehandle_manually(struct lws *wsi);
+LWS_EXTERN int
+lws_libuv_check_watcher_active(struct lws *wsi);
 
 LWS_VISIBLE LWS_EXTERN int
 lws_plat_plugins_init(struct lws_context * context, const char * const *d);
@@ -922,7 +1065,7 @@ enum {
 
 #if defined(LWS_USE_LIBEV)
 LWS_EXTERN void
-lws_libev_accept(struct lws *new_wsi, lws_sockfd_type accept_fd);
+lws_libev_accept(struct lws *new_wsi, lws_sock_file_fd_type desc);
 LWS_EXTERN void
 lws_libev_io(struct lws *wsi, int flags);
 LWS_EXTERN int
@@ -940,7 +1083,7 @@ LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info)
 #define lws_libev_run(_a, _b) ((void) 0)
 #define lws_libev_destroyloop(_a, _b) ((void) 0)
 #define LWS_LIBEV_ENABLED(context) (0)
-#if LWS_POSIX
+#if LWS_POSIX && !defined(LWS_WITH_ESP32)
 #define lws_feature_status_libev(_a) \
                        lwsl_notice("libev support not compiled in\n")
 #else
@@ -950,7 +1093,7 @@ LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info)
 
 #if defined(LWS_USE_LIBUV)
 LWS_EXTERN void
-lws_libuv_accept(struct lws *new_wsi, lws_sockfd_type accept_fd);
+lws_libuv_accept(struct lws *new_wsi, lws_sock_file_fd_type desc);
 LWS_EXTERN void
 lws_libuv_io(struct lws *wsi, int flags);
 LWS_EXTERN int
@@ -959,6 +1102,8 @@ LWS_EXTERN void
 lws_libuv_run(const struct lws_context *context, int tsi);
 LWS_EXTERN void
 lws_libuv_destroyloop(struct lws_context *context, int tsi);
+LWS_EXTERN int
+lws_uv_initvhost(struct lws_vhost* vh, struct lws*);
 #define LWS_LIBUV_ENABLED(context) lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV)
 LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info);
 #else
@@ -968,7 +1113,7 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info)
 #define lws_libuv_run(_a, _b) ((void) 0)
 #define lws_libuv_destroyloop(_a, _b) ((void) 0)
 #define LWS_LIBUV_ENABLED(context) (0)
-#if LWS_POSIX
+#if LWS_POSIX && !defined(LWS_WITH_ESP32)
 #define lws_feature_status_libuv(_a) \
                        lwsl_notice("libuv support not compiled in\n")
 #else
@@ -976,6 +1121,34 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info)
 #endif
 #endif
 
+#if defined(LWS_USE_LIBEVENT)
+LWS_EXTERN void
+lws_libevent_accept(struct lws *new_wsi, lws_sock_file_fd_type desc);
+LWS_EXTERN void
+lws_libevent_io(struct lws *wsi, int flags);
+LWS_EXTERN int
+lws_libevent_init_fd_table(struct lws_context *context);
+LWS_EXTERN void
+lws_libevent_destroyloop(struct lws_context *context, int tsi);
+LWS_EXTERN void
+lws_libevent_run(const struct lws_context *context, int tsi);
+#define LWS_LIBEVENT_ENABLED(context) lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEVENT)
+LWS_EXTERN void lws_feature_status_libevent(struct lws_context_creation_info *info);
+#else
+#define lws_libevent_accept(_a, _b) ((void) 0)
+#define lws_libevent_io(_a, _b) ((void) 0)
+#define lws_libevent_init_fd_table(_a) (0)
+#define lws_libevent_run(_a, _b) ((void) 0)
+#define lws_libevent_destroyloop(_a, _b) ((void) 0)
+#define LWS_LIBEVENT_ENABLED(context) (0)
+#if LWS_POSIX && !defined(LWS_WITH_ESP32)
+#define lws_feature_status_libevent(_a) \
+                       lwsl_notice("libevent support not compiled in\n")
+#else
+#define lws_feature_status_libevent(_a)
+#endif
+#endif
+
 
 #ifdef LWS_USE_IPV6
 #define LWS_IPV6_ENABLED(vh) \
@@ -991,6 +1164,14 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info)
 #else
 #define LWS_UNIX_SOCK_ENABLED(vhost) (0)
 #endif
+
+typedef union {
+#ifdef LWS_USE_IPV6
+       struct sockaddr_in6 sa6;
+#endif
+       struct sockaddr_in sa4;
+} sockaddr46;
+
 enum uri_path_states {
        URIPS_IDLE,
        URIPS_SEEN_SLASH,
@@ -1020,11 +1201,12 @@ enum uri_esc_states {
 #ifndef LWS_NO_CLIENT
 struct client_info_stash {
        char address[256];
-       char path[1024];
+       char path[4096];
        char host[256];
        char origin[256];
        char protocol[256];
        char method[16];
+       char iface[16];
 };
 #endif
 
@@ -1041,15 +1223,39 @@ struct _lws_header_related {
        enum uri_esc_states ues;
        short lextable_pos;
        unsigned int current_token_limit;
-#ifndef LWS_NO_CLIENT
-       unsigned short c_port;
-#endif
+
        char esc_stash;
        char post_literal_equal;
        unsigned char parser_state; /* enum lws_token_indexes */
-       char redirects;
 };
 
+#if defined(LWS_WITH_RANGES)
+enum range_states {
+       LWSRS_NO_ACTIVE_RANGE,
+       LWSRS_BYTES_EQ,
+       LWSRS_FIRST,
+       LWSRS_STARTING,
+       LWSRS_ENDING,
+       LWSRS_COMPLETED,
+       LWSRS_SYNTAX,
+};
+
+struct lws_range_parsing {
+       unsigned long long start, end, extent, agg, budget;
+       const char buf[128];
+       int pos;
+       enum range_states state;
+       char start_valid, end_valid, ctr, count_ranges, did_try, inside, send_ctr;
+};
+
+int
+lws_ranges_init(struct lws *wsi, struct lws_range_parsing *rp, unsigned long long extent);
+int
+lws_ranges_next(struct lws_range_parsing *rp);
+void
+lws_ranges_reset(struct lws_range_parsing *rp);
+#endif
+
 struct _lws_http_mode_related {
        /* MUST be first in struct */
        struct allocated_headers *ah; /* mirroring  _lws_header_related */
@@ -1060,14 +1266,19 @@ struct _lws_http_mode_related {
 #endif
        unsigned int preamble_rx_len;
        struct lws *new_wsi_list;
-       unsigned long filepos;
-       unsigned long filelen;
-       lws_filefd_type fd;
+       lws_filepos_t filepos;
+       lws_filepos_t filelen;
+       lws_fop_fd_t fop_fd;
+
+#if defined(LWS_WITH_RANGES)
+       struct lws_range_parsing range;
+       char multipart_content_type[64];
+#endif
 
        enum http_version request_version;
        enum http_connection_type connection_type;
-       unsigned int content_length;
-       unsigned int content_remain;
+       lws_filepos_t content_length;
+       lws_filepos_t content_remain;
 };
 
 #ifdef LWS_USE_HTTP2
@@ -1263,18 +1474,38 @@ struct _lws_websocket_related {
 
 #ifdef LWS_WITH_CGI
 
+enum {
+       SIGNIFICANT_HDR_CONTENT_LENGTH,
+       SIGNIFICANT_HDR_LOCATION,
+       SIGNIFICANT_HDR_STATUS,
+       SIGNIFICANT_HDR_TRANSFER_ENCODING,
+
+       SIGNIFICANT_HDR_COUNT
+};
+
 /* wsi who is master of the cgi points to an lws_cgi */
 
 struct lws_cgi {
        struct lws_cgi *cgi_list;
        struct lws *stdwsi[3]; /* points to the associated stdin/out/err wsis */
        struct lws *wsi; /* owner */
-       unsigned long content_length;
-       unsigned long content_length_seen;
+       unsigned char *headers_buf;
+       unsigned char *headers_pos;
+       unsigned char *headers_dumped;
+       unsigned char *headers_end;
+       lws_filepos_t content_length;
+       lws_filepos_t content_length_seen;
        int pipe_fds[3][2];
+       int match[SIGNIFICANT_HDR_COUNT];
        int pid;
+       int response_code;
+       int lp;
+       char l[12];
 
        unsigned int being_closed:1;
+       unsigned int explicitly_chunked:1;
+
+       unsigned char chunked_grace;
 };
 #endif
 
@@ -1317,10 +1548,10 @@ struct lws {
 
        /* lifetime members */
 
-#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV)
+#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBUV) || defined(LWS_USE_LIBEVENT)
        struct lws_io_watcher w_read;
 #endif
-#if defined(LWS_USE_LIBEV)
+#if defined(LWS_USE_LIBEV) || defined(LWS_USE_LIBEVENT)
        struct lws_io_watcher w_write;
 #endif
        time_t pending_timeout_limit;
@@ -1359,10 +1590,12 @@ struct lws {
 #endif
 #ifdef LWS_OPENSSL_SUPPORT
        SSL *ssl;
-#if !defined(LWS_USE_POLARSSL) && !defined(LWS_USE_MBEDTLS)
        BIO *client_bio;
-#endif
        struct lws *pending_read_list_prev, *pending_read_list_next;
+#if defined(LWS_WITH_STATS)
+       uint64_t accept_start_us;
+       char seen_rx;
+#endif
 #endif
 #ifdef LWS_WITH_HTTP_PROXY
        struct lws_rewrite *rw;
@@ -1371,9 +1604,10 @@ struct lws {
        unsigned long action_start;
        unsigned long latency_start;
 #endif
-       /* pointer / int */
-       lws_sockfd_type sock;
-
+       lws_sock_file_fd_type desc; /* .filefd / .sockfd */
+#if defined(LWS_WITH_STATS)
+       uint64_t active_writable_req_us;
+#endif
        /* ints */
        int position_in_fds_table;
        int rxflow_len;
@@ -1401,6 +1635,8 @@ struct lws {
        unsigned int sending_chunked:1;
        unsigned int already_did_cce:1;
        unsigned int told_user_closed:1;
+       unsigned int ipv6:1;
+
 #if defined(LWS_WITH_ESP8266)
        unsigned int pending_send_completion:3;
        unsigned int close_is_pending_send_completion:1;
@@ -1421,8 +1657,7 @@ struct lws {
        unsigned int extension_data_pending:1;
 #endif
 #ifdef LWS_OPENSSL_SUPPORT
-       unsigned int use_ssl:3;
-       unsigned int upgraded:1;
+       unsigned int use_ssl:4;
 #endif
 #ifdef _WIN32
        unsigned int sock_send_blocking:1;
@@ -1431,6 +1666,14 @@ struct lws {
        unsigned int redirect_to_https:1;
 #endif
 
+       /* volatile to make sure code is aware other thread can change */
+       volatile unsigned int handling_pollout:1;
+       volatile unsigned int leave_pollout_active:1;
+
+#ifndef LWS_NO_CLIENT
+       unsigned short c_port;
+#endif
+
        /* chars */
 #ifndef LWS_NO_EXTENSIONS
        unsigned char count_act_ext;
@@ -1445,6 +1688,7 @@ struct lws {
        char pps; /* enum lws_pending_protocol_send */
        char tsi; /* thread service index we belong to */
        char protocol_interpret_idx;
+       char redirects;
 #ifdef LWS_WITH_CGI
        char cgi_channel; /* which of stdin/out/err */
        char hdr_state;
@@ -1460,9 +1704,14 @@ struct lws {
 LWS_EXTERN int log_level;
 
 LWS_EXTERN int
-lws_socket_bind(struct lws_vhost *vhost, int sockfd, int port,
+lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
                const char *iface);
 
+#if defined(LWS_USE_IPV6)
+LWS_EXTERN unsigned long
+lws_get_addr_scope(const char *ipaddr);
+#endif
+
 LWS_EXTERN void
 lws_close_free_wsi(struct lws *wsi, enum lws_close_status);
 
@@ -1509,7 +1758,7 @@ lws_b64_selftest(void);
 LWS_EXTERN int
 lws_service_flag_pending(struct lws_context *context, int tsi);
 
-#if defined(_WIN32) || defined(MBED_OPERATORS) || defined(LWS_WITH_ESP8266)
+#if defined(_WIN32) || defined(LWS_WITH_ESP8266)
 LWS_EXTERN struct lws *
 wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd);
 
@@ -1520,7 +1769,7 @@ LWS_EXTERN int
 delete_from_fd(struct lws_context *context, lws_sockfd_type fd);
 #else
 #define wsi_from_fd(A,B)  A->lws_lookup[B]
-#define insert_wsi(A,B)   assert(A->lws_lookup[B->sock] == 0); A->lws_lookup[B->sock]=B
+#define insert_wsi(A,B)   assert(A->lws_lookup[B->desc.sockfd] == 0); A->lws_lookup[B->desc.sockfd]=B
 #define delete_from_fd(A,B) A->lws_lookup[B]=0
 #endif
 
@@ -1534,11 +1783,14 @@ lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);
 LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_service_timeout_check(struct lws *wsi, unsigned int sec);
 
+LWS_EXTERN void
+lws_remove_from_timeout_list(struct lws *wsi);
+
 LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
 lws_client_connect_2(struct lws *wsi);
 
 LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT
-lws_client_reset(struct lws *wsi, int ssl, const char *address, int port,
+lws_client_reset(struct lws **wsi, int ssl, const char *address, int port,
                 const char *path, const char *host);
 
 LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
@@ -1650,6 +1902,13 @@ lws_header_table_detach(struct lws *wsi, int autoservice);
 
 LWS_EXTERN void
 lws_header_table_reset(struct lws *wsi, int autoservice);
+void
+_lws_header_table_reset(struct allocated_headers *ah);
+
+void
+lws_header_table_force_to_detachable_state(struct lws *wsi);
+int
+lws_header_table_is_in_detachable_state(struct lws *wsi);
 
 LWS_EXTERN char * LWS_WARN_UNUSED_RESULT
 lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);
@@ -1687,7 +1946,7 @@ LWS_EXTERN int get_daemonize_pid();
 #define get_daemonize_pid() (0)
 #endif
 
-#if !defined(MBED_OPERATORS) && !defined(LWS_WITH_ESP8266)
+#if !defined(LWS_WITH_ESP8266)
 LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 interface_to_sa(struct lws_vhost *vh, const char *ifname,
                struct sockaddr_in *addr, size_t addrlen);
@@ -1751,7 +2010,6 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 #endif
 LWS_EXTERN void
 lws_ssl_destroy(struct lws_vhost *vhost);
-
 /* HTTP2-related */
 
 #ifdef LWS_USE_HTTP2
@@ -1839,6 +2097,10 @@ lws_http_transaction_completed_client(struct lws *wsi);
 LWS_EXTERN int
 lws_context_init_client_ssl(struct lws_context_creation_info *info,
                            struct lws_vhost *vhost);
+
+LWS_EXTERN void
+lws_ssl_info_callback(const SSL *ssl, int where, int ret);
+
 #else
        #define lws_context_init_client_ssl(_a, _b) (0)
 #endif
@@ -1863,12 +2125,9 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
                          struct lws_pollfd *pollfd);
 LWS_EXTERN int
 lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len);
-LWS_EXTERN int
-_lws_server_listen_accept_flow_control(struct lws *twsi, int on);
 #else
 #define lws_server_socket_service(_a, _b, _c) (0)
 #define lws_handshake_server(_a, _b, _c) (0)
-#define _lws_server_listen_accept_flow_control(a, b) (0)
 #endif
 
 #ifdef LWS_WITH_ACCESS_LOG
@@ -1899,9 +2158,19 @@ lws_realloc(void *ptr, size_t size);
 LWS_EXTERN void * LWS_WARN_UNUSED_RESULT
 lws_zalloc(size_t size);
 
+#ifdef LWS_PLAT_OPTEE
+void *lws_malloc(size_t size);
+void lws_free(void *p);
+#define lws_free_set_NULL(P)    do { lws_free(P); (P) = NULL; } while(0)
+#else
 #define lws_malloc(S)  lws_realloc(NULL, S)
 #define lws_free(P)    lws_realloc(P, 0)
 #define lws_free_set_NULL(P)   do { lws_realloc(P, 0); (P) = NULL; } while(0)
+#endif
+
+const struct lws_plat_file_ops *
+lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,
+                   const char **vpath);
 
 /* lws_plat_ */
 LWS_EXTERN void
@@ -1916,6 +2185,10 @@ lws_plat_service_periodic(struct lws_context *context);
 LWS_EXTERN int
 lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,
                       struct lws_pollfd *pfd);
+LWS_EXTERN void
+lws_add_wsi_to_draining_ext_list(struct lws *wsi);
+LWS_EXTERN void
+lws_remove_wsi_from_draining_ext_list(struct lws *wsi);
 LWS_EXTERN int
 lws_plat_context_early_init(void);
 LWS_EXTERN void
@@ -1927,7 +2200,7 @@ lws_poll_listen_fd(struct lws_pollfd *fd);
 LWS_EXTERN int
 lws_plat_service(struct lws_context *context, int timeout_ms);
 LWS_EXTERN LWS_VISIBLE int
-lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
 LWS_EXTERN int
 lws_plat_init(struct lws_context *context,
              struct lws_context_creation_info *info);
@@ -1937,9 +2210,40 @@ LWS_EXTERN unsigned long long
 time_in_microseconds(void);
 LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
 lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt);
+LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_plat_inet_pton(int af, const char *src, void *dst);
 
 LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);
+LWS_EXTERN int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,
+                               lws_filepos_t *amount);
+LWS_EXTERN int alloc_pem_to_der_file(struct lws_context *context, const char *filename, uint8_t **buf,
+              lws_filepos_t *amount);
+
+LWS_EXTERN void
+lws_same_vh_protocol_remove(struct lws *wsi);
+LWS_EXTERN void
+lws_same_vh_protocol_insert(struct lws *wsi, int n);
+
+#if defined(LWS_WITH_STATS)
+void
+lws_stats_atomic_bump(struct lws_context * context,
+               struct lws_context_per_thread *pt, int index, uint64_t bump);
+void
+lws_stats_atomic_max(struct lws_context * context,
+               struct lws_context_per_thread *pt, int index, uint64_t val);
+#else
+static inline uint64_t lws_stats_atomic_bump(struct lws_context * context,
+               struct lws_context_per_thread *pt, int index, uint64_t bump) {
+       (void)context; (void)pt; (void)index; (void)bump; return 0; }
+static inline uint64_t lws_stats_atomic_max(struct lws_context * context,
+               struct lws_context_per_thread *pt, int index, uint64_t val) {
+       (void)context; (void)pt; (void)index; (void)val; return 0; }
+#endif
+
+/* socks */
+void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
+                       size_t *msg_len);
 
 #ifdef __cplusplus
 };