Update libwebsockets headers for v4.3-stable 90/268990/1
authorSeonah Moon <seonah1.moon@samsung.com>
Thu, 6 Jan 2022 05:03:48 +0000 (14:03 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Thu, 6 Jan 2022 05:04:03 +0000 (14:04 +0900)
Change-Id: I78adee9a9882c24160c2b1b0728855f747444430

36 files changed:
packaging/capi-network-vine.spec
third-party/prebuilt/include/libwebsockets.h
third-party/prebuilt/include/libwebsockets/lws-cache-ttl.h [new file with mode: 0644]
third-party/prebuilt/include/libwebsockets/lws-callbacks.h
third-party/prebuilt/include/libwebsockets/lws-client.h
third-party/prebuilt/include/libwebsockets/lws-conmon.h
third-party/prebuilt/include/libwebsockets/lws-context-vhost.h
third-party/prebuilt/include/libwebsockets/lws-cose.h [new file with mode: 0644]
third-party/prebuilt/include/libwebsockets/lws-dll2.h
third-party/prebuilt/include/libwebsockets/lws-eventlib-exports.h
third-party/prebuilt/include/libwebsockets/lws-fault-injection.h
third-party/prebuilt/include/libwebsockets/lws-gencrypto.h
third-party/prebuilt/include/libwebsockets/lws-genec.h
third-party/prebuilt/include/libwebsockets/lws-genhash.h
third-party/prebuilt/include/libwebsockets/lws-genrsa.h
third-party/prebuilt/include/libwebsockets/lws-http.h
third-party/prebuilt/include/libwebsockets/lws-jose.h
third-party/prebuilt/include/libwebsockets/lws-jwk.h
third-party/prebuilt/include/libwebsockets/lws-jws.h
third-party/prebuilt/include/libwebsockets/lws-lecp.h [new file with mode: 0644]
third-party/prebuilt/include/libwebsockets/lws-lejp.h
third-party/prebuilt/include/libwebsockets/lws-logs.h
third-party/prebuilt/include/libwebsockets/lws-map.h [new file with mode: 0644]
third-party/prebuilt/include/libwebsockets/lws-misc.h
third-party/prebuilt/include/libwebsockets/lws-mqtt.h
third-party/prebuilt/include/libwebsockets/lws-network-helper.h
third-party/prebuilt/include/libwebsockets/lws-protocols-plugins.h
third-party/prebuilt/include/libwebsockets/lws-secure-streams-client.h
third-party/prebuilt/include/libwebsockets/lws-secure-streams-policy.h
third-party/prebuilt/include/libwebsockets/lws-secure-streams.h
third-party/prebuilt/include/libwebsockets/lws-service.h
third-party/prebuilt/include/libwebsockets/lws-system.h
third-party/prebuilt/include/libwebsockets/lws-timeout-timer.h
third-party/prebuilt/include/libwebsockets/lws-tokenize.h
third-party/prebuilt/include/libwebsockets/lws-x509.h
third-party/prebuilt/include/lws_config.h

index 6ac96b3..ab0ee55 100755 (executable)
@@ -3,7 +3,7 @@
 %bcond_without use_glib_event_loop
 Name:    capi-network-vine
 Summary: An service discovery framework
-Version: 1.2.4
+Version: 1.2.5
 Release: 0
 Group:   Network & Connectivity/API
 License: Apache-2.0
index 7215161..4409ee2 100644 (file)
@@ -125,7 +125,11 @@ typedef int suseconds_t;
 #define LWS_EXTERN
 #endif
 
+#if defined(__MINGW32__)
+#define LWS_INVALID_FILE -1
+#else
 #define LWS_INVALID_FILE INVALID_HANDLE_VALUE
+#endif
 #define LWS_SOCK_INVALID (INVALID_SOCKET)
 #define LWS_O_RDONLY _O_RDONLY
 #define LWS_O_WRONLY _O_WRONLY
@@ -287,6 +291,11 @@ typedef int suseconds_t;
 #include <mbedtls/ssl.h>
 #include <mbedtls/entropy.h>
 #include <mbedtls/ctr_drbg.h>
+
+#if !defined(MBEDTLS_PRIVATE)
+#define MBEDTLS_PRIVATE(_q) _q
+#endif
+
 #endif
 #else
 #include <openssl/ssl.h>
@@ -378,8 +387,12 @@ struct lws;
 #if defined(_WIN32)
 #if !defined(LWS_WIN32_HANDLE_TYPES)
 typedef SOCKET lws_sockfd_type;
+#if defined(__MINGW32__)
+typedef int lws_filefd_type;
+#else
 typedef HANDLE lws_filefd_type;
 #endif
+#endif
 
 
 #define lws_pollfd pollfd
@@ -566,8 +579,11 @@ struct lws_vhost;
 struct lws;
 
 #include <libwebsockets/lws-dll2.h>
+#include <libwebsockets/lws-map.h>
+
 #include <libwebsockets/lws-fault-injection.h>
 #include <libwebsockets/lws-timeout-timer.h>
+#include <libwebsockets/lws-cache-ttl.h>
 #if defined(LWS_WITH_SYS_SMD)
 #include <libwebsockets/lws-smd.h>
 #endif
@@ -608,7 +624,11 @@ struct lws;
 #if defined(LWS_WITH_FILE_OPS)
 #include <libwebsockets/lws-vfs.h>
 #endif
+#include <libwebsockets/lws-gencrypto.h>
+
 #include <libwebsockets/lws-lejp.h>
+#include <libwebsockets/lws-lecp.h>
+#include <libwebsockets/lws-cose.h>
 #include <libwebsockets/lws-struct.h>
 #include <libwebsockets/lws-threadpool.h>
 #include <libwebsockets/lws-tokenize.h>
@@ -638,7 +658,6 @@ struct lws;
 #include <mbedtls/sha512.h>
 #endif
 
-#include <libwebsockets/lws-gencrypto.h>
 #include <libwebsockets/lws-genhash.h>
 #include <libwebsockets/lws-genrsa.h>
 #include <libwebsockets/lws-genaes.h>
diff --git a/third-party/prebuilt/include/libwebsockets/lws-cache-ttl.h b/third-party/prebuilt/include/libwebsockets/lws-cache-ttl.h
new file mode 100644 (file)
index 0000000..9942dc7
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup lws_cache_ttl Cache supporting expiry
+ * ##Cache supporting expiry
+ *
+ * These apis let you quickly and reliably implement caches of named objects,
+ * that have a "destroy-by date" and cache limits that will be observed.
+ *
+ * You can instantiate as many caches as you need.  The first one must be an
+ * L1 / heap cache type, it can have parents and grandparents of other types
+ * which are accessible why writing / looking up and getting from the L1 cache.
+ * The outer "cache" layer may persistently store items to a backing store.
+ *
+ * Allocated object memory is entirely for the use of user code, up to the
+ * requested size.
+ *
+ * The key name for the listed objects may be any string chosen by the user,
+ * there is no special length limit as it is also allocated.
+ *
+ * Both expiry and LRU orderings are kept so it is easy to find out usage
+ * ordering and when the next object that will expire.
+ *
+ * Cached objects may be destroyed any time you go around the event loop, when
+ * you allocate new objects (to keep the whole cache under the specified limit),
+ * or when their expiry time arrives.  So you shouldn't keep copies of pointers
+ * to cached objects after returning to the event loop.
+ */
+///@{
+
+
+struct lws_cache_ttl_lru;
+
+/**
+ * lws_cache_write_through() - add a new cache item object in all layers
+ *
+ * \param cache: the existing cache to allocate the object in
+ * \param specific_key: a key string that identifies the item in the cache
+ * \param source: optional payload for the cached item, NULL means caller will
+ *               write the payload
+ * \param size: the size of the object to allocate
+ * \param expiry: the usec time that the object will autodestroy
+ * \param ppay: NULL, or a pointer to a void * to be set to the L1 payload
+ *
+ * If an item with the key already exists, it is destroyed before allocating a
+ * new one.
+ *
+ * Returns 0 if successful.  The written entry will be scheduled to be auto-
+ * destroyed when \p expiry occurs.
+ *
+ * Adding or removing cache items may cause invalidation of cached queries.
+ */
+LWS_VISIBLE LWS_EXTERN int /* only valid until return to event loop */
+lws_cache_write_through(struct lws_cache_ttl_lru *cache,
+                       const char *specific_key, const uint8_t *source,
+                       size_t size, lws_usec_t expiry, void **ppay);
+
+typedef struct lws_cache_match {
+       lws_dll2_t                      list;
+       lws_usec_t                      expiry;
+       /* earliest expiry amongst results */
+       size_t                          payload_size;
+       /**< the payload is not attached here.  This is a hint about what
+        * (*get)() will return for this tag name.
+        */
+       size_t                          tag_size;
+
+       /* tag name + NUL is overcommitted */
+} lws_cache_match_t;
+
+/**
+ * lws_cache_heap_lookup() - get a list of matching items
+ *
+ * \param cache: the cache to search for the key
+ * \param wildcard_key: the item key string, may contain wildcards
+ * \param pdata: pointer to pointer to be set to the serialized result list
+ * \param psize: pointer to size_t to receive length of serialized result list
+ *
+ * This finds all unique items in the final cache that match search_key, which
+ * may contain wildcards.  It does not return the payloads for matching items,
+ * just a list of specific tags in the that match.
+ *
+ * If successful, results are provided in a serialized list format, in no
+ * particular order, each result has the following fields
+ *
+ * - BE32: payload size in bytes (payload itself is not included)
+ * - BE32: specific tag name length in bytes
+ * - chars: tag name with terminating NUL
+ *
+ * These serialized results are themselves cached in L1 cache (only) and the
+ * result pointers are set pointing into that.  If the results are still in L1
+ * cache next time this api is called, the results will be returned directly
+ * from that without repeating the expensive lookup on the backup store.  That
+ * is why the results are provided in serialized form.
+ *
+ * The cached results list expiry is set to the earliest expiry of any listed
+ * item.  Additionally any cached results are invalidated on addition or
+ * deletion (update is done as addition + deletion) of any item that would
+ * match the results' original wildcard_key.  For the typical case new items
+ * are rare compared to lookups, this is efficient.
+ *
+ * Lookup matching does not itself affect LRU or cache status of the result
+ * itsems.  Typically user code will get the lookup results, and then perform
+ * get operations on each item in its desired order, that will bring the items
+ * to the head of the LRU list and occupy L1 cache.
+ *
+ * Returns 0 if proceeded alright, or nonzero if error.  If there was an error,
+ * any partial results set has been deallocated cleanly before returning.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cache_lookup(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
+                const void **pdata, size_t *psize);
+
+/**
+ * lws_cache_item_get() - bring a specific item into L1 and get payload info
+ *
+ * \param cache: the cache to search for the key
+ * \param specific_key: the key string of the item to get
+ * \param pdata: pointer to a void * to be set to the payload in L1 cache
+ * \param psize: pointer to a size_t to be set to the payload size
+ *
+ * If the cache still has an item matching the key string, it will be destroyed.
+ *
+ * Adding or removing cache items may cause invalidation of cached queries.
+ *
+ * Notice the cache payload is a blob of the given size.  If you are storing
+ * strings, there is no NUL termination unless you stored them with it.
+ *
+ * Returns 0 if successful.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cache_item_get(struct lws_cache_ttl_lru *cache, const char *specific_key,
+                  const void **pdata, size_t *psize);
+
+/**
+ * lws_cache_item_remove() - remove item from all cache levels
+ *
+ * \param cache: the cache to search for the key
+ * \param wildcard_key: the item key string
+ *
+ * Removes any copy of any item matching the \p wildcard_key from any cache
+ * level in one step.
+ *
+ * Adding or removing cache items may cause invalidation of cached queries
+ * that could refer to the removed item.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cache_item_remove(struct lws_cache_ttl_lru *cache, const char *wildcard_key);
+
+/**
+ * lws_cache_footprint() - query the amount of storage used by the cache layer
+ *
+ * \param cache: cache to query
+ *
+ * Returns number of payload bytes stored in cache currently
+ */
+LWS_VISIBLE LWS_EXTERN uint64_t
+lws_cache_footprint(struct lws_cache_ttl_lru *cache);
+
+/**
+ * lws_cache_debug_dump() - if built in debug mode dump cache contents to log
+ *
+ * \param cache: cache to dump
+ *
+ * If lws was built in debug mode, dump cache to log, otherwise a NOP.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_cache_debug_dump(struct lws_cache_ttl_lru *cache);
+
+typedef struct lws_cache_results {
+       const uint8_t           *ptr; /* set before using walk api */
+       size_t                  size; /* set before using walk api */
+
+       size_t                  payload_len;
+       size_t                  tag_len;
+       const uint8_t           *tag;
+} lws_cache_results_t;
+
+/**
+ * lws_cache_results_walk() - parse next result
+ *
+ * \param walk_ctx: the context of the results blob to walk
+ *
+ * Caller must initialize \p walk_ctx.ptr and \p walk_ctx.size before calling.
+ * These are set to the results returned from a _lookup api call.
+ *
+ * The call returns 0 if the struct elements have been set to a result, or 1
+ * if there where no more results in the blob to walk.
+ *
+ * If successful, after the call \p payload_len is set to the length of the
+ * payload related to this result key (the payload itself is not present),
+ * \p tag_len is set to the length of the result key name, and \p tag is set
+ * to the result tag name, with a terminating NUL.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cache_results_walk(lws_cache_results_t *walk_ctx);
+
+typedef void (*lws_cache_item_destroy_cb)(void *item, size_t size);
+struct lws_cache_creation_info {
+       struct lws_context              *cx;
+       /**< Mandatory: the lws_context */
+       const char                      *name;
+       /**< Mandatory: short cache name */
+       lws_cache_item_destroy_cb       cb;
+       /**< NULL, or a callback that can hook cache item destory */
+       struct lws_cache_ttl_lru        *parent;
+       /**< NULL, or next cache level */
+       const struct lws_cache_ops      *ops;
+       /**< NULL for default, heap-based ops, else custom cache storage and
+        * query implementation */
+
+       union {
+               struct {
+                       const char      *filepath;
+                       /**< the filepath to store items in */
+               } nscookiejar;
+       } u;
+       /**< these are extra configuration for specific cache types */
+
+       size_t                          max_footprint;
+       /**< 0, or the max heap allocation allowed before destroying
+        *   lru items to keep it under the limit */
+       size_t                          max_items;
+       /**< 0, or the max number of items allowed in the cache before
+        *   destroying lru items to keep it under the limit */
+       size_t                          max_payload;
+       /**< 0, or the max allowed payload size for one item */
+       int                             tsi;
+       /**< 0 unless using SMP, then tsi to bind sul to */
+};
+
+struct lws_cache_ops {
+       struct lws_cache_ttl_lru *
+       (*create)(const struct lws_cache_creation_info *info);
+       /**< create an instance of the cache type specified in info */
+
+       void
+       (*destroy)(struct lws_cache_ttl_lru **_cache);
+       /**< destroy the logical cache instance pointed to by *_cache, doesn't
+        * affect any NV backing storage */
+
+       int
+       (*expunge)(struct lws_cache_ttl_lru *cache);
+       /**< completely delete any backing storage related to the cache
+        * instance, eg, delete the backing file */
+
+       int
+       (*write)(struct lws_cache_ttl_lru *cache, const char *specific_key,
+                const uint8_t *source, size_t size, lws_usec_t expiry,
+                void **ppvoid);
+       /**< create an entry in the cache level according to the given info */
+       int
+       (*tag_match)(struct lws_cache_ttl_lru *cache, const char *wc,
+                    const char *tag, char lookup_rules);
+       /**< Just tell us if tag would match wildcard, using whatever special
+        * rules the backing store might use for tag matching.  0 indicates
+        * it is a match on wildcard, nonzero means does not match.
+        */
+       int
+       (*lookup)(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
+                     lws_dll2_owner_t *results_owner);
+       /**+ add keys for search_key matches not already listed in the results
+        * owner */
+       int
+       (*invalidate)(struct lws_cache_ttl_lru *cache, const char *wildcard_key);
+       /**< remove matching item(s) from cache level */
+
+       int
+       (*get)(struct lws_cache_ttl_lru *cache, const char *specific_key,
+              const void **pdata, size_t *psize);
+       /**< if it has the item, fills L1 with item. updates LRU, and returns
+        * pointer to payload in L1 */
+
+       void
+       (*debug_dump)(struct lws_cache_ttl_lru *cache);
+       /**< Helper to dump the whole cache contents to log, useful for debug */
+};
+
+/**
+ * lws_cache_create() - create an empty cache you can allocate items in
+ *
+ * \param info: a struct describing the cache to create
+ *
+ * Create an empty cache you can allocate items in.  The cache will be kept
+ * below the max_footprint and max_items limits if they are nonzero, by
+ * destroying least-recently-used items until it remains below the limits.
+ *
+ * Items will auto-destroy when their expiry time is reached.
+ *
+ * When items are destroyed from the cache, if \p cb is non-NULL, it will be
+ * called back with the item pointer after it has been removed from the cache,
+ * but before it is deallocated and destroyed.
+ *
+ * context and tsi are used when scheduling expiry callbacks
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_cache_ttl_lru *
+lws_cache_create(const struct lws_cache_creation_info *info);
+
+/**
+ * lws_cache_destroy() - destroy a previously created cache
+ *
+ * \param cache: pointer to the cache
+ *
+ * Everything in the cache is destroyed, then the cache itself is destroyed,
+ * and *cache set to NULL.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_cache_destroy(struct lws_cache_ttl_lru **cache);
+
+/**
+ * lws_cache_expunge() - destroy all items in cache and parents
+ *
+ * \param cache: pointer to the cache
+ *
+ * Everything in the cache and parents is destroyed, leaving it empty.
+ * If the cache has a backing store, it is deleted.
+ *
+ * Returns 0 if no problems reported at any cache layer, else nonzero.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cache_expunge(struct lws_cache_ttl_lru *cache);
+
+LWS_VISIBLE extern const struct lws_cache_ops lws_cache_ops_heap,
+                                             lws_cache_ops_nscookiejar;
+
+///@}
+
index 7a78262..62848fa 100644 (file)
@@ -878,8 +878,13 @@ enum lws_callback_reasons {
         * close the wsi.
         */
        LWS_CALLBACK_MQTT_RESEND                                = 210,
-       /**< In QoS1, this callback is generated instead of the _ACK one if
-        * we timed out waiting for a PUBACK and we must resend the message.
+       /**< In QoS1 or QoS2, this callback is generated instead of the _ACK one
+        * if we timed out waiting for a PUBACK or a PUBREC, and we must resend
+        * the message.  Return nonzero to close the wsi.
+        */
+       LWS_CALLBACK_MQTT_UNSUBSCRIBE_TIMEOUT                   = 211,
+       /**< When a UNSUBSCRIBE is sent, this callback is generated instead of
+        * the _UNSUBSCRIBED one if we timed out waiting for a UNSUBACK.
         * Return nonzero to close the wsi.
         */
 
index 38de897..bb5f2d0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * libwebsockets - small server side websockets and web server implementation
  *
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -93,6 +93,12 @@ enum lws_client_connect_ssl_connection_flags {
        LCCSCF_CONMON                           = (1 << 28),
        /**< If LWS_WITH_CONMON enabled for build, keeps a copy of the
         * getaddrinfo results so they can be queried subsequently */
+       LCCSCF_ACCEPT_TLS_DOWNGRADE_REDIRECTS   = (1 << 29),
+       /**< By default lws rejects https redirecting to http.  Set this
+        * flag on the client connection to allow it. */
+       LCCSCF_CACHE_COOKIES                    = (1 << 30),
+       /**< If built with -DLWS_WITH_CACHE_NSCOOKIEJAR, store and reapply
+        * http cookies in a Netscape Cookie Jar on this connection */
 };
 
 /** struct lws_client_connect_info - parameters to connect with when using
@@ -108,7 +114,8 @@ struct lws_client_connect_info {
        int ssl_connection;
        /**< 0, or a combination of LCCSCF_ flags */
        const char *path;
-       /**< uri path */
+       /**< URI path. Prefix with + for a UNIX socket. (+@ for
+     * a Linux abstract-namespace socket) */
        const char *host;
        /**< content of host header */
        const char *origin;
@@ -216,12 +223,18 @@ struct lws_client_connect_info {
         * connection, allows targeting by "wsi=XXX/..." if you give XXX here.
         */
 
-       uint16_t        keep_warm_secs;
+       uint16_t                                keep_warm_secs;
        /**< 0 means 5s.  If the client connection to the endpoint becomes idle,
         * defer closing it for this many seconds in case another outgoing
         * connection to the same endpoint turns up.
         */
 
+       lws_log_cx_t                            *log_cx;
+       /**< NULL to use lws_context log context, else a pointer to a log
+        * context template to take a copy of for this wsi.  Used to isolate
+        * wsi-specific logs into their own stream or file.
+        */
+
        /* Add new things just above here ---^
         * This is part of the ABI, don't needlessly break compatibility
         *
@@ -300,6 +313,7 @@ lws_http_client_read(struct lws *wsi, char **buf, int *len);
  * \param wsi: client connection
  *
  * Returns the last server response code, eg, 200 for client http connections.
+ * If there is no valid response, it will return 0.
  *
  * You should capture this during the LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP
  * callback, because after that the memory reserved for storing the related
index 2e25f8c..12a0eec 100644 (file)
@@ -31,7 +31,7 @@
  */
 ///@{
 
-/* enough for 4191us, or just over an hour */
+/* enough for 4191s, or just over an hour */
 typedef uint32_t lws_conmon_interval_us_t;
 
 /*
@@ -44,18 +44,56 @@ typedef uint32_t lws_conmon_interval_us_t;
  *     {
  *        "peer": "46.105.127.147",
  *        "dns_us": 1234,
+ *        "dns_disp": 1,
  *        "sockconn_us": 1234,
  *        "tls_us": 1234,
  *        "txn_resp_us": 1234,
- *        "dns":["46.105.127.147", "2001:41d0:2:ee93::1"]
+ *        "dns":["46.105.127.147", "2001:41d0:2:ee93::1"],
+ *        "prot_specific": {
+ *             "protocol": "http",
+ *             "resp": 200
+ *        }
  *      }
+ *
+ * The indexes in "dns_disp" are declared in lws_conmon_dns_disposition_t
+ * below.
+ *
+ * "prot_specific" may not be present if the protocol doesn't have anything
+ * to report or is not supported.
  */
 
+typedef enum lws_conmon_pcol {
+       LWSCONMON_PCOL_NONE,
+       LWSCONMON_PCOL_HTTP, /* .protocol_specific.http is valid */
+} lws_conmon_pcol_t;
+
+typedef enum lws_conmon_dns_disposition {
+       LWSCONMON_DNS_NONE,
+       /**< did not attempt DNS */
+       LWSCONMON_DNS_OK                                = 1,
+       /**< DNS lookup did give results */
+       LWSCONMON_DNS_SERVER_UNREACHABLE                = 2,
+       /**< DNS server was not reachable */
+       LWSCONMON_DNS_NO_RESULT                         = 3
+       /**< DNS server replied but nothing usable */
+} lws_conmon_dns_disposition_t;
+
 struct lws_conmon {
        lws_sockaddr46                          peer46;
        /**< The peer we actually connected to, if any.  .peer46.sa4.sa_family
         * is either 0 if invalid, or the AF_ */
 
+       union {
+               struct {
+                       int     response;
+                       /**< h1 http response code */
+               } http;
+       } protocol_specific;
+       /**< possibly-present protocol-specific additional information.  This
+        * is only valid for the first transaction after connection and does
+        * not capture results for persistent or muxed connections like ws
+        * messages, mqtt messages, or h2 streams */
+
        struct addrinfo                         *dns_results_copy;
        /**< NULL, or Allocated copy of dns results, owned by this object and
         * freed when object destroyed.
@@ -72,7 +110,15 @@ struct lws_conmon {
        /**< 0 if no tls, or us taken to establish the tls tunnel */
        lws_conmon_interval_us_t                ciu_txn_resp;
        /**< 0, or if the protocol supports transactions, the interval between
-        * sending the transaction request and starting to receive the resp */
+        * sending the initial transaction request and starting to receive the
+        * response */
+
+       lws_conmon_pcol_t                       pcol;
+       /**< indicates which extra protocol_specific info member is valid,
+        *   if any */
+
+       lws_conmon_dns_disposition_t            dns_disposition;
+       /**< indicates general disposition of DNS request */
 };
 
 /**
index ee7d57d..b3de140 100644 (file)
@@ -453,6 +453,8 @@ struct lws_context_creation_info {
        int simultaneous_ssl_restriction;
        /**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions
         * possible.*/
+       int simultaneous_ssl_handshake_restriction;
+       /**< CONTEXT: 0 (no limit) or limit of simultaneous SSL handshakes ongoing */
        int ssl_info_event_mask;
        /**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO
         * callback for connections on this vhost.  The mask values are of
@@ -536,6 +538,17 @@ struct lws_context_creation_info {
          * implementation for the one provided by provided_ssl_ctx.
          * Libwebsockets no longer is responsible for freeing the context
          * if this option is selected. */
+#else /* WITH_MBEDTLS */
+       const char *mbedtls_client_preload_filepath;
+       /**< CONTEXT: If NULL, no effect.  Otherwise it should point to a
+        * filepath where every created client SSL_CTX is preloaded from the
+        * system trust bundle.
+        *
+        * This sets a processwide variable that affects all contexts.
+        *
+        * Requires that the mbedtls provides mbedtls_x509_crt_parse_file(),
+        * else disabled.
+        */
 #endif
 #endif
 
@@ -621,7 +634,10 @@ struct lws_context_creation_info {
        const char *vhost_name;
        /**< VHOST: name of vhost, must match external DNS name used to
         * access the site, like "warmcat.com" as it's used to match
-        * Host: header and / or SNI name for SSL. */
+        * Host: header and / or SNI name for SSL.
+        * CONTEXT: NULL, or the name to associate with the context for
+        * context-specific logging
+        */
 #if defined(LWS_WITH_PLUGINS)
        const char * const *plugin_dirs;
        /**< CONTEXT: NULL, or NULL-terminated array of directories to
@@ -843,16 +859,60 @@ struct lws_context_creation_info {
 
 #if defined(LWS_WITH_SYS_METRICS)
        const struct lws_metric_policy          *metrics_policies;
-       /**< non-SS policy metrics policies */
+       /**< CONTEXT: non-SS policy metrics policies */
        const char                              *metrics_prefix;
-       /**< prefix for this context's metrics, used to distinguish metrics
-        * pooled from different processes / applications, so, eg what would
-        * be "cpu.svc" if this is NULL becomes "myapp.cpu.svc" is this is
+       /**< CONTEXT: prefix for this context's metrics, used to distinguish
+        * metrics pooled from different processes / applications, so, eg what
+        * would be "cpu.svc" if this is NULL becomes "myapp.cpu.svc" is this is
         * set to "myapp".  Policies are applied using the name with the prefix,
         * if present.
         */
 #endif
 
+       int                                     fo_listen_queue;
+       /**< VHOST: 0 = no TCP_FASTOPEN, nonzero = enable TCP_FASTOPEN if the
+        * platform supports it, with the given queue length for the listen
+        * socket.
+        */
+
+       const struct lws_plugin_evlib           *event_lib_custom;
+       /**< CONTEXT: If non-NULL, override event library selection so it uses
+        * this custom event library implementation, instead of default internal
+        * loop.  Don't set any other event lib context creation flags in that
+        * case. it will be used automatically.  This is useful for integration
+        * where an existing application is using its own handrolled event loop
+        * instead of an event library, it provides a way to allow lws to use
+        * the custom event loop natively as if it were an "event library".
+        */
+
+#if defined(LWS_WITH_TLS_JIT_TRUST)
+       size_t                                  jitt_cache_max_footprint;
+       /**< CONTEXT: 0 for no limit, else max bytes used by JIT Trust cache...
+        * LRU items are evicted to keep under this limit */
+       int                                     vh_idle_grace_ms;
+       /**< CONTEXT: 0 for default of 5000ms, or number of ms JIT Trust vhosts
+        * are allowed to live without active connections using them. */
+#endif
+
+       lws_log_cx_t                            *log_cx;
+       /**< CONTEXT: NULL to use the default, process-scope logging context,
+        * else a specific logging context to associate with this context */
+
+#if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT)
+       const char                              *http_nsc_filepath;
+       /**< CONTEXT: Filepath to use for http netscape cookiejar file */
+
+       size_t                                  http_nsc_heap_max_footprint;
+       /**< CONTEXT: 0, or limit in bytes for heap usage of memory cookie
+        * cache */
+       size_t                                  http_nsc_heap_max_items;
+       /**< CONTEXT: 0, or the max number of items allowed in the cookie cache
+        * before destroying lru items to keep it under the limit */
+       size_t                                  http_nsc_heap_max_payload;
+       /**< CONTEXT: 0, or the maximum size of a single cookie we are able to
+        * handle */
+#endif
+
        /* Add new things just above here ---^
         * This is part of the ABI, don't needlessly break compatibility
         *
@@ -1265,13 +1325,7 @@ struct lws_http_mount {
 
        /* Add new things just above here ---^
         * This is part of the ABI, don't needlessly break compatibility
-        *
-        * The below is to ensure later library versions with new
-        * members added above will see 0 (default) even if the app
-        * was not built against the newer headers.
         */
-
-       void *_unused[2]; /**< dummy */
 };
 
 ///@}
diff --git a/third-party/prebuilt/include/libwebsockets/lws-cose.h b/third-party/prebuilt/include/libwebsockets/lws-cose.h
new file mode 100644 (file)
index 0000000..1ea6791
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup cose COSE apis
+ * ##COSE related functions
+ * \ingroup lwsaoi
+ *
+ * COSE RFC 8152 relates to signed and encrypted CBOR
+ */
+//@{
+
+enum {
+       /*  RFC8152: Table 2: Common Header Parameters
+        * https://www.iana.org/assignments/cose/cose.xhtml#header-parameters
+        */
+
+       LWSCOSE_WKL_ALG                         = 1,   /* int / tstr */
+       LWSCOSE_WKL_CRIT,                              /* [+ label ] */
+       LWSCOSE_WKL_CONTENT_TYPE,                      /* tstr / uint */
+       LWSCOSE_WKL_KID,                               /* bstr */
+       LWSCOSE_WKL_IV,                                /* bstr */
+       LWSCOSE_WKL_IV_PARTIAL,                        /* bstr */
+       LWSCOSE_WKL_COUNTERSIG,                        /* COSE sig(s) */
+       LWSCOSE_WKL_COUNTERSIG0                 = 9,   /* bstr */
+       LWSCOSE_WKL_KID_CONTEXT,                       /* bstr */
+       LWSCOSE_WKL_CUPH_NONCE                  = 256, /* bstr */
+       LWSCOSE_WKL_CUPH_OWNER_PUBKEY           = 257, /* array */
+
+       /*  RFC8152: Table 3: key map labels */
+
+       LWSCOSE_WKK_KTY                         = 1, /* int / tstr */
+       LWSCOSE_WKK_KID,                             /* bstr */
+       LWSCOSE_WKK_ALG,                             /* int / tstr */
+       LWSCOSE_WKK_KEY_OPS,                         /* [ + (int / tstr) ] */
+       LWSCOSE_WKK_BASE_IV,                         /* bstr */
+
+       /*  RFC8152: Table 4: Key Operation Values */
+
+       LWSCOSE_WKKO_SIGN                       = 1,
+       LWSCOSE_WKKO_VERIFY,
+       LWSCOSE_WKKO_ENCRYPT,
+       LWSCOSE_WKKO_DECRYPT,
+       LWSCOSE_WKKO_WRAP_KEY,
+       LWSCOSE_WKKO_UNWRAP_KEY,
+       LWSCOSE_WKKO_DERIVE_KEY,
+       LWSCOSE_WKKO_DERIVE_BITS,
+       LWSCOSE_WKKO_MAC_CREATE,
+       LWSCOSE_WKKO_MAC_VERIFY,
+
+       /*  RFC8152: Table 5: ECDSA algs */
+
+       LWSCOSE_WKAECDSA_ALG_ES256              = -7,
+       LWSCOSE_WKAECDSA_ALG_ES384              = -35,
+       LWSCOSE_WKAECDSA_ALG_ES512              = -36,
+
+       /*  RFC8152: Table 6: EDDSA algs */
+
+       LWSCOSE_WKAEDDSA_ALG_EDDSA              = -8,
+
+       /*  RFC8152: Table 7: HMAC algs */
+
+       LWSCOSE_WKAHMAC_256_64                  = 4,
+       LWSCOSE_WKAHMAC_256_256,
+       LWSCOSE_WKAHMAC_384_384,
+       LWSCOSE_WKAHMAC_512_512,
+
+       /*  RFC8152: Table 8: AES algs */
+
+       LWSCOSE_WKAAES_128_64                   = 14,
+       LWSCOSE_WKAAES_256_64,
+       LWSCOSE_WKAAES_128_128                  = 25,
+       LWSCOSE_WKAAES_256_128,
+
+       /*  RFC8152: Table 9: AES GCM algs */
+
+       LWSCOSE_WKAAESGCM_128                   = 1,
+       LWSCOSE_WKAAESGCM_192,
+       LWSCOSE_WKAAESGCM_256,
+
+       /*  RFC8152: Table 10: AES CCM algs */
+
+       LWSCOSE_WKAAESCCM_16_64_128             = 10,
+       LWSCOSE_WKAAESCCM_16_64_256,
+       LWSCOSE_WKAAESCCM_64_64_128,
+       LWSCOSE_WKAAESCCM_64_64_256,
+       LWSCOSE_WKAAESCCM_16_128_128,
+       LWSCOSE_WKAAESCCM_16_128_256,
+       LWSCOSE_WKAAESCCM_64_128_128,
+       LWSCOSE_WKAAESCCM_64_128_256,
+
+       /*  RFC8152: Table 11: CHACHA20 / Poly1305 */
+
+       LWSCOSE_WKACHACHA_POLY1305              = 24,
+
+       /*  RFC8152: Table 13: HKDF param */
+
+       LWSCOSE_WKAPHKDF_SALT                   = -20,
+
+       /* RFC8152: Table 14: Context Algorithm Parameters */
+
+       LWSCOSE_WKAPCTX_PARTY_U_IDENTITY        = -21,
+       LWSCOSE_WKAPCTX_PARTY_U_NONCE           = -22,
+       LWSCOSE_WKAPCTX_PARTY_U_OTHER           = -23,
+       LWSCOSE_WKAPCTX_PARTY_V_IDENTITY        = -24,
+       LWSCOSE_WKAPCTX_PARTY_V_NONCE           = -25,
+       LWSCOSE_WKAPCTX_PARTY_V_OTHER           = -26,
+
+       /* RFC8152: Table 15: Direct key */
+
+       LWSCOSE_WKK_DIRECT_CEK                  = -6,
+
+       /* RFC8152: Table 16: Direct key with KDF */
+
+       LWSCOSE_WKK_DIRECT_HKDF_SHA_256         = -10,
+       LWSCOSE_WKK_DIRECT_HKDF_SHA_512         = -11,
+       LWSCOSE_WKK_DIRECT_HKDF_AES_128         = -12,
+       LWSCOSE_WKK_DIRECT_HKDF_AES_256         = -13,
+
+       /* RFC8152: Table 17: AES Key Wrap Algorithm Values */
+
+       LWSCOSE_WKK_DIRECT_HKDFKW_SHA_256       = -3,
+       LWSCOSE_WKK_DIRECT_HKDFKW_SHA_512       = -4,
+       LWSCOSE_WKK_DIRECT_HKDFKW_AES_128       = -5,
+
+       /* RFC8152: Table 18: ECDH Algorithm Values */
+
+       LWSCOSE_WKAECDH_ALG_ES_HKDF_256         = -25,
+       LWSCOSE_WKAECDH_ALG_ES_HKDF_512         = -26,
+       LWSCOSE_WKAECDH_ALG_SS_HKDF_256         = -27,
+       LWSCOSE_WKAECDH_ALG_SS_HKDF_512         = -28,
+
+       /* RFC8152: Table 19: ECDH Algorithm Parameters */
+
+       LWSCOSE_WKAPECDH_EPHEMERAL_KEY          = -1,
+       LWSCOSE_WKAPECDH_STATIC_KEY             = -2,
+       LWSCOSE_WKAPECDH_STATIC_KEY_ID          = -3,
+
+       /* RFC8152: Table 20: ECDH Algorithm Parameters with key wrap */
+
+       LWSCOSE_WKAPECDH_ES_A128KW              = -29,
+       LWSCOSE_WKAPECDH_ES_A192KW              = -30,
+       LWSCOSE_WKAPECDH_ES_A256KW              = -31,
+       LWSCOSE_WKAPECDH_SS_A128KW              = -32,
+       LWSCOSE_WKAPECDH_SS_A192KW              = -33,
+       LWSCOSE_WKAPECDH_SS_A256KW              = -34,
+
+       /* RFC8152: Table 21: Key Type Values
+        *  https://www.iana.org/assignments/cose/cose.xhtml#key-type
+        */
+
+       LWSCOSE_WKKTV_OKP                       = 1,
+       LWSCOSE_WKKTV_EC2                       = 2,
+       LWSCOSE_WKKTV_RSA                       = 3,
+       LWSCOSE_WKKTV_SYMMETRIC                 = 4,
+       LWSCOSE_WKKTV_HSS_LMS                   = 5,
+       LWSCOSE_WKKTV_WALNUTDSA                 = 6,
+
+
+       /* RFC8152: Table 22: Elliptic Curves
+        * https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
+        */
+
+       LWSCOSE_WKEC_P256                       = 1,
+       LWSCOSE_WKEC_P384,
+       LWSCOSE_WKEC_P521,
+       LWSCOSE_WKEC_X25519,
+       LWSCOSE_WKEC_X448,
+       LWSCOSE_WKEC_ED25519,
+       LWSCOSE_WKEC_ED448,
+       LWSCOSE_WKEC_SECP256K1,
+
+       /* RFC8152: Table 23: EC Key Parameters */
+
+       LWSCOSE_WKECKP_CRV                      = -1,
+       LWSCOSE_WKECKP_X                        = -2,
+       LWSCOSE_WKECKP_Y                        = -3,
+       LWSCOSE_WKECKP_D                        = -4,
+
+       /* RFC8152: Table 24: Octet Key Pair (OKP) Parameters */
+
+       LWSCOSE_WKOKP_CRV                       = -1,
+       LWSCOSE_WKOKP_X                         = -2,
+       LWSCOSE_WKOKP_D                         = -4,
+
+       /* Additional from
+        * https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters
+        */
+
+       LWSCOSE_WKKPRSA_N                       = -1,
+       LWSCOSE_WKKPRSA_E                       = -2,
+       LWSCOSE_WKKPRSA_D                       = -3,
+       LWSCOSE_WKKPRSA_P                       = -4,
+       LWSCOSE_WKKPRSA_Q                       = -5,
+       LWSCOSE_WKKPRSA_DP                      = -6,
+       LWSCOSE_WKKPRSA_DQ                      = -7,
+       LWSCOSE_WKKPRSA_QINV                    = -8,
+       LWSCOSE_WKKPRSA_OTHER                   = -9,
+       LWSCOSE_WKKPRSA_RI                      = -10,
+       LWSCOSE_WKKPRSA_DI                      = -11,
+       LWSCOSE_WKKPRSA_TI                      = -12,
+
+       /* RFC8152: Table 25: Symmetric Key Parameters */
+
+       LWSCOSE_WKSYMKP_KEY_VALUE               = 4,
+
+       /* RFC8152: Table 26: CoAP Content-Formats for COSE */
+
+       LWSCOAP_CONTENTFORMAT_COSE_SIGN         = 98,
+       LWSCOAP_CONTENTFORMAT_COSE_SIGN1        = 18,
+       LWSCOAP_CONTENTFORMAT_COSE_ENCRYPT      = 96,
+       LWSCOAP_CONTENTFORMAT_COSE_ENCRYPT0     = 16,
+       LWSCOAP_CONTENTFORMAT_COSE_MAC          = 97,
+       LWSCOAP_CONTENTFORMAT_COSE_MAC0         = 17,
+       LWSCOAP_CONTENTFORMAT_COSE_KEY          = 101,
+       LWSCOAP_CONTENTFORMAT_COSE_KEY_SET      = 102,
+
+       /* RFC8152: Table 27: Header Parameter for CounterSignature0 */
+
+       LWSCOSE_WKL_COUNTERSIGNATURE0           = 9, /* bstr */
+
+       /* RFC8812: Table 1: RSASSA-PKCS1-v1_5 Algorithm Values */
+
+       LWSCOSE_WKARSA_ALG_RS256                = -257, /* + SHA-256 */
+       LWSCOSE_WKARSA_ALG_RS384                = -258, /* + SHA-384 */
+       LWSCOSE_WKARSA_ALG_RS512                = -259, /* + SHA-512 */
+};
+
+enum enum_cose_key_meta_tok {
+       COSEKEY_META_KTY,
+       COSEKEY_META_KID,
+       COSEKEY_META_KEY_OPS,
+       COSEKEY_META_BASE_IV,
+       COSEKEY_META_ALG,
+
+       LWS_COUNT_COSE_KEY_ELEMENTS
+};
+
+typedef int64_t cose_param_t;
+
+LWS_VISIBLE LWS_EXTERN const char *
+lws_cose_alg_to_name(cose_param_t alg);
+
+LWS_VISIBLE LWS_EXTERN cose_param_t
+lws_cose_name_to_alg(const char *name);
+
+/*
+ * cose_key
+ */
+
+typedef struct lws_cose_key {
+       /* key data elements */
+       struct lws_gencrypto_keyelem    e[LWS_GENCRYPTO_MAX_KEYEL_COUNT];
+       /* generic meta key elements, like KID */
+       struct lws_gencrypto_keyelem    meta[LWS_COUNT_COSE_KEY_ELEMENTS];
+       lws_dll2_t                      list; /* used when part of a set */
+       int                             gencrypto_kty;  /**< one of LWS_GENCRYPTO_KTY_ */
+       cose_param_t                    kty;
+       cose_param_t                    cose_alg;
+       cose_param_t                    cose_curve;
+       char                            private_key; /* nonzero = has private key elements */
+} lws_cose_key_t;
+
+typedef int (*lws_cose_key_import_callback)(struct lws_cose_key *s, void *user);
+
+/** lws_cose_jwk_import() - Create an lws_cose_key_t object from cose_key CBOR
+ *
+ * \param pkey_set: NULL, or a pointer to an lws_dll2_owner_t for a cose_key set
+ * \param cb: callback for each jwk-processed key, or NULL if importing a single
+ *           key with no parent "keys" JSON
+ * \param user: pointer to be passed to the callback, otherwise ignored by lws.
+ *             NULL if importing a single key with no parent "keys" JSON
+ * \param in: a single cose_key
+ * \param len: the length of the cose_key in bytes
+ *
+ * Creates a single lws_cose_key_t if \p pkey_set is NULL or if the incoming
+ * CBOR doesn't start with an array, otherwise expects a CBOR array containing
+ * zero or more cose_key CBOR, and adds each to the \p pkey_set
+ * lws_dll2_owner_t struct.  Created lws_cose_key_t are filled with data from
+ * the COSE representation and can be used with other COSE crypto ops.
+ */
+LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
+lws_cose_key_import(lws_dll2_owner_t *pkey_set, lws_cose_key_import_callback cb,
+                   void *user, const uint8_t *in, size_t len);
+
+/** lws_cose_key_export() - Create cose_key CBOR from an lws_cose_key_t
+ *
+ * \param ck: the lws_cose_key_t to export to CBOR
+ * \param ctx: the CBOR writing context (same as for lws_lec_printf())
+ * \param flags: 0 to export only public elements, or LWSJWKF_EXPORT_PRIVATE
+ *
+ * Creates an lws_jwk struct filled with data from the COSE representation.
+ */
+LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
+lws_cose_key_export(lws_cose_key_t *ck, lws_lec_pctx_t *ctx, int flags);
+
+/**
+ * lws_cose_key_generate() - generate a fresh key
+ *
+ * \param context: the lws_context used to get random
+ * \param cose_kty: one of LWSCOSE_WKKTV_ indicating the well-known key type
+ * \param use_mask: 0, or a bitfield where (1 << LWSCOSE_WKKO_...) set means valid for use
+ * \param bits: key bits for RSA
+ * \param curve: for EC keys, one of "P-256", "P-384" or "P-521" currently
+ * \param kid: string describing the key, or NULL
+ *
+ * Create an lws_cose_key_t of the specified type and return it
+ */
+LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
+lws_cose_key_generate(struct lws_context *context, cose_param_t cose_kty,
+                     int use_mask, int bits, const char *curve,
+                     const uint8_t *kid, size_t kl);
+
+LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
+lws_cose_key_from_set(lws_dll2_owner_t *set, const uint8_t *kid, size_t kl);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cose_key_destroy(lws_cose_key_t **ck);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cose_key_set_destroy(lws_dll2_owner_t *o);
+
+/* only available in _DEBUG build */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cose_key_dump(const lws_cose_key_t *ck);
+
+/*
+ * cose_sign
+ */
+
+struct lws_cose_validate_context;
+
+
+enum lws_cose_sig_types {
+       SIGTYPE_UNKNOWN,
+       SIGTYPE_MULTI,
+       SIGTYPE_SINGLE,
+       SIGTYPE_COUNTERSIGNED, /* not yet supported */
+       SIGTYPE_MAC, /* only supported for validation */
+       SIGTYPE_MAC0,
+};
+
+/* a list of these result objects is the output of the validation process */
+
+typedef struct {
+       lws_dll2_t              list;
+
+       const lws_cose_key_t    *cose_key;
+       cose_param_t            cose_alg;
+
+       int                     result; /* 0 = validated */
+
+} lws_cose_validate_res_t;
+
+enum {
+       LCOSESIGEXTCB_RET_FINISHED,
+       LCOSESIGEXTCB_RET_AGAIN,
+       LCOSESIGEXTCB_RET_ERROR         = -1
+};
+
+typedef struct {
+       struct lws_cose_validate_context *cps;
+       const uint8_t                    *ext;
+       size_t                           xl;
+} lws_cose_sig_ext_pay_t;
+
+typedef int (*lws_cose_sign_ext_pay_cb_t)(lws_cose_sig_ext_pay_t *x);
+typedef int (*lws_cose_validate_pay_cb_t)(struct lws_cose_validate_context *cps,
+                                         void *opaque, const uint8_t *paychunk,
+                                         size_t paychunk_len);
+
+typedef struct lws_cose_validate_create_info {
+       struct lws_context              *cx;
+       /**< REQUIRED: the lws context */
+       lws_dll2_owner_t                *keyset;
+       /**< REQUIRED: one or more cose_keys */
+
+       enum lws_cose_sig_types         sigtype;
+       /**<  0 if a CBOR tag is in the sig, else one of SIGTYPE_MULTI,
+        * SIGTYPE_SINGLE, etc*/
+
+       lws_cose_validate_pay_cb_t      pay_cb;
+       /**< optional: called back with unvalidated payload pieces */
+       void                            *pay_opaque;
+       /**< optional: passed into pay_cb callback along with payload chunk */
+
+       lws_cose_sign_ext_pay_cb_t      ext_cb;
+       /**< optional extra application data provision callback */
+       void                            *ext_opaque;
+       /**< optional extra application data provision callback opaque */
+       size_t                          ext_len;
+       /**< if we have extra app data, this must be set to the length of it */
+} lws_cose_validate_create_info_t;
+
+/**
+ * lws_cose_validate_create() - create a signature validation context
+ *
+ * \param info: struct describing the validation context to create
+ *
+ * Creates a signature validation context set up as described in \p info.
+ *
+ * You can then pass the signature cbor chunks to it using
+ * lws_cose_validate_chunk(), finialize and get the results list using
+ * lws_cose_validate_results() and destroy with lws_cose_validate_destroy().
+ */
+LWS_VISIBLE LWS_EXTERN struct lws_cose_validate_context *
+lws_cose_validate_create(const lws_cose_validate_create_info_t *info);
+
+/**
+ * lws_cose_validate_chunk() - passes chunks of CBOR into the signature validator
+ *
+ * \param cps: the validation context
+ * \param in: the chunk of CBOR (does not have to be logically complete)
+ * \param in_len: number of bytes available at \p in
+ *
+ * Parses signature CBOR to produce a list of result objects.
+ *
+ *
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_cose_validate_chunk(struct lws_cose_validate_context *cps,
+                       const uint8_t *in, size_t in_len, size_t *used_in);
+
+LWS_VISIBLE LWS_EXTERN lws_dll2_owner_t *
+lws_cose_validate_results(struct lws_cose_validate_context *cps);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cose_validate_destroy(struct lws_cose_validate_context **cps);
+
+struct lws_cose_sign_context;
+
+#define LCSC_FL_ADD_CBOR_TAG           (1 << 0)
+#define LCSC_FL_ADD_CBOR_PREFER_MAC0   (1 << 1)
+
+typedef struct lws_cose_sign_create_info {
+       struct lws_context              *cx;
+       /**< REQUIRED: the lws context */
+       lws_dll2_owner_t                *keyset;
+       /**< REQUIRED: one or more cose_keys */
+
+       lws_lec_pctx_t                  *lec;
+       /**< REQUIRED: the cbor output context to emit to, user must
+        * initialize with lws_lec_init() beforehand */
+
+       lws_cose_sign_ext_pay_cb_t      ext_cb;
+       /**< optional extra application data provision callback */
+       void                            *ext_opaque;
+       /**< optional extra application data provision callback opaque */
+       size_t                          ext_len;
+       /**< if we have extra app data, this must be set to the length of it */
+
+       size_t                          inline_payload_len;
+       /**< REQUIRED: size of the inline payload we will provide */
+
+       int                             flags;
+       /**< bitmap of  LCSC_FL_* */
+       enum lws_cose_sig_types         sigtype;
+       /**< 0, or sign type hint */
+} lws_cose_sign_create_info_t;
+
+/**
+ * lws_cose_sign_create() - Create a signing context
+ *
+ * \param info: a structure describing the signing context you want to create
+ *
+ * This allocates and returns a signing context created according to what is in
+ * the \p info parameter.
+ *
+ * \p info must be prepared with the lws_context, a keyset to use, a CBOR
+ * output context, and the inline payload length.
+ *
+ * Returns NULL on failure or the created signing context ready to add alg(s)
+ * to.
+ */
+
+LWS_VISIBLE LWS_EXTERN struct lws_cose_sign_context *
+lws_cose_sign_create(const lws_cose_sign_create_info_t *info);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_cose_sign_add(struct lws_cose_sign_context *csc, cose_param_t alg,
+                 const lws_cose_key_t *ck);
+
+LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
+lws_cose_sign_payload_chunk(struct lws_cose_sign_context *csc,
+                           const uint8_t *in, size_t in_len);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_cose_sign_destroy(struct lws_cose_sign_context **csc);
+
+//@}
index 478aa43..14f0fcd 100644 (file)
@@ -228,9 +228,11 @@ lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner);
 LWS_VISIBLE LWS_EXTERN void
 lws_dll2_remove(struct lws_dll2 *d);
 
+typedef int (*lws_dll2_foreach_cb_t)(struct lws_dll2 *d, void *user);
+
 LWS_VISIBLE LWS_EXTERN int
 lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,
-                     int (*cb)(struct lws_dll2 *d, void *user));
+                     lws_dll2_foreach_cb_t cb);
 
 LWS_VISIBLE LWS_EXTERN void
 lws_dll2_clear(struct lws_dll2 *d);
index 87c4085..5d01caa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * libwebsockets - small server side websockets and web server implementation
  *
- * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
  * IN THE SOFTWARE.
  *
  * These are exports needed by event lib plugins.
- *
- * You should consider these opaque for normal user code.
  */
 
+enum lws_event_lib_ops_flags {
+       LELOF_ISPOLL                            = (1 >> 0),
+       LELOF_DESTROY_FINAL                     = (1 >> 1),
+};
+
+enum {
+       LWS_EV_READ                             = (1 << 0),
+       LWS_EV_WRITE                            = (1 << 1),
+       LWS_EV_START                            = (1 << 2),
+       LWS_EV_STOP                             = (1 << 3),
+};
+
+struct lws_event_loop_ops {
+       const char *name;
+       /* event loop-specific context init during context creation */
+       int (*init_context)(struct lws_context *context,
+                           const struct lws_context_creation_info *info);
+       /* called during lws_destroy_context */
+       int (*destroy_context1)(struct lws_context *context);
+       /* called during lws_destroy_context2 */
+       int (*destroy_context2)(struct lws_context *context);
+       /* init vhost listening wsi */
+       int (*init_vhost_listen_wsi)(struct lws *wsi);
+       /* init the event loop for a pt */
+       int (*init_pt)(struct lws_context *context, void *_loop, int tsi);
+       /* called at end of first phase of close_free_wsi()  */
+       int (*wsi_logical_close)(struct lws *wsi);
+       /* return nonzero if client connect not allowed  */
+       int (*check_client_connect_ok)(struct lws *wsi);
+       /* close handle manually  */
+       void (*close_handle_manually)(struct lws *wsi);
+       /* event loop accept processing  */
+       int (*sock_accept)(struct lws *wsi);
+       /* control wsi active events  */
+       void (*io)(struct lws *wsi, unsigned int flags);
+       /* run the event loop for a pt */
+       void (*run_pt)(struct lws_context *context, int tsi);
+       /* called before pt is destroyed */
+       void (*destroy_pt)(struct lws_context *context, int tsi);
+       /* called just before wsi is freed  */
+       void (*destroy_wsi)(struct lws *wsi);
+       /* return nonzero if caller thread is not loop service thread  */
+       int (*foreign_thread)(struct lws_context *context, int tsi);
+
+       uint8_t flags;
+
+       uint16_t        evlib_size_ctx;
+       uint16_t        evlib_size_pt;
+       uint16_t        evlib_size_vh;
+       uint16_t        evlib_size_wsi;
+};
+
+LWS_VISIBLE LWS_EXTERN void *
+lws_evlib_wsi_to_evlib_pt(struct lws *wsi);
+
+LWS_VISIBLE LWS_EXTERN void *
+lws_evlib_tsi_to_evlib_pt(struct lws_context *ctx, int tsi);
+
+ /*
+  * You should consider these opaque for normal user code.
+  */
+
 LWS_VISIBLE LWS_EXTERN void *
 lws_realloc(void *ptr, size_t size, const char *reason);
 
@@ -36,6 +96,10 @@ LWS_VISIBLE LWS_EXTERN void
 lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
                   const char *caller);
 
+LWS_VISIBLE LWS_EXTERN int
+lws_vhost_foreach_listen_wsi(struct lws_context *cx, void *arg,
+                            lws_dll2_foreach_cb_t cb);
+
 struct lws_context_per_thread;
 LWS_VISIBLE LWS_EXTERN void
 lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
index 6f8e1aa..e913376 100644 (file)
@@ -72,6 +72,7 @@ enum {
        LWSFI_PROBABILISTIC,    /* .pre % chance of injection */
        LWSFI_PATTERN,          /* use .count bits in .pattern after .pre */
        LWSFI_PATTERN_ALLOC,    /* as _PATTERN, but .pattern is malloc'd */
+       LWSFI_RANGE             /* pick a number between pre and count */
 };
 
 typedef struct lws_fi {
@@ -109,6 +110,27 @@ LWS_VISIBLE LWS_EXTERN int
 lws_fi(const lws_fi_ctx_t *fic, const char *fi_name);
 
 /**
+ * lws_fi_range() - get a random number from a range
+ *
+ * \param fic: fault injection tracking context
+ * \param fi_name: name of fault injection
+ * \param result: points to uint64_t to be set to the result
+ *
+ * This lets you get a random number from an externally-set range, set using a
+ * fault injection syntax like "myfault(123..456)".  That will cause us to
+ * return a number between those two inclusive, from the seeded PRNG.
+ *
+ * This is useful when you used lws_fi() with its own fault name to decide
+ * whether to inject the fault, and then the code to cause the fault needs
+ * additional constrained pseudo-random fuzzing for, eg, delays before issuing
+ * the fault.
+ *
+ * Returns 0 if \p *result is set, else nonzero for failure.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_fi_range(const lws_fi_ctx_t *fic, const char *name, uint64_t *result);
+
+/**
  * lws_fi_add() - add an allocated copy of fault injection to a context
  *
  * \param fic: fault injection tracking context
index 644ce89..0018231 100644 (file)
@@ -59,6 +59,13 @@ enum lws_gencrypto_rsa_tok {
        LWS_GENCRYPTO_RSA_KEYEL_DQ,
        LWS_GENCRYPTO_RSA_KEYEL_QI,
 
+       /* we don't actively use these if given, but may come from COSE */
+
+       LWS_GENCRYPTO_RSA_KEYEL_OTHER,
+       LWS_GENCRYPTO_RSA_KEYEL_RI,
+       LWS_GENCRYPTO_RSA_KEYEL_DI,
+       LWS_GENCRYPTO_RSA_KEYEL_TI,
+
        LWS_GENCRYPTO_RSA_KEYEL_COUNT
 };
 
@@ -89,10 +96,10 @@ enum lws_gencrypto_aes_tok {
  * type.
  */
 
-struct lws_gencrypto_keyelem {
+typedef struct lws_gencrypto_keyelem {
        uint8_t *buf;
        uint32_t len;
-};
+} lws_gc_elem_t;
 
 
 /**
index ee62abe..5ae1d2f 100644 (file)
@@ -147,7 +147,7 @@ lws_genecdsa_new_keypair(struct lws_genec_ctx *ctx, const char *curve_name,
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_genecdsa_set_key(struct lws_genec_ctx *ctx,
-                    struct lws_gencrypto_keyelem *el);
+                    const struct lws_gencrypto_keyelem *el);
 
 /** lws_genecdsa_hash_sig_verify_jws() - Verifies a JWS ECDSA signature on a given hash
  *
@@ -184,7 +184,7 @@ lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
  * \param sig: pointer to buffer to take signature
  * \param sig_len: length of the buffer (must be >= length of key N)
  *
- * Returns <0 for error, or 0 for success.
+ * Returns <0 for error, or >=0 for success.
  *
  * This creates a JWS ECDSA signature for a hash you already computed and provide.
  *
index 8407d2f..f27c3b9 100644 (file)
@@ -93,7 +93,8 @@ struct lws_genhmac_ctx {
  *
  * \param type:        one of LWS_GENHASH_TYPE_...
  *
- * Returns number of bytes in this type of hash
+ * Returns number of bytes in this type of hash, if the hash type is unknown, it
+ * will return 0.
  */
 LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT
 lws_genhash_size(enum lws_genhash_types type);
@@ -102,7 +103,8 @@ lws_genhash_size(enum lws_genhash_types type);
  *
  * \param type:        one of LWS_GENHASH_TYPE_...
  *
- * Returns number of bytes in this type of hmac
+ * Returns number of bytes in this type of hmac, if the hmac type is unknown, it
+ * will return 0.
  */
 LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT
 lws_genhmac_size(enum lws_genhmac_types type);
index 744a484..3f23031 100644 (file)
@@ -74,7 +74,8 @@ struct lws_genrsa_ctx {
  * This and related APIs operate identically with OpenSSL or mbedTLS backends.
  */
 LWS_VISIBLE LWS_EXTERN int
-lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_gencrypto_keyelem *el,
+lws_genrsa_create(struct lws_genrsa_ctx *ctx,
+                 const struct lws_gencrypto_keyelem *el,
                  struct lws_context *context, enum enum_genrsa_mode mode,
                  enum lws_genhash_types oaep_hashid);
 
@@ -215,7 +216,7 @@ lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
  * \param sig: pointer to buffer to take signature
  * \param sig_len: length of the buffer (must be >= length of key N)
  *
- * Returns <0 for error, or 0 for success.
+ * Returns <0 for error, or \p sig_len for success.
  *
  * This creates an RSA signature for a hash you already computed and provide.
  * You should have created the hash before calling this by iterating over the
index d1ecacf..2c5bd64 100644 (file)
@@ -494,6 +494,26 @@ LWS_VISIBLE LWS_EXTERN int
 lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name,
                    int nlen);
 
+typedef void (*lws_hdr_custom_fe_cb_t)(const char *name, int nlen, void *opaque);
+/**
+ * lws_hdr_custom_name_foreach() - Iterate the custom header names
+ *
+ * \param wsi: websocket connection
+ * \param cb: callback for each custom header name
+ * \param opaque: ignored by lws except to pass to callback
+ *
+ * Lws knows about 100 common http headers, and parses them into indexes when
+ * it recognizes them.  When it meets a header that it doesn't know, it stores
+ * the name and value directly, and you can look them up using
+ * lws_hdr_custom_length() and lws_hdr_custom_copy().
+ * 
+ * This api returns -1 on error else 0. Use lws_hdr_custom_copy() to get the
+ * values of headers. Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by
+ * default) to use this api.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_hdr_custom_name_foreach(struct lws *wsi, lws_hdr_custom_fe_cb_t cb, void *opaque);
+
 /**
  * lws_get_urlarg_by_name_safe() - get copy and return length of y for x=y urlargs
  *
@@ -846,7 +866,7 @@ lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len,
  * lws_http_transaction_completed() - wait for new http transaction or close
  * \param wsi: websocket connection
  *
- *     Returns 1 if the HTTP connection must close now
+ *     Returns nonzero if the HTTP connection must close now
  *     Returns 0 and resets connection to wait for new HTTP header /
  *       transaction if possible
  */
index 247d02c..c780c0e 100644 (file)
@@ -189,7 +189,8 @@ lws_gencrypto_jwe_enc_to_definition(const char *enc,
  * \param temp: parent-owned buffer to "allocate" elements into
  * \param temp_len: amount of space available in temp
  *
- * returns the amount of temp used, or -1 for error
+ * returns 0 for success, or -1 for error
+ * *\p temp_len is updated to reflect the amount of \p temp used if successful.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jws_parse_jose(struct lws_jose *jose,
@@ -204,7 +205,8 @@ lws_jws_parse_jose(struct lws_jose *jose,
  * \param temp: parent-owned buffer to "allocate" elements into
  * \param temp_len: amount of space available in temp
  *
- * returns the amount of temp used, or -1 for error
+ * returns 0 for success, or -1 for error
+ * *\p temp_len is updated to reflect the amount of \p temp used if successful.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jwe_parse_jose(struct lws_jose *jose,
index ab4aff5..a2205d2 100644 (file)
@@ -52,7 +52,7 @@ struct lws_jwk {
        struct lws_gencrypto_keyelem e[LWS_GENCRYPTO_MAX_KEYEL_COUNT];
        /* generic meta key elements, like KID */
        struct lws_gencrypto_keyelem meta[LWS_COUNT_JWK_ELEMENTS];
-       int kty;                        /**< one of LWS_JWK_ */
+       int kty;                        /**< one of LWS_GENCRYPTO_KTY_ */
        char private_key; /* nonzero = has private key elements */
 };
 
@@ -64,6 +64,8 @@ struct lws_jwk_parse_state {
        lws_jwk_key_import_callback per_key_cb;
        void *user;
        int pos;
+       int cose_state;
+       int seen;
        unsigned short possible;
 };
 
@@ -191,7 +193,7 @@ lws_jwk_rfc7638_fingerprint(struct lws_jwk *jwk, char *digest32);
  * \param in: string to copy
  * \param len: length of string to copy
  *
- * Returns 0 for OK or -1 for failure
+ * Returns 0 for OK or nonzero for failure
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jwk_strdup_meta(struct lws_jwk *jwk, enum enum_jwk_meta_tok idx,
@@ -209,7 +211,7 @@ lws_jwk_dump(struct lws_jwk *jwk);
  * \param bits: for OCT and RSA keys, the number of bits
  * \param curve: for EC keys, the name of the curve
  *
- * Returns 0 for OK or -1 for failure
+ * Returns 0 for OK or nonzero for failure
  */
 LWS_VISIBLE int
 lws_jwk_generate(struct lws_context *context, struct lws_jwk *jwk,
index 0ad4714..f15d503 100644 (file)
@@ -111,7 +111,7 @@ lws_jws_destroy(struct lws_jws *jws);
  * in a map... it'll make a temp b64 version needed for comparison.  See below
  * for other variants.
  *
- * Returns 0 on match.
+ * Returns 0 on match, else nonzero.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jws_sig_confirm_compact(struct lws_jws_map *map, struct lws_jwk *jwk,
@@ -139,7 +139,7 @@ lws_jws_sig_confirm_compact_b64_map(struct lws_jws_map *map_b64,
  * (jose.payload.hdr.sig) as an aggregated string... it'll make a temp plain
  * version needed for comparison.
  *
- * Returns 0 on match.
+ * Returns 0 on match, else nonzero.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jws_sig_confirm_compact_b64(const char *in, size_t len,
@@ -163,7 +163,7 @@ lws_jws_sig_confirm_compact_b64(const char *in, size_t len,
  * will end up with both maps, and can use this api version, saving needlessly
  * regenerating any temp map.
  *
- * Returns 0 on match.
+ * Returns 0 on match, else nonzero.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jws_sig_confirm(struct lws_jws_map *map_b64, /* b64-encoded */
@@ -187,7 +187,9 @@ lws_jws_sig_confirm(struct lws_jws_map *map_b64, /* b64-encoded */
  * case \p b64_hdr may be NULL, and only the payload will be hashed before
  * signing.
  *
- * Returns the length of the encoded signature written to \p b64_sig, or -1.
+ * If successful, returns the length of the encoded signature written to
+ * \p b64_sig.  If the jose signing type is unknown, 0 is returned.  Otherwise
+ * -1 indicates failure.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_jws_sign_from_b64(struct lws_jose *jose, struct lws_jws *jws, char *b64_sig,
@@ -556,7 +558,7 @@ struct lws_jwt_sign_set_cookie {
 };
 
 /**
- * lws_jwt_sign_token_set_cookie() - creates sets a JWT in a wsi cookie
+ * lws_jwt_sign_token_set_http_cookie() - creates sets a JWT in a wsi cookie
  *
  * \param wsi: the wsi to create the cookie header on
  * \param i: structure describing what should be in the JWT
diff --git a/third-party/prebuilt/include/libwebsockets/lws-lecp.h b/third-party/prebuilt/include/libwebsockets/lws-lecp.h
new file mode 100644 (file)
index 0000000..8133e4b
--- /dev/null
@@ -0,0 +1,539 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup lecp CBOR parser
+ * ##CBOR parsing related functions
+ * \ingroup lwsapi
+ *
+ * LECP is an extremely lightweight CBOR stream parser included in lws.  It
+ * is aligned in approach with the LEJP JSON stream parser, with some additional
+ * things needed for CBOR.
+ */
+//@{
+
+#ifndef LECP_MAX_PARSING_STACK_DEPTH
+#define LECP_MAX_PARSING_STACK_DEPTH   5
+#endif
+#ifndef LECP_MAX_DEPTH
+#define LECP_MAX_DEPTH                 12
+#endif
+#ifndef LECP_MAX_INDEX_DEPTH
+#define LECP_MAX_INDEX_DEPTH           8
+#endif
+#ifndef LECP_MAX_PATH
+#define LECP_MAX_PATH                  128
+#endif
+#ifndef LECP_STRING_CHUNK
+/* must be >= 30 to assemble floats */
+#define LECP_STRING_CHUNK              254
+#endif
+
+#define LECP_FLAG_CB_IS_VALUE 64
+
+/*
+ * CBOR initial byte 3 x MSB bits are these
+ */
+
+enum {
+       LWS_CBOR_MAJTYP_UINT            = 0 << 5,
+       LWS_CBOR_MAJTYP_INT_NEG         = 1 << 5,
+       LWS_CBOR_MAJTYP_BSTR            = 2 << 5,
+       LWS_CBOR_MAJTYP_TSTR            = 3 << 5,
+       LWS_CBOR_MAJTYP_ARRAY           = 4 << 5,
+       LWS_CBOR_MAJTYP_MAP             = 5 << 5,
+       LWS_CBOR_MAJTYP_TAG             = 6 << 5,
+       LWS_CBOR_MAJTYP_FLOAT           = 7 << 5,  /* also BREAK */
+
+       LWS_CBOR_MAJTYP_MASK            = 7 << 5,
+
+       /*
+        * For the low 5 bits of the opcode, 0-23 are literals, unless it's
+        * FLOAT.
+        *
+        * 24 = 1 byte; 25 = 2..., 26 = 4... and 27 = 8 bytes following literal.
+        */
+       LWS_CBOR_1                      = 24,
+       LWS_CBOR_2                      = 25,
+       LWS_CBOR_4                      = 26,
+       LWS_CBOR_8                      = 27,
+
+       LWS_CBOR_RESERVED               = 28,
+
+       LWS_CBOR_SUBMASK                = 0x1f,
+
+       /*
+        * Major type 7 discriminators in low 5 bits
+        * 0 - 23 is SIMPLE implicit value (like, eg, LWS_CBOR_SWK_TRUE)
+        */
+       LWS_CBOR_SWK_FALSE              = 20,
+       LWS_CBOR_SWK_TRUE               = 21,
+       LWS_CBOR_SWK_NULL               = 22,
+       LWS_CBOR_SWK_UNDEFINED          = 23,
+
+       LWS_CBOR_M7_SUBTYP_SIMPLE_X8    = 24, /* simple with additional byte */
+       LWS_CBOR_M7_SUBTYP_FLOAT16      = 25,
+       LWS_CBOR_M7_SUBTYP_FLOAT32      = 26,
+       LWS_CBOR_M7_SUBTYP_FLOAT64      = 27,
+       LWS_CBOR_M7_BREAK               = 31,
+
+/* 28, 29, 30 are illegal.
+ *
+ * 31 is illegal for UINT, INT_NEG, and TAG;
+ *               for BSTR, TSTR, ARRAY and MAP it means "indefinite length", ie,
+ *               it's made up of an endless amount of determinite-length
+ *               fragments terminated with a BREAK (FLOAT | 31) instead of the
+ *               next determinite-length fragment.  The second framing level
+ *               means no need for escapes for BREAK in the data.
+ */
+
+       LWS_CBOR_INDETERMINITE          = 31,
+
+/*
+ * Well-known tags
+ */
+
+       LWS_CBOR_WKTAG_DATETIME_STD     = 0, /* text */
+       LWS_CBOR_WKTAG_DATETIME_EPOCH   = 1, /* int or float */
+       LWS_CBOR_WKTAG_BIGNUM_UNSIGNED  = 2, /* byte string */
+       LWS_CBOR_WKTAG_BIGNUM_NEGATIVE  = 3, /* byte string */
+       LWS_CBOR_WKTAG_DECIMAL_FRAC     = 4, /* array */
+       LWS_CBOR_WKTAG_BIGFLOAT         = 5, /* array */
+
+       LWS_CBOR_WKTAG_COSE_ENC0        = 16,
+       LWS_CBOR_WKTAG_COSE_MAC0        = 17,
+       LWS_CBOR_WKTAG_COSE_SIGN1       = 18,
+
+       LWS_CBOR_WKTAG_TO_B64U          = 21, /* any */
+       LWS_CBOR_WKTAG_TO_B64           = 22, /* any */
+       LWS_CBOR_WKTAG_TO_B16           = 23, /* any */
+       LWS_CBOR_WKTAG_CBOR             = 24, /* byte string */
+
+       LWS_CBOR_WKTAG_URI              = 32, /* text string */
+       LWS_CBOR_WKTAG_B64U             = 33, /* text string */
+       LWS_CBOR_WKTAG_B64              = 34, /* text string */
+       LWS_CBOR_WKTAG_MIME             = 36, /* text string */
+
+       LWS_CBOR_WKTAG_COSE_ENC         = 96,
+       LWS_CBOR_WKTAG_COSE_MAC         = 97,
+       LWS_CBOR_WKTAG_COSE_SIGN        = 98,
+
+       LWS_CBOR_WKTAG_SELFDESCCBOR     = 55799
+};
+
+enum lecp_callbacks {
+       LECPCB_CONSTRUCTED              = 0,
+       LECPCB_DESTRUCTED               = 1,
+
+       LECPCB_COMPLETE                 = 3,
+       LECPCB_FAILED                   = 4,
+
+       LECPCB_PAIR_NAME                = 5,
+
+       LECPCB_VAL_TRUE                 = LECP_FLAG_CB_IS_VALUE | 6,
+       LECPCB_VAL_FALSE                = LECP_FLAG_CB_IS_VALUE | 7,
+       LECPCB_VAL_NULL                 = LECP_FLAG_CB_IS_VALUE | 8,
+       LECPCB_VAL_NUM_INT              = LECP_FLAG_CB_IS_VALUE | 9,
+       LECPCB_VAL_RESERVED             = LECP_FLAG_CB_IS_VALUE | 10,
+       LECPCB_VAL_STR_START            = 11, /* notice handle separately */
+       LECPCB_VAL_STR_CHUNK            = LECP_FLAG_CB_IS_VALUE | 12,
+       LECPCB_VAL_STR_END              = LECP_FLAG_CB_IS_VALUE | 13,
+
+       LECPCB_ARRAY_START              = 14,
+       LECPCB_ARRAY_END                = 15,
+
+       LECPCB_OBJECT_START             = 16,
+       LECPCB_OBJECT_END               = 17,
+
+       LECPCB_TAG_START                = 18,
+       LECPCB_TAG_END                  = 19,
+
+       LECPCB_VAL_NUM_UINT             = LECP_FLAG_CB_IS_VALUE | 20,
+       LECPCB_VAL_UNDEFINED            = LECP_FLAG_CB_IS_VALUE | 21,
+       LECPCB_VAL_FLOAT16              = LECP_FLAG_CB_IS_VALUE | 22,
+       LECPCB_VAL_FLOAT32              = LECP_FLAG_CB_IS_VALUE | 23,
+       LECPCB_VAL_FLOAT64              = LECP_FLAG_CB_IS_VALUE | 24,
+
+       LECPCB_VAL_SIMPLE               = LECP_FLAG_CB_IS_VALUE | 25,
+
+       LECPCB_VAL_BLOB_START           = 26, /* notice handle separately */
+       LECPCB_VAL_BLOB_CHUNK           = LECP_FLAG_CB_IS_VALUE | 27,
+       LECPCB_VAL_BLOB_END             = LECP_FLAG_CB_IS_VALUE | 28,
+
+       LECPCB_ARRAY_ITEM_START         = 29,
+       LECPCB_ARRAY_ITEM_END           = 30,
+
+       LECPCB_LITERAL_CBOR             = 31,
+};
+
+enum lecp_reasons {
+       LECP_CONTINUE                   = -1,
+       LECP_REJECT_BAD_CODING          = -2,
+       LECP_REJECT_UNKNOWN             = -3,
+       LECP_REJECT_CALLBACK            = -4,
+       LECP_STACK_OVERFLOW             = -5,
+};
+
+
+struct lecp_item {
+       union {
+               uint64_t        u64;
+               int64_t         i64;
+
+               uint64_t        u32;
+
+               uint16_t        hf;
+#if defined(LWS_WITH_CBOR_FLOAT)
+               float           f;
+               double          d;
+#else
+               uint32_t        f;
+               uint64_t        d;
+#endif
+       } u;
+       uint8_t                 opcode;
+};
+
+struct lecp_ctx;
+typedef signed char (*lecp_callback)(struct lecp_ctx *ctx, char reason);
+
+struct _lecp_stack {
+       char                    s; /* lejp_state stack*/
+       uint8_t                 p; /* path length */
+       char                    i; /* index array length */
+       char                    indet; /* indeterminite */
+       char                    intermediate; /* in middle of string */
+
+       char                    pop_iss;
+       uint64_t                tag;
+       uint64_t                collect_rem;
+       uint32_t                ordinal;
+       uint8_t                 opcode;
+       uint8_t                 send_new_array_item;
+       uint8_t                 barrier;
+};
+
+struct _lecp_parsing_stack {
+       void                    *user;  /* private to the stack level */
+       lecp_callback           cb;
+       const char * const      *paths;
+       uint8_t                 count_paths;
+       uint8_t                 ppos;
+       uint8_t                 path_match;
+};
+
+struct lecp_ctx {
+
+       /* sorted by type for most compact alignment
+        *
+        * pointers
+        */
+       void *user;
+       uint8_t                 *collect_tgt;
+
+       /* arrays */
+
+       struct _lecp_parsing_stack pst[LECP_MAX_PARSING_STACK_DEPTH];
+       struct _lecp_stack      st[LECP_MAX_DEPTH];
+       uint16_t                i[LECP_MAX_INDEX_DEPTH]; /* index array */
+       uint16_t                wild[LECP_MAX_INDEX_DEPTH]; /* index array */
+       char                    path[LECP_MAX_PATH];
+       uint8_t                 cbor[64]; /* literal cbor capture */
+
+       struct lecp_item        item;
+
+
+       /* size_t */
+
+       size_t                  path_stride; /* 0 means default ptr size, else
+                                             * stride...  allows paths to be
+                                             * provided composed inside a
+                                             * larger user struct instead of a
+                                             * duplicated array */
+       size_t                  used_in;     /* bytes of input consumed */
+
+       /* short */
+
+       uint16_t                uni;
+
+       /* char */
+
+       uint8_t                 npos;
+       uint8_t                 dcount;
+       uint8_t                 f;
+       uint8_t                 sp; /* stack head */
+       uint8_t                 ipos; /* index stack depth */
+       uint8_t                 count_paths;
+       uint8_t                 path_match;
+       uint8_t                 path_match_len;
+       uint8_t                 wildcount;
+       uint8_t                 pst_sp; /* parsing stack head */
+       uint8_t                 outer_array;
+       uint8_t                 cbor_pos;
+       uint8_t                 literal_cbor_report;
+       char                    present; /* temp for cb reason to use */
+
+       uint8_t                 be; /* big endian */
+
+       /* at end so we can memset the rest of it */
+
+       char buf[LECP_STRING_CHUNK + 1];
+};
+
+enum lws_lec_pctx_ret {
+       LWS_LECPCTX_RET_FINISHED                = 0,
+       LWS_LECPCTX_RET_AGAIN, /* call again to continue writing buffer */
+       LWS_LECPCTX_RET_FAIL /* something broken, eg, format string */
+};
+
+enum cbp_state {
+       CBPS_IDLE,
+       CBPS_PC1,
+       CBPS_PC2,
+       CBPS_PC3,
+
+       CBPS_STRING_BODY,
+
+       CBPS_NUM_LIT,
+
+       CBPS_STRING_LIT,
+
+       CBPS_CONTYPE,
+};
+
+typedef struct lws_lec_pctx {
+       uint8_t                 stack[16];
+       uint8_t                 vaa[16];
+       uint8_t                 indet[16];
+       uint8_t                 scratch[24];
+       uint8_t                 *start;    /* the beginning of the out buf */
+       uint8_t                 *buf;      /* cur pos in output buf */
+       uint8_t                 *end;      /* the end of the output buf */
+
+       const uint8_t           *ongoing_src;
+       uint64_t                ongoing_len;
+       uint64_t                ongoing_done;
+
+       struct lecp_item        item;
+
+       size_t                  used;      /* number of bytes valid from start */
+
+       int                     opaque[4]; /* ignored by lws, caller may use */
+
+       enum cbp_state          state;
+       unsigned int            fmt_pos;
+       uint8_t                 sp;
+       uint8_t                 scratch_len;
+       uint8_t                 escflag;
+       uint8_t                 _long;
+       uint8_t                 vaa_pos;
+       uint8_t                 dotstar;
+} lws_lec_pctx_t;
+
+LWS_VISIBLE LWS_EXTERN void
+lws_lec_int(lws_lec_pctx_t *ctx, uint8_t opcode, uint8_t indet, uint64_t num);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_lec_scratch(lws_lec_pctx_t *ctx);
+
+/*
+ * lws_lec_init() - prepare a cbor writing context
+ *
+ * \param ctx: the cbor writing context to prepare
+ * \param buf: the output buffer start
+ * \param len: the amount of the output buffer we can use
+ *
+ * Prepares a cbor writing context so that les_lec_printf can be used to
+ * write into it.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_lec_init(lws_lec_pctx_t *ctx, uint8_t *buf, size_t len);
+
+/*
+ * lws_lec_setbuf() - update the output buffer for an initialized cbor writing ctx
+ *
+ * \param ctx: the cbor writing context to prepare
+ * \param buf: the output buffer start
+ * \param len: the amount of the output buffer we can use
+ *
+ * Leaves the cbor writing context state as it is, but resets the output buffer
+ * it writes into as given in \p buf and \p len
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_lec_setbuf(lws_lec_pctx_t *ctx, uint8_t *buf, size_t len);
+
+/*
+ * lws_lec_vsprintf() - write into a cbor writing context
+ *
+ * \param ctx: the cbor writing context to prepare
+ * \param format: a printf style argument map
+ * \param args: the va args
+ *
+ * CBOR-aware vsprintf which pauses output when it fills the output buffer.  You
+ * can call it again with the same args and same lws_lex_pctx to resume filling
+ *
+ * Returns either LWS_LECPCTX_RET_FINISHED if we have nothing left over that we
+ * want to put in the buffer, or LWS_LECPCTX_RET_AGAIN if the function should
+ * be called again with the same arguments (perhaps into a different output
+ * buffer) to continue emitting output from where it left off.
+ *
+ * If LWS_LECPCTX_RET_AGAIN is returned, lws_lec_setbuf() must be used on the
+ * context to reset or change the output buffer before calling again.
+ *
+ * The number of bytes placed in the output buffer is available in ctx->used.
+ *
+ * \p format is a printf-type format string that is specialized for CBOR
+ * generation.  It understands the following specifiers
+ *
+ * |`123`||unsigned literal number|
+ * |`-123`||signed literal number|
+ * |`%u`|`unsigned int`|number|
+ * |`%lu`|`unsigned long int`|number|
+ * |`%llu`|`unsigned long long int`|number|
+ * |`%d`|`signed int`|number|
+ * |`%ld`|`signed long int`|number|
+ * |`%lld`|`signed long long int`|number|
+ * |`%f`|`double`|floating point number|
+ * |`123(...)`||literal tag and scope|
+ * |`%t(...)`|`unsigned int`|tag and scope|
+ * |`%lt(...)`|`unsigned long int`|tag and scope|
+ * |`%llt(...)`|`unsigned long long int`|tag and scope|
+ * |`[...]`||Array (fixed len if `]` in same format string)|
+ * |`{...}`||Map (fixed len if `}` in same format string)|
+ * |`<t...>`||Container for indeterminite text string frags|
+ * |`<b...>`||Container for indeterminite binary string frags|
+ * |`'string'`||Literal text of known length|
+ * |`%s`|`const char *`|NUL-terminated string|
+ * |`%.*s`|`int`, `const char *`|length-specified string|
+ * |`%.*b`|`int`, `const uint8_t *`|length-specified binary|
+ * |`:`||separator between Map items (a:b)|
+ * |`,`||separator between Map pairs or array items|
+ *
+ * See READMEs/README.cbor-lecp.md for more details.
+ */
+LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
+lws_lec_vsprintf(lws_lec_pctx_t *ctx, const char *format, va_list args);
+
+/*
+ * lws_lec_printf() - write into a cbor writing context
+ *
+ * \param ctx: the cbor writing context to prepare
+ * \param format: a printf style argument map
+ * \param ...: format args
+ *
+ * See lws_lec_vsprintf() for format details.  This is the most common way
+ * to format the CBOR output.
+ *
+ * See READMEs/README.cbor-lecp.md for more details.
+ */
+LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
+lws_lec_printf(lws_lec_pctx_t *ctx, const char *format, ...);
+
+/**
+ * lecp_construct() - Construct an LECP parser context
+ *
+ * \param ctx: the parser context object to be initialized
+ * \param cb: the user callback to receive the parsing events
+ * \param user: an opaque user pointer available at \p cb
+ * \param paths: an optional array of parsing paths
+ * \param paths_count: how many paths in \p paths
+ *
+ * Prepares an LECP parser context for parsing.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lecp_construct(struct lecp_ctx *ctx, lecp_callback cb, void *user,
+              const char * const *paths, unsigned char paths_count);
+
+/**
+ * lecp_destruct() - Destroys an LECP parser context
+ *
+ * \param ctx: the parser context object to be destroyed
+ */
+LWS_VISIBLE LWS_EXTERN void
+lecp_destruct(struct lecp_ctx *ctx);
+
+/**
+ * lecp_parse() - parses a chunk of input CBOR
+ *
+ * \p ctx: the parsing context
+ * \p cbor: the start of the chunk of CBOR
+ * \p len: the number of bytes of CBOR available at \p cbor
+ *
+ * Returns LECP_CONTINUE if more input needed, one of enum lecp_reasons for a
+ * fatal error, else 0 for successful parsing completion.
+ *
+ * On success or _CONTINUE, ctx->used_in is set to the number of input bytes
+ * consumed.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lecp_parse(struct lecp_ctx *ctx, const uint8_t *cbor, size_t len);
+
+LWS_VISIBLE LWS_EXTERN void
+lecp_change_callback(struct lecp_ctx *ctx, lecp_callback cb);
+
+LWS_VISIBLE LWS_EXTERN const char *
+lecp_error_to_string(int e);
+
+/**
+ * lecp_parse_report_raw() - turn cbor raw reporting on and off
+ *
+ * \param ctx: the lecp context
+ * \param on: 0 to disable (defaults disabled), 1 to enable
+ *
+ * For cose_sign, it needs access to raw cbor subtrees for the hash input.
+ * This api causes LECPCB_LITERAL_CBOR parse callbacks when there are
+ * ctx->cbor_pos bytes of raw cbor available in ctx->cbor[]. the callbacks
+ * occur when the ctx->cbor[] buffer fills or if it holds anything when this
+ * spi is used to stop the reports.
+ *
+ * The same CBOR that is being captured continues to be passed for parsing.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lecp_parse_report_raw(struct lecp_ctx *ctx, int on);
+
+/**
+ * lecp_parse_map_is_key() - return nonzero if we're in a map and this is a key
+ *
+ * \param ctx: the lwcp context
+ *
+ * Checks if the current value is a key in a map, ie, that you are on a "key" in
+ * a list of "{key: value}" pairs.  Zero means you're either not in a map or not
+ * on the key part, and nonzero means you are in a map and on a key part.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lecp_parse_map_is_key(struct lecp_ctx *ctx);
+
+LWS_VISIBLE LWS_EXTERN int
+lecp_parse_subtree(struct lecp_ctx *ctx, const uint8_t *in, size_t len);
+
+/*
+ * Helpers for half-float
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_singles2halfp(uint16_t *hp, uint32_t x);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_halfp2singles(uint32_t *xp, uint16_t h);
+
+//@}
index 6ea6d3d..f9f5027 100644 (file)
@@ -193,26 +193,26 @@ typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
 #endif
 
 enum num_flags {
-       LEJP_SEEN_MINUS = (1 << 0),
-       LEJP_SEEN_POINT = (1 << 1),
-       LEJP_SEEN_POST_POINT = (1 << 2),
-       LEJP_SEEN_EXP = (1 << 3)
+       LEJP_SEEN_MINUS         = (1 << 0),
+       LEJP_SEEN_POINT         = (1 << 1),
+       LEJP_SEEN_POST_POINT    = (1 << 2),
+       LEJP_SEEN_EXP           = (1 << 3)
 };
 
 struct _lejp_stack {
-       char s; /* lejp_state stack*/
-       char p; /* path length */
-       char i; /* index array length */
-       char b; /* user bitfield */
+       char                    s; /* lejp_state stack*/
+       char                    p;      /* path length */
+       char                    i; /* index array length */
+       char                    b; /* user bitfield */
 };
 
 struct _lejp_parsing_stack {
-       void *user;     /* private to the stack level */
-       signed char (*callback)(struct lejp_ctx *ctx, char reason);
-       const char * const *paths;
-       uint8_t count_paths;
-       uint8_t ppos;
-       uint8_t path_match;
+       void                    *user;  /* private to the stack level */
+       signed char             (*callback)(struct lejp_ctx *ctx, char reason);
+       const char * const      *paths;
+       uint8_t                 count_paths;
+       uint8_t                 ppos;
+       uint8_t                 path_match;
 };
 
 struct lejp_ctx {
index 3a3c892..3f21b81 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * libwebsockets - small server side websockets and web server implementation
  *
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
  *
  * Log categories may be individually filtered bitwise, and directed to built-in
  * sinks for syslog-compatible logging, or a user-defined function.
+ *
+ * Traditional logs use a single, processwide logging context.  New style log
+ * apis (lws_xxx_cx()) can pass the logging context to use in.
  */
 ///@{
 
-#define LLL_ERR                (1 << 0)
-#define        LLL_WARN        (1 << 1)
-#define        LLL_NOTICE      (1 << 2)
-#define        LLL_INFO        (1 << 3)
-#define        LLL_DEBUG       (1 << 4)
-#define        LLL_PARSER      (1 << 5)
-#define        LLL_HEADER      (1 << 6)
-#define        LLL_EXT         (1 << 7)
-#define        LLL_CLIENT      (1 << 8)
-#define        LLL_LATENCY     (1 << 9)
-#define        LLL_USER        (1 << 10)
-#define        LLL_THREAD      (1 << 11)
-
-#define        LLL_COUNT       (12) /* set to count of valid flags */
+#define LLL_ERR                        (1 << 0)
+#define        LLL_WARN                (1 << 1)
+#define        LLL_NOTICE              (1 << 2)
+#define        LLL_INFO                (1 << 3)
+#define        LLL_DEBUG               (1 << 4)
+#define        LLL_PARSER              (1 << 5)
+#define        LLL_HEADER              (1 << 6)
+#define        LLL_EXT                 (1 << 7)
+#define        LLL_CLIENT              (1 << 8)
+#define        LLL_LATENCY             (1 << 9)
+#define        LLL_USER                (1 << 10)
+#define        LLL_THREAD              (1 << 11)
+
+#define        LLL_COUNT               (12) /* set to count of valid flags */
+
+#define        LLLF_SECRECY_PII        (1 << 16)
+       /**< contains Personally Identifiable Information */
+#define LLLF_SECRECY_BEARER    (1 << 17)
+       /**< possession of this data allows impersonation */
+
+#define        LLLF_LOG_TIMESTAMP      (1 << 18)
+       /**< set to prepend logs with timestamp */
+
+#define        LLLF_LOG_CONTEXT_AWARE  (1 << 30)
+/**< set if the context uses an emit function that takes the logctx, auto-
+ * applied when setting emit using lws_set_log_level_cx() api */
+
+struct lws_log_cx;
+
+typedef void (*lws_log_emit_t)(int level, const char *line);
+typedef void (*lws_log_emit_cx_t)(struct lws_log_cx *cx, int level,
+                                 const char *line, size_t len);
+typedef void (*lws_log_prepend_cx_t)(struct lws_log_cx *cx, void *obj,
+                                    char **p, char *e);
+typedef void (*lws_log_use_cx_t)(struct lws_log_cx *cx, int _new);
+
+/*
+ * This is the logging context
+ */
+
+typedef struct lws_log_cx {
+       union {
+               lws_log_emit_t          emit; /* legacy emit function */
+               lws_log_emit_cx_t       emit_cx; /* LLLF_LOG_CONTEXT_AWARE */
+       } u;
+       lws_log_use_cx_t                refcount_cb;
+       /**< NULL, or a function called after each change to .refcount below,
+        * this enables implementing side-effects like opening and closing
+        * log files when the first and last object binds / unbinds */
+       lws_log_prepend_cx_t            prepend;
+       /**< NULL, or a cb to optionally prepend a string to logs we are a
+        * parent of */
+       struct lws_log_cx               *parent;
+       /**< NULL, or points to log ctx we are a child of */
+       void                            *opaque;
+       /**< ignored by lws, used to pass config to emit_cx, eg, filepath */
+       void                            *stg;
+       /**< ignored by lws, may be used a storage by refcount_cb / emit_cx */
+       uint32_t                        lll_flags;
+       /**< mask of log levels we want to emit in this context */
+       int32_t                         refcount;
+       /**< refcount of objects bound to this log context */
+} lws_log_cx_t;
 
 /**
  * lwsl_timestamp: generate logging timestamp string
@@ -64,10 +116,84 @@ lwsl_timestamp(int level, char *p, size_t len);
 #if defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_NETWORK)
 #define _lws_log(aaa, ...) SMSG(__VA_ARGS__)
 #else
-LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...) LWS_FORMAT(2);
-LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl);
+LWS_VISIBLE LWS_EXTERN void
+_lws_log(int filter, const char *format, ...) LWS_FORMAT(2);
+LWS_VISIBLE LWS_EXTERN void
+_lws_logv(int filter, const char *format, va_list vl);
+#endif
+
+struct lws_vhost;
+struct lws;
+
+LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
+lwsl_context_get_cx(struct lws_context *cx);
+LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
+lwsl_vhost_get_cx(struct lws_vhost *vh);
+LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
+lwsl_wsi_get_cx(struct lws *wsi);
+#if defined(LWS_WITH_SECURE_STREAMS)
+struct lws_ss_handle;
+struct lws_sspc_handle;
+LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
+lwsl_ss_get_cx(struct lws_ss_handle *ss);
+LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
+lwsl_sspc_get_cx(struct lws_sspc_handle *ss);
 #endif
 
+LWS_VISIBLE LWS_EXTERN void
+lws_log_emit_cx_file(struct lws_log_cx *cx, int level, const char *line,
+                       size_t len);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_log_use_cx_file(struct lws_log_cx *cx, int _new);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_log_prepend_context(struct lws_log_cx *cx, void *obj, char **p, char *e);
+LWS_VISIBLE LWS_EXTERN void
+lws_log_prepend_vhost(struct lws_log_cx *cx, void *obj, char **p, char *e);
+LWS_VISIBLE LWS_EXTERN void
+lws_log_prepend_wsi(struct lws_log_cx *cx, void *obj, char **p, char *e);
+#if defined(LWS_WITH_SECURE_STREAMS)
+LWS_VISIBLE LWS_EXTERN void
+lws_log_prepend_ss(struct lws_log_cx *cx, void *obj, char **p, char *e);
+LWS_VISIBLE LWS_EXTERN void
+lws_log_prepend_sspc(struct lws_log_cx *cx, void *obj, char **p, char *e);
+#endif
+
+LWS_VISIBLE LWS_EXTERN void
+_lws_log_cx(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj,
+           int filter, const char *_fun, const char *format, ...) LWS_FORMAT(6);
+
+#define lwsl_cx(_c, _fil, ...) \
+                _lws_log_cx(lwsl_context_get_cx(_c), lws_log_prepend_context, \
+                                       _c, _fil, __func__, __VA_ARGS__)
+#define lwsl_vhost(_v, _fil, ...) \
+                _lws_log_cx(lwsl_vhost_get_cx(_v), lws_log_prepend_vhost, _v, \
+                                       _fil, __func__, __VA_ARGS__)
+#define lwsl_wsi(_w, _fil, ...) \
+                _lws_log_cx(lwsl_wsi_get_cx(_w), lws_log_prepend_wsi, _w, \
+                                       _fil, __func__, __VA_ARGS__)
+#define lwsl_ss(_h, _fil, ...) \
+                _lws_log_cx(lwsl_ss_get_cx(_h), lws_log_prepend_ss, _h, \
+                                       _fil, __func__, __VA_ARGS__)
+
+#define lwsl_hexdump_context(_c, _fil, _buf, _len) \
+               lwsl_hexdump_level_cx(lwsl_context_get_cx(_c), \
+                                     lws_log_prepend_context, \
+                                     _c, _fil, _buf, _len)
+#define lwsl_hexdump_vhost(_v, _fil, _buf, _len) \
+               lwsl_hexdump_level_cx(lwsl_vhost_get_cx(_v), \
+                                     lws_log_prepend_vhost, \
+                                     _v, _fil, _buf, _len)
+#define lwsl_hexdump_wsi(_w, _fil, _buf, _len) \
+               lwsl_hexdump_level_cx(lwsl_wsi_get_cx(_w), \
+                                     lws_log_prepend_wsi, \
+                                     _w, _fil, _buf, _len)
+#define lwsl_hexdump_ss(_h, _fil, _buf, _len) \
+               lwsl_hexdump_level_cx(lwsl_ss_get_cx(_h), \
+                                     lws_log_prepend_ss, \
+                                     _h, _fil, _buf, _len)
+
 /*
  * Figure out which logs to build in or not
  */
@@ -120,6 +246,10 @@ LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl
  * depending on what was computed
  */
 
+/*
+ * Process scope logs
+ */
+
 #if (_LWS_ENABLED_LOGS & LLL_ERR)
 #define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
 #else
@@ -192,13 +322,344 @@ LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl
 #define lwsl_user(...) do {} while(0)
 #endif
 
-
 #define lwsl_hexdump_err(...) lwsl_hexdump_level(LLL_ERR, __VA_ARGS__)
 #define lwsl_hexdump_warn(...) lwsl_hexdump_level(LLL_WARN, __VA_ARGS__)
 #define lwsl_hexdump_notice(...) lwsl_hexdump_level(LLL_NOTICE, __VA_ARGS__)
 #define lwsl_hexdump_info(...) lwsl_hexdump_level(LLL_INFO, __VA_ARGS__)
 #define lwsl_hexdump_debug(...) lwsl_hexdump_level(LLL_DEBUG, __VA_ARGS__)
 
+/*
+ * lws_context scope logs
+ */
+
+#if (_LWS_ENABLED_LOGS & LLL_ERR)
+#define lwsl_cx_err(_c, ...) lwsl_cx(_c, LLL_ERR, __VA_ARGS__)
+#else
+#define lwsl_cx_err(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_WARN)
+#define lwsl_cx_warn(_c, ...) lwsl_cx(_c, LLL_WARN, __VA_ARGS__)
+#else
+#define lwsl_cx_warn(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
+#define lwsl_cx_notice(_c, ...) lwsl_cx(_c, LLL_NOTICE, __VA_ARGS__)
+#else
+#define lwsl_cx_notice(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_INFO)
+#define lwsl_cx_info(_c, ...) lwsl_cx(_c, LLL_INFO, __VA_ARGS__)
+#else
+#define lwsl_cx_info(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
+#define lwsl_cx_debug(_c, ...) lwsl_cx(_c, LLL_DEBUG, __VA_ARGS__)
+#else
+#define lwsl_cx_debug(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_PARSER)
+#define lwsl_cx_parser(_c, ...) lwsl_cx(_c, LLL_PARSER, __VA_ARGS__)
+#else
+#define lwsl_cx_parser(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_HEADER)
+#define lwsl_cx_header(_c, ...) lwsl_cx(_c, LLL_HEADER, __VA_ARGS__)
+#else
+#define lwsl_cx_header(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_EXT)
+#define lwsl_cx_ext(_c, ...) lwsl_cx(_c, LLL_EXT, __VA_ARGS__)
+#else
+#define lwsl_cx_ext(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
+#define lwsl_cx_client(_c, ...) lwsl_cx(_c, LLL_CLIENT, __VA_ARGS__)
+#else
+#define lwsl_cx_client(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
+#define lwsl_cx_latency(_c, ...) lwsl_cx(_c, LLL_LATENCY, __VA_ARGS__)
+#else
+#define lwsl_cx_latency(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_THREAD)
+#define lwsl_cx_thread(_c, ...) lwsl_cx(_c, LLL_THREAD, __VA_ARGS__)
+#else
+#define lwsl_cx_thread(_c, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_USER)
+#define lwsl_cx_user(_c, ...) lwsl_cx(_c, LLL_USER, __VA_ARGS__)
+#else
+#define lwsl_cx_user(_c, ...) do {} while(0)
+#endif
+
+#define lwsl_hexdump_cx_err(_c, ...)    lwsl_hexdump_context(_c, LLL_ERR, __VA_ARGS__)
+#define lwsl_hexdump_cx_warn(_c, ...)   lwsl_hexdump_context(_c, LLL_WARN, __VA_ARGS__)
+#define lwsl_hexdump_cx_notice(_c, ...) lwsl_hexdump_context(_c, LLL_NOTICE, __VA_ARGS__)
+#define lwsl_hexdump_cx_info(_c, ...)   lwsl_hexdump_context(_c, LLL_INFO, __VA_ARGS__)
+#define lwsl_hexdump_cx_debug(_c, ...)  lwsl_hexdump_context(_c, LLL_DEBUG, __VA_ARGS__)
+
+/*
+ * lws_vhost
+ */
+
+#if (_LWS_ENABLED_LOGS & LLL_ERR)
+#define lwsl_vhost_err(_v, ...) lwsl_vhost(_v, LLL_ERR, __VA_ARGS__)
+#else
+#define lwsl_vhost_err(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_WARN)
+#define lwsl_vhost_warn(_v, ...) lwsl_vhost(_v, LLL_WARN, __VA_ARGS__)
+#else
+#define lwsl_vhost_warn(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
+#define lwsl_vhost_notice(_v, ...) lwsl_vhost(_v, LLL_NOTICE, __VA_ARGS__)
+#else
+#define lwsl_vhost_notice(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_INFO)
+#define lwsl_vhost_info(_v, ...) lwsl_vhost(_v, LLL_INFO, __VA_ARGS__)
+#else
+#define lwsl_vhost_info(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
+#define lwsl_vhost_debug(_v, ...) lwsl_vhost(_v, LLL_DEBUG, __VA_ARGS__)
+#else
+#define lwsl_vhost_debug(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_PARSER)
+#define lwsl_vhost_parser(_v, ...) lwsl_vhost(_v, LLL_PARSER, __VA_ARGS__)
+#else
+#define lwsl_vhost_parser(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_HEADER)
+#define lwsl_vhost_header(_v, ...) lwsl_vhost(_v, LLL_HEADER, __VA_ARGS__)
+#else
+#define lwsl_vhost_header(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_EXT)
+#define lwsl_vhost_ext(_v, ...) lwsl_vhost(_v, LLL_EXT, __VA_ARGS__)
+#else
+#define lwsl_vhost_ext(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
+#define lwsl_vhost_client(_v, ...) lwsl_vhost(_v, LLL_CLIENT, __VA_ARGS__)
+#else
+#define lwsl_vhost_client(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
+#define lwsl_vhost_latency(_v, ...) lwsl_vhost(_v, LLL_LATENCY, __VA_ARGS__)
+#else
+#define lwsl_vhost_latency(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_THREAD)
+#define lwsl_vhost_thread(_v, ...) lwsl_vhost(_v, LLL_THREAD, __VA_ARGS__)
+#else
+#define lwsl_vhost_thread(_v, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_USER)
+#define lwsl_vhost_user(_v, ...) lwsl_vhost(_v, LLL_USER, __VA_ARGS__)
+#else
+#define lwsl_vhost_user(_v, ...) do {} while(0)
+#endif
+
+#define lwsl_hexdump_vhost_err(_v, ...)    lwsl_hexdump_vhost(_v, LLL_ERR, __VA_ARGS__)
+#define lwsl_hexdump_vhost_warn(_v, ...)   lwsl_hexdump_vhost(_v, LLL_WARN, __VA_ARGS__)
+#define lwsl_hexdump_vhost_notice(_v, ...) lwsl_hexdump_vhost(_v, LLL_NOTICE, __VA_ARGS__)
+#define lwsl_hexdump_vhost_info(_v, ...)   lwsl_hexdump_vhost(_v, LLL_INFO, __VA_ARGS__)
+#define lwsl_hexdump_vhost_debug(_v, ...)  lwsl_hexdump_vhost(_v, LLL_DEBUG, __VA_ARGS__)
+
+
+/*
+ * lws_wsi
+ */
+
+#if (_LWS_ENABLED_LOGS & LLL_ERR)
+#define lwsl_wsi_err(_w, ...) lwsl_wsi(_w, LLL_ERR, __VA_ARGS__)
+#else
+#define lwsl_wsi_err(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_WARN)
+#define lwsl_wsi_warn(_w, ...) lwsl_wsi(_w, LLL_WARN, __VA_ARGS__)
+#else
+#define lwsl_wsi_warn(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
+#define lwsl_wsi_notice(_w, ...) lwsl_wsi(_w, LLL_NOTICE, __VA_ARGS__)
+#else
+#define lwsl_wsi_notice(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_INFO)
+#define lwsl_wsi_info(_w, ...) lwsl_wsi(_w, LLL_INFO, __VA_ARGS__)
+#else
+#define lwsl_wsi_info(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
+#define lwsl_wsi_debug(_w, ...) lwsl_wsi(_w, LLL_DEBUG, __VA_ARGS__)
+#else
+#define lwsl_wsi_debug(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_PARSER)
+#define lwsl_wsi_parser(_w, ...) lwsl_wsi(_w, LLL_PARSER, __VA_ARGS__)
+#else
+#define lwsl_wsi_parser(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_HEADER)
+#define lwsl_wsi_header(_w, ...) lwsl_wsi(_w, LLL_HEADER, __VA_ARGS__)
+#else
+#define lwsl_wsi_header(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_EXT)
+#define lwsl_wsi_ext(_w, ...) lwsl_wsi(_w, LLL_EXT, __VA_ARGS__)
+#else
+#define lwsl_wsi_ext(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
+#define lwsl_wsi_client(_w, ...) lwsl_wsi(_w, LLL_CLIENT, __VA_ARGS__)
+#else
+#define lwsl_wsi_client(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
+#define lwsl_wsi_latency(_w, ...) lwsl_wsi(_w, LLL_LATENCY, __VA_ARGS__)
+#else
+#define lwsl_wsi_latency(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_THREAD)
+#define lwsl_wsi_thread(_w, ...) lwsl_wsi(_w, LLL_THREAD, __VA_ARGS__)
+#else
+#define lwsl_wsi_thread(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_USER)
+#define lwsl_wsi_user(_w, ...) lwsl_wsi(_w, LLL_USER, __VA_ARGS__)
+#else
+#define lwsl_wsi_user(_w, ...) do {} while(0)
+#endif
+
+#define lwsl_hexdump_wsi_err(_v, ...)    lwsl_hexdump_wsi(_v, LLL_ERR, __VA_ARGS__)
+#define lwsl_hexdump_wsi_warn(_v, ...)   lwsl_hexdump_wsi(_v, LLL_WARN, __VA_ARGS__)
+#define lwsl_hexdump_wsi_notice(_v, ...) lwsl_hexdump_wsi(_v, LLL_NOTICE, __VA_ARGS__)
+#define lwsl_hexdump_wsi_info(_v, ...)   lwsl_hexdump_wsi(_v, LLL_INFO, __VA_ARGS__)
+#define lwsl_hexdump_wsi_debug(_v, ...)  lwsl_hexdump_wsi(_v, LLL_DEBUG, __VA_ARGS__)
+
+
+/*
+ * lwsl_ss
+ */
+
+#if (_LWS_ENABLED_LOGS & LLL_ERR)
+#define lwsl_ss_err(_w, ...) lwsl_ss(_w, LLL_ERR, __VA_ARGS__)
+#else
+#define lwsl_ss_err(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_WARN)
+#define lwsl_ss_warn(_w, ...) lwsl_ss(_w, LLL_WARN, __VA_ARGS__)
+#else
+#define lwsl_ss_warn(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
+#define lwsl_ss_notice(_w, ...) lwsl_ss(_w, LLL_NOTICE, __VA_ARGS__)
+#else
+#define lwsl_ss_notice(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_INFO)
+#define lwsl_ss_info(_w, ...) lwsl_ss(_w, LLL_INFO, __VA_ARGS__)
+#else
+#define lwsl_ss_info(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
+#define lwsl_ss_debug(_w, ...) lwsl_ss(_w, LLL_DEBUG, __VA_ARGS__)
+#else
+#define lwsl_ss_debug(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_PARSER)
+#define lwsl_ss_parser(_w, ...) lwsl_ss(_w, LLL_PARSER, __VA_ARGS__)
+#else
+#define lwsl_ss_parser(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_HEADER)
+#define lwsl_ss_header(_w, ...) lwsl_ss(_w, LLL_HEADER, __VA_ARGS__)
+#else
+#define lwsl_ss_header(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_EXT)
+#define lwsl_ss_ext(_w, ...) lwsl_ss(_w, LLL_EXT, __VA_ARGS__)
+#else
+#define lwsl_ss_ext(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
+#define lwsl_ss_client(_w, ...) lwsl_ss(_w, LLL_CLIENT, __VA_ARGS__)
+#else
+#define lwsl_ss_client(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
+#define lwsl_ss_latency(_w, ...) lwsl_ss(_w, LLL_LATENCY, __VA_ARGS__)
+#else
+#define lwsl_ss_latency(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_THREAD)
+#define lwsl_ss_thread(_w, ...) lwsl_ss(_w, LLL_THREAD, __VA_ARGS__)
+#else
+#define lwsl_ss_thread(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_USER)
+#define lwsl_ss_user(_w, ...) lwsl_ss(_w, LLL_USER, __VA_ARGS__)
+#else
+#define lwsl_ss_user(_w, ...) do {} while(0)
+#endif
+
+#define lwsl_hexdump_ss_err(_v, ...)    lwsl_hexdump_ss(_v, LLL_ERR, __VA_ARGS__)
+#define lwsl_hexdump_ss_warn(_v, ...)   lwsl_hexdump_ss(_v, LLL_WARN, __VA_ARGS__)
+#define lwsl_hexdump_ss_notice(_v, ...) lwsl_hexdump_ss(_v, LLL_NOTICE, __VA_ARGS__)
+#define lwsl_hexdump_ss_info(_v, ...)   lwsl_hexdump_ss(_v, LLL_INFO, __VA_ARGS__)
+#define lwsl_hexdump_ss_debug(_v, ...)  lwsl_hexdump_ss(_v, LLL_DEBUG, __VA_ARGS__)
+
+
+
 /**
  * lwsl_hexdump_level() - helper to hexdump a buffer at a selected debug level
  *
@@ -212,6 +673,10 @@ LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl
 LWS_VISIBLE LWS_EXTERN void
 lwsl_hexdump_level(int level, const void *vbuf, size_t len);
 
+LWS_VISIBLE LWS_EXTERN void
+lwsl_hexdump_level_cx(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj,
+                     int hexdump_level, const void *vbuf, size_t len);
+
 /**
  * lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only)
  *
@@ -241,13 +706,20 @@ static LWS_INLINE int lws_is_be(void) {
  *                     function to perform log string emission instead of
  *                     the default stderr one.
  *
- *     log level defaults to "err", "warn" and "notice" contexts enabled and
- *     emission on stderr.  If stderr is a tty (according to isatty()) then
- *     the output is coloured according to the log level using ANSI escapes.
+ * log level defaults to "err", "warn" and "notice" contexts enabled and
+ * emission on stderr.  If stderr is a tty (according to isatty()) then
+ * the output is coloured according to the log level using ANSI escapes.
+ *
+ * You can set the default security level for logging using the
+ * secrecy_and_log_level() macro to set the \p level parameter, eg
+ *
+ * lws_set_log_level(secrecy_and_log_level(LWS_SECRECY_PII, LLL_ERR | LLL_WARN),
+ *                  my_emit_function);
+ *
+ * Normally you can just leave it at the default.
  */
 LWS_VISIBLE LWS_EXTERN void
-lws_set_log_level(int level,
-                 void (*log_emit_function)(int level, const char *line));
+lws_set_log_level(int level, lws_log_emit_t log_emit_function);
 
 /**
  * lwsl_emit_syslog() - helper log emit function writes to system log
@@ -308,4 +780,7 @@ struct lws;
 LWS_VISIBLE LWS_EXTERN const char *
 lws_wsi_tag(struct lws *wsi);
 
+LWS_VISIBLE LWS_EXTERN void
+lwsl_refcount_cx(lws_log_cx_t *cx, int _new);
+
 ///@}
diff --git a/third-party/prebuilt/include/libwebsockets/lws-map.h b/third-party/prebuilt/include/libwebsockets/lws-map.h
new file mode 100644 (file)
index 0000000..4462881
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \defgroup lws_map generic map apis
+ * ##Generic map structures and apis
+ * \ingroup lwsapi
+ *
+ * lws_map
+ *
+ * Discrete owner object represents the whole map, created with key-specific
+ * ops for hashing the key to a uint32_t and comparing two keys.  Owns a list
+ * of hash tables whose size / modulo it set at creation time.
+ *
+ * Items in the map are contained in a lws_map_item_t that is indexed in a
+ * hash table.
+ *
+ * It's difficult to make a single compact map abstraction that fits all cases,
+ * this is useful to the extent you have the memory to trade off the number of
+ * hashtables needed for the amount of items and the lookup latency limit for
+ * your application, typically for hundreds or low thousands of items.
+ */
+//@{
+
+typedef struct lws_map lws_map_t;
+typedef struct lws_map_item lws_map_item_t;
+
+typedef void * lws_map_key_t;
+typedef void * lws_map_value_t;
+typedef uint32_t lws_map_hash_t;
+
+typedef lws_map_hash_t (*lws_map_hash_from_key_t)(const lws_map_key_t key,
+                                                 size_t kl);
+typedef int (*lws_map_compare_key_t)(const lws_map_key_t key1, size_t kl1,
+                                    const lws_map_value_t key2, size_t kl2);
+typedef void * (*lws_map_alloc_t)(struct lws_map *mo, size_t x);
+typedef void (*lws_map_free_t)(void *);
+
+/*
+ * Creation parameters for the map, copied into the map owner
+ */
+
+typedef struct lws_map_info {
+       lws_map_hash_from_key_t         _hash;
+       lws_map_compare_key_t           _compare;
+       lws_map_alloc_t                 _alloc; /* NULL = lws_malloc */
+       lws_map_free_t                  _free;  /* NULL = lws_free */
+
+       void                            *opaque;
+       /**< &lwsac if using lwsac allocator */
+       void                            *aux;
+       /**< chunk size if using lwsac allocator */
+       /**< this can be used by the alloc handler, eg for lws_ac */
+       size_t                          modulo;
+       /**< number of hashed owner lists to create */
+} lws_map_info_t;
+
+LWS_VISIBLE LWS_EXTERN const void *
+lws_map_item_key(lws_map_item_t *_item);
+LWS_VISIBLE LWS_EXTERN const void *
+lws_map_item_value(lws_map_item_t *_item);
+LWS_VISIBLE LWS_EXTERN size_t
+lws_map_item_key_len(lws_map_item_t *_item);
+LWS_VISIBLE LWS_EXTERN size_t
+lws_map_item_value_len(lws_map_item_t *_item);
+
+/*
+ * Helpers for C string keys case
+ */
+
+#define lws_map_item_create_ks(_map, _str, _v, _vl) \
+               lws_map_item_create(_map, (const lws_map_key_t)_str, \
+                                   strlen(_str), (const lws_map_value_t)_v, \
+                                                   _vl)
+#define lws_map_item_lookup_ks(_map, _str) \
+               lws_map_item_lookup(_map, (const lws_map_key_t)_str, strlen(_str))
+
+/**
+ * lws_map_create() - create a map object and hashtables on heap
+ *
+ * \param info: description of map to create
+ *
+ * Creates a map object on heap, using lws_malloc().
+ *
+ * \p info may be all zeros inside, if so, modulo defaults to 8, and the
+ * operation callbacks default to using lws_malloc() / _free() for item alloc,
+ * a default xor / shift based hash and simple linear memory key compare.
+ *
+ * For less typical use-cases, the provided \p info members can be tuned to
+ * control how the allocation of mapped items is done, lws provides two exports
+ * lws_map_alloc_lwsac() and lws_map_free_lwsac() that can be used for _alloc
+ * and _free to have items allocated inside an lwsac.
+ *
+ * The map itself is created on the heap directly, the info._alloc() op is only
+ * used when creating items.
+ *
+ * keys have individual memory sizes and do not need to all be the same length.
+ */
+LWS_VISIBLE LWS_EXTERN lws_map_t *
+lws_map_create(const lws_map_info_t *info);
+
+/*
+ * helpers that can be used for info._alloc and info._free if using lwsac
+ * allocation for items, set info.opaque to point to the lwsac pointer, and
+ * aux to (void *)chunksize, or leave zero / NULL for the default
+ */
+
+LWS_VISIBLE LWS_EXTERN void *
+lws_map_alloc_lwsac(struct lws_map *map, size_t x);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_map_free_lwsac(void *v);
+
+/**
+ * lws_map_destroy() - deallocate all items and free map
+ *
+ * \param pmap: pointer to pointer map object to deallocate
+ *
+ * Frees all items in the map, using info._free(), and then frees the map
+ * from heap directly.  \p *pmap is set to NULL.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_map_destroy(lws_map_t **pmap);
+
+/**
+ * lws_map_item_create() - allocate and map an item into an existing map
+ *
+ * \param map: the map to add items into
+ * \param key: the key, may be any kind of object
+ * \param keylen: the length of the key in bytes
+ * \param value: the value, may be any kind of object
+ * \param valuelen: the length of value
+ *
+ * Allocates space for the item, key and value using the map allocator, and
+ * if non-NULL, copies the key and value into the item.
+ *
+ * If an item with the same key exists, it is removed and destroyed before
+ * creating and adding the new one.
+ */
+
+LWS_VISIBLE LWS_EXTERN lws_map_item_t *
+lws_map_item_create(lws_map_t *map,
+                   const lws_map_key_t key, size_t keylen,
+                   const lws_map_value_t value, size_t valuelen);
+
+/**
+ * lws_map_item_destroy() - remove item from map and free
+ *
+ * \param item: the item in the map to remove and free
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_map_item_destroy(lws_map_item_t *item);
+
+/**
+ * lws_map_item_lookup() - look for a item with the given key in the map
+ *
+ * \param map: the map
+ * \param key: the key to look for
+ * \param keylen: the length of the key to look for
+ *
+ * Searches for the key in the map, using the map's key hash and key compare
+ * functions.
+ */
+
+LWS_VISIBLE LWS_EXTERN lws_map_item_t *
+lws_map_item_lookup(lws_map_t *map, const lws_map_key_t key, size_t keylen);
+
+//@}
index 17a4b3b..c6dc439 100644 (file)
@@ -818,6 +818,25 @@ LWS_VISIBLE LWS_EXTERN int
 lws_is_cgi(struct lws *wsi);
 
 /**
+ * lws_tls_jit_trust_blob_queury_skid() - walk jit trust blob for skid
+ *
+ * \param _blob: the start of the blob in memory
+ * \param blen: the length of the blob in memory
+ * \param skid: the SKID we are looking for
+ * \param skid_len: the length of the SKID we are looking for
+ * \param prpder: result pointer to receive a pointer to the matching DER
+ * \param prder_len: result pointer to receive matching DER length
+ *
+ * Helper to scan a JIT Trust blob in memory for a trusted CA cert matching
+ * a given SKID.  Returns 0 if found and *prpder and *prder_len are set, else
+ * nonzero.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_tls_jit_trust_blob_queury_skid(const void *_blob, size_t blen,
+                                  const uint8_t *skid, size_t skid_len,
+                                  const uint8_t **prpder, size_t *prder_len);
+
+/**
  * lws_open() - platform-specific wrapper for open that prepares the fd
  *
  * \param __file: the filepath to open
index 462374d..2286580 100644 (file)
@@ -70,8 +70,14 @@ typedef struct lws_mqtt_client_connect_param_s {
        uint16_t                        keep_alive;     /* MQTT keep alive
                                                           interval in
                                                           seconds */
-       uint8_t                         clean_start;    /* MQTT clean
+       uint8_t                         clean_start:1;  /* MQTT clean
                                                           session */
+       uint8_t                         client_id_nofree:1;
+       /**< do not free the client id */
+       uint8_t                         username_nofree:1;
+       /**< do not free the username */
+       uint8_t                         password_nofree:1;
+       /**< do not free the password */
        struct {
                const char              *topic;
                const char              *message;
@@ -79,6 +85,13 @@ typedef struct lws_mqtt_client_connect_param_s {
                uint8_t                 retain;
        } will_param;                           /* MQTT LWT
                                                   parameters */
+       struct {
+               const char              *topic;
+               const char              *message;
+               lws_mqtt_qos_levels_t   qos;
+               uint8_t                 retain;
+       } birth_param;                          /* MQTT Birth
+                                                  parameters */
        const char                      *username;
        const char                      *password;
        uint8_t                         aws_iot;
@@ -143,6 +156,10 @@ typedef enum {
 
 /* flags from byte 8 of C_TO_S CONNECT */
 typedef enum {
+       LMQCFT_USERNAME_NOFREE                                  = (1 << 10),
+       LMQCFT_PASSWORD_NOFREE                                  = (1 << 9),
+       LMQCFT_CLIENT_ID_NOFREE                                 = (1 << 8),
+       /* only the low 8 are standardized and go out in the protocol */
        LMQCFT_USERNAME                                         = (1 << 7),
        LMQCFT_PASSWORD                                         = (1 << 6),
        LMQCFT_WILL_RETAIN                                      = (1 << 5),
index 4ad16be..20a3225 100644 (file)
@@ -223,8 +223,9 @@ lws_sa46_parse_numeric_address(const char *ads, lws_sockaddr46 *sa46);
  * \param len: max size of text buffer
  *
  * Converts an array of network-ordered byte address elements to a textual
- * representation of the numeric address, like "1.2.3.4" or "::1".  Return 0
- * if OK else < 0.  ipv6 only supported with LWS_IPV6=1 at cmake.
+ * representation of the numeric address, like "1.2.3.4" or "::1".  Returns the
+ * number of chars written into buf, else < 0.  ipv6 only supported with
+ * LWS_IPV6=1 at cmake.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_write_numeric_address(const uint8_t *ads, int size, char *buf, size_t len);
@@ -237,8 +238,9 @@ lws_write_numeric_address(const uint8_t *ads, int size, char *buf, size_t len);
  * \param len: max size of text buffer
  *
  * Converts the ipv4 or ipv6 address in an lws_sockaddr46 to a textual
- * representation of the numeric address, like "1.2.3.4" or "::1".  Return 0
- * if OK else < 0.  ipv6 only supported with LWS_IPV6=1 at cmake.
+ * representation of the numeric address, like "1.2.3.4" or "::1".  Returns the
+ * number of chars written into buf, else < 0.  ipv6 only supported with
+ * LWS_IPV6=1 at cmake.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_sa46_write_numeric_address(lws_sockaddr46 *sa46, char *buf, size_t len);
index ec9d8d8..66240c9 100644 (file)
@@ -86,6 +86,8 @@ struct lws_protocols {
         * This is part of the ABI, don't needlessly break compatibility */
 };
 
+#define LWS_PROTOCOL_LIST_TERM { NULL, NULL, 0, 0, 0, NULL, 0 }
+
 /**
  * lws_vhost_name_to_protocol() - get vhost's protocol object from its name
  *
index eac12e7..4d24cba 100644 (file)
@@ -40,6 +40,8 @@
  * lws_sspc_ in one step by #define LWS_SS_USE_SSPC before including
  */
 
+struct lws_sspc_handle;
+
 #if defined(LWS_SS_USE_SSPC)
 #define lws_ss_handle                  lws_sspc_handle
 #define lws_ss_create                  lws_sspc_create
 #define lws_smd_ss_rx_forward          lws_smd_sspc_rx_forward
 #define lws_ss_tag                     lws_sspc_tag
 #define _lws_fi_user_ss_fi             _lws_fi_user_sspc_fi
+#define lwsl_ss_get_cx                 lwsl_sspc_get_cx
+
+LWS_VISIBLE LWS_EXTERN void
+lws_log_prepend_sspc(struct lws_log_cx *cx, void *obj, char **p, char *e);
+
+LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
+lwsl_sspc_get_cx(struct lws_sspc_handle *ss);
+
+#undef lwsl_ss
+#define lwsl_ss lwsl_sspc
+
+#undef lwsl_hexdump_ss
+#define lwsl_hexdump_ss lwsl_hexdump_sspc
 #endif
 
+#define lwsl_sspc(_h, _fil, ...) \
+                _lws_log_cx(lwsl_sspc_get_cx(_h), lws_log_prepend_sspc, _h, \
+                                       _fil, __func__, __VA_ARGS__)
+
+#define lwsl_hexdump_sspc(_h, _fil, _buf, _len) \
+               lwsl_hexdump_level_cx(lwsl_sspc_get_cx(_h), \
+                                     lws_log_prepend_sspc, \
+                                     _h, _fil, _buf, _len)
+
+/*
+ * lwsl_sspc
+ */
+
+#if (_LWS_ENABLED_LOGS & LLL_ERR)
+#define lwsl_sspc_err(_w, ...) lwsl_sspc(_w, LLL_ERR, __VA_ARGS__)
+#else
+#define lwsl_sspc_err(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_WARN)
+#define lwsl_sspc_warn(_w, ...) lwsl_sspc(_w, LLL_WARN, __VA_ARGS__)
+#else
+#define lwsl_sspc_warn(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
+#define lwsl_sspc_notice(_w, ...) lwsl_sspc(_w, LLL_NOTICE, __VA_ARGS__)
+#else
+#define lwsl_sspc_notice(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_INFO)
+#define lwsl_sspc_info(_w, ...) lwsl_sspc(_w, LLL_INFO, __VA_ARGS__)
+#else
+#define lwsl_sspc_info(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
+#define lwsl_sspc_debug(_w, ...) lwsl_sspc(_w, LLL_DEBUG, __VA_ARGS__)
+#else
+#define lwsl_sspc_debug(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_PARSER)
+#define lwsl_sspc_parser(_w, ...) lwsl_sspc(_w, LLL_PARSER, __VA_ARGS__)
+#else
+#define lwsl_sspc_parser(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_HEADER)
+#define lwsl_sspc_header(_w, ...) lwsl_sspc(_w, LLL_HEADER, __VA_ARGS__)
+#else
+#define lwsl_sspc_header(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_EXT)
+#define lwsl_sspc_ext(_w, ...) lwsl_sspc(_w, LLL_EXT, __VA_ARGS__)
+#else
+#define lwsl_sspc_ext(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
+#define lwsl_sspc_client(_w, ...) lwsl_sspc(_w, LLL_CLIENT, __VA_ARGS__)
+#else
+#define lwsl_sspc_client(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
+#define lwsl_sspc_latency(_w, ...) lwsl_sspc(_w, LLL_LATENCY, __VA_ARGS__)
+#else
+#define lwsl_sspc_latency(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_THREAD)
+#define lwsl_sspc_thread(_w, ...) lwsl_sspc(_w, LLL_THREAD, __VA_ARGS__)
+#else
+#define lwsl_sspc_thread(_w, ...) do {} while(0)
+#endif
+
+#if (_LWS_ENABLED_LOGS & LLL_USER)
+#define lwsl_sspc_user(_w, ...) lwsl_sspc(_w, LLL_USER, __VA_ARGS__)
+#else
+#define lwsl_sspc_user(_w, ...) do {} while(0)
+#endif
+
+#define lwsl_hexdump_sspc_err(_v, ...)    lwsl_hexdump_sspc(_v, LLL_ERR, __VA_ARGS__)
+#define lwsl_hexdump_sspc_warn(_v, ...)   lwsl_hexdump_sspc(_v, LLL_WARN, __VA_ARGS__)
+#define lwsl_hexdump_sspc_notice(_v, ...) lwsl_hexdump_sspc(_v, LLL_NOTICE, __VA_ARGS__)
+#define lwsl_hexdump_sspc_info(_v, ...)   lwsl_hexdump_sspc(_v, LLL_INFO, __VA_ARGS__)
+#define lwsl_hexdump_sspc_debug(_v, ...)  lwsl_hexdump_sspc(_v, LLL_DEBUG, __VA_ARGS__)
 
-struct lws_sspc_handle;
 
 LWS_VISIBLE LWS_EXTERN int
 lws_sspc_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
@@ -119,8 +223,7 @@ lws_sspc_request_tx_len(struct lws_sspc_handle *h, unsigned long len);
  *
  * \param h: secure streams handle
  *
- * Starts the connection process for the secure stream.  Returns 0 if OK or
- * nonzero if we have already failed.
+ * Starts the connection process for the secure stream.  Returns 0.
  */
 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
 lws_sspc_client_connect(struct lws_sspc_handle *h);
@@ -188,7 +291,7 @@ lws_sspc_rideshare(struct lws_sspc_handle *h);
  * when the policy is using h1 is interpreted to add h1 headers of the given
  * name with the value of the metadata on the left.
  *
- * Return 0 if OK.
+ * Return 0 if OK, or nonzero if failed.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
index 55587e1..863140d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * libwebsockets - small server side websockets and web server implementation
  *
- * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -158,6 +158,13 @@ enum {
        /**< stream is not critical and should be handled as cheap as poss */
        LWSSSPOLF_PERF                                          = (1 << 22),
        /**< capture and report performace information */
+       LWSSSPOLF_DIRECT_PROTO_STR                              = (1 << 23),
+       /**< metadata as direct protocol string, e.g. http header */
+       LWSSSPOLF_HTTP_CACHE_COOKIES                            = (1 << 24),
+       /**< Record http cookies and pass them back on future requests */
+       LWSSSPOLF_PRIORITIZE_READS                              = (1 << 25),
+       /**< prioritize clearing reads at expense of writes */
+
 };
 
 typedef struct lws_ss_trust_store {
@@ -197,6 +204,9 @@ typedef struct lws_ss_metadata {
 
        uint8_t                 value_length; /* only valid if set by policy */
        uint8_t                 value_is_http_token; /* valid if set by policy */
+#if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
+       uint8_t                 name_on_lws_heap:1;  /* proxy metatadata does this */
+#endif
        uint8_t                 value_on_lws_heap:1; /* proxy + rx metadata does this */
 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
        uint8_t                 pending_onward:1;
@@ -302,11 +312,16 @@ typedef struct lws_ss_policy {
                        const char      *will_topic;
                        const char      *will_message;
 
+                       const char      *birth_topic;
+                       const char      *birth_message;
+
                        uint16_t        keep_alive;
                        uint8_t         qos;
                        uint8_t         clean_start;
                        uint8_t         will_qos;
                        uint8_t         will_retain;
+                       uint8_t         birth_qos;
+                       uint8_t         birth_retain;
                        uint8_t         aws_iot;
 
                } mqtt;
index 0aa79ec..8157c70 100644 (file)
@@ -217,6 +217,15 @@ typedef enum {
        LWSSSCS_SERVER_TXN,
        LWSSSCS_SERVER_UPGRADE,         /* the server protocol upgraded */
 
+       LWSSSCS_EVENT_WAIT_CANCELLED, /* somebody called lws_cancel_service */
+
+       LWSSSCS_UPSTREAM_LINK_RETRY,    /* if we are being proxied over some
+                                        * intermediate link, this transient
+                                        * state may be sent to indicate we are
+                                        * waiting to establish that link before
+                                        * creation can proceed.. ack is the
+                                        * number of ms we have been trying */
+
        LWSSSCS_SINK_JOIN,              /* sinks get this when a new source
                                         * stream joins the sink */
        LWSSSCS_SINK_PART,              /* sinks get this when a new source
@@ -345,6 +354,11 @@ typedef lws_ss_state_return_t (*lws_sscb_state)(void *userobj, void *h_src,
                                                lws_ss_constate_t state,
                                                lws_ss_tx_ordinal_t ack);
 
+#if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
+typedef void (*lws_ss_buffer_dump_cb)(void *userobj, const uint8_t *buf,
+               size_t len, int done);
+#endif
+
 struct lws_ss_policy;
 
 typedef struct lws_ss_info {
@@ -377,6 +391,10 @@ typedef struct lws_ss_info {
        /**< advisory cb about state of stream and QoS status if applicable...
         * h_src is only used with sinks and LWSSSCS_SINK_JOIN/_PART events.
         * Return nonzero to indicate you want to destroy the stream. */
+#if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
+       lws_ss_buffer_dump_cb dump;
+       /**< cb to record needed protocol buffer data*/
+#endif
        int         manual_initial_tx_credit;
        /**< 0 = manage any tx credit automatically, nonzero explicitly sets the
         * peer stream to have the given amount of tx credit, if the protocol
@@ -436,7 +454,7 @@ typedef struct lws_ss_info {
  * formats, \p ppayload_fmt is set to point to the name of the needed payload
  * format from the policy database if non-NULL.
  */
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
              void *opaque_user_data, struct lws_ss_handle **ppss,
              struct lws_sequencer *seq_owner, const char **ppayload_fmt);
@@ -460,9 +478,9 @@ lws_ss_destroy(struct lws_ss_handle **ppss);
  * write on this stream, the \p *tx callback will occur with an empty buffer for
  * the stream owner to fill in.
  *
- * Returns 0 or LWSSSSRET_SS_HANDLE_DESTROYED
+ * Returns 0 or LWSSSSRET_DESTROY_ME
  */
-LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
 lws_ss_request_tx(struct lws_ss_handle *pss);
 
 /**
@@ -478,7 +496,7 @@ lws_ss_request_tx(struct lws_ss_handle *pss);
  * This api variant should be used when it's possible the payload will go out
  * over h1 with x-web-form-urlencoded or similar Content-Type.
  */
-LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
 lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len);
 
 /**
@@ -494,7 +512,7 @@ lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len);
  * LWSSSSRET_OK means the connection is ongoing.
  *
  */
-LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
 lws_ss_client_connect(struct lws_ss_handle *h);
 
 /**
index 2f597b3..73e498a 100644 (file)
@@ -59,7 +59,7 @@ lws_service(struct lws_context *context, int timeout_ms);
  * \param tsi:         Thread service index, starting at 0
  *
  * Same as lws_service(), but for a specific thread service index.  Only needed
- * if you are spawning multiple service threads.
+ * if you are spawning multiple service threads that operate on the same lws_context.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
index 5d57a1f..07900e0 100644 (file)
@@ -139,6 +139,7 @@ typedef enum { /* keep system_state_names[] in sync in context.c */
                                          * drop everything done with old
                                          * policy, switch to new then enter
                                          * LWS_SYSTATE_POLICY_VALID */
+       LWS_SYSTATE_CONTEXT_DESTROYING,  /* Context is being destroyed */
 } lws_system_states_t;
 
 /* Captive Portal Detect -related */
@@ -154,6 +155,11 @@ typedef enum {
 typedef void (*lws_attach_cb_t)(struct lws_context *context, int tsi, void *opaque);
 struct lws_attach_item;
 
+LWS_EXTERN LWS_VISIBLE int
+lws_tls_jit_trust_got_cert_cb(struct lws_context *cx, void *got_opaque,
+                             const uint8_t *skid, size_t skid_len,
+                             const uint8_t *der, size_t der_len);
+
 typedef struct lws_system_ops {
        int (*reboot)(void);
        int (*set_clock)(lws_usec_t us);
@@ -186,6 +192,15 @@ typedef struct lws_system_ops {
         * held in \p mdata... return 0 to leave the metric object as it is,
         * or nonzero to reset it. */
 
+       int (*jit_trust_query)(struct lws_context *cx, const uint8_t *skid,
+                              size_t skid_len, void *got_opaque);
+       /**< user defined trust store search, if we do trust a cert with SKID
+        * matching skid / skid_len, then it should get hold of the DER for the
+        * matching root CA and call
+        * lws_tls_jit_trust_got_cert_cb(..., got_opaque) before cleaning up and
+        * returning.  The DER should be destroyed if in heap before returning.
+        */
+
        uint32_t        wake_latency_us;
        /**< time taken for this device to wake from suspend, in us
         */
index 6fd6a0e..102a25f 100644 (file)
@@ -150,64 +150,6 @@ lws_set_timeout_us(struct lws *wsi, enum pending_timeout reason, lws_usec_t us);
 LWS_VISIBLE LWS_EXTERN void
 lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs);
 
-#if defined(LWS_WITH_DEPRECATED_THINGS)
-
-/*
- * lws_timed_callback_vh_protocol() - calls back a protocol on a vhost after
- *                                     the specified delay in seconds
- *
- * \param vh:   the vhost to call back
- * \param protocol: the protocol to call back
- * \param reason: callback reason
- * \param secs:        how many seconds in the future to do the callback.
- *
- * DEPRECATED since v4.1
- *
- * Callback the specified protocol with a fake wsi pointing to the specified
- * vhost and protocol, with the specified reason, at the specified time in the
- * future.
- *
- * Returns 0 if OK or 1 on OOM.
- *
- * In the multithreaded service case, the callback will occur in the same
- * service thread context as the call to this api that requested it.  If it is
- * called from a non-service thread, tsi 0 will handle it.
- */
-LWS_VISIBLE LWS_EXTERN int
-lws_timed_callback_vh_protocol(struct lws_vhost *vh,
-                              const struct lws_protocols *prot,
-                              int reason, int secs)
-LWS_WARN_DEPRECATED;
-
-/*
- * lws_timed_callback_vh_protocol_us() - calls back a protocol on a vhost after
- *                                      the specified delay in us
- *
- * \param vh:   the vhost to call back
- * \param protocol: the protocol to call back
- * \param reason: callback reason
- * \param us:  how many us in the future to do the callback.
- *
- * DEPRECATED since v4.1
- *
- * Callback the specified protocol with a fake wsi pointing to the specified
- * vhost and protocol, with the specified reason, at the specified time in the
- * future.
- *
- * Returns 0 if OK or 1 on OOM.
- *
- * In the multithreaded service case, the callback will occur in the same
- * service thread context as the call to this api that requested it.  If it is
- * called from a non-service thread, tsi 0 will handle it.
- */
-LWS_VISIBLE LWS_EXTERN int
-lws_timed_callback_vh_protocol_us(struct lws_vhost *vh,
-                                 const struct lws_protocols *prot, int reason,
-                                 lws_usec_t us)
-LWS_WARN_DEPRECATED;
-
-#endif
-
 struct lws_sorted_usec_list;
 
 typedef void (*sul_cb_t)(struct lws_sorted_usec_list *sul);
index 9af6c59..66b34b4 100644 (file)
@@ -259,11 +259,14 @@ lws_strexp_expand(lws_strexp_t *exp, const char *in, size_t len,
  * lws_strcmp_wildcard() - strcmp but the first arg can have wildcards
  *
  * \p wildcard: a string that may contain zero to three *, and may lack a NUL
- * \p len: length of the wildcard string
+ * \p wlen: length of the wildcard string
  * \p check: string to test to see if it matches wildcard
+ * \p clen: length of check string
  *
- * Exactly like strcmp, but supports patterns like "a*", "a*b", "a*b*" etc
- * where a and b are arbitrary substrings
+ * Like strcmp, but supports patterns like "a*", "a*b", "a*b*" etc
+ * where a and b are arbitrary substrings.  Both the wc and check strings need
+ * not be NUL terminated, but are specified by lengths.
  */
 LWS_VISIBLE LWS_EXTERN int
-lws_strcmp_wildcard(const char *wildcard, size_t len, const char *check);
+lws_strcmp_wildcard(const char *wildcard, size_t wlen, const char *check,
+                   size_t clen);
index 55b6600..e60d6d1 100644 (file)
@@ -47,6 +47,14 @@ enum lws_tls_cert_info {
         * -1 is returned and the size will be returned in buf->ns.len.
         * If the certificate cannot be found -1 is returned and 0 in
         * buf->ns.len. */
+       LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID,
+       /**< If the cert has one, the key ID responsible for the signature */
+       LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_ISSUER,
+       /**< If the cert has one, the issuer responsible for the signature */
+       LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_SERIAL,
+       /**< If the cert has one, serial number responsible for the signature */
+       LWS_TLS_CERT_INFO_SUBJECT_KEY_ID,
+       /**< If the cert has one, the cert's subject key ID */
 };
 
 union lws_tls_cert_info_results {
@@ -98,7 +106,7 @@ lws_x509_create(struct lws_x509_cert **x509);
  * IMPORTANT for compatibility with mbedtls, the last used byte of \p pem
  * must be '\0' and the \p len must include it.
  *
- * Returns 0 if all went OK.
+ * Returns 0 if all went OK, or nonzero for failure.
  */
 LWS_VISIBLE LWS_EXTERN int
 lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len);
@@ -140,6 +148,7 @@ lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
  * lws_x509_jwk_privkey_pem() - Copy a private key PEM into a jwk that has the
  *                             public part already
  *
+ * \param cx: lws_context (for random)
  * \param jwk: pointer to the jwk to initialize and set to the public key
  * \param pem: pointer to PEM private key in memory
  * \param len: length of PEM private key in memory
@@ -155,8 +164,8 @@ lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
  * The caller should take care to zero down passphrase if used.
  */
 LWS_VISIBLE LWS_EXTERN int
-lws_x509_jwk_privkey_pem(struct lws_jwk *jwk, void *pem, size_t len,
-                        const char *passphrase);
+lws_x509_jwk_privkey_pem(struct lws_context *cx, struct lws_jwk *jwk,
+                        void *pem, size_t len, const char *passphrase);
 
 /**
  * lws_x509_destroy() - Destroy a previously allocated lws_x509_cert object
@@ -183,8 +192,8 @@ lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
  * lws_tls_peer_cert_info() lets you get hold of information from the peer
  * certificate.
  *
- * Return 0 if there is a result in \p buf, or -1 indicating there was no cert
- * or another problem.
+ * Return 0 if there is a result in \p buf, or nonzero indicating there was no
+ * cert, or another problem.
  *
  * This function works the same no matter if the TLS backend is OpenSSL or
  * mbedTLS.
@@ -204,8 +213,8 @@ lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
  * lws_tls_vhost_cert_info() lets you get hold of information from the vhost
  * certificate.
  *
- * Return 0 if there is a result in \p buf, or -1 indicating there was no cert
- * or another problem.
+ * Return 0 if there is a result in \p buf, or nonzero indicating there was no
+ * cert, or another problem.
  *
  * This function works the same no matter if the TLS backend is OpenSSL or
  * mbedTLS.
@@ -223,8 +232,8 @@ lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
  * \param san_b: second SAN written into the certificate
  *
  *
- * Returns 0 if created and attached to the vhost.  Returns -1 if problems and
- * frees all allocations before returning.
+ * Returns 0 if created and attached to the vhost.  Returns nonzero if problems,
+ * and frees all allocations before returning.
  *
  * On success, any allocations are destroyed at vhost destruction automatically.
  */
index 1a58097..95cc75f 100644 (file)
@@ -6,11 +6,11 @@
        #endif
 #endif
 
-#define LWS_INSTALL_DATADIR "/usr/local/share"
-#define LWS_INSTALL_LIBDIR "/usr/local/lib"
+#define LWS_INSTALL_DATADIR "/usr/share"
+#define LWS_INSTALL_LIBDIR "/usr/lib"
 #define LWS_LIBRARY_VERSION_MAJOR 4
-#define LWS_LIBRARY_VERSION_MINOR 2
-#define LWS_LIBRARY_VERSION_PATCH_ELABORATED 0-submit/tizen/20210621.075049-4-g849b36a
+#define LWS_LIBRARY_VERSION_MINOR 3
+#define LWS_LIBRARY_VERSION_PATCH_ELABORATED 0-unknown
 #define LWS_LIBRARY_VERSION_PATCH 0
 
 /* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
@@ -25,7 +25,7 @@
 /* #undef LWS_EXT_PTHREAD_LIBRARIES */
 
 /* #undef LWS_AVOID_SIGPIPE_IGN */
-#define LWS_BUILD_HASH "submit/tizen/20210621.075049-4-g849b36a"
+#define LWS_BUILD_HASH "unknown"
 /* #undef LWS_BUILTIN_GETIFADDRS */
 #define LWS_CLIENT_HTTP_PROXYING
 /* #undef LWS_DETECTED_PLAT_IOS */
 #define LWS_HAVE_EVP_aes_192_cfb128
 #define LWS_HAVE_EVP_aes_256_cfb8
 #define LWS_HAVE_EVP_aes_256_cfb128
+#define LWS_HAVE_EVP_aes_128_ofb
 #define LWS_HAVE_EVP_aes_128_xts
+#define LWS_HAVE_EVP_aes_128_ctr
+#define LWS_HAVE_EVP_aes_128_ecb
 #define LWS_HAVE_EVP_PKEY_new_raw_private_key
 #define LWS_HAVE_EXECVPE
 #define LWS_HAVE_LOCALTIME_R
 /* #undef LWS_HAVE_mbedtls_ssl_set_hs_ca_chain */
 /* #undef LWS_HAVE_mbedtls_ssl_set_hs_own_cert */
 /* #undef LWS_HAVE_mbedtls_ssl_set_hs_authmode */
+/* #undef LWS_HAVE_mbedtls_ssl_set_verify */
+/* #undef LWS_HAVE_mbedtls_x509_crt_parse_file */
 /* #undef LWS_HAVE_MBEDTLS_NET_SOCKETS */
+/* #undef LWS_HAVE_MBEDTLS_AUTH_KEY_ID */
 /* #undef LWS_HAVE_NEW_UV_VERSION_H */
 #define LWS_HAVE_OPENSSL_ECDH_H
+#define LWS_HAVE_OPENSSL_STACK
 #define LWS_HAVE_PIPE2
 #define LWS_HAVE_EVENTFD
 #define LWS_HAVE_PTHREAD_H
@@ -87,7 +94,7 @@
 /* #undef LWS_HAVE_SSL_CTX_set_ciphersuites */
 #define LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
 #define LWS_HAVE_SSL_get0_alpn_selected
-#define LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key
+/* #undef LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key */
 #define LWS_HAVE_SSL_set_alpn_protos
 #define LWS_HAVE_SSL_SET_INFO_CALLBACK
 #define LWS_HAVE_SSL_SESSION_set_time
 /* #undef LWS_HAVE__STAT32I64 */
 #define LWS_HAVE_STDINT_H
 /* #undef LWS_HAVE_SYS_CAPABILITY_H */
+#define LWS_HAVE_TIMEGM
 #define LWS_HAVE_TLS_CLIENT_METHOD
 #define LWS_HAVE_TLSV1_2_CLIENT_METHOD
 #define LWS_HAVE_SUSECONDS_T
 #define LWS_HAVE_VFORK
 #define LWS_HAVE_X509_get_key_usage
 #define LWS_HAVE_X509_VERIFY_PARAM_set1_host
-#define LWS_LIBRARY_VERSION "4.2.0-submit/tizen/20210621.075049-4-g849b36a"
+#define LWS_LIBRARY_VERSION "4.3.0-unknown"
 #define LWS_LOGGING_BITFIELD_CLEAR 0
 #define LWS_LOGGING_BITFIELD_SET 0
 #define LWS_LOG_TAG_LIFECYCLE
 /* #undef LWS_SHA1_USE_OPENSSL_NAME */
 #define LWS_SSL_CLIENT_USE_OS_CA_CERTS
 /* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
-/* #undef LWS_SUPPRESS_DEPRECATED_API_WARNINGS */
+#define LWS_SUPPRESS_DEPRECATED_API_WARNINGS
 /* #undef LWS_TLS_LOG_PLAINTEXT_RX */
 /* #undef LWS_TLS_LOG_PLAINTEXT_TX */
 /* #undef LWS_WITH_ABSTRACT */
 /* #undef LWS_WITH_BORINGSSL */
 /* #undef LWS_WITH_CGI */
 #define LWS_WITH_CONMON
+/* #undef LWS_WITH_COSE */
 #define LWS_WITH_CUSTOM_HEADERS
 /* #undef LWS_WITH_DEPRECATED_LWS_DLL */
 /* #undef LWS_WITH_DETAILED_LATENCY */
 #define LWS_WITH_HTTP_UNCOMMON_HEADERS
 #define LWS_WITH_IPV6
 /* #undef LWS_WITH_JOSE */
+/* #undef LWS_WITH_CBOR */
+#define LWS_WITH_CBOR_FLOAT
 #define LWS_WITH_LEJP
 /* #undef LWS_WITH_LIBEV */
 /* #undef LWS_WITH_LIBEVENT */
 /* #undef LWS_WITH_NETLINK */
 #define LWS_WITH_NETWORK
 /* #undef LWS_WITH_NO_LOGS */
+#define LWS_WITH_CACHE_NSCOOKIEJAR
 #define LWS_WITH_CLIENT
 #define LWS_WITHOUT_EXTENSIONS
 #define LWS_WITH_SERVER
 /* #undef LWS_WITH_SECURE_STREAMS_PROXY_API */
 /* #undef LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY */
 /* #undef LWS_WITH_SECURE_STREAMS_AUTH_SIGV4 */
+/* #undef LWS_WITH_SECURE_STREAMS_BUFFER_DUMP */
+/* #undef LWS_WITH_SS_DIRECT_PROTOCOL_STR */
 /* #undef LWS_WITH_SELFTESTS */
 /* #undef LWS_WITH_SEQUENCER */
 /* #undef LWS_WITH_SERVER_STATUS */
 #define LWS_WITH_SYS_STATE
 /* #undef LWS_WITH_THREADPOOL */
 #define LWS_WITH_TLS
+/* #undef LWS_WITH_TLS_JIT_TRUST */
 #define LWS_WITH_TLS_SESSIONS
 #define LWS_WITH_UDP
 /* #undef LWS_WITH_ULOOP */
 /* #undef LWS_WITH_EVLIB_PLUGINS */
 /* #undef LWS_WITH_LIBUV_INTERNAL */
 /* #undef LWS_WITH_PLUGINS_API */
-#define LWS_HAVE_RTA_PREF
+/* #undef LWS_HAVE_RTA_PREF */