libwebsockets
Lightweight C library for HTML5 websockets
lws-secure-streams.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  *
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 
53 /** \defgroup secstr Secure Streams
54 * ##Secure Streams
55 *
56 * Secure Streams related apis
57 */
58 ///@{
59 
60 #define LWS_SS_MTU 1540
61 
62 struct lws_ss_handle;
64 
65 #if defined(STANDALONE)
66 #define lws_context lws_context_standalone
67 struct lws_context_standalone;
68 #endif
69 
70 /*
71  * connection state events
72  *
73  * If you add states, take care about the state names and state transition
74  * validity enforcement tables too
75  */
76 typedef enum {
77  /* zero means unset */
80  LWSSSCS_UNREACHABLE, /* oridinal arg = 1 = caused by dns
81  * server reachability failure */
87  LWSSSCS_ALL_RETRIES_FAILED, /* all retries in bo policy failed */
88  LWSSSCS_QOS_ACK_REMOTE, /* remote peer received and acked tx */
90  LWSSSCS_QOS_ACK_LOCAL, /* local proxy accepted our tx */
91  LWSSSCS_QOS_NACK_LOCAL, /* local proxy refused our tx */
92  LWSSSCS_TIMEOUT, /* optional timeout timer fired */
93 
95  LWSSSCS_SERVER_UPGRADE, /* the server protocol upgraded */
96 
97  LWSSSCS_EVENT_WAIT_CANCELLED, /* somebody called lws_cancel_service */
98 
99  LWSSSCS_UPSTREAM_LINK_RETRY, /* if we are being proxied over some
100  * intermediate link, this transient
101  * state may be sent to indicate we are
102  * waiting to establish that link before
103  * creation can proceed.. ack is the
104  * number of ms we have been trying */
105 
106  LWSSSCS_SINK_JOIN, /* sinks get this when a new source
107  * stream joins the sink */
108  LWSSSCS_SINK_PART, /* sinks get this when a new source
109  * stream leaves the sink */
110 
111  LWSSSCS_USER_BASE = 1000
112 } lws_ss_constate_t;
113 
114 enum {
115  LWSSS_FLAG_SOM = (1 << 0),
116  /* payload contains the start of new message */
117  LWSSS_FLAG_EOM = (1 << 1),
118  /* payload contains the end of message */
119  LWSSS_FLAG_POLL = (1 << 2),
120  /* Not a real transmit... poll for rx if protocol needs it */
122  /* Appears in a zero-length message indicating a message group of zero
123  * or more messages is now starting. */
125  /* Appears in a zero-length message indicating a message group of zero
126  * or more messages has now finished. */
128  /* Serialized payload starts with non-default rideshare name length and
129  * name string without NUL, then payload */
131  /* This RX is JSON performance data, only on streams with "perf" flag
132  * set */
133 };
134 
135 /*
136  * Returns from state() callback can tell the caller what the user code
137  * wants to do
138  */
139 
140 typedef enum lws_ss_state_return {
141  LWSSSSRET_TX_DONT_SEND = 1, /* (*tx) only, or failure */
142 
143  LWSSSSRET_OK = 0, /* no error */
144  LWSSSSRET_DISCONNECT_ME = -1, /* caller should disconnect us */
145  LWSSSSRET_DESTROY_ME = -2, /* caller should destroy us */
146 } lws_ss_state_return_t;
147 
148 /**
149  * lws_ss_info_t: information about stream to be created
150  *
151  * Prepare this struct with information about what the stream type is and how
152  * the stream should interface with your code, and pass it to lws_ss_create()
153  * to create the requested stream.
154  */
155 
156 enum {
157  LWSSSINFLAGS_REGISTER_SINK = (1 << 0),
158  /**< If set, we're not creating a specific stream, but registering
159  * ourselves as the "sink" for .streamtype. It's analogous to saying
160  * we want to be the many-to-one "server" for .streamtype; when other
161  * streams are created with that streamtype, they should be forwarded
162  * to this stream owner, where they join and part from the sink via
163  * (*state) LWSSSCS_SINK_JOIN / _PART events, the new client handle
164  * being provided in the h_src parameter.
165  */
166  LWSSSINFLAGS_PROXIED = (1 << 1),
167  /**< Set if the stream is being created as a stand-in at the proxy */
168  LWSSSINFLAGS_SERVER = (1 << 2),
169  /**< Set on the server object copy of the ssi / info to indicate that
170  * stream creation using this ssi is for Accepted connections belonging
171  * to a server */
172  LWSSSINFLAGS_ACCEPTED = (1 << 3),
173  /**< Set on the accepted object copy of the ssi / info to indicate that
174  * we are an accepted connection from a server's listening socket */
175  LWSSSINFLAGS_ACCEPTED_SINK = (1 << 4),
176  /**< Set on the accepted object copy of the ssi / info to indicate that
177  * we are an accepted connection from a local sink */
178 };
179 
180 typedef lws_ss_state_return_t (*lws_sscb_rx)(void *userobj, const uint8_t *buf,
181  size_t len, int flags);
182 typedef lws_ss_state_return_t (*lws_sscb_tx)(void *userobj,
184  uint8_t *buf, size_t *len,
185  int *flags);
186 typedef lws_ss_state_return_t (*lws_sscb_state)(void *userobj, void *h_src,
187  lws_ss_constate_t state,
188  lws_ss_tx_ordinal_t ack);
189 
190 #if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
191 typedef void (*lws_ss_buffer_dump_cb)(void *userobj, const uint8_t *buf,
192  size_t len, int done);
193 #endif
194 
195 struct lws_ss_policy;
196 
197 typedef struct lws_ss_info {
198  const char *streamtype; /**< type of stream we want to create */
199  size_t user_alloc; /**< size of user allocation */
200  size_t handle_offset; /**< offset of handle stg in user_alloc type,
201  set to offsetof(mytype, my_handle_member) */
203  /**< offset of opaque user data ptr in user_alloc type, set to
204  offsetof(mytype, opaque_ud_member) */
205 
206 #if defined(LWS_WITH_SECURE_STREAMS_CPP)
207  const struct lws_ss_policy *policy;
208  /**< Normally NULL, or a locally-generated policy to apply to this
209  * connection instead of a named streamtype */
210 #endif
211 
212 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
214  /**< Attach external Fault Injection context to the stream, hierarchy
215  * is ss->context */
216 #endif
217 
218  lws_sscb_rx rx;
219  /**< callback with rx payload for this stream */
220  lws_sscb_tx tx;
221  /**< callback to send payload on this stream... 0 = send as set in
222  * len and flags, 1 = do not send anything (ie, not even 0 len frame) */
223  lws_sscb_state state;
224  /**< advisory cb about state of stream and QoS status if applicable...
225  * h_src is only used with sinks and LWSSSCS_SINK_JOIN/_PART events.
226  * Return nonzero to indicate you want to destroy the stream. */
227 #if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
229  /**< cb to record needed protocol buffer data*/
230 #endif
232  /**< 0 = manage any tx credit automatically, nonzero explicitly sets the
233  * peer stream to have the given amount of tx credit, if the protocol
234  * can support it.
235  *
236  * In the special case of _lws_smd streamtype, this is used to indicate
237  * the connection's rx class mask.
238  * */
240  /**< used in proxy / serialization case to hold the client pid this
241  * proxied connection is to be tagged with
242  */
245  /**< used in proxy / serialization case to hold the SS serialization
246  * protocol level to use with this peer... clients automatically request
247  * the most recent version they were built with
248  * (LWS_SSS_CLIENT_PROTOCOL_VERSION) and the proxy stores the requested
249  * version in here
250  */
251 
252 } lws_ss_info_t;
253 
254 #define LWS_SS_USER_TYPEDEF
255  typedef struct {
256  struct lws_ss_handle *ss;
257  void *opaque_data;
258 
259 #define LWS_SS_INFO(_streamtype, _type)
260  const lws_ss_info_t ssi_##_type = {
261  .handle_offset = offsetof(_type, ss),
262  .opaque_user_data_offset = offsetof(_type, opaque_data),
263  .user_alloc = sizeof(_type),
264  .streamtype = _streamtype,
265 
266 #define lws_ss_from_user(_u) (_u)->ss
267 #define lws_ss_opaque_from_user(_u) (_u)->opaque_data
268 #define lws_ss_cx_from_user(_u) lws_ss_get_context((_u)->ss)
269 
270 #if defined(LWS_SS_USE_SSPC)
271 #define lws_context_info_defaults(_x, _y) _lws_context_info_defaults(_x, NULL)
272 #else
273 #define lws_context_info_defaults(_x, _y) _lws_context_info_defaults(_x, _y)
274 #endif
275 
276 /**
277  * lws_ss_create() - Create secure stream
278  *
279  * \param context: the lws context to create this inside
280  * \param tsi: service thread index to create on (normally 0)
281  * \param ssi: pointer to lws_ss_info_t filled in with info about desired stream
282  * \param opaque_user_data: opaque data to set in the stream's user object
283  * \param ppss: pointer to secure stream handle pointer set on exit
284  * \param ppayload_fmt: NULL or pointer to a string ptr to take payload format
285  * name from the policy
286  *
287  * Requests a new secure stream described by \p ssi be created. If successful,
288  * the stream is created, its state callback called with LWSSSCS_CREATING, \p *ppss
289  * is set to point to the handle, and it returns 0. If it failed, it returns
290  * nonzero.
291  *
292  * Along with the opaque stream object, streams overallocate
293  *
294  * 1) a user data struct whose size is set in ssi
295  * 2) nauth plugin instantiation data (size set in the plugin struct)
296  * 3) sauth plugin instantiation data (size set in the plugin struct)
297  * 4) space for a copy of the stream type name
298  *
299  * The user data struct is initialized to all zeros, then the .handle_offset and
300  * .opaque_user_data_offset fields of the ssi are used to prepare the user data
301  * struct with the ss handle that was created, and a copy of the
302  * opaque_user_data pointer given as an argument.
303  *
304  * If you want to set up the stream with specific information, point to it in
305  * opaque_user_data and use the copy of that pointer in your user data member
306  * for it starting from the LWSSSCS_CREATING state call.
307  *
308  * Since different endpoints chosen by the policy may require different payload
309  * formats, \p ppayload_fmt is set to point to the name of the needed payload
310  * format from the policy database if non-NULL.
311  */
312 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
313 lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
314  void *opaque_user_data, struct lws_ss_handle **ppss,
315  void *reserved, const char **ppayload_fmt);
316 
317 /**
318  * lws_ss_destroy() - Destroy secure stream
319  *
320  * \param ppss: pointer to lws_ss_t pointer to be destroyed
321  *
322  * Destroys the lws_ss_t pointed to by \p *ppss, and sets \p *ppss to NULL.
323  */
324 LWS_VISIBLE LWS_EXTERN void
325 lws_ss_destroy(struct lws_ss_handle **ppss);
326 
327 /**
328  * lws_ss_request_tx() - Schedule stream for tx
329  *
330  * \param pss: pointer to lws_ss_t representing stream that wants to transmit
331  *
332  * Schedules a write on the stream represented by \p pss. When it's possible to
333  * write on this stream, the \p *tx callback will occur with an empty buffer for
334  * the stream owner to fill in.
335  *
336  * Returns 0 or LWSSSSRET_DESTROY_ME
337  */
338 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
339 lws_ss_request_tx(struct lws_ss_handle *pss);
340 
341 /**
342  * lws_ss_request_tx() - Schedule stream for tx
343  *
344  * \param pss: pointer to lws_ss_t representing stream that wants to transmit
345  * \param len: the length of the write in bytes
346  *
347  * Schedules a write on the stream represented by \p pss. When it's possible to
348  * write on this stream, the \p *tx callback will occur with an empty buffer for
349  * the stream owner to fill in.
350  *
351  * This api variant should be used when it's possible the payload will go out
352  * over h1 with x-web-form-urlencoded or similar Content-Type.
353  */
354 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
355 lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len);
356 
357 /**
358  * lws_ss_client_connect() - Attempt the client connect
359  *
360  * \param h: secure streams handle
361  *
362  * Starts the connection process for the secure stream.
363  *
364  * Can return any of the lws_ss_state_return_t values depending on user
365  * state callback returns.
366  *
367  * LWSSSSRET_OK means the connection is ongoing.
368  *
369  */
370 LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
371 lws_ss_client_connect(struct lws_ss_handle *h);
372 
373 /**
374  * lws_ss_proxy_create() - Start a unix domain socket proxy for Secure Streams
375  *
376  * \param context: lws_context
377  * \param bind: if port is 0, unix domain path with leading @ for abstract.
378  * if port nonzero, NULL, or network interface to bind listen to
379  * \param port: tcp port to listen on
380  *
381  * Creates a vhost that listens either on an abstract namespace unix domain
382  * socket (port = 0) or a tcp listen socket (port nonzero). If bind is NULL
383  * and port is 0, the abstract unix domain socket defaults to "proxy.ss.lws".
384  *
385  * Client connections to this proxy to Secure Streams are fulfilled using the
386  * policy local to the proxy and the data passed between the client and the
387  * proxy using serialized Secure Streams protocol.
388  */
389 LWS_VISIBLE LWS_EXTERN int
390 lws_ss_proxy_create(struct lws_context *context, const char *bind, int port);
391 
392 /**
393  * lws_ss_state_name() - convenience helper to get a printable conn state name
394  *
395  * \param state: the connection state index
396  *
397  * Returns a printable name for the connection state index passed in.
398  */
399 LWS_VISIBLE LWS_EXTERN const char *
400 lws_ss_state_name(int state);
401 
402 /**
403  * lws_ss_get_context() - convenience helper to recover the lws context
404  *
405  * \param h: secure streams handle
406  *
407  * Returns the lws context. Dispenses with the need to pass a copy of it into
408  * your secure streams handler.
409  */
410 LWS_VISIBLE LWS_EXTERN struct lws_context *
411 lws_ss_get_context(struct lws_ss_handle *h);
412 
413 #define LWSSS_TIMEOUT_FROM_POLICY 0
414 
415 /**
416  * lws_ss_start_timeout() - start or restart the timeout on the stream
417  *
418  * \param h: secure streams handle
419  * \param timeout_ms: LWSSS_TIMEOUT_FROM_POLICY for policy value, else use timeout_ms
420  *
421  * Starts or restarts the stream's own timeout timer. If the specified time
422  * passes without lws_ss_cancel_timeout() being called on the stream, then the
423  * stream state callback receives LWSSSCS_TIMEOUT
424  *
425  * The process being protected by the timeout is up to the user code, it may be
426  * arbitrarily long and cross multiple protocol transactions or involve other
427  * streams. It's up to the user to decide when to start and when / if to cancel
428  * the stream timeout.
429  */
430 LWS_VISIBLE LWS_EXTERN void
431 lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms);
432 
433 /**
434  * lws_ss_cancel_timeout() - remove any timeout on the stream
435  *
436  * \param h: secure streams handle
437  *
438  * Disable any timeout that was applied to the stream by lws_ss_start_timeout().
439  */
440 LWS_VISIBLE LWS_EXTERN void
441 lws_ss_cancel_timeout(struct lws_ss_handle *h);
442 
443 /**
444  * lws_ss_to_user_object() - convenience helper to get user object from handle
445  *
446  * \param h: secure streams handle
447  *
448  * Returns the user allocation related to the handle. Normally you won't need
449  * this since it's available in the rx, tx and state callbacks as "userdata"
450  * already.
451  */
452 LWS_VISIBLE LWS_EXTERN void *
453 lws_ss_to_user_object(struct lws_ss_handle *h);
454 
455 /**
456  * lws_ss_rideshare() - find the current streamtype when types rideshare
457  *
458  * \param h: the stream handle
459  *
460  * Under some conditions, the payloads may be structured using protocol-
461  * specific formatting, eg, http multipart mime. It's possible to map the
462  * logical partitions in the payload to different stream types using
463  * the policy "rideshare" feature.
464  *
465  * This api lets the callback code find out which rideshare stream type the
466  * current payload chunk belongs to.
467  */
468 LWS_VISIBLE LWS_EXTERN const char *
469 lws_ss_rideshare(struct lws_ss_handle *h);
470 
471 
472 /**
473  * lws_ss_set_metadata() - allow user to bind external data to defined ss metadata
474  *
475  * \param h: secure streams handle
476  * \param name: metadata name from the policy
477  * \param value: pointer to user-managed data to bind to name
478  * \param len: length of the user-managed data in value
479  *
480  * Binds user-managed data to the named metadata item from the ss policy.
481  * If present, the metadata item is handled in a protocol-specific way using
482  * the associated policy information. For example, in the policy
483  *
484  * "\"metadata\":" "["
485  * "{\"uptag\":" "\"X-Upload-Tag:\"},"
486  * "{\"ctype\":" "\"Content-Type:\"},"
487  * "{\"xctype\":" "\"\"}"
488  * "],"
489  *
490  * when the policy is using h1 is interpreted to add h1 headers of the given
491  * name with the value of the metadata on the left.
492  *
493  * Return 0 if OK or nonzero if, eg, metadata name does not exist on the
494  * streamtype. You must check the result of this, eg, transient OOM can cause
495  * these to fail and you should retry later.
496  */
497 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
498 lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
499  const void *value, size_t len);
500 
501 /**
502  * lws_ss_alloc_set_metadata() - copy data and bind to ss metadata
503  *
504  * \param h: secure streams handle
505  * \param name: metadata name from the policy
506  * \param value: pointer to user-managed data to bind to name
507  * \param len: length of the user-managed data in value
508  *
509  * Same as lws_ss_set_metadata(), but allocates a heap buffer for the data
510  * first and takes a copy of it, so the original can go out of scope
511  * immediately after.
512  */
513 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
514 lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name,
515  const void *value, size_t len);
516 
517 /**
518  * lws_ss_get_metadata() - get current value of stream metadata item
519  *
520  * \param h: secure streams handle
521  * \param name: metadata name from the policy
522  * \param value: pointer to pointer to be set to point at the value
523  * \param len: pointer to size_t to set to the length of the value
524  *
525  * Binds user-managed data to the named metadata item from the ss policy.
526  * If present, the metadata item is handled in a protocol-specific way using
527  * the associated policy information. For example, in the policy
528  *
529  * "\"metadata\":" "["
530  * "{\"uptag\":" "\"X-Upload-Tag:\"},"
531  * "{\"ctype\":" "\"Content-Type:\"},"
532  * "{\"xctype\":" "\"\"}"
533  * "],"
534  *
535  * when the policy is using h1 is interpreted to add h1 headers of the given
536  * name with the value of the metadata on the left.
537  *
538  * Return 0 if \p *value and \p *len set OK, or nonzero if, eg, metadata \p name does
539  * not exist on the streamtype.
540  *
541  * The pointed-to values may only exist until the next time around the event
542  * loop.
543  */
544 LWS_VISIBLE LWS_EXTERN int
545 lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
546  const void **value, size_t *len);
547 
548 /**
549  * lws_ss_server_ack() - indicate how we feel about what the server has sent
550  *
551  * \param h: ss handle of accepted connection
552  * \param nack: 0 means we are OK with it, else some problem
553  *
554  * For SERVER secure streams
555  *
556  * Depending on the protocol, the server sending us something may be
557  * transactional, ie, built into it sending something is the idea we will
558  * respond somehow out-of-band; HTTP is like this with, eg, 200 response code.
559  *
560  * Calling this with nack=0 indicates that when we later respond, we want to
561  * acknowledge the transaction (eg, it means a 200 if http underneath), if
562  * nonzero that the transaction should act like it failed.
563  *
564  * If the underlying protocol doesn't understand transactions (eg, ws) then this
565  * has no effect either way.
566  */
567 LWS_VISIBLE LWS_EXTERN void
568 lws_ss_server_ack(struct lws_ss_handle *h, int nack);
569 
570 typedef void (*lws_sssfec_cb)(struct lws_ss_handle *h, void *arg);
571 
572 /**
573  * lws_ss_server_foreach_client() - callback for each live client connected to server
574  *
575  * \param h: server ss handle
576  * \param cb: the callback
577  * \param arg: arg passed to callback
578  *
579  * For SERVER secure streams
580  *
581  * Call the callback \p cb once for each client ss connected to the server,
582  * passing \p arg as an additional callback argument each time.
583  */
584 LWS_VISIBLE LWS_EXTERN void
585 lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
586  void *arg);
587 
588 /**
589  * lws_ss_change_handlers() - helper for dynamically changing stream handlers
590  *
591  * \param h: ss handle
592  * \param rx: the new RX handler
593  * \param tx: the new TX handler
594  * \param state: the new state handler
595  *
596  * Handlers set to NULL are left unchanged.
597  *
598  * This works on any handle, client or server and takes effect immediately.
599  *
600  * Depending on circumstances this may be helpful when
601  *
602  * a) a server stream undergoes an LWSSSCS_SERVER_UPGRADE (as in http -> ws) and
603  * the payloads in the new protocol have a different purpose that is best
604  * handled in their own rx and tx callbacks, and
605  *
606  * b) you may want to serve several different, possibly large things based on
607  * what was requested. Setting a customized handler allows clean encapsulation
608  * of the different serving strategies.
609  *
610  * If the stream is long-lived, like ws, you should set the changed handler back
611  * to the default when the transaction wanting it is completed.
612  */
613 LWS_VISIBLE LWS_EXTERN void
614 lws_ss_change_handlers(struct lws_ss_handle *h, lws_sscb_rx rx, lws_sscb_tx tx,
615  lws_sscb_state state);
616 
617 /**
618  * lws_ss_add_peer_tx_credit() - allow peer to transmit more to us
619  *
620  * \param h: secure streams handle
621  * \param add: additional tx credit (signed)
622  *
623  * Indicate to remote peer that we can accept \p add bytes more payload being
624  * sent to us.
625  */
626 LWS_VISIBLE LWS_EXTERN int
627 lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t add);
628 
629 /**
630  * lws_ss_get_est_peer_tx_credit() - get our current estimate of peer's tx credit
631  *
632  * \param h: secure streams handle
633  *
634  * Based on what credit we gave it, and what we have received, report our
635  * estimate of peer's tx credit usable to transmit to us. This may be outdated
636  * in that some or all of its credit may already have been expended by sending
637  * stuff to us that is in flight already.
638  */
639 LWS_VISIBLE LWS_EXTERN int
640 lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h);
641 
642 LWS_VISIBLE LWS_EXTERN const char *
643 lws_ss_tag(struct lws_ss_handle *h);
644 
645 
646 #if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
647 /**
648  * lws_ss_sigv4_set_aws_key() - set aws credential into system blob
649  *
650  * \param context: lws_context
651  * \param idx: the system blob index specified in the policy, currently
652  * up to 4 blobs.
653  * \param keyid: aws access keyid
654  * \param key: aws access key
655  *
656  * Return 0 if OK or nonzero if e.g. idx is invalid; system blob heap appending
657  * fails.
658  */
659 
660 LWS_VISIBLE LWS_EXTERN int
661 lws_ss_sigv4_set_aws_key(struct lws_context* context, uint8_t idx,
662  const char * keyid, const char * key);
663 
664 /**
665  * lws_aws_filesystem_credentials_helper() - read aws credentials from file
666  *
667  * \param path: path to read, ~ at start is converted to $HOME contents if any
668  * \param kid: eg, "aws_access_key_id"
669  * \param ak: eg, "aws_secret_access_key"
670  * \param aws_keyid: pointer to pointer for allocated keyid from credentials file
671  * \param aws_key: pointer to pointer for allocated key from credentials file
672  *
673  * Return 0 if both *aws_keyid and *aws_key allocated from the config file, else
674  * nonzero, and neither *aws_keyid or *aws_key are allocated.
675  *
676  * If *aws_keyid and *aws_key are set, it's the user's responsibility to
677  * free() them when they are no longer needed.
678  */
679 
680 LWS_VISIBLE LWS_EXTERN int
681 lws_aws_filesystem_credentials_helper(const char *path, const char *kid,
682  const char *ak, char **aws_keyid,
683  char **aws_key);
684 
685 #endif
686 
687 #if defined(STANDALONE)
688 #undef lws_context
689 #endif
690 
691 ///@}