lws-secure-streams.h (31145B)
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 181/** \defgroup secstr Secure Streams 182* ##Secure Streams 183* 184* Secure Streams related apis 185*/ 186///@{ 187 188#define LWS_SS_MTU 1540 189 190struct lws_ss_handle; 191typedef 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 */ 199typedef 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 237enum { 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 290typedef 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 310typedef 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 318/** 319 * lws_ss_info_t: information about stream to be created 320 * 321 * Prepare this struct with information about what the stream type is and how 322 * the stream should interface with your code, and pass it to lws_ss_create() 323 * to create the requested stream. 324 */ 325 326enum { 327 LWSSSINFLAGS_REGISTER_SINK = (1 << 0), 328 /**< If set, we're not creating a specific stream, but registering 329 * ourselves as the "sink" for .streamtype. It's analogous to saying 330 * we want to be the many-to-one "server" for .streamtype; when other 331 * streams are created with that streamtype, they should be forwarded 332 * to this stream owner, where they join and part from the sink via 333 * (*state) LWSSSCS_SINK_JOIN / _PART events, the new client handle 334 * being provided in the h_src parameter. 335 */ 336 LWSSSINFLAGS_PROXIED = (1 << 1), 337 /**< Set if the stream is being created as a stand-in at the proxy */ 338 LWSSSINFLAGS_SERVER = (1 << 2), 339 /**< Set on the server object copy of the ssi / info to indicate that 340 * stream creation using this ssi is for Accepted connections belonging 341 * to a server */ 342 LWSSSINFLAGS_ACCEPTED = (1 << 3), 343 /**< Set on the accepted object copy of the ssi / info to indicate that 344 * we are an accepted connection from a server's listening socket */ 345}; 346 347typedef lws_ss_state_return_t (*lws_sscb_rx)(void *userobj, const uint8_t *buf, 348 size_t len, int flags); 349typedef 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); 353typedef 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) 358typedef void (*lws_ss_buffer_dump_cb)(void *userobj, const uint8_t *buf, 359 size_t len, int done); 360#endif 361 362struct lws_ss_policy; 363 364typedef struct lws_ss_info { 365 const char *streamtype; /**< type of stream we want to create */ 366 size_t user_alloc; /**< size of user allocation */ 367 size_t handle_offset; /**< offset of handle stg in user_alloc type, 368 set to offsetof(mytype, my_handle_member) */ 369 size_t opaque_user_data_offset; 370 /**< offset of opaque user data ptr in user_alloc type, set to 371 offsetof(mytype, opaque_ud_member) */ 372 373#if defined(LWS_WITH_SECURE_STREAMS_CPP) 374 const struct lws_ss_policy *policy; 375 /**< Normally NULL, or a locally-generated policy to apply to this 376 * connection instead of a named streamtype */ 377#endif 378 379#if defined(LWS_WITH_SYS_FAULT_INJECTION) 380 lws_fi_ctx_t fic; 381 /**< Attach external Fault Injection context to the stream, hierarchy 382 * is ss->context */ 383#endif 384 385 lws_sscb_rx rx; 386 /**< callback with rx payload for this stream */ 387 lws_sscb_tx tx; 388 /**< callback to send payload on this stream... 0 = send as set in 389 * len and flags, 1 = do not send anything (ie, not even 0 len frame) */ 390 lws_sscb_state state; 391 /**< advisory cb about state of stream and QoS status if applicable... 392 * h_src is only used with sinks and LWSSSCS_SINK_JOIN/_PART events. 393 * Return nonzero to indicate you want to destroy the stream. */ 394#if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP) 395 lws_ss_buffer_dump_cb dump; 396 /**< cb to record needed protocol buffer data*/ 397#endif 398 int manual_initial_tx_credit; 399 /**< 0 = manage any tx credit automatically, nonzero explicitly sets the 400 * peer stream to have the given amount of tx credit, if the protocol 401 * can support it. 402 * 403 * In the special case of _lws_smd streamtype, this is used to indicate 404 * the connection's rx class mask. 405 * */ 406 uint32_t client_pid; 407 /**< used in proxy / serialization case to hold the client pid this 408 * proxied connection is to be tagged with 409 */ 410 uint8_t flags; 411 uint8_t sss_protocol_version; 412 /**< used in proxy / serialization case to hold the SS serialization 413 * protocol level to use with this peer... clients automatically request 414 * the most recent version they were built with 415 * (LWS_SSS_CLIENT_PROTOCOL_VERSION) and the proxy stores the requested 416 * version in here 417 */ 418 419} lws_ss_info_t; 420 421/** 422 * lws_ss_create() - Create secure stream 423 * 424 * \param context: the lws context to create this inside 425 * \param tsi: service thread index to create on (normally 0) 426 * \param ssi: pointer to lws_ss_info_t filled in with info about desired stream 427 * \param opaque_user_data: opaque data to set in the stream's user object 428 * \param ppss: pointer to secure stream handle pointer set on exit 429 * \param ppayload_fmt: NULL or pointer to a string ptr to take payload format 430 * name from the policy 431 * 432 * Requests a new secure stream described by \p ssi be created. If successful, 433 * the stream is created, its state callback called with LWSSSCS_CREATING, \p *ppss 434 * is set to point to the handle, and it returns 0. If it failed, it returns 435 * nonzero. 436 * 437 * Along with the opaque stream object, streams overallocate 438 * 439 * 1) a user data struct whose size is set in ssi 440 * 2) nauth plugin instantiation data (size set in the plugin struct) 441 * 3) sauth plugin instantiation data (size set in the plugin struct) 442 * 4) space for a copy of the stream type name 443 * 444 * The user data struct is initialized to all zeros, then the .handle_offset and 445 * .opaque_user_data_offset fields of the ssi are used to prepare the user data 446 * struct with the ss handle that was created, and a copy of the 447 * opaque_user_data pointer given as an argument. 448 * 449 * If you want to set up the stream with specific information, point to it in 450 * opaque_user_data and use the copy of that pointer in your user data member 451 * for it starting from the LWSSSCS_CREATING state call. 452 * 453 * Since different endpoints chosen by the policy may require different payload 454 * formats, \p ppayload_fmt is set to point to the name of the needed payload 455 * format from the policy database if non-NULL. 456 */ 457LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT 458lws_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 462/** 463 * lws_ss_destroy() - Destroy secure stream 464 * 465 * \param ppss: pointer to lws_ss_t pointer to be destroyed 466 * 467 * Destroys the lws_ss_t pointed to by \p *ppss, and sets \p *ppss to NULL. 468 */ 469LWS_VISIBLE LWS_EXTERN void 470lws_ss_destroy(struct lws_ss_handle **ppss); 471 472/** 473 * lws_ss_request_tx() - Schedule stream for tx 474 * 475 * \param pss: pointer to lws_ss_t representing stream that wants to transmit 476 * 477 * Schedules a write on the stream represented by \p pss. When it's possible to 478 * write on this stream, the \p *tx callback will occur with an empty buffer for 479 * the stream owner to fill in. 480 * 481 * Returns 0 or LWSSSSRET_DESTROY_ME 482 */ 483LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT 484lws_ss_request_tx(struct lws_ss_handle *pss); 485 486/** 487 * lws_ss_request_tx() - Schedule stream for tx 488 * 489 * \param pss: pointer to lws_ss_t representing stream that wants to transmit 490 * \param len: the length of the write in bytes 491 * 492 * Schedules a write on the stream represented by \p pss. When it's possible to 493 * write on this stream, the \p *tx callback will occur with an empty buffer for 494 * the stream owner to fill in. 495 * 496 * This api variant should be used when it's possible the payload will go out 497 * over h1 with x-web-form-urlencoded or similar Content-Type. 498 */ 499LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT 500lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len); 501 502/** 503 * lws_ss_client_connect() - Attempt the client connect 504 * 505 * \param h: secure streams handle 506 * 507 * Starts the connection process for the secure stream. 508 * 509 * Can return any of the lws_ss_state_return_t values depending on user 510 * state callback returns. 511 * 512 * LWSSSSRET_OK means the connection is ongoing. 513 * 514 */ 515LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT 516lws_ss_client_connect(struct lws_ss_handle *h); 517 518/** 519 * lws_ss_get_sequencer() - Return parent sequencer pointer if any 520 * 521 * \param h: secure streams handle 522 * 523 * Returns NULL if the secure stream is not associated with a sequencer. 524 * Otherwise returns a pointer to the owning sequencer. You can use this to 525 * identify which sequencer to direct messages to, from the secure stream 526 * callback. 527 */ 528LWS_VISIBLE LWS_EXTERN struct lws_sequencer * 529lws_ss_get_sequencer(struct lws_ss_handle *h); 530 531/** 532 * lws_ss_proxy_create() - Start a unix domain socket proxy for Secure Streams 533 * 534 * \param context: lws_context 535 * \param bind: if port is 0, unix domain path with leading @ for abstract. 536 * if port nonzero, NULL, or network interface to bind listen to 537 * \param port: tcp port to listen on 538 * 539 * Creates a vhost that listens either on an abstract namespace unix domain 540 * socket (port = 0) or a tcp listen socket (port nonzero). If bind is NULL 541 * and port is 0, the abstract unix domain socket defaults to "proxy.ss.lws". 542 * 543 * Client connections to this proxy to Secure Streams are fulfilled using the 544 * policy local to the proxy and the data passed between the client and the 545 * proxy using serialized Secure Streams protocol. 546 */ 547LWS_VISIBLE LWS_EXTERN int 548lws_ss_proxy_create(struct lws_context *context, const char *bind, int port); 549 550/** 551 * lws_ss_state_name() - convenience helper to get a printable conn state name 552 * 553 * \param state: the connection state index 554 * 555 * Returns a printable name for the connection state index passed in. 556 */ 557LWS_VISIBLE LWS_EXTERN const char * 558lws_ss_state_name(int state); 559 560/** 561 * lws_ss_get_context() - convenience helper to recover the lws context 562 * 563 * \param h: secure streams handle 564 * 565 * Returns the lws context. Dispenses with the need to pass a copy of it into 566 * your secure streams handler. 567 */ 568LWS_VISIBLE LWS_EXTERN struct lws_context * 569lws_ss_get_context(struct lws_ss_handle *h); 570 571#define LWSSS_TIMEOUT_FROM_POLICY 0 572 573/** 574 * lws_ss_start_timeout() - start or restart the timeout on the stream 575 * 576 * \param h: secure streams handle 577 * \param timeout_ms: LWSSS_TIMEOUT_FROM_POLICY for policy value, else use timeout_ms 578 * 579 * Starts or restarts the stream's own timeout timer. If the specified time 580 * passes without lws_ss_cancel_timeout() being called on the stream, then the 581 * stream state callback receives LWSSSCS_TIMEOUT 582 * 583 * The process being protected by the timeout is up to the user code, it may be 584 * arbitrarily long and cross multiple protocol transactions or involve other 585 * streams. It's up to the user to decide when to start and when / if to cancel 586 * the stream timeout. 587 */ 588LWS_VISIBLE LWS_EXTERN void 589lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms); 590 591/** 592 * lws_ss_cancel_timeout() - remove any timeout on the stream 593 * 594 * \param h: secure streams handle 595 * 596 * Disable any timeout that was applied to the stream by lws_ss_start_timeout(). 597 */ 598LWS_VISIBLE LWS_EXTERN void 599lws_ss_cancel_timeout(struct lws_ss_handle *h); 600 601/** 602 * lws_ss_to_user_object() - convenience helper to get user object from handle 603 * 604 * \param h: secure streams handle 605 * 606 * Returns the user allocation related to the handle. Normally you won't need 607 * this since it's available in the rx, tx and state callbacks as "userdata" 608 * already. 609 */ 610LWS_VISIBLE LWS_EXTERN void * 611lws_ss_to_user_object(struct lws_ss_handle *h); 612 613/** 614 * lws_ss_rideshare() - find the current streamtype when types rideshare 615 * 616 * \param h: the stream handle 617 * 618 * Under some conditions, the payloads may be structured using protocol- 619 * specific formatting, eg, http multipart mime. It's possible to map the 620 * logical partitions in the payload to different stream types using 621 * the policy "rideshare" feature. 622 * 623 * This api lets the callback code find out which rideshare stream type the 624 * current payload chunk belongs to. 625 */ 626LWS_VISIBLE LWS_EXTERN const char * 627lws_ss_rideshare(struct lws_ss_handle *h); 628 629 630/** 631 * lws_ss_set_metadata() - allow user to bind external data to defined ss metadata 632 * 633 * \param h: secure streams handle 634 * \param name: metadata name from the policy 635 * \param value: pointer to user-managed data to bind to name 636 * \param len: length of the user-managed data in value 637 * 638 * Binds user-managed data to the named metadata item from the ss policy. 639 * If present, the metadata item is handled in a protocol-specific way using 640 * the associated policy information. For example, in the policy 641 * 642 * "\"metadata\":" "[" 643 * "{\"uptag\":" "\"X-Upload-Tag:\"}," 644 * "{\"ctype\":" "\"Content-Type:\"}," 645 * "{\"xctype\":" "\"\"}" 646 * "]," 647 * 648 * when the policy is using h1 is interpreted to add h1 headers of the given 649 * name with the value of the metadata on the left. 650 * 651 * Return 0 if OK or nonzero if, eg, metadata name does not exist on the 652 * streamtype. You must check the result of this, eg, transient OOM can cause 653 * these to fail and you should retry later. 654 */ 655LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT 656lws_ss_set_metadata(struct lws_ss_handle *h, const char *name, 657 const void *value, size_t len); 658 659/** 660 * lws_ss_alloc_set_metadata() - copy data and bind to ss metadata 661 * 662 * \param h: secure streams handle 663 * \param name: metadata name from the policy 664 * \param value: pointer to user-managed data to bind to name 665 * \param len: length of the user-managed data in value 666 * 667 * Same as lws_ss_set_metadata(), but allocates a heap buffer for the data 668 * first and takes a copy of it, so the original can go out of scope 669 * immediately after. 670 */ 671LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT 672lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name, 673 const void *value, size_t len); 674 675/** 676 * lws_ss_get_metadata() - get current value of stream metadata item 677 * 678 * \param h: secure streams handle 679 * \param name: metadata name from the policy 680 * \param value: pointer to pointer to be set to point at the value 681 * \param len: pointer to size_t to set to the length of the value 682 * 683 * Binds user-managed data to the named metadata item from the ss policy. 684 * If present, the metadata item is handled in a protocol-specific way using 685 * the associated policy information. For example, in the policy 686 * 687 * "\"metadata\":" "[" 688 * "{\"uptag\":" "\"X-Upload-Tag:\"}," 689 * "{\"ctype\":" "\"Content-Type:\"}," 690 * "{\"xctype\":" "\"\"}" 691 * "]," 692 * 693 * when the policy is using h1 is interpreted to add h1 headers of the given 694 * name with the value of the metadata on the left. 695 * 696 * Return 0 if \p *value and \p *len set OK, or nonzero if, eg, metadata \p name does 697 * not exist on the streamtype. 698 * 699 * The pointed-to values may only exist until the next time around the event 700 * loop. 701 */ 702LWS_VISIBLE LWS_EXTERN int 703lws_ss_get_metadata(struct lws_ss_handle *h, const char *name, 704 const void **value, size_t *len); 705 706/** 707 * lws_ss_server_ack() - indicate how we feel about what the server has sent 708 * 709 * \param h: ss handle of accepted connection 710 * \param nack: 0 means we are OK with it, else some problem 711 * 712 * For SERVER secure streams 713 * 714 * Depending on the protocol, the server sending us something may be 715 * transactional, ie, built into it sending something is the idea we will 716 * respond somehow out-of-band; HTTP is like this with, eg, 200 response code. 717 * 718 * Calling this with nack=0 indicates that when we later respond, we want to 719 * acknowledge the transaction (eg, it means a 200 if http underneath), if 720 * nonzero that the transaction should act like it failed. 721 * 722 * If the underlying protocol doesn't understand transactions (eg, ws) then this 723 * has no effect either way. 724 */ 725LWS_VISIBLE LWS_EXTERN void 726lws_ss_server_ack(struct lws_ss_handle *h, int nack); 727 728typedef void (*lws_sssfec_cb)(struct lws_ss_handle *h, void *arg); 729 730/** 731 * lws_ss_server_foreach_client() - callback for each live client connected to server 732 * 733 * \param h: server ss handle 734 * \param cb: the callback 735 * \param arg: arg passed to callback 736 * 737 * For SERVER secure streams 738 * 739 * Call the callback \p cb once for each client ss connected to the server, 740 * passing \p arg as an additional callback argument each time. 741 */ 742LWS_VISIBLE LWS_EXTERN void 743lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb, 744 void *arg); 745 746/** 747 * lws_ss_change_handlers() - helper for dynamically changing stream handlers 748 * 749 * \param h: ss handle 750 * \param rx: the new RX handler 751 * \param tx: the new TX handler 752 * \param state: the new state handler 753 * 754 * Handlers set to NULL are left unchanged. 755 * 756 * This works on any handle, client or server and takes effect immediately. 757 * 758 * Depending on circumstances this may be helpful when 759 * 760 * a) a server stream undergoes an LWSSSCS_SERVER_UPGRADE (as in http -> ws) and 761 * the payloads in the new protocol have a different purpose that is best 762 * handled in their own rx and tx callbacks, and 763 * 764 * b) you may want to serve several different, possibly large things based on 765 * what was requested. Setting a customized handler allows clean encapsulation 766 * of the different serving strategies. 767 * 768 * If the stream is long-lived, like ws, you should set the changed handler back 769 * to the default when the transaction wanting it is completed. 770 */ 771LWS_VISIBLE LWS_EXTERN void 772lws_ss_change_handlers(struct lws_ss_handle *h, lws_sscb_rx rx, lws_sscb_tx tx, 773 lws_sscb_state state); 774 775/** 776 * lws_ss_add_peer_tx_credit() - allow peer to transmit more to us 777 * 778 * \param h: secure streams handle 779 * \param add: additional tx credit (signed) 780 * 781 * Indicate to remote peer that we can accept \p add bytes more payload being 782 * sent to us. 783 */ 784LWS_VISIBLE LWS_EXTERN int 785lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t add); 786 787/** 788 * lws_ss_get_est_peer_tx_credit() - get our current estimate of peer's tx credit 789 * 790 * \param h: secure streams handle 791 * 792 * Based on what credit we gave it, and what we have received, report our 793 * estimate of peer's tx credit usable to transmit to us. This may be outdated 794 * in that some or all of its credit may already have been expended by sending 795 * stuff to us that is in flight already. 796 */ 797LWS_VISIBLE LWS_EXTERN int 798lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h); 799 800LWS_VISIBLE LWS_EXTERN const char * 801lws_ss_tag(struct lws_ss_handle *h); 802 803 804#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4) 805/** 806 * lws_ss_sigv4_set_aws_key() - set aws credential into system blob 807 * 808 * \param context: lws_context 809 * \param idx: the system blob index specified in the policy, currently 810 * up to 4 blobs. 811 * \param keyid: aws access keyid 812 * \param key: aws access key 813 * 814 * Return 0 if OK or nonzero if e.g. idx is invalid; system blob heap appending 815 * fails. 816 */ 817 818LWS_VISIBLE LWS_EXTERN int 819lws_ss_sigv4_set_aws_key(struct lws_context* context, uint8_t idx, 820 const char * keyid, const char * key); 821 822/** 823 * lws_aws_filesystem_credentials_helper() - read aws credentials from file 824 * 825 * \param path: path to read, ~ at start is converted to $HOME contents if any 826 * \param kid: eg, "aws_access_key_id" 827 * \param ak: eg, "aws_secret_access_key" 828 * \param aws_keyid: pointer to pointer for allocated keyid from credentials file 829 * \param aws_key: pointer to pointer for allocated key from credentials file 830 * 831 * Return 0 if both *aws_keyid and *aws_key allocated from the config file, else 832 * nonzero, and neither *aws_keyid or *aws_key are allocated. 833 * 834 * If *aws_keyid and *aws_key are set, it's the user's responsibility to 835 * free() them when they are no longer needed. 836 */ 837 838LWS_VISIBLE LWS_EXTERN int 839lws_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 845///@} 846