1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00
Commit graph

44 commits

Author SHA1 Message Date
Andy Green
21697b3210 ss: handle DESTROY_ME from inside ss creation
Normally when doing a Client Connection Error handling,
we can action any ss relationship straight away since
we are in a wsi callback without any ss-aware parents
in the call stack.

But in the specific case we're doing the initial onward
wsi connection part on behalf of a ss, in fact the call
stack does have earlier  parents holding references on
the related ss.

For example

  secstream_h1 (ss-h1.c:470)                          CCE
  lws_inform_client_conn_fail (close.c:319)           fails early
  lws_client_connect_2_dnsreq (connect2.c:349)
  lws_http_client_connect_via_info2 (connect.c:71)
  lws_header_table_attach (parsers.c:291)
  rops_client_bind_h1 (ops-h1.c:1001)
  lws_client_connect_via_info (connect.c:429)         start onward connect
  _lws_ss_client_connect (secure-streams.c:859)
  _lws_ss_request_tx (secure-streams.c:1577)
  lws_ss_request_tx (secure-streams.c:1515)           request tx
  ss_cpd_state (captive-portal-detect.c:50)
  lws_ss_event_helper (secure-streams.c:408)
  lws_ss_create (secure-streams.c:1256)                SS Create

Under these conditions, we can't action the DESTROY_ME that
is coming when the CCE exhausts the retries.

This patch adds a flag that is set during the SS's onward wsi
connection attempt and causes it to stash rather than action
the result code.

The result code is brought out from the stash when we return to
_lws_ss_client_connect level, and passed up in the SS flow until
it is actioned, cleanly aborting the ss create.
2021-08-13 05:47:00 +01:00
Jed Lu
c3dd4d05fe ss: sspc: handle destroy for client_connect and request_tx 2021-06-06 11:46:06 +01:00
Andy Green
a0bebb9f67 ss: proxy: fix conn deref on onward
Trying to use the opaque pointer in the handle to point to the conn isn't
going to work when we need it to point to the ss handle.

Move it to have its on place in the handle.
2021-04-21 19:31:45 +01:00
Andy Green
42dc817d8f ss: proxy: get rx flow control working
This fixes the proxy rx flow by adding an lws_dsh helper to hide the
off-by-one in the "kind" array (kind 0 is reserved for tracking the
unallocated dsh blocks).

For testing, it adds a --blob option on minimal-secure-streams[-client]
which uses a streamtype "bulkproxflow" from here

https://warmcat.com/policy/minimal-proxy-v4.2-v2.json

		"bulkproxflow": {
			"endpoint": "warmcat.com",
			"port": 443,
			"protocol": "h1",
			"http_method": "GET",
			"http_url": "blob.bin",
			"proxy_buflen": 32768,
			"proxy_buflen_rxflow_on_above": 24576,
			"proxy_buflen_rxflow_off_below": 8192,
			"tls": true,
			"retry": "default",
			"tls_trust_store": "le_via_dst"
		}

This downloads a 51MB blob of random data with the SHA256sum

ed5720c16830810e5829dfb9b66c96b2e24efc4f93aa5e38c7ff4150d31cfbbf

The minimal-secure-streams --blob example client delays the download by
50ms every 10KiB it sees to force rx flow usage at the proxy.

It downloads the whole thing and checks the SHA256 is as expected.

Logs about rxflow status are available at LLL_INFO log level.
2021-04-07 15:54:26 +01:00
Andy Green
d291c02a23 ss: sspc: add conmon performance telemetry
This provides a way to get ahold of LWS_WITH_CONMON telemetry from Secure
Streams, it works the same with direct onward connections or via the proxy.

You can mark streamtypes with a "perf": true policy attribute... this
causes the onward connections on those streamtypes to collect information
about the connection performance, and the unsorted DNS results.

Streams with that policy attribute receive extra data in their rx callback,
with the LWSSS_FLAG_PERF_JSON flag set on it, containing JSON describing the
performance of the onward connection taken from CONMON data, in a JSON
representation.  Streams without the "perf" attribute set never receive
this extra rx.

The received JSON is based on the CONMON struct info and looks like

{"peer":"46.105.127.147","dns_us":596,"sockconn_us":31382,"tls_us":28180,"txn_resp_us:23015,"dns":["2001:41d0:2:ee93::1","46.105.127.147"]}

A new minimal example minimal-secure-streams-perf is added that collects
this data on an HTTP GET from warmcat.com, and is built with a -client
version as well if LWS_WITH_SECURE_STREAMS_PROXY_API is set, that operates
via the ss proxy and produces the same result at the client.
2021-04-05 10:55:04 +01:00
Andy Green
51490ae6e6 Fault injection
add lws_xos: xoshiro256 PRNG
2021-04-05 10:55:04 +01:00
Andy Green
546c151555 ss: add set_metadata that takes a heap copy and make ss-h1 use it
Until now we set metadata value pointers into the onward wsi ah data
area... that's OK until we get a situation the wsi has gone away before we
have a chance to deliver the metadata over the proxy link.

Add a variant lws_ss_alloc_set_metadata() that allocates space on the heap
and takes a copy of the input metadata.  Change ss-h1 to alloc copies of
its metadata so we no longer race the wsi ah lifetime.
2021-03-14 15:05:18 +00:00
Andy Green
3f4623bb36 lws_metrics
There are a few build options that are trying to keep and report
various statistics

 - DETAILED_LATENCY
 - SERVER_STATUS
 - WITH_STATS

remove all those and establish a generic rplacement, lws_metrics.

lws_metrics makes its stats available via an lws_system ops function
pointer that the user code can set.

Openmetrics export is supported, for, eg, prometheus scraping.
2021-03-08 21:47:28 +00:00
Andy Green
14c5b7ebaf ss: state violations need to report lifecycle tags
The state tracking and violation detection is very powerful at enforcing
only legal transitions, but if it's busy, we don't get to see which stream
had to problem.  Add a pointer to the handle lc tag, do that rather than
just pass the handle so we can deal with ss and sspc handles cleanly.
2021-02-20 13:54:37 +00:00
Andy Green
3fe08ce5d8 fault injection 2021-02-20 13:54:35 +00:00
Jed Lu
780a165a76 ss: http: mime parsing with unusual section boundaries 2021-01-11 08:12:46 +00:00
Andy Green
aa45de9e2a ss: enforce only valid state transitions
The various stream transitions for direct ss, SSPC, smd, and
different protocols are all handled in different code, let's
stop hoping for the best and add a state transition validation
function that is used everywhere we pass a state change to a
user callback, and knows what is valid for the user state()
callback to see next, given the last state it was shown.

Let's assert if lws manages to violate that so we can find
where the problem is and provide a stricter guarantee about
what user state handler will see, no matter if ss or sspc
or other cases.

To facilitate that, move the states to start from 1, where
0 indicates the state unset.
2021-01-11 08:12:43 +00:00
Andy Green
1033e1d4c8 sspc: ssv1: pass client PID into proxy for tagging
Let's have the client processes pass in their pid, and tag the related proxy SS
with that pid, so we can see on whose behalf the proxy is acting.
2021-01-05 10:56:38 +00:00
Andy Green
4fc4c671fa sspc: ssv1: add serialization protocol versioning
Let's add a byte on the first message that sspc clients send,
indicating the version of the serialization protocol that the
client was built with.

Start the version at 1, we will add some more changes in other
patches and call v1 (now it has the versioning baked in)
the first real supported serialization version, this patch must
be applied with the next patches to actually represent v1
protocol changes.

This doesn't require user setting, the client is told what version
it supports in LWS_SSS_CLIENT_PROTOCOL_VERSION.  The proxy knows
what version(s) it can support and loudly hangs up on the client
if it doesn't understand its protocol version.
2021-01-05 10:56:38 +00:00
Jed Lu
c82910d30c ss: auth: sigv4
Add SS pieces for Sigv4 auth support
2021-01-05 10:56:38 +00:00
Andy Green
940abe557a ss: policy: add auth mapping section 2021-01-05 10:56:38 +00:00
Andy Green
e11d78dc5e sspc: cleanup bridged wsi 2021-01-04 05:40:12 +00:00
Andy Green
905e5373c6 ss: proxy_buflen in policy sets proxy max dsh alloc per streamtype 2021-01-04 05:39:06 +00:00
Andy Green
93f54c61c5 ss: enforce balanced CONNECT vs DISCONNECT 2021-01-04 05:26:50 +00:00
Andy Green
0ceba15d9c lws_lifecycle
This adds some new objects and helpers for keeping and logging
info on grouped allocations, a group is, eg, SS handles or client
wsis.

Allocated objects get a context-unique "tag" string intended to replace
%p / wsi pointers etc.  Pointers quickly become confusing when
allocations are freed and reused, the tag string won't repeat
until you produce 2^64 objects in a context.

In addition the tag string documents the object group, with prefixes
like "wsi-" or "vh-" and contain object-specific additional
information like the vhost name, address / port  or the role of the wsi.
At creation time the lws code can use a format string and args
to add whatever group-specific info makes sense, eg, a wsi bound
to a secure stream can also append the guid of the secure stream,
it's copied into the new object tag and so is still available
cleanly after the stream is destroyed if the wsi outlives it.
2021-01-04 05:26:50 +00:00
Andy Green
097bbbd1eb ss: client_connect and request_tx also return dispositions
Since client_connect and request_tx can be called from code that expects
the ss handle to be in scope, these calls can't deal with destroying the
ss handle and must pass the lws_ss_state_return_t disposition back to
the caller to handle.
2020-12-24 16:14:36 +00:00
Andy Green
3216d4d087 ss: server: add foreach client cb api
Server SS maintains a list of accepted client ss, add an api allowing
iterating through the clients via a user callback.
2020-11-11 06:58:20 +00:00
Jed Lu
ee78b90c8c ss: take care to free any metadata heap values before overwrite
Break out the core ss_set_metadata action into a subfunction that
takes the lws_ss_metadata_t, and is fixed to retire heap-based
values before they go out of scope, and adapt the exported version
to call through to that.

Simplify extract_metadata() to reuse the subfunction as well, in
both well-known and custom header cases.
2020-10-07 19:20:12 +01:00
Andy Green
49e92ba089 http: add RFC7231 date and time helpers and retry-after handling
Teach lws how to deal with date: and retry-after:

Add quick selftest into apt-test-lws_tokenize

Expand lws_retry_sul_schedule_retry_wsi() to check for retry_after and
increase the backoff if a larger one found.

Finally, change SS h1 protocol to handle 503 + retry-after: as a
failure, and apply any increased backoff from retry-after
automatically.
2020-09-19 14:11:56 +01:00
Andy Green
33da902ed4 ss: policy: response code mapping
This adds a per-streamtype JSON mapping table in the policy.

In addition to the previous flow, it lets you generate custom
SS state notifications for specific http response codes, eg:

   "http_resp_map": [ { "530": 1530 }, { "531": 1531 } ],

It's not recommended to overload the transport-layer response
code with application layer responses.  It's better to return
a 200 and then in the application protocol inside http, explain
what happened from the application perspective, usually with
JSON.  But this is designed to let you handle existing systems
that do overload the transport layer response code.

SS states for user use start at LWSSSCS_USER_BASE, which is
1000.

You can do a basic test with minimal-secure-streams and --respmap
flag, this will go to httpbin.org and get a 404, and the warmcat.com
policy has the mapping for 404 -> LWSSSCS_USER_BASE (1000).

Since the mapping emits states, these are serialized and handled
like any other state in the proxy case.

The policy2c example / tool is also updated to handle the additional
mapping tables.
2020-09-16 13:10:26 +01:00
Andy Green
101b474217 ss: rx metadata
At the moment you can define and set per-stream metadata at the client,
which will be string-substituted and if configured in the policy, set in
related outgoing protocol specific content like h1 headers.

This patch extends the metadata concept to also check incoming protocol-
specific content like h1 headers and where it matches the binding in the
streamtype's metadata entry, make it available to the client by name, via
a new lws_ss_get_metadata() api.

Currently warmcat.com has additional headers for

server: lwsws                (well-known header name)
test-custom-header: hello    (custom header name)

minimal-secure-streams test is updated to try to recover these both
in direct and -client (via proxy) versions.  The corresponding metadata
part of the "mintest" stream policy from warmcat.com is

                        {
                                "srv": "server:"
                        }, {
                                "test": "test-custom-header:"
                        },

If built direct, or at the proxy, the stream has access to the static
policy metadata definitions and can store the rx metadata in the stream
metadata allocation, with heap-allocated a value.  For client side that
talks to a proxy, only the proxy knows the policy, and it returns rx
metadata inside the serialized link to the client, which stores it on
the heap attached to the stream.

In addition an optimization for mapping static policy metadata definitions
to individual stream handle metadata is changed to match by name.
2020-09-16 13:10:26 +01:00
Andy Green
936e1c71ce sspc: client: call CREATING on linkup to proxy
Before this we simply proxy the CREATING state from the proxy
version of the stream to the client version of the stream.

However this can result in disordering of onward connection
attempt request happening before the client has called back its
CREATING (*state()), meaning that any metadata set in the
state handler is missed for the onward connection.

This patch suppresses the CREATING forwarded from the proxy
and instead does its own local CREATING state callback at the
time the proxy indicates that the remote stream creation
(ie, with the requested policy streamtype) succeeded.

This then guarantees that the client has seen CREATING, and
had a chance to set metadata there, before the onward connection
request goes out.  Since metadata has higher priority at the
writeable than the onward connection request it also means
any metadata set in client CREATING gets sync'd to the proxy
before the onward connection.
2020-09-04 12:59:34 +01:00
Andy Green
4ae3ef51c1 ss: improve callback return consistency
Formalize the LWSSSSRET_ enums into a type "lws_ss_state_return_t"
returned by the rx, tx and state callbacks, and some private helpers
lws_ss_backoff() and lws_ss_event_helper().

Remove LWSSSSRET_SS_HANDLE_DESTROYED concept... the two helpers that could
have destroyed the ss and returned that, now return LWSSSSRET_DESTROY_ME
to the caller to perform or pass up to their caller instead.

Handle helper returns in all the ss protocols and update the rx / tx
calls to have their returns from rx / tx / event helper and ss backoff
all handled by unified code.
2020-08-31 16:51:37 +01:00
Jed Lu
3b9e468516 ss: protect against reentry in lws_destroy 2020-08-31 16:51:37 +01:00
Andy Green
83912f40e8 sspc: proxy: extend DESTROY_ME 2020-08-17 14:36:33 +01:00
Andy Green
1b4bf38d5e sspc: add request_tx length variant
Add in the missing request_tx length variant, serialization and proxy
handling for it
2020-08-10 15:04:10 +01:00
Andy Green
a6a9f22556 sspc: LWSSSPC: track onward request status 2020-08-10 15:04:10 +01:00
Andy Green
7eb36102a9 ss: server: h1, h2, ws basic support
Add initial support for defining servers using Secure Streams
policy and api semantics.

Serving h1, h2 and ws should be functional, the new minimal
example shows a combined http + SS server with an incrementing
ws message shown in the browser over tls, in around 200 lines
of user code.

NOP out anything to do with plugins, they're not currently used.

Update the docs correspondingly.
2020-07-27 12:05:24 +01:00
Andy Green
625bade63e ss: static policy: dynamic vhost instantiation
Presently a vh is allocated per trust store at policy parsing-time, this
is no problem on a linux-class device or if you decide you need a dynamic
policy for functionality reasons.

However if you're in a constrained enough situation that the static policy
makes sense, in the case your trust stores do not have 100% duty cycle, ie,
are anyway always in use, the currently-unused vhosts and their x.509 stack
are sitting there taking up heap for no immediate benefit.

This patch modifies behaviour in ..._STATIC_POLICY_ONLY so that vhosts and
associated x.509 tls contexts are not instantiated until a secure stream using
them is created; they are refcounted, and when the last logical secure
stream using a vhost is destroyed, the vhost and its tls context is also
destroyed.

If another ss connection is created that wants to use the trust store, the
vhost and x.509 context is regenerated again as needed.

Currently the refcounting is by ss, it's also possible to move the refcounting
to be by connection.  The choice is between the delay to generate the vh
being visisble at logical ss creation-time, or at connection-time.  It's anyway
not preferable to have ss instantiated and taking up space with no associated
connection or connection attempt underway.

NB you will need to reprocess any static policies after this patch so they
conform to the trust_store changes.
2020-07-21 12:43:32 +01:00
Andy Green
f902873634 ss: add timeout 2020-07-07 11:28:28 +01:00
Andy Green
64aee81ba7 ss: reset retry count for explicit connection request
This differentiates between client connections for retry / writeable requests
and explicit lws_ss_client_connect() api calls.  The former effectively uses
retry / backoff, and the latter resets the retry / backoff.

If you receive ALL_RETRIES_FAILED due to the retry policy, you can do whatever
you need to do there and call lws_ss_client_connect() to try to connect again
with a fresh, reset retry / backoff state.
2020-06-30 19:35:41 +01:00
Andy Green
8eca7e17f2 lws_smd: system message distribution
- Add low level system message distibution framework
 - Add support for local Secure Streams to participate using _lws_smd streamtype
 - Add apit test and minimal example
 - Add SS proxy support for _lws_smd

See minimal-secure-streams-smd README.md
2020-06-27 07:57:22 +01:00
Andy Green
c9f31bdceb ss-mqtt: additional strexp in MQTT policy elements
Allow usage of ${metadata} string substitution in more policy elements
for MQTT:

 - associated subscription topic in policy
 - associated publish topic in policy
 - associated will topic in policy
 - associated will message in policy

Tested against lws-minimal-mqtt-client-multi / mosquitto
2020-06-16 19:45:35 +01:00
Andy Green
2d55e18947 ss: windows build adaptations
Windows compiler finds various non-bug things to complain about when
building with SS and other options, fix them up
2020-04-06 20:25:06 +01:00
Andy Green
e26f83bd83 ss: add support for raw-skt protocol 2020-03-28 16:20:50 +00:00
Andy Green
4cc7f4ed02 ss: add static policy as a build option
In some cases devices may be too constrained to handle JSON policies but still
want to use SS apis and methodology.

This introduces an off-by-default cmake option LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY,
if enabled the JSON parsing part is excluded and it's assumed the user code
provides its policy as hardcoded policy structs.
2020-03-26 06:48:34 +00:00
Andy Green
704eaa5e63 ss: allow streamtype policy overlays
Make the policy load apis public with an extra argument that says if you want the
JSON to overlay on an existing policy rather than replace it.

Teach the stream type parser stuff to realize it already has an entry for the
stream type and to modify that rather than create a second one, allowing overlays
to modify stream types.

Add --force-portal and --force-no-internet flags to minimal-secure-streams and
use the new policy overlay stuff to force the policy for captive portal detection
to feel that there is one or that there's no internet.
2020-03-14 17:04:43 +00:00
Andy Green
a60cb84c9e captive portal
Implement Captive Portal detection support in lws, with the actual
detection happening in platform code hooked up by lws_system_ops_t.

Add an implementation using Secure Streams as well, if the policy
defines captive_portal_detect streamtype, a SS using that streamtype
is used to probe if it's behind a captive portal.
2020-03-11 12:44:01 +00:00
Andy Green
28ce32af64 client: secure streams
Secure Streams is an optional layer on top of lws that separates policy
like endpoint selection and tls cert validation into a device JSON
policy document.

Code that wants to open a client connection just specifies a streamtype name,
and no longer deals with details like the endpoint, the protocol (!) or anything
else other than payloads and optionally generic metadata; the JSON policy
contains all the details for each streamtype.  h1, h2, ws and mqtt client
connections are supported.

Logical secure streams outlive any particular connection and supports "nailed-up"
connectivity regardless of underlying connection stability.
2020-03-04 12:17:49 +00:00