47#define PPID_STRING_EMPTY 56
48#define PPID_BINARY_EMPTY 57
52#define CWIST_SCTP_PORT 5000
55#define CWIST_SCTP_STREAMS 1024
60#define CWIST_SCTP_MTU 1160
63#define CWIST_SCTP_HEARTBEAT_MS 10000
66#define CWIST_SCTP_SOCKBUF (1 << 20)
88static int sctp_global_output(
void *
addr,
void *buffer,
size_t length,
uint8_t tos,
99static void sctp_init_once(
void) {
103 g_sctp_clock_ms = sctp_now_ms();
114 if (
now > g_sctp_clock_ms) {
116 g_sctp_clock_ms =
now;
126 size_t off = (
size_t)ch * 2 + (
size_t)
bit;
128 return (conn->
ch_bits[off / 8] >> (off % 8)) & 1u;
137 size_t off = (
size_t)ch * 2 + (
size_t)
bit;
140 while (off / 8 >= len) len *= 2;
142 if (!bits)
return -1;
186 info.snd_sid = channel;
190 if (
rc >= 0)
return 0;
203 if (12 +
n > datalen)
n = datalen - 12;
206 ch_set(conn,
sid, 0);
222static void sctp_apply_sockopts(
struct socket *
sock) {
230 struct linger lg = {.l_onoff = 1, .l_linger = 0};
238 memset(&init, 0,
sizeof(init));
276 local.sconn_addr = conn;
348 sctp_apply_sockopts(conn->
sctp_acc);
368 if (
n == 0)
return -1;
371 if ((
size_t)
n >=
sizeof(
note->sn_header) &&
373 (
size_t)
n >=
sizeof(
note->sn_assoc_change)) {
384 if (rx_partial_append(conn, buf, (
size_t)
n) < 0)
return -1;
388 if (rx_partial_append(conn, buf, (
size_t)
n) < 0)
return -1;
393 dispatch_message(conn,
rcv.rcv_sid,
ntohl(
rcv.rcv_ppid), buf, (
size_t)
n);
404 memset(&status, 0,
sizeof(status));
411 size_t len,
int is_string) {
414 if (!ch_get(conn, channel, 0) && !ch_get(conn, channel, 1)) {
419 if (
rc != 0)
return rc;
420 if (ch_set(conn, channel, 1) < 0)
return -1;
424 info.snd_sid = channel;
437 if (
rc >= 0)
return 0;
Memory allocation wrappers backed by libttak.
void cwist_free(void *ptr)
Free memory obtained via cwist_alloc/cwist_strdup/etc.
void * cwist_alloc(size_t size)
Allocate zeroed memory tracked by libttak.
int cwist_sctp_conn_open(struct cwist_webrtc_conn *conn)
Create, bind and listen/connect the conn's SCTP socket.
#define CWIST_SCTP_SOCKBUF
#define CWIST_SCTP_HEARTBEAT_MS
int cwist_sctp_global_init(void)
One-time usrsctp initialisation (no threads, AF_CONN only).
int cwist_sctp_conn_drain(struct cwist_webrtc_conn *conn)
Accept (server role), then deliver every complete inbound message.
#define PPID_STRING_EMPTY
void cwist_sctp_tick(void)
Advance usrsctp's process-wide timer clock to now. Any thread.
bool cwist_sctp_assoc_established(struct cwist_webrtc_conn *conn)
true once the SCTP association is up.
int cwist_sctp_send(struct cwist_webrtc_conn *conn, uint16_t channel, const uint8_t *data, size_t len, int is_string)
Send one message, announcing the channel with DCEP OPEN first if we are opening it.
#define PPID_BINARY_EMPTY
void cwist_sctp_conn_close(struct cwist_webrtc_conn *conn)
Abort the association and release SCTP state. Idempotent.
#define CWIST_SCTP_STREAMS
void cwist_sctp_conn_input(struct cwist_webrtc_conn *conn, const uint8_t *data, size_t len)
Feed one decrypted SCTP packet to usrsctp.
One peer: ICE state, DTLS session, SCTP association.
struct socket * sctp_sock
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_sctp_out(struct cwist_webrtc_conn *conn, const void *buffer, size_t len)
usrsctp output for conn; marshalled to the owner thread when needed.
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.
Internal types and cross-file helpers for the WebRTC DataChannel module (ICE-lite + DTLS + SCTP over ...
#define CWIST_WEBRTC_MAX_MESSAGE