|
cwist
Modern C web framework with libttak runtime
|
WebRTC DataChannel context: UDP I/O, ICE-lite, DTLS, SCTP driving. More...
#include "webrtc_internal.h"#include <cwist/core/mem/alloc.h>#include <arpa/inet.h>#include <errno.h>#include <fcntl.h>#include <ifaddrs.h>#include <openssl/rand.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>
Go to the source code of this file.
Macros | |
| #define | RX_BUDGET 256 |
| #define | UDP_SOCKBUF (4 << 20) |
Timing | |
| #define | STUN_RTO_INITIAL_MS 300 |
| #define | STUN_RTO_MAX_MS 3000 |
| #define | STUN_MAX_ATTEMPTS 7 |
| #define | PARK_TIMEOUT_MS 30000 |
| #define | HANDSHAKE_TIMEOUT_MS 30000 |
| #define | LIVENESS_TIMEOUT_MS 30000 |
| #define | SCTP_TICK_ACTIVE_MS 10 |
| #define | SCTP_TICK_IDLE_MS 250 |
| #define | SCTP_ACTIVE_WINDOW_MS 1000 |
Functions | |
| void | cwist_webrtc_conn_retain (cwist_webrtc_conn *conn) |
Take a reference on conn so it stays valid outside a callback. | |
| void | cwist_webrtc_conn_release (cwist_webrtc_conn *conn) |
| Drop a reference taken with cwist_webrtc_conn_retain(). | |
| bool | cwist_webrtc_on_owner (const cwist_webrtc_ctx *ctx) |
true when the calling thread is servicing ctx right now. | |
| void | cwist_webrtc_conn_on_message (struct cwist_webrtc_conn *conn, uint16_t channel, const uint8_t *data, size_t len, int is_string) |
| Deliver a complete inbound message to the message handler. | |
| void | cwist_webrtc_conn_on_channel_open (struct cwist_webrtc_conn *conn, uint16_t channel, const char *label) |
| Report a channel the peer opened to the channel handler. | |
| void | cwist_webrtc_conn_dtls_out (struct cwist_webrtc_conn *conn, const uint8_t *data, size_t len) |
| Queue one datagram to the conn's peer (owner thread). | |
| void | cwist_webrtc_conn_sctp_out (struct cwist_webrtc_conn *conn, const void *buffer, size_t len) |
usrsctp output for conn; marshalled to the owner thread when needed. | |
| cwist_webrtc_ctx * | cwist_webrtc_ctx_new (uint16_t port) |
| Create a WebRTC context bound to a UDP port (0 picks an ephemeral port), running on its own reactor thread. | |
| cwist_webrtc_ctx * | cwist_webrtc_ctx_new_on (cwist_reactor_t *reactor, uint16_t port) |
| Create a WebRTC context on a reactor the caller runs. | |
| void | cwist_webrtc_ctx_free (cwist_webrtc_ctx *ctx) |
| Close every connection and free the context. | |
| uint16_t | cwist_webrtc_ctx_port (const cwist_webrtc_ctx *ctx) |
| UDP port the context is bound to. | |
| const char * | cwist_webrtc_ctx_fingerprint (const cwist_webrtc_ctx *ctx) |
| Local certificate fingerprint (SHA-256, colon-separated hex). | |
| void | cwist_webrtc_ctx_set_message_handler (cwist_webrtc_ctx *ctx, cwist_webrtc_message_cb cb, void *user) |
| Set the callback for incoming DataChannel messages. Set handlers before answering the first offer. | |
| void | cwist_webrtc_ctx_set_channel_handler (cwist_webrtc_ctx *ctx, cwist_webrtc_channel_cb cb, void *user) |
| Set the callback for incoming DataChannel open (DCEP) events. | |
| void | cwist_webrtc_ctx_set_close_handler (cwist_webrtc_ctx *ctx, cwist_webrtc_close_cb cb, void *user) |
| Set the callback for closed connections. | |
| int | cwist_webrtc_ctx_connection_count (const cwist_webrtc_ctx *ctx) |
| Number of connections whose SCTP association is up. | |
| size_t | cwist_webrtc_conn_buffered_amount (const cwist_webrtc_conn *conn) |
| Bytes accepted by cwist_webrtc_conn_send() and not yet handed to SCTP (like RTCDataChannel.bufferedAmount, summed over channels). | |
| int | cwist_webrtc_handle_offer (cwist_webrtc_ctx *ctx, const char *offer, char *answer_out, size_t out_len) |
| Answer a browser SDP offer (ICE-lite, setup:passive). | |
| cwist_webrtc_conn * | cwist_webrtc_connect (cwist_webrtc_ctx *ctx, const struct sockaddr_in *remote, const char *peer_ufrag, const char *peer_pwd) |
Offering-side dialer used by the loopback tests: registers a client conn to remote and starts ICE. | |
| int | cwist_webrtc_conn_send (cwist_webrtc_conn *conn, uint16_t channel_id, const uint8_t *data, size_t len, cwist_webrtc_data_type type) |
| Send a message on a DataChannel. | |
| void | cwist_webrtc_conn_close (cwist_webrtc_conn *conn) |
| Close a connection (SCTP abort, DTLS teardown). Safe from any thread; the close handler runs on the reactor thread. | |
WebRTC DataChannel context: UDP I/O, ICE-lite, DTLS, SCTP driving.
A ctx is one UDP socket served by one cwist reactor (see webrtc_internal.h for the threading and lifetime rules). Work happens only in reactor callbacks, and every callback follows the same shape:
ctx_enter() - mark this thread as servicing the ctx, cache the time ... - handle datagrams / a timer / a posted request ctx_leave() - service conns touched this round (drain SCTP, flush queued sends, apply closes), then send every queued datagram in one sendmmsg()
Datagrams are read in batches with recvmmsg(). A DTLS record is decrypted and fed to usrsctp right away, but draining SCTP and flushing sends waits until the batch is done, so a burst of packets for one conn costs one drain. Nothing runs on a fixed tick: each conn has one timer (STUN retransmit, DTLS retransmit, liveness or park expiry, whichever applies) and the ctx drives usrsctp's clock only while it holds associations, every 10 ms after recent traffic and every 250 ms otherwise.
Definition in file webrtc.c.
| #define HANDSHAKE_TIMEOUT_MS 30000 |
| #define LIVENESS_TIMEOUT_MS 30000 |
| #define PARK_TIMEOUT_MS 30000 |
| #define RX_BUDGET 256 |
| #define SCTP_ACTIVE_WINDOW_MS 1000 |
| #define SCTP_TICK_ACTIVE_MS 10 |
| #define SCTP_TICK_IDLE_MS 250 |
| #define STUN_MAX_ATTEMPTS 7 |
| #define STUN_RTO_INITIAL_MS 300 |
| #define UDP_SOCKBUF (4 << 20) |
| size_t cwist_webrtc_conn_buffered_amount | ( | const cwist_webrtc_conn * | conn | ) |
Bytes accepted by cwist_webrtc_conn_send() and not yet handed to SCTP (like RTCDataChannel.bufferedAmount, summed over channels).
Definition at line 1019 of file webrtc.c.
References cwist_webrtc_conn::buffered, and cap.
| void cwist_webrtc_conn_close | ( | cwist_webrtc_conn * | conn | ) |
Close a connection (SCTP abort, DTLS teardown). Safe from any thread; the close handler runs on the reactor thread.
Definition at line 1227 of file webrtc.c.
References cap, cwist_reactor_post::cb, cwist_webrtc_conn::close_post, cwist_webrtc_conn::close_posted, cwist_webrtc_conn::close_requested, cwist_reactor_post::ctx, cwist_webrtc_conn::ctx, cwist_webrtc_conn_retain(), cwist_webrtc_on_owner(), cwist_webrtc_conn::detached, and cwist_webrtc_ctx::reactor.
| void cwist_webrtc_conn_dtls_out | ( | struct cwist_webrtc_conn * | conn, |
| const uint8_t * | data, | ||
| size_t | len | ||
| ) |
Queue one datagram to the conn's peer (owner thread).
Definition at line 554 of file webrtc.c.
References cwist_webrtc_conn::ctx, and cwist_webrtc_conn::remote.
| void cwist_webrtc_conn_on_channel_open | ( | struct cwist_webrtc_conn * | conn, |
| uint16_t | channel, | ||
| const char * | label | ||
| ) |
Report a channel the peer opened to the channel handler.
Definition at line 548 of file webrtc.c.
References cap, cwist_webrtc_ctx::ch_cb, cwist_webrtc_ctx::ch_user, and cwist_webrtc_conn::ctx.
| void cwist_webrtc_conn_on_message | ( | struct cwist_webrtc_conn * | conn, |
| uint16_t | channel, | ||
| const uint8_t * | data, | ||
| size_t | len, | ||
| int | is_string | ||
| ) |
Deliver a complete inbound message to the message handler.
Definition at line 540 of file webrtc.c.
References cwist_webrtc_conn::ctx, CWIST_WEBRTC_DATA_BINARY, CWIST_WEBRTC_DATA_STRING, cwist_webrtc_ctx::msg_cb, and cwist_webrtc_ctx::msg_user.
| void cwist_webrtc_conn_release | ( | cwist_webrtc_conn * | conn | ) |
Drop a reference taken with cwist_webrtc_conn_retain().
Definition at line 86 of file webrtc.c.
References cap, cwist_webrtc_conn::ch_bits, cwist_webrtc_conn::ctx, cwist_free(), cwist_webrtc_conn::refs, cwist_webrtc_conn::rx_partial, cwist_webrtc_conn::ssl, and SSL_free.
| void cwist_webrtc_conn_retain | ( | cwist_webrtc_conn * | conn | ) |
Take a reference on conn so it stays valid outside a callback.
Definition at line 82 of file webrtc.c.
References cap, and cwist_webrtc_conn::refs.
Referenced by cwist_webrtc_conn_close(), cwist_webrtc_conn_sctp_out(), cwist_webrtc_conn_send(), and cwist_webrtc_connect().
| void cwist_webrtc_conn_sctp_out | ( | struct cwist_webrtc_conn * | conn, |
| const void * | buffer, | ||
| size_t | len | ||
| ) |
usrsctp output for conn; marshalled to the owner thread when needed.
Definition at line 577 of file webrtc.c.
References cap, cwist_webrtc_conn::ctx, cwist_alloc(), cwist_webrtc_conn_retain(), cwist_webrtc_on_owner(), cwist_webrtc_ctx::reactor, cwist_webrtc_conn::ssl, and SSL_write.
| int cwist_webrtc_conn_send | ( | cwist_webrtc_conn * | conn, |
| uint16_t | channel_id, | ||
| const uint8_t * | data, | ||
| size_t | len, | ||
| cwist_webrtc_data_type | type | ||
| ) |
Send a message on a DataChannel.
Safe from any thread. The message is queued if SCTP is not ready or its send buffer is full; queued bytes are reported by cwist_webrtc_conn_buffered_amount().
len exceeds 262144 bytes (the advertised max-message-size), or the queue already holds 4 MiB. Definition at line 1158 of file webrtc.c.
References cwist_webrtc_conn::buffered, cap, cwist_reactor_post::cb, cwist_reactor_post::ctx, cwist_webrtc_conn::ctx, cwist_alloc(), cwist_sctp_send(), cwist_webrtc_conn_retain(), CWIST_WEBRTC_DATA_STRING, CWIST_WEBRTC_MAX_MESSAGE, cwist_webrtc_on_owner(), cwist_webrtc_conn::detached, head, cwist_webrtc_conn::kick_post, cwist_webrtc_conn::pending_head, cwist_webrtc_ctx::reactor, and cwist_webrtc_conn::sctp_ready.
| cwist_webrtc_conn * cwist_webrtc_connect | ( | cwist_webrtc_ctx * | ctx, |
| const struct sockaddr_in * | remote, | ||
| const char * | peer_ufrag, | ||
| const char * | peer_pwd | ||
| ) |
Offering-side dialer used by the loopback tests: registers a client conn to remote and starts ICE.
Definition at line 1078 of file webrtc.c.
References cap, cwist_reactor_post::cb, cwist_reactor_post::ctx, cwist_webrtc_conn::ctx, cwist_webrtc_conn_retain(), cwist_webrtc_conn::peer_pwd, cwist_webrtc_conn::peer_ufrag, RAND_bytes, cwist_webrtc_ctx::reactor, cwist_webrtc_conn::reg_post, cwist_webrtc_conn::remote, and cwist_webrtc_conn::stun_txid.
| int cwist_webrtc_ctx_connection_count | ( | const cwist_webrtc_ctx * | ctx | ) |
Number of connections whose SCTP association is up.
Definition at line 1015 of file webrtc.c.
References cap, and cwist_webrtc_ctx::ready_count.
| const char * cwist_webrtc_ctx_fingerprint | ( | const cwist_webrtc_ctx * | ctx | ) |
Local certificate fingerprint (SHA-256, colon-separated hex).
Definition at line 993 of file webrtc.c.
References cwist_webrtc_ctx::fingerprint.
| void cwist_webrtc_ctx_free | ( | cwist_webrtc_ctx * | ctx | ) |
Close every connection and free the context.
Safe from any thread. For a ctx made with cwist_webrtc_ctx_new_on() and called off the reactor thread, this waits for the reactor to finish the teardown, so the reactor must still be running.
Definition at line 944 of file webrtc.c.
References cap, cwist_reactor_post::cb, cwist_reactor_post::ctx, cwist_reactor_destroy(), cwist_webrtc_ctx::fd_closed, cwist_webrtc_ctx::free_cv, cwist_webrtc_ctx::free_mu, cwist_webrtc_ctx::free_post, cwist_webrtc_ctx::owner_pid, cwist_webrtc_ctx::owns_reactor, cwist_webrtc_ctx::reactor, cwist_webrtc_ctx::thread, cwist_webrtc_ctx::thread_running, and cwist_webrtc_ctx::udp_fd.
Referenced by cwist_webrtc_ctx_new().
| cwist_webrtc_ctx * cwist_webrtc_ctx_new | ( | uint16_t | port | ) |
Create a WebRTC context bound to a UDP port (0 picks an ephemeral port), running on its own reactor thread.
Definition at line 879 of file webrtc.c.
References cap, cwist_reactor_create(), cwist_reactor_destroy(), cwist_webrtc_ctx_free(), cwist_webrtc_ctx::thread, and cwist_webrtc_ctx::thread_running.
| cwist_webrtc_ctx * cwist_webrtc_ctx_new_on | ( | cwist_reactor_t * | reactor, |
| uint16_t | port | ||
| ) |
Create a WebRTC context on a reactor the caller runs.
The ctx registers its UDP socket and timers with reactor and does all of its work inside that reactor's callbacks; no thread is created. The reactor must keep running until cwist_webrtc_ctx_free() returns.
Definition at line 895 of file webrtc.c.
References cap, and cwist_webrtc_ctx::udp_fd.
| uint16_t cwist_webrtc_ctx_port | ( | const cwist_webrtc_ctx * | ctx | ) |
UDP port the context is bound to.
Definition at line 989 of file webrtc.c.
References cwist_webrtc_ctx::port.
| void cwist_webrtc_ctx_set_channel_handler | ( | cwist_webrtc_ctx * | ctx, |
| cwist_webrtc_channel_cb | cb, | ||
| void * | user | ||
| ) |
Set the callback for incoming DataChannel open (DCEP) events.
Definition at line 1003 of file webrtc.c.
References cap, cwist_webrtc_ctx::ch_cb, and cwist_webrtc_ctx::ch_user.
| void cwist_webrtc_ctx_set_close_handler | ( | cwist_webrtc_ctx * | ctx, |
| cwist_webrtc_close_cb | cb, | ||
| void * | user | ||
| ) |
Set the callback for closed connections.
Definition at line 1009 of file webrtc.c.
References cap, cwist_webrtc_ctx::close_cb, and cwist_webrtc_ctx::close_user.
| void cwist_webrtc_ctx_set_message_handler | ( | cwist_webrtc_ctx * | ctx, |
| cwist_webrtc_message_cb | cb, | ||
| void * | user | ||
| ) |
Set the callback for incoming DataChannel messages. Set handlers before answering the first offer.
Definition at line 997 of file webrtc.c.
References cap, cwist_webrtc_ctx::msg_cb, and cwist_webrtc_ctx::msg_user.
| int cwist_webrtc_handle_offer | ( | cwist_webrtc_ctx * | ctx, |
| const char * | offer, | ||
| char * | answer_out, | ||
| size_t | out_len | ||
| ) |
Answer a browser SDP offer (ICE-lite, setup:passive).
| offer | The remote SDP offer. |
| answer_out | Buffer receiving the generated SDP answer. |
| out_len | Size of answer_out. |
Safe from any thread. The connection completes asynchronously (ICE nomination, DTLS, SCTP) on the ctx's reactor thread. An answered offer whose peer never shows up is dropped after 30 seconds.
Definition at line 1042 of file webrtc.c.
References cap, cwist_reactor_post::cb, cwist_reactor_post::ctx, cwist_webrtc_conn::ctx, cwist_sdp_parse(), cwist_sdp_write_answer(), cwist_webrtc_ctx::fingerprint, cwist_webrtc_ctx::host_ip, cwist_webrtc_ctx::ice_lite_server, cwist_webrtc_ctx::ice_pwd, cwist_webrtc_ctx::ice_ufrag, cwist_sdp_info::mid, cwist_webrtc_ctx::owner_pid, cwist_webrtc_conn::peer_pwd, cwist_webrtc_conn::peer_ufrag, cwist_webrtc_ctx::port, cwist_webrtc_ctx::reactor, and cwist_webrtc_conn::reg_post.
| bool cwist_webrtc_on_owner | ( | const cwist_webrtc_ctx * | ctx | ) |
true when the calling thread is servicing ctx right now.
Definition at line 100 of file webrtc.c.
Referenced by cwist_webrtc_conn_close(), cwist_webrtc_conn_sctp_out(), and cwist_webrtc_conn_send().