libwebsockets
Lightweight C library for HTML5 websockets
Loading...
Searching...
No Matches
lws-secure-streams-serialization.h
Go to the documentation of this file.
1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * included from libwebsockets.h
25 *
26 * This defines the Serialized Secure Streams framing, and the optional
27 * lws_transport_mux framing.
28 *
29 * APIs are declared for lws_transport and binding those to the SSPC and proxy
30 * sides in lws.
31 */
32
33#if defined(STANDALONE)
35#define lws_context lws_context_standalone
36#endif
37
38#define LWSSSS_VERSION 1
39
40typedef enum {
41 /*
42 * This is the Serialized Serure Streams framing. It's sufficient to
43 * carry all SS API actions over a point-to-point bytestream between
44 * an SSPC client and an SS oroxy, in both directions.
45 *
46 * These serialized streams may be multiplexed by the transport (eg,
47 * for unix domain sockets transport, each SS opens its own UDS socket
48 * to the proxy) or via lws_transport_mux framing encapsulation.
49 *
50 *
51 * Framing for Proxy -> Client direction
52 */
53
55 /*
56 * Proxied rx
57 *
58 * - 0: LWSSS_SER_RXPRE_RX_PAYLOAD
59 * - 1: 2 byte MSB-first rest-of-frame length
60 * - 3: 4-byte MSB-first flags
61 * - 7: 4-byte MSB-first us between inbound read and wrote to client
62 * - 11: 8-byte MSB-first us resolution unix time proxy wrote to client
63 * - 17: (rideshare name len + rideshare name if flags &
64 * LWSSS_FLAG_RIDESHARE) payload
65 */
67 /*
68 * Proxied connection setup result
69 *
70 * - 0: LWSSS_SER_RXPRE_CREATE_RESULT
71 * - 1: 2 byte MSB-first rest-of-frame length (at least 00, 05)
72 * - 3: 1 byte result, 0 = success. On failure, the client closes
73 * the connection.
74 * - 4: 4 byte MSB-first client dsh allocation recommended for the
75 * stream type, from policy (introduced in SSSv1)
76 * - 8: if present, comma-sep list of rideshare types from policy
77 */
79 /*
80 * Proxied state (8 or 11 byte packet)
81 *
82 * - 0: LWSSS_SER_RXPRE_CONNSTATE
83 * - 1: 00, 05 if state < 256, else 00, 08
84 * - 3: 1 byte state index if state < 256, else 4-byte MSB-first
85 * state index
86 * - 4 or 7: 4-byte MSB-first ordinal
87 */
89 /*
90 * Proxied tx credit
91 *
92 * - 0: LWSSS_SER_RXPRE_TXCR_UPDATE
93 * - 1: 00, 04
94 * - 3: 4-byte MSB-first addition tx credit bytes
95 */
97 /*
98 * Proxied rx metadata
99 *
100 * - 0: LWSSS_SER_RXPRE_METADATA
101 * - 1: 2-byte MSB-first rest-of-frame length
102 * - 3: 1-byte metadata name length
103 * - 4: metadata name
104 * - ...: metadata value (for rest of packet)
105 */
107 /* reserved */
109 /*
110 * Proxied performance information
111 *
112 * - 0: LWSSS_SER_RXPRE_PERF
113 * - 1: 2-byte MSB-first rest-of-frame length
114 * - 3: ... performance JSON (for rest of packet)
115 */
116
117 /*
118 * Framing for Client -> Proxy direction
119 */
120
122 /*
123 * Proxied connection setup
124 *
125 * - 0: LWSSS_SER_TXPRE_STREAMTYPE
126 * - 1: 2-byte MSB-first rest-of-frame length
127 * - 3: 1-byte Client SSS protocol version (introduced in SSSv1)
128 * - 4: 4-byte Client PID (introduced in SSSv1)
129 * - 8: 4-byte MSB-first initial tx credit
130 * - 12: the streamtype name with no NUL
131 */
133 /*
134 * Proxied request for onward connection
135 *
136 * - 0: LWSSS_SER_TXPRE_ONWARD_CONNECT
137 * - 1: 00, 00
138 */
140 /*
141 * Proxied secure stream destroy
142 *
143 * - 0: LWSSS_SER_TXPRE_DESTROYING
144 * - 1: 00, 00
145 */
147 /*
148 * Proxied tx
149 *
150 * - 0: LWSSS_SER_TXPRE_TX_PAYLOAD
151 * - 1: 2 byte MSB-first rest-of-frame length
152 * - 3: 4-byte MSB-first flags
153 * - 7: 4-byte MSB-first us between client requested write and wrote
154 * to proxy
155 * - 11: 8-byte MSB-first us resolution unix time client wrote to proxy
156 * - 19: ...payload (for rest of packet)
157 */
159 /*
160 * Proxied metadata - sent when one metadata item set clientside
161 *
162 * - 0: LWSSS_SER_TXPRE_METADATA
163 * - 1: 2-byte MSB-first rest-of-frame length
164 * - 3: 1-byte metadata name length
165 * - 4: metadata name
166 * - ...: metadata value (for rest of packet)
167 */
169 /*
170 * TX credit management - sent when using tx credit apis, cf METADATA
171 *
172 * - 0: LWSSS_SER_TXPRE_TXCR_UPDATE
173 * - 1: 2-byte MSB-first rest-of-frame length 00, 04
174 * - 3: 4-byte additional tx credit adjust value
175 */
177 /*
178 * Stream timeout management - forwarded when user applying or
179 * cancelling t.o.
180 *
181 * - 0: LWSSS_SER_TXPRE_TIMEOUT_UPDATE
182 * - 1: 2-byte MSB-first rest-of-frame length 00, 04
183 * - 3: 4-byte MSB-first unsigned 32-bit timeout,
184 * 0 = use policy, -1 = cancel
185 */
187 /*
188 * Passing up payload length hint
189 *
190 * - 0: LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT
191 * - 1: 2-byte MSB-first rest-of-frame length 00, 04
192 * - 3: 4-byte MSB-first unsigned 32-bit payload length hint
193 */
195 /* reserved */
198
199/* SSPC serialization states */
200
201 typedef enum {
202 LPCSPROX_WAIT_INITIAL_TX = 1, /* after connect, must send streamtype */
203 LPCSPROX_REPORTING_FAIL, /* stream creation failed, wait to to tell */
204 LPCSPROX_REPORTING_OK, /* stream creation succeeded, wait to to tell */
205 LPCSPROX_OPERATIONAL, /* ready for payloads */
207
208 LPCSCLI_SENDING_INITIAL_TX, /* after connect, must send streamtype */
209 LPCSCLI_WAITING_CREATE_RESULT, /* wait to hear if proxy ss create OK */
210 LPCSCLI_LOCAL_CONNECTED, /* we are in touch with the proxy */
211 LPCSCLI_ONWARD_CONNECT, /* request onward ss connection */
212 LPCSCLI_OPERATIONAL, /* ready for payloads */
213
215
216 /*
217 * Optional multiplexing layer
218 *
219 * Either side can:
220 *
221 * - open and close channels asynchronously
222 * - send and receive transport-level (not mux channel) timed PINGs / PONGs
223 * - send and receive data bound to an open mux channel
224 *
225 * PONGs are produced and sent automatically on recipt of a PING from the peer
226 * The peer sends a PONGACK so the single transaction can validate connection
227 * viability in both directions.
228 */
229
230 enum {
311};
312
313typedef void * lws_transport_priv_t; /* care - this is a pointer type already */
314struct lws_transport_mux;
315struct lws_sss_proxy_conn;
318struct lws_sspc_handle;
319
320/*
321 * These describe the path through different transport layers. Each has an
322 * 'in' and 'onw' (onward) side that can be bound to different parts in lws.
323 * SSPC and the SS Proxy code in lws each exposes one of these as terminals
324 * for the "path" to handle the SS Serialization on each side.
325 *
326 * sspc-transport-wsi and proxy-transport-wsi expose possible endpoints for the
327 * paths, so you can simply "wire SSPC and proxy up to a wsi transport".
328 *
329 * You can also create a lws_transport_mux_t and interpose it in the transport
330 * path on each side, and produce your own custom lws_transport ops implementing
331 * arbitrary transport support.
332 */
333
341
349
350/*
351 * Operations for client-side transport
352 */
353
355 const char *name;
356
358 struct lws_sspc_handle *h);
361 struct lws_sspc_handle *h, int disposition);
365 int (*_write)(lws_transport_priv_t priv, uint8_t *buf, size_t len);
369 const uint8_t *buf, size_t len);
379 lws_ss_state_return_t (*event_can_write)(struct lws_sspc_handle *h,
380 size_t metadata_limit);
382 lws_ss_state_return_t (*event_closed)(lws_transport_priv_t priv /*struct lws_sspc_handle *h */);
388
389/*
390 * Operations for proxy-side transport
391 */
392
394 const char *name;
395 int (*init_proxy_server)(struct lws_context *context,
396 const struct lws_transport_proxy_ops *txp_ops_inward,
397 lws_transport_priv_t txp_priv_inward,
398 lws_txp_path_proxy_t *txp_ppath, const void *aux,
399 const char *bind, int port);
402 int (*destroy_proxy_server)(struct lws_context *context);
403 lws_ss_state_return_t (*event_new_conn)(struct lws_context *cx,
404 const struct lws_transport_proxy_ops *txp_ops_inward,
405 lws_transport_priv_t txp_priv_inward,
406 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
407 const lws_fi_ctx_t *fic,
408 #endif
409 struct lws_sss_proxy_conn **conn,
410 lws_transport_priv_t txp_priv);
413 struct lws_ss_handle *h);
419#if defined(LWS_WITH_SYS_FAULT_INJECTION)
420 , const lws_fi_ctx_t *fic
421#endif
422 );
424 int (*proxy_write)(lws_transport_priv_t priv, uint8_t *buf, size_t *len);
429 struct lws_sss_proxy_conn *conn);
431#if defined(LWS_WITH_SYS_FAULT_INJECTION)
432 const lws_fi_ctx_t * (*fault_context)(lws_transport_priv_t priv);
434#endif
435 lws_ss_state_return_t (*close_conn)(struct lws_sss_proxy_conn *conn);
438 const uint8_t *buf, size_t len);
443 uint32_t flags; /* dsh flags */
445
446/* lws_transport_mux parser states */
447
458
459/* lws_transport_mux channel definitions */
460
462#define LWS_MUCH_RANGE 256
463
464/* lws_transport mux states */
465
466enum {
467 /* lws_transport_mux_ch_t created */
468 LWSTMC_PENDING_CREATE_CHANNEL, /* waiting to send create channel */
469 LWSTMC_AWAITING_CREATE_CHANNEL_ACK, /* sent create ch, awaiting ack */
470 LWSTMC_PENDING_CREATE_CHANNEL_NACK, /* waiting to send create ch ack */
471 LWSTMC_PENDING_CREATE_CHANNEL_ACK, /* waiting to send create ch ack */
472 LWSTMC_OPERATIONAL, /* had ack, we are operational */
473 LWSTMC_PENDING_CLOSE_CHANNEL, /* waiting to send close channel */
474 LWSTMC_AWAITING_CLOSE_CHANNEL_ACK, /* sent close ch, awaiting ack */
475 LWSTMC_PENDING_CLOSE_CHANNEL_ACK, /* waiting to send close ch ack */
476 /* lws_transport_mux_ch_t destroyed */
477};
478
479#define LWS_TRANSPORT_MUXCH_MAGIC LWS_FOURCC('T', 'm', 'C', 'h')
480#define assert_is_tmch(_tm) lws_assert_fourcc(_tm->magic, LWS_TRANSPORT_MUXCH_MAGIC)
481
495
496enum { /* states of the transport */
499};
500
501#define LWSTMINFO_SERVER (1 << 0)
502
513
514#define LWS_TRANSPORT_MUX_MAGIC LWS_FOURCC('I', 's', 'T', 'M')
515#define assert_is_tm(_tm) lws_assert_fourcc(_tm->magic, LWS_TRANSPORT_MUX_MAGIC)
516
550
552lws_transport_mux_create(struct lws_context *cx, lws_transport_info_t *info,
553 void *txp_handle);
554
555void
557
558void
560
561#if defined(_DEBUG)
562void
564void
566#else
567#define lws_transport_path_client_dump(_a, _b)
568#define lws_transport_path_proxy_dump(_a, _b)
569#endif
570
571/*
572 * Callback set used to customize parser and _pending apis
573 */
574
585
586int
588 size_t len, const lws_txp_mux_parse_cbs_t *cbs);
589
590/*
591 * Returns nonzero if the transport mux has put something in buf and wants this
592 * write opportunity to send it; *len is always set to the amount to send, and
593 * is only nonzero when this returns nonzero. A channel whose owner's
594 * txp_can_write() verdict is nonzero is closed by the mux itself.
595 */
596int
598 const lws_txp_mux_parse_cbs_t *cbs);
599
602
605
606#if defined(STANDALONE)
607#undef lws_context
608#endif
609
struct lws_dll2 lws_dll2_t
struct lws_dll2_owner lws_dll2_owner_t
enum lws_ss_state_return lws_ss_state_return_t
#define LWS_EXTERN_FOR_DATA
unsigned int uint32_t
unsigned char uint8_t
#define LWS_VISIBLE
uint32_t _open[LWS_MUCH_RANGE/32]
LWS_VISIBLE LWS_EXTERN_FOR_DATA const lws_transport_proxy_ops_t lws_transport_mux_proxy_ops
int lws_transport_mux_pending(lws_transport_mux_t *tm, uint8_t *buf, size_t *len, const lws_txp_mux_parse_cbs_t *cbs)
struct lws_txp_mux_parse_cbs lws_txp_mux_parse_cbs_t
LWS_VISIBLE LWS_EXTERN_FOR_DATA const lws_transport_client_ops_t lws_transport_mux_client_ops
LWS_VISIBLE LWS_EXTERN_FOR_DATA const lws_transport_proxy_ops_t lws_txp_inside_proxy
const struct lws_transport_client_ops * ops_onw
@ LWSSS_SER_TXPRE_TLSNEG_ENCLAVE_SIGNED
struct lws_transport_client_ops lws_transport_client_ops_t
struct lws_transport_info lws_transport_info_t
int lws_transport_mux_rx_parse(lws_transport_mux_t *tm, const uint8_t *buf, size_t len, const lws_txp_mux_parse_cbs_t *cbs)
void lws_transport_mux_request_tx(lws_transport_mux_t *tm)
struct lws_transport_mux lws_transport_mux_t
struct lws_transport_proxy_ops lws_transport_proxy_ops_t
struct lws_transport_info * onward_txp_info
uint32_t fin[LWS_MUCH_RANGE/32]
const struct lws_transport_proxy_ops * ops_in
struct lws_txp_path_client lws_txp_path_client_t
#define lws_transport_path_proxy_dump(_a, _b)
const struct lws_transport_client_ops * ops_in
void lws_transport_mux_destroy(lws_transport_mux_t **tm)
lws_transport_mux_t * lws_transport_mux_create(struct lws_context *cx, lws_transport_info_t *info, void *txp_handle)
struct lws_transport_mux * mux
#define lws_transport_path_client_dump(_a, _b)
struct lws_txp_path_proxy lws_txp_path_proxy_t
LWS_VISIBLE LWS_EXTERN_FOR_DATA const lws_transport_client_ops_t lws_txp_inside_sspc
const struct lws_transport_proxy_ops * ops_onw
struct lws_transport_mux_ch lws_transport_mux_ch_t
struct lws_sorted_usec_list lws_sorted_usec_list_t
void(* req_write)(lws_transport_priv_t priv)
int(* event_retry_connect)(lws_txp_path_client_t *path, struct lws_sspc_handle *h)
lws_ss_state_return_t(* event_can_write)(struct lws_sspc_handle *h, size_t metadata_limit)
void(* event_client_up)(lws_transport_priv_t priv)
void(* lost_coherence)(lws_transport_priv_t priv)
void(* event_stream_up)(lws_transport_priv_t priv)
lws_ss_state_return_t(* event_read)(lws_transport_priv_t priv, const uint8_t *buf, size_t len)
lws_ss_state_return_t(* event_closed)(lws_transport_priv_t priv)
void(* _close)(lws_transport_priv_t priv)
int(* _write)(lws_transport_priv_t priv, uint8_t *buf, size_t len)
lws_ss_state_return_t(* event_connect_disposition)(struct lws_sspc_handle *h, int disposition)
void(* event_client_up)(lws_transport_priv_t priv)
lws_ss_state_return_t(* event_new_conn)(struct lws_context *cx, const struct lws_transport_proxy_ops *txp_ops_inward, lws_transport_priv_t txp_priv_inward, struct lws_sss_proxy_conn **conn, lws_transport_priv_t txp_priv)
void(* proxy_req_write)(lws_transport_priv_t priv)
int(* proxy_check_write_more)(lws_transport_priv_t priv)
lws_ss_state_return_t(* event_close_conn)(struct lws_sss_proxy_conn *conn)
lws_ss_state_return_t(* event_proxy_can_write)(lws_transport_priv_t priv)
void(* event_onward_bind)(lws_transport_priv_t priv, struct lws_ss_handle *h)
lws_ss_state_return_t(* close_conn)(struct lws_sss_proxy_conn *conn)
int(* init_proxy_server)(struct lws_context *context, const struct lws_transport_proxy_ops *txp_ops_inward, lws_transport_priv_t txp_priv_inward, lws_txp_path_proxy_t *txp_ppath, const void *aux, const char *bind, int port)
lws_ss_state_return_t(* proxy_read)(lws_transport_priv_t priv, const uint8_t *buf, size_t len)
int(* proxy_write)(lws_transport_priv_t priv, uint8_t *buf, size_t *len)
int(* destroy_proxy_server)(struct lws_context *context)
int(* txp_can_write)(lws_transport_mux_ch_t *tmc)
int(* ch_opens)(lws_transport_mux_ch_t *tmc, int determination)
int(* ch_closes)(lws_transport_mux_ch_t *tmc)
int(* payload)(lws_transport_mux_ch_t *tmc, const uint8_t *buf, size_t len)
void(* txp_req_write)(lws_transport_mux_t *tm)