libwebsockets
Lightweight C library for HTML5 websockets
lws-secure-streams.h
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2019 - 2020 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  *
27  * Secure Streams is a *payload-only* client communication channel where all the
28  * details about the connection are held in a systemwide policy database and
29  * are keyed by the streamtype field... the user of the communication channel
30  * does not know or manage the choice of endpoint, tls CA, or even wire
31  * protocol. The advantage is he then does not have any dependency on any of
32  * those and they can be changed just by changing the policy database without
33  * touching the code using the stream.
34  *
35  * There are two ways secure streams interfaces to user code:
36  *
37  * 1) [Linux / RTOS] the natural, smallest interface is to call back to user
38  * code that only operates directly from the lws event loop thread context
39  * (direct callbacks from lws_ss_t)
40  *
41  * lws_thread( [user code] ---- lws )
42  *
43  * 2) [Linux] where the user code is in a different process and communicates
44  * asynchronously via a proxy socket
45  *
46  * user_process{ [user code] | shim | socket-}------ lws_process{ lws }
47  *
48  * In the second, IPC, case, all packets are prepended by one or more bytes
49  * indicating the packet type and serializing any associated data, known as
50  * Serialized Secure Streams or SSS.
51  *
52  * Serialized Secure Streams
53  * -------------------------
54  *
55  * On the transport, adjacent packets may be coalesced, that is, the original
56  * packet sizes are lost and two or more packets are combined. For that reason
57  * the serialization format always contains a 1-byte type and then a 2-byte
58  * frame length.
59  *
60  * Client to proxy
61  *
62  * - Proxied connection setup
63  *
64  * - 0: LWSSS_SER_TXPRE_STREAMTYPE
65  * - 1: 2-byte MSB-first rest-of-frame length
66  * - 3: 1-byte Client SSS protocol version (introduced in SSSv1)
67  * - 4: 4-byte Client PID (introduced in SSSv1)
68  * - 8: 4-byte MSB-first initial tx credit
69  * - 12: the streamtype name with no NUL
70  *
71  * - Proxied tx
72  *
73  * - 0: LWSSS_SER_TXPRE_TX_PAYLOAD
74  * - 1: 2 byte MSB-first rest-of-frame length
75  * - 3: 4-byte MSB-first flags
76  * - 7: 4-byte MSB-first us between client requested write and wrote to proxy
77  * - 11: 8-byte MSB-first us resolution unix time client wrote to proxy
78  * - 19: payload
79  *
80  * - Proxied secure stream destroy
81  *
82  * - 0: LWSSS_SER_TXPRE_DESTROYING
83  * - 1: 00, 00
84  *
85  * - Proxied metadata - sent when one metadata item set clientside
86  *
87  * - 0: LWSSS_SER_TXPRE_METADATA
88  * - 1: 2-byte MSB-first rest-of-frame length
89  * - 3: 1-byte metadata name length
90  * - 4: metadata name
91  * - ...: metadata value (for rest of packet)
92  *
93  * - TX credit management - sent when using tx credit apis, cf METADATA
94  *
95  * - 0: LWSSS_SER_TXPRE_TXCR_UPDATE
96  * - 1: 2-byte MSB-first rest-of-frame length 00, 04
97  * - 3: 4-byte additional tx credit adjust value
98  *
99  * - Stream timeout management - forwarded when user applying or cancelling t.o.
100  *
101  * - 0: LWSSS_SER_TXPRE_TIMEOUT_UPDATE
102  * - 1: 2-byte MSB-first rest-of-frame length 00, 04
103  * - 3: 4-byte MSB-first unsigned 32-bit timeout, 0 = use policy, -1 = cancel
104  *
105  * - Passing up payload length hint
106  *
107  * - 0: LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT
108  * - 1: 2-byte MSB-first rest-of-frame length 00, 04
109  * - 3: 4-byte MSB-first unsigned 32-bit payload length hint
110  *
111  * Proxy to client
112  *
113  * - Proxied connection setup result
114  *
115  * - 0: LWSSS_SER_RXPRE_CREATE_RESULT
116  * - 1: 2 byte MSB-first rest-of-frame length (usually 00, 03)
117  * - 3: 1 byte result, 0 = success. On failure, proxy will close connection.
118  * - 4: 4 byte client dsh allocation recommended for stream type, from policy
119  * (introduced in SSSv1)
120  * - 8: 2 byte MSB-first initial tx credit
121  * - 10: if present, comma-sep list of rideshare types from policy
122  *
123  * - Proxied rx
124  *
125  * - 0: LWSSS_SER_RXPRE_RX_PAYLOAD
126  * - 1: 2 byte MSB-first rest-of-frame length
127  * - 3: 4-byte MSB-first flags
128  * - 7: 4-byte MSB-first us between inbound read and wrote to client
129  * - 11: 8-byte MSB-first us resolution unix time proxy wrote to client
130  * - 17: (rideshare name len + rideshare name if flags & LWSSS_FLAG_RIDESHARE)
131  * payload
132  *
133  * - Proxied tx credit
134  *
135  * - 0: LWSSS_SER_RXPRE_TXCR_UPDATE
136  * - 1: 00, 04
137  * - 3: 4-byte MSB-first addition tx credit bytes
138  *
139  * - Proxied rx metadata
140  *
141  * - 0: LWSSS_SER_RXPRE_METADATA
142  * - 1: 2-byte MSB-first rest-of-frame length
143  * - 3: 1-byte metadata name length
144  * - 4: metadata name
145  * - ...: metadata value (for rest of packet)
146  *
147  * - Proxied state (8 or 11 byte packet)
148  *
149  * - 0: LWSSS_SER_RXPRE_CONNSTATE
150  * - 1: 00, 05 if state < 256, else 00, 08
151  * - 3: 1 byte state index if state < 256, else 4-byte MSB-first state index
152  * - 4 or 7: 4-byte MSB-first ordinal
153  *
154  * - Proxied performance information
155  *
156  * - 0: LWSSS_SER_RXPRE_PERF
157  * - 1: 2-byte MSB-first rest-of-frame length
158  * - 3: ... performance JSON (for rest of packet)
159  *
160  * Proxied tx may be read by the proxy but rejected due to lack of buffer space
161  * at the proxy. For that reason, tx must be held at the sender until it has
162  * been acknowledged or denied.
163  *
164  * Sinks
165  * -----
166  *
167  * Sinks are logical "servers", you can register as a sink for a particular
168  * streamtype by using the lws_ss_create() api with ssi->register_sink set to 1.
169  *
170  * For directly fulfilled Secure Streams, new streams of that streamtype bind
171  * to the rx, tx and state handlers given when it was registered.
172  *
173  * - When new streams are created the registered sink handler for (*state) is
174  * called with event LWSSSCS_SINK_JOIN and the new client stream handle in
175  * the h_src parameter.
176  *
177  * - When the client stream sends something to the sink, it calls the sink's
178  * (*rx) with the client stream's
179  */
180 
187 
188 #define LWS_SS_MTU 1540
189 
190 struct lws_ss_handle;
191 typedef uint32_t lws_ss_tx_ordinal_t;
192 
193 /*
194  * connection state events
195  *
196  * If you add states, take care about the state names and state transition
197  * validity enforcement tables too
198  */
199 typedef enum {
200  /* zero means unset */
201  LWSSSCS_CREATING = 1,
202  LWSSSCS_DISCONNECTED,
203  LWSSSCS_UNREACHABLE, /* oridinal arg = 1 = caused by dns
204  * server reachability failure */
205  LWSSSCS_AUTH_FAILED,
206  LWSSSCS_CONNECTED,
207  LWSSSCS_CONNECTING,
208  LWSSSCS_DESTROYING,
209  LWSSSCS_POLL,
210  LWSSSCS_ALL_RETRIES_FAILED, /* all retries in bo policy failed */
211  LWSSSCS_QOS_ACK_REMOTE, /* remote peer received and acked tx */
212  LWSSSCS_QOS_NACK_REMOTE,
213  LWSSSCS_QOS_ACK_LOCAL, /* local proxy accepted our tx */
214  LWSSSCS_QOS_NACK_LOCAL, /* local proxy refused our tx */
215  LWSSSCS_TIMEOUT, /* optional timeout timer fired */
216 
217  LWSSSCS_SERVER_TXN,
218  LWSSSCS_SERVER_UPGRADE, /* the server protocol upgraded */
219 
220  LWSSSCS_EVENT_WAIT_CANCELLED, /* somebody called lws_cancel_service */
221 
222  LWSSSCS_UPSTREAM_LINK_RETRY, /* if we are being proxied over some
223  * intermediate link, this transient
224  * state may be sent to indicate we are
225  * waiting to establish that link before
226  * creation can proceed.. ack is the
227  * number of ms we have been trying */
228 
229  LWSSSCS_SINK_JOIN, /* sinks get this when a new source
230  * stream joins the sink */
231  LWSSSCS_SINK_PART, /* sinks get this when a new source
232  * stream leaves the sink */
233 
234  LWSSSCS_USER_BASE = 1000
235 } lws_ss_constate_t;
236 
237 enum {
238  LWSSS_FLAG_SOM = (1 << 0),
239  /* payload contains the start of new message */
240  LWSSS_FLAG_EOM = (1 << 1),
241  /* payload contains the end of message */
242  LWSSS_FLAG_POLL = (1 << 2),
243  /* Not a real transmit... poll for rx if protocol needs it */
244  LWSSS_FLAG_RELATED_START = (1 << 3),
245  /* Appears in a zero-length message indicating a message group of zero
246  * or more messages is now starting. */
247  LWSSS_FLAG_RELATED_END = (1 << 4),
248  /* Appears in a zero-length message indicating a message group of zero
249  * or more messages has now finished. */
250  LWSSS_FLAG_RIDESHARE = (1 << 5),
251  /* Serialized payload starts with non-default rideshare name length and
252  * name string without NUL, then payload */
253  LWSSS_FLAG_PERF_JSON = (1 << 6),
254  /* This RX is JSON performance data, only on streams with "perf" flag
255  * set */
256 
257  /*
258  * In the case the secure stream is proxied across a process or thread
259  * boundary, eg by proxying through a socket for IPC, metadata must be
260  * carried in-band. A byte is prepended to each rx payload to
261  * differentiate what it is.
262  *
263  * Secure streams where the user is called back directly does not need
264  * any of this and only pure payloads are passed.
265  *
266  * rx (received by client) prepends for proxied connections
267  */
268 
269  LWSSS_SER_RXPRE_RX_PAYLOAD = 0x55,
270  LWSSS_SER_RXPRE_CREATE_RESULT,
271  LWSSS_SER_RXPRE_CONNSTATE,
272  LWSSS_SER_RXPRE_TXCR_UPDATE,
273  LWSSS_SER_RXPRE_METADATA,
274  LWSSS_SER_RXPRE_TLSNEG_ENCLAVE_SIGN,
275  LWSSS_SER_RXPRE_PERF,
276 
277  /* tx (send by client) prepends for proxied connections */
278 
279  LWSSS_SER_TXPRE_STREAMTYPE = 0xaa,
280  LWSSS_SER_TXPRE_ONWARD_CONNECT,
281  LWSSS_SER_TXPRE_DESTROYING,
282  LWSSS_SER_TXPRE_TX_PAYLOAD,
283  LWSSS_SER_TXPRE_METADATA,
284  LWSSS_SER_TXPRE_TXCR_UPDATE,
285  LWSSS_SER_TXPRE_TIMEOUT_UPDATE,
286  LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT,
287  LWSSS_SER_TXPRE_TLSNEG_ENCLAVE_SIGNED,
288 };
289 
290 typedef enum {
291  LPCSPROX_WAIT_INITIAL_TX = 1, /* after connect, must send streamtype */
292  LPCSPROX_REPORTING_FAIL, /* stream creation failed, wait to to tell */
293  LPCSPROX_REPORTING_OK, /* stream creation succeeded, wait to to tell */
294  LPCSPROX_OPERATIONAL, /* ready for payloads */
295  LPCSPROX_DESTROYED,
296 
297  LPCSCLI_SENDING_INITIAL_TX, /* after connect, must send streamtype */
298  LPCSCLI_WAITING_CREATE_RESULT, /* wait to hear if proxy ss create OK */
299  LPCSCLI_LOCAL_CONNECTED, /* we are in touch with the proxy */
300  LPCSCLI_ONWARD_CONNECT, /* request onward ss connection */
301  LPCSCLI_OPERATIONAL, /* ready for payloads */
302 
303 } lws_ss_conn_states_t;
304 
305 /*
306  * Returns from state() callback can tell the caller what the user code
307  * wants to do
308  */
309 
310 typedef enum lws_ss_state_return {
311  LWSSSSRET_TX_DONT_SEND = 1, /* (*tx) only, or failure */
312 
313  LWSSSSRET_OK = 0, /* no error */
314  LWSSSSRET_DISCONNECT_ME = -1, /* caller should disconnect us */
315  LWSSSSRET_DESTROY_ME = -2, /* caller should destroy us */
316 } lws_ss_state_return_t;
317 
326 enum {
327  LWSSSINFLAGS_REGISTER_SINK = (1 << 0),
336  LWSSSINFLAGS_PROXIED = (1 << 1),
338  LWSSSINFLAGS_SERVER = (1 << 2),
342  LWSSSINFLAGS_ACCEPTED = (1 << 3),
345 };
346 
347 typedef lws_ss_state_return_t (*lws_sscb_rx)(void *userobj, const uint8_t *buf,
348  size_t len, int flags);
349 typedef lws_ss_state_return_t (*lws_sscb_tx)(void *userobj,
350  lws_ss_tx_ordinal_t ord,
351  uint8_t *buf, size_t *len,
352  int *flags);
353 typedef lws_ss_state_return_t (*lws_sscb_state)(void *userobj, void *h_src,
354  lws_ss_constate_t state,
355  lws_ss_tx_ordinal_t ack);
356 
357 #if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
358 typedef void (*lws_ss_buffer_dump_cb)(void *userobj, const uint8_t *buf,
359  size_t len, int done);
360 #endif
361 
362 struct lws_ss_policy;
363 
364 typedef struct lws_ss_info {
365  const char *streamtype;
366  size_t user_alloc;
367  size_t handle_offset;
373 #if defined(LWS_WITH_SECURE_STREAMS_CPP)
374  const struct lws_ss_policy *policy;
377 #endif
378 
379 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
380  lws_fi_ctx_t fic;
383 #endif
384 
385  lws_sscb_rx rx;
387  lws_sscb_tx tx;
390  lws_sscb_state state;
394 #if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
395  lws_ss_buffer_dump_cb dump;
397 #endif
406  uint32_t client_pid;
410  uint8_t flags;
419 } lws_ss_info_t;
420 
457 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
458 lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
459  void *opaque_user_data, struct lws_ss_handle **ppss,
460  struct lws_sequencer *seq_owner, const char **ppayload_fmt);
461 
469 LWS_VISIBLE LWS_EXTERN void
470 lws_ss_destroy(struct lws_ss_handle **ppss);
471 
483 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
484 lws_ss_request_tx(struct lws_ss_handle *pss);
485 
499 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
500 lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len);
501 
515 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
516 lws_ss_client_connect(struct lws_ss_handle *h);
517 
528 LWS_VISIBLE LWS_EXTERN struct lws_sequencer *
529 lws_ss_get_sequencer(struct lws_ss_handle *h);
530 
547 LWS_VISIBLE LWS_EXTERN int
548 lws_ss_proxy_create(struct lws_context *context, const char *bind, int port);
549 
557 LWS_VISIBLE LWS_EXTERN const char *
558 lws_ss_state_name(int state);
559 
568 LWS_VISIBLE LWS_EXTERN struct lws_context *
569 lws_ss_get_context(struct lws_ss_handle *h);
570 
571 #define LWSSS_TIMEOUT_FROM_POLICY 0
572 
588 LWS_VISIBLE LWS_EXTERN void
589 lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms);
590 
598 LWS_VISIBLE LWS_EXTERN void
599 lws_ss_cancel_timeout(struct lws_ss_handle *h);
600 
610 LWS_VISIBLE LWS_EXTERN void *
611 lws_ss_to_user_object(struct lws_ss_handle *h);
612 
626 LWS_VISIBLE LWS_EXTERN const char *
627 lws_ss_rideshare(struct lws_ss_handle *h);
628 
629 
655 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
656 lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
657  const void *value, size_t len);
658 
671 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
672 lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name,
673  const void *value, size_t len);
674 
702 LWS_VISIBLE LWS_EXTERN int
703 lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
704  const void **value, size_t *len);
705 
725 LWS_VISIBLE LWS_EXTERN void
726 lws_ss_server_ack(struct lws_ss_handle *h, int nack);
727 
728 typedef void (*lws_sssfec_cb)(struct lws_ss_handle *h, void *arg);
729 
742 LWS_VISIBLE LWS_EXTERN void
743 lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
744  void *arg);
745 
771 LWS_VISIBLE LWS_EXTERN void
772 lws_ss_change_handlers(struct lws_ss_handle *h, lws_sscb_rx rx, lws_sscb_tx tx,
773  lws_sscb_state state);
774 
784 LWS_VISIBLE LWS_EXTERN int
785 lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t add);
786 
797 LWS_VISIBLE LWS_EXTERN int
798 lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h);
799 
800 LWS_VISIBLE LWS_EXTERN const char *
801 lws_ss_tag(struct lws_ss_handle *h);
802 
803 
804 #if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
818 LWS_VISIBLE LWS_EXTERN int
819 lws_ss_sigv4_set_aws_key(struct lws_context* context, uint8_t idx,
820  const char * keyid, const char * key);
821 
838 LWS_VISIBLE LWS_EXTERN int
839 lws_aws_filesystem_credentials_helper(const char *path, const char *kid,
840  const char *ak, char **aws_keyid,
841  char **aws_key);
842 
843 #endif
844 
846 
LWS_VISIBLE LWS_EXTERN void lws_ss_destroy(struct lws_ss_handle **ppss)
LWS_VISIBLE LWS_EXTERN void lws_ss_change_handlers(struct lws_ss_handle *h, lws_sscb_rx rx, lws_sscb_tx tx, lws_sscb_state state)
LWS_VISIBLE LWS_EXTERN int lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t add)
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)
LWS_VISIBLE LWS_EXTERN int lws_ss_proxy_create(struct lws_context *context, const char *bind, int port)
LWS_VISIBLE LWS_EXTERN void lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms)
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)
LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT lws_ss_client_connect(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT lws_ss_request_tx(struct lws_ss_handle *pss)
LWS_VISIBLE LWS_EXTERN void * lws_ss_to_user_object(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name, const void *value, size_t len)
LWS_VISIBLE LWS_EXTERN void lws_ss_cancel_timeout(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_ss_set_metadata(struct lws_ss_handle *h, const char *name, const void *value, size_t len)
LWS_VISIBLE LWS_EXTERN void lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb, void *arg)
LWS_VISIBLE LWS_EXTERN const char * lws_ss_rideshare(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN struct lws_context * lws_ss_get_context(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN int lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN struct lws_sequencer * lws_ss_get_sequencer(struct lws_ss_handle *h)
LWS_VISIBLE LWS_EXTERN const char * lws_ss_state_name(int state)
LWS_VISIBLE LWS_EXTERN void lws_ss_server_ack(struct lws_ss_handle *h, int nack)
LWS_VISIBLE LWS_EXTERN int lws_ss_get_metadata(struct lws_ss_handle *h, const char *name, const void **value, size_t *len)
@ LWSSSINFLAGS_REGISTER_SINK
Definition: lws-secure-streams.h:327
@ LWSSSINFLAGS_SERVER
Definition: lws-secure-streams.h:338
@ LWSSSINFLAGS_ACCEPTED
Definition: lws-secure-streams.h:342
@ LWSSSINFLAGS_PROXIED
Definition: lws-secure-streams.h:336
Definition: lws-secure-streams.h:364
lws_sscb_state state
Definition: lws-secure-streams.h:390
uint32_t client_pid
Definition: lws-secure-streams.h:406
size_t handle_offset
Definition: lws-secure-streams.h:367
lws_sscb_tx tx
Definition: lws-secure-streams.h:387
uint8_t sss_protocol_version
Definition: lws-secure-streams.h:411
size_t user_alloc
Definition: lws-secure-streams.h:366
const char * streamtype
Definition: lws-secure-streams.h:365
int manual_initial_tx_credit
Definition: lws-secure-streams.h:398
lws_sscb_rx rx
Definition: lws-secure-streams.h:385
size_t opaque_user_data_offset
Definition: lws-secure-streams.h:369
Definition: lws-secure-streams-policy.h:249
uint32_t flags
Definition: lws-secure-streams-policy.h:376