Documentation
¶
Overview ¶
Package socket is the UDP transport for RIST. The Simple profile (VSF TR-06-1) uses a pair of unconnected UDP sockets on adjacent even/odd ports — RTP media on the even port P, compound RTCP on the odd port P+1. The Main profile (TR-06-2) tunnels everything over a single GRE port; ListenSingle / ListenEphemeralSingle bind that one socket (the Conn's media and rtcp aliases then refer to it, and the session reads/writes it via ReadMedia/WriteMedia).
The sockets are deliberately unconnected (net.ListenUDP, not DialUDP) and every send takes an explicit destination, so one transport serves both roles: a receiver binds the well-known port pair and learns the sender's source addresses from inbound datagrams, while a sender binds an ephemeral pair and addresses the receiver's well-known ports. Address learning and the even/odd split mirror libRIST (bind, address matching).
This package only moves bytes; it never parses RTP/RTCP or touches the flow core. Read/Write are safe for concurrent use across the two sockets (each *net.UDPConn is independently goroutine-safe), which is how the host runs a reader goroutine per socket alongside the event loop.
Index ¶
- type Conn
- func FromConns(media, rtcp *net.UDPConn) *Conn
- func Listen(host string, port int) (*Conn, error)
- func ListenEphemeral(host string) (*Conn, error)
- func ListenEphemeralEvenOdd(host string) (*Conn, error)
- func ListenEphemeralFamily(network, host string) (*Conn, error)
- func ListenEphemeralSingle(host string) (*Conn, error)
- func ListenEphemeralSingleFamily(network, host string) (*Conn, error)
- func ListenSingle(host string, port int) (*Conn, error)
- func (c *Conn) Close() error
- func (c *Conn) DTLSEnabled() bool
- func (c *Conn) EnableDTLSClient(remote *net.UDPAddr, cfg *dtls.Config)
- func (c *Conn) EnableDTLSServer(cfg *dtls.Config)
- func (c *Conn) Handshake() error
- func (c *Conn) JoinMulticast(opts MulticastOptions) error
- func (c *Conn) MediaPort() int
- func (c *Conn) ReadMedia(buf []byte) (int, netip.AddrPort, error)
- func (c *Conn) ReadRTCP(buf []byte) (int, netip.AddrPort, error)
- func (c *Conn) SetMulticast(opts MulticastOptions) error
- func (c *Conn) WriteMedia(b []byte, dst netip.AddrPort) error
- func (c *Conn) WriteRTCP(b []byte, dst netip.AddrPort) error
- type MulticastOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn is a RIST UDP transport. For the Simple profile it holds a media socket (even port) and an RTCP socket (odd port). For the Main profile it holds one socket carrying everything: media and rtcp both alias it and single is true.
func FromConns ¶
FromConns wraps two already-bound UDP sockets (media even, rtcp odd). It lets a caller inject sockets — for tests or to satisfy a PacketConn-style API — and takes ownership: Close closes both.
func Listen ¶
Listen binds the media socket to host:port and the RTCP socket to host:port+1. port must be even (TR-06-1 §4: the media port is even, RTCP is the adjacent odd port); port 0 is rejected because the pair cannot be derived from an ephemeral media bind. host may be empty to bind all interfaces. It is the receiver-side constructor.
func ListenEphemeral ¶
ListenEphemeral binds both sockets to OS-chosen ports on host (empty host binds all interfaces). It is the sender-side constructor: the sender's local ports are arbitrary; the receiver learns them from inbound datagrams.
func ListenEphemeralEvenOdd ¶
ListenEphemeralEvenOdd binds an OS-chosen even media port and the adjacent odd RTCP port on host (empty host binds all interfaces). It is the Simple-profile caller-receiver constructor: a receiver that dials a listening sender still needs a local even/odd pair, because a Simple listener-sender infers the receiver's media address as its RTCP source port − 1 (the even/odd rule). A probe bind picks a free port; if it is odd the even neighbour below is tried, then port+1. The small TOCTOU window between probe and the real binds is tolerated by retrying.
func ListenEphemeralFamily ¶
ListenEphemeralFamily is ListenEphemeral with an explicit address family ("udp4" or "udp6"). A multicast sender must bind its egress socket in the group's family: a dual-stack ("udp", [::]) socket cannot have an IPv4 multicast interface/TTL set on it (the ipv4 socket options reject a v6-bound fd with EINVAL). network "udp" (the default) preserves the dual-stack unicast behavior.
func ListenEphemeralSingle ¶
ListenEphemeralSingle binds one OS-chosen UDP socket on host (empty host binds all interfaces) for the Main profile. It is the Main sender-side constructor; the receiver learns the local port from inbound datagrams.
func ListenEphemeralSingleFamily ¶
ListenEphemeralSingleFamily is ListenEphemeralSingle with an explicit address family ("udp4"/"udp6"); see ListenEphemeralFamily for why a multicast sender needs it.
func ListenSingle ¶
ListenSingle binds one UDP socket on host:port for the Main profile, where a single GRE-tunnelled port carries both media and feedback (TR-06-2). Unlike Listen it accepts any port (the Main port is not constrained to be even); host may be empty to bind all interfaces. It is the Main receiver-side constructor. Reads and writes use ReadMedia/WriteMedia on the single socket.
func (*Conn) Close ¶
Close closes both sockets, unblocking any in-flight reads (which return a net.ErrClosed-wrapped error). It is safe to call more than once.
func (*Conn) DTLSEnabled ¶
DTLSEnabled reports whether a DTLS session is configured (and so Handshake must run before media flows).
func (*Conn) EnableDTLSClient ¶
EnableDTLSClient configures the Conn to run a DTLS client handshake to remote on Handshake. The RIST sender is the DTLS client.
func (*Conn) EnableDTLSServer ¶
EnableDTLSServer configures the Conn to run a DTLS server handshake, learning the peer from the first inbound datagram on Handshake. The RIST receiver is the DTLS server.
func (*Conn) Handshake ¶
Handshake performs the configured DTLS handshake over the single socket, binding the session to one peer. It is a no-op when DTLS is not enabled. After it returns, ReadMedia/WriteMedia carry application records.
func (*Conn) JoinMulticast ¶
func (c *Conn) JoinMulticast(opts MulticastOptions) error
JoinMulticast joins opts.Group on the receiver's sockets so inbound group traffic is delivered. It joins on both the media and RTCP sockets (the Simple profile even/odd pair); for a single-socket Main/Advanced Conn the two alias one socket, so the second join is skipped. ASM uses JoinGroup; SSM (opts.Source set) uses JoinSourceSpecificGroup, restricting delivery to that source. It is a no-op when opts.Group is not a multicast address.
func (*Conn) ReadMedia ¶
ReadMedia reads one media (RTP) datagram into buf, returning the byte count and the source address (the sender's media address, for a receiver). When DTLS is enabled (Main profile), it returns the next decrypted application record and the established peer's address.
It uses (*net.UDPConn).ReadFromUDPAddrPort so the per-datagram receive path is allocation-free: a netip.AddrPort is a value type, so the source address is not heap-allocated the way ReadFromUDP's *net.UDPAddr was.
func (*Conn) ReadRTCP ¶
ReadRTCP reads one RTCP datagram into buf, returning the byte count and the source address. Like ReadMedia it reads via ReadFromUDPAddrPort (alloc-free).
func (*Conn) SetMulticast ¶
func (c *Conn) SetMulticast(opts MulticastOptions) error
SetMulticast configures the sender's outbound multicast options on its media (and, for the Simple even/odd pair, RTCP) socket: the egress interface, the multicast hop limit (TTL), and loopback. It is a no-op when opts.Group is not a multicast address. Only the options the caller set are applied (TTL 0 and a nil Iface leave the OS default in place).
func (*Conn) WriteMedia ¶
WriteMedia sends a media (RTP) datagram to dst. When DTLS is enabled (Main profile) it seals b as a DTLS application record to the established peer and dst is ignored (the DTLS session is bound to one peer).
type MulticastOptions ¶
type MulticastOptions struct {
// Group is the multicast destination/bind group. A receiver joins it; a
// sender stamps its egress options when transmitting to it. The zero Addr
// means "not multicast" (unicast, the default).
Group netip.Addr
// Source, when set, selects source-specific multicast (SSM, RFC 4607): a
// receiver joins the group filtered to this source IP. The zero Addr means
// any-source multicast (ASM).
Source netip.Addr
// Iface is the membership (receiver) or egress (sender) interface; nil lets
// the OS choose the system default.
Iface *net.Interface
// TTL is the sender's multicast hop limit; 0 leaves the OS default (1).
TTL int
// Loopback controls whether a sender receives its own multicast on the same
// host.
Loopback bool
}
MulticastOptions configures IP-multicast behavior on a Conn. The zero value is "no multicast" — Conn is a plain unicast transport unless these are set.