cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
sctp.c File Reference

SCTP DataChannels over DTLS (RFC 8831) and DCEP (RFC 8832). More...

#include "webrtc_internal.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <usrsctp.h>
#include <cwist/core/mem/alloc.h>
Include dependency graph for sctp.c:

Go to the source code of this file.

Macros

#define CWIST_SCTP_PORT   5000
 
#define CWIST_SCTP_STREAMS   1024
 
#define CWIST_SCTP_MTU   1160
 
#define CWIST_SCTP_HEARTBEAT_MS   10000
 
#define CWIST_SCTP_SOCKBUF   (1 << 20)
 
DCEP message types (RFC 8832)
#define DCEP_ACK   0x02
 
#define DCEP_OPEN   0x03
 
SCTP payload protocol identifiers (RFC 8831 section 8)
#define PPID_DCEP   50
 
#define PPID_STRING   51
 
#define PPID_BINARY   53
 
#define PPID_STRING_EMPTY   56
 
#define PPID_BINARY_EMPTY   57
 

Functions

int cwist_sctp_global_init (void)
 One-time usrsctp initialisation (no threads, AF_CONN only).
 
void cwist_sctp_tick (void)
 Advance usrsctp's process-wide timer clock to now. Any thread.
 
int cwist_sctp_conn_open (struct cwist_webrtc_conn *conn)
 Create, bind and listen/connect the conn's SCTP socket.
 
void cwist_sctp_conn_close (struct cwist_webrtc_conn *conn)
 Abort the association and release SCTP state. Idempotent.
 
void cwist_sctp_conn_input (struct cwist_webrtc_conn *conn, const uint8_t *data, size_t len)
 Feed one decrypted SCTP packet to usrsctp.
 
int cwist_sctp_conn_drain (struct cwist_webrtc_conn *conn)
 Accept (server role), then deliver every complete inbound message.
 
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.
 

Detailed Description

SCTP DataChannels over DTLS (RFC 8831) and DCEP (RFC 8832).

usrsctp runs in AF_CONN raw mode tunneled over the DTLS connection (RFC 8831), initialised without its own threads. Its global output callback hands packets to cwist_webrtc_conn_sctp_out(), which encrypts them on the conn's owner thread.

The address handle convention follows usrsctp's ekr_loop example: every endpoint registers its connection pointer as its handle, binds with it, and the offering side "connects" to its own handle. Packets are injected with usrsctp_conninput(conn) and replies come back through the same handle, which keeps routing unambiguous when several associations share one usrsctp instance. The answering side listens and accepts. Inbound data is drained with usrsctp_recvv() by the event loop; no receive callbacks are registered, so usrsctp never calls into us with data on an arbitrary thread.

Timers: usrsctp keeps one process-wide timer wheel. cwist_sctp_tick() advances it by the real time elapsed since the previous tick, whichever ctx calls it, so several ctxs ticking concurrently cannot make SCTP time run fast. A timer that fires may emit a packet for a conn owned by another reactor; the output path marshals it there. Teardown takes the same lock as the tick, so a timer pass never runs against a half-closed conn.

Definition in file sctp.c.

Macro Definition Documentation

◆ CWIST_SCTP_HEARTBEAT_MS

#define CWIST_SCTP_HEARTBEAT_MS   10000

SCTP heartbeat interval (ms).

Definition at line 63 of file sctp.c.

◆ CWIST_SCTP_MTU

#define CWIST_SCTP_MTU   1160

SCTP packet size. DTLS 1.2 with AES-GCM adds 37 bytes (13 header, 8 explicit nonce, 16 tag), so the datagram stays under the 1200-byte DTLS link MTU with room to spare.

Definition at line 60 of file sctp.c.

◆ CWIST_SCTP_PORT

#define CWIST_SCTP_PORT   5000

WebRTC DataChannel well-known SCTP port (RFC 8831, both endpoints use it).

Definition at line 52 of file sctp.c.

◆ CWIST_SCTP_SOCKBUF

#define CWIST_SCTP_SOCKBUF   (1 << 20)

Socket buffer for each association: holds several max-size messages.

Definition at line 66 of file sctp.c.

◆ CWIST_SCTP_STREAMS

#define CWIST_SCTP_STREAMS   1024

Streams negotiated in each direction (libwebrtc uses the same count).

Definition at line 55 of file sctp.c.

◆ DCEP_ACK

#define DCEP_ACK   0x02

DCEP ACK: acknowledges a received OPEN.

Definition at line 38 of file sctp.c.

◆ DCEP_OPEN

#define DCEP_OPEN   0x03

DCEP OPEN: announces a new DataChannel.

Definition at line 39 of file sctp.c.

◆ PPID_BINARY

#define PPID_BINARY   53

Binary message.

Definition at line 46 of file sctp.c.

◆ PPID_BINARY_EMPTY

#define PPID_BINARY_EMPTY   57

Empty binary message (sent as one 0x00 byte).

Definition at line 48 of file sctp.c.

◆ PPID_DCEP

#define PPID_DCEP   50

DCEP control message (OPEN/ACK).

Definition at line 44 of file sctp.c.

◆ PPID_STRING

#define PPID_STRING   51

UTF-8 string message.

Definition at line 45 of file sctp.c.

◆ PPID_STRING_EMPTY

#define PPID_STRING_EMPTY   56

Empty string (sent as one 0x00 byte).

Definition at line 47 of file sctp.c.

Function Documentation

◆ cwist_sctp_assoc_established()

bool cwist_sctp_assoc_established ( struct cwist_webrtc_conn *  conn)

true once the SCTP association is up.

Definition at line 399 of file sctp.c.

References cap, cwist_webrtc_conn::is_server_role, cwist_webrtc_conn::sctp_acc, and cwist_webrtc_conn::sctp_sock.

◆ cwist_sctp_conn_close()

◆ cwist_sctp_conn_drain()

int cwist_sctp_conn_drain ( struct cwist_webrtc_conn *  conn)

Accept (server role), then deliver every complete inbound message.

Returns
0 normally, -1 if the association is gone and the conn should close.

Definition at line 343 of file sctp.c.

References cap, cwist_webrtc_conn::close_requested, cwist_webrtc_conn::ctx, CWIST_WEBRTC_MAX_MESSAGE, cwist_webrtc_conn::detached, cwist_webrtc_conn::is_server_role, cwist_webrtc_conn::rx_partial, cwist_webrtc_conn::rx_partial_len, cwist_webrtc_conn::sctp_acc, cwist_webrtc_ctx::sctp_buf, and cwist_webrtc_conn::sctp_sock.

◆ cwist_sctp_conn_input()

void cwist_sctp_conn_input ( struct cwist_webrtc_conn *  conn,
const uint8_t *  data,
size_t  len 
)

Feed one decrypted SCTP packet to usrsctp.

Definition at line 317 of file sctp.c.

References cap, cwist_webrtc_conn::sctp_acc, and cwist_webrtc_conn::sctp_sock.

◆ cwist_sctp_conn_open()

int cwist_sctp_conn_open ( struct cwist_webrtc_conn *  conn)

Create, bind and listen/connect the conn's SCTP socket.

Returns
0 or -1.

Definition at line 265 of file sctp.c.

References cap, cwist_sctp_conn_close(), cwist_sctp_global_init(), CWIST_SCTP_PORT, cwist_webrtc_conn::is_server_role, and cwist_webrtc_conn::sctp_sock.

◆ cwist_sctp_global_init()

int cwist_sctp_global_init ( void  )

One-time usrsctp initialisation (no threads, AF_CONN only).

Returns
0.

Definition at line 106 of file sctp.c.

References cap.

Referenced by cwist_sctp_conn_open().

◆ cwist_sctp_send()

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.

Returns
0 when SCTP took it, 1 when the send buffer is full (retry after the next inbound packet), -1 on a hard error (message dropped).

Definition at line 410 of file sctp.c.

References cap, CWIST_SCTP_STREAMS, DCEP_OPEN, PPID_BINARY, PPID_BINARY_EMPTY, PPID_STRING, PPID_STRING_EMPTY, and cwist_webrtc_conn::sctp_ready.

Referenced by cwist_webrtc_conn_send().

◆ cwist_sctp_tick()

void cwist_sctp_tick ( void  )

Advance usrsctp's process-wide timer clock to now. Any thread.

Definition at line 111 of file sctp.c.

References cap.