%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
#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
#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>
#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
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
#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>
#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>
--- /dev/null
+/*
+ * 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;
+
+///@}
+
* 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.
*/
/*
* 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
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
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;
* 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
*
* \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
*/
///@{
-/* enough for 4191us, or just over an hour */
+/* enough for 4191s, or just over an hour */
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.
/**< 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 */
};
/**
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
* 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
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
#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
*
/* 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 */
};
///@}
--- /dev/null
+/*
+ * 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);
+
+//@}
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);
/*
* 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);
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);
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 {
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
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
};
* type.
*/
-struct lws_gencrypto_keyelem {
+typedef struct lws_gencrypto_keyelem {
uint8_t *buf;
uint32_t len;
-};
+} lws_gc_elem_t;
/**
*/
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
*
* \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.
*
*
* \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);
*
* \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);
* 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);
* \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
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
*
* 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
*/
* \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,
* \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,
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 */
};
lws_jwk_key_import_callback per_key_cb;
void *user;
int pos;
+ int cose_state;
+ int seen;
unsigned short possible;
};
* \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,
* \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,
* 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,
* (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,
* 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 */
* 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,
};
/**
- * 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
--- /dev/null
+/*
+ * 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);
+
+//@}
#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 {
/*
* 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
#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
*/
* depending on what was computed
*/
+/*
+ * Process scope logs
+ */
+
#if (_LWS_ENABLED_LOGS & LLL_ERR)
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
#else
#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
*
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)
*
* 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
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);
+
///@}
--- /dev/null
+/*
+ * 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);
+
+//@}
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
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;
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;
/* 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),
* \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);
* \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);
* 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
*
* 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,
*
* \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);
* 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,
/*
* 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
/**< 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 {
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;
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;
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
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 {
/**< 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
* 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);
* 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);
/**
* 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);
/**
* 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);
/**
* \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);
* 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 */
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);
* 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
*/
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);
* 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);
* -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 {
* 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);
* 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
* 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
* 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.
* 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.
* \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.
*/
#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 */
/* #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
/* #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 */