srt

package module
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2026 License: MIT Imports: 26 Imported by: 0

README

srtgo

A pure Go implementation of the SRT (Secure Reliable Transport) protocol.

Go Reference CI Go Report Card

Features

  • Live streaming with Timestamp-Based Packet Delivery (TSBPD) and too-late packet drop
  • File transfer with AIMD congestion control and reliable delivery
  • AES-128/192/256 encryption with CTR and GCM cipher modes
  • Forward Error Correction (row + column XOR-based FEC)
  • Rendezvous mode for peer-to-peer NAT traversal connections
  • Connection bonding with broadcast and backup failover groups
  • net.Conn compatible interface for drop-in use with existing Go code
  • Zero external dependencies -- stdlib only (plus golang.org/x/crypto for PBKDF2)
  • Server framework with publish/subscribe routing and graceful shutdown

Install

go get github.com/zsiec/srtgo

Requires Go 1.24 or later.

Quick Start

Receiver (server side)
package main

import (
	"log"

	srt "github.com/zsiec/srtgo"
)

func main() {
	l, err := srt.Listen("0.0.0.0:6000", srt.DefaultConfig())
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()

	l.SetAcceptFunc(func(req srt.ConnRequest) bool {
		return req.StreamID == "live/stream"
	})

	conn, err := l.Accept()
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	buf := make([]byte, 1500)
	for {
		n, err := conn.Read(buf)
		if err != nil {
			log.Println("read error:", err)
			return
		}
		// Process buf[:n]
		_ = n
	}
}
Sender (client side)
package main

import (
	"log"

	srt "github.com/zsiec/srtgo"
)

func main() {
	cfg := srt.DefaultConfig()
	cfg.StreamID = "live/stream"

	conn, err := srt.Dial("server:6000", cfg)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	payload := make([]byte, 1316) // typical MPEG-TS: 7 * 188
	for {
		if _, err := conn.Write(payload); err != nil {
			log.Println("write error:", err)
			return
		}
	}
}

Configuration

Use srt.DefaultConfig() as a starting point and override fields as needed.

Field Type Default Description
Latency time.Duration 120ms TSBPD receive delay. Negotiated to max(local, remote). Minimum 20ms.
RecvLatency time.Duration 0 (uses Latency) TSBPD latency for receiving. Overrides Latency when set.
PeerLatency time.Duration 0 (uses Latency) Minimum TSBPD latency requested of the peer.
MSS int 1500 Maximum Segment Size. Range: 76--1500.
FC int 25600 Flow control window in packets.
MaxBW int64 125000000 Maximum send bandwidth (bytes/sec). 0 = auto from InputBW.
OverheadBW int 25 Bandwidth overhead percentage for retransmissions (5--100).
SendBufSize int 8192 Send buffer size in packets.
RecvBufSize int 8192 Receive buffer size in packets.
PayloadSize int 0 (auto) Max payload per packet. 0 = MSS - 44. Used for CC pacing.
StreamID string "" Stream identifier sent during handshake. Max 512 bytes.
Passphrase string "" Encryption passphrase. 10--80 bytes when set.
KeyLength int 16 AES key size: 16 (AES-128), 24 (AES-192), or 32 (AES-256).
CryptoMode int 0 (auto) Cipher mode: 0 = auto, 1 = AES-CTR, 2 = AES-GCM.
TransType TransType TransTypeLive Transfer type: TransTypeLive or TransTypeFile.
Congestion CongestionType "live" Congestion control: CongestionLive or CongestionFile.
ConnTimeout time.Duration 3s Handshake timeout.
PeerIdleTimeout time.Duration 5s Peer inactivity timeout. Minimum 1s.
Linger time.Duration 0 Time Close() waits for send buffer to drain. Max 180s.
PacketFilter string "" FEC configuration string (e.g., "fec,cols:10,rows:5,layout:staircase,arq:onreq").
LossMaxTTL int 0 Reorder tolerance in packets. 0 = immediate NAK.
SndDropDelay int 0 Extra sender drop delay (ms). -1 = disable sender-side drop.
GroupConnect bool false Allow grouped connections on a listener.
Logger Logger nil Diagnostic logger. Nil = zero overhead.

See the full Config documentation for all fields.

Modes

Live Mode (default)

Live mode is optimized for real-time audio/video streaming:

  • TSBPD (Timestamp-Based Packet Delivery) delays packets to smooth jitter
  • TLPKTDROP (Too-Late Packet Drop) discards packets that arrive past the latency window
  • Fixed-rate pacing via LiveCC prevents bursts from overwhelming the network
  • Message API preserves packet boundaries (each Write maps to one Read)
cfg := srt.DefaultConfig() // live mode by default
cfg.Latency = 200 * time.Millisecond
File Mode

File mode is optimized for reliable bulk data transfer:

  • AIMD congestion control (slow start + congestion avoidance) adapts to available bandwidth
  • No packet drop -- all data is delivered reliably
  • Stream API -- data is treated as a byte stream, no message boundaries
  • Linger -- Close() waits up to 180s for the send buffer to drain
cfg := srt.DefaultConfig()
cfg.TransType = srt.TransTypeFile

Advanced Features

Encryption

SRT supports AES encryption with key exchange over the handshake. Set a passphrase (10--80 characters) on both sides:

cfg := srt.DefaultConfig()
cfg.Passphrase = "my-secret-passphrase"
cfg.KeyLength = 32       // AES-256 (default: 16 for AES-128)
cfg.CryptoMode = 2       // AES-GCM (default: 0 for auto/CTR)

Keys are derived via PBKDF2 and wrapped per RFC 3394. Key rotation occurs automatically every ~16.7M packets by default (configurable via KMRefreshRate and KMPreAnnounce).

Forward Error Correction

FEC adds parity packets using XOR across rows and columns, allowing the receiver to recover lost packets without retransmission:

cfg := srt.DefaultConfig()
cfg.PacketFilter = "fec,cols:10,rows:5,layout:staircase,arq:onreq"

Parameters:

  • cols -- number of columns in the FEC matrix
  • rows -- number of rows (0 = row FEC disabled)
  • layout -- staircase (default) or even
  • arq -- always (default), onreq (FEC first, retransmit on request), or never
Rendezvous Mode

Rendezvous mode enables peer-to-peer connections where neither side acts as a traditional server. Both peers bind to a local port and connect to each other simultaneously:

cfg := srt.DefaultConfig()
cfg.Passphrase = "shared-secret"

// Peer A (local :5000, remote peerB:5000)
conn, err := srt.DialRendezvous(":5000", "peerB:5000", cfg)

// Peer B (local :5000, remote peerA:5000)
conn, err := srt.DialRendezvous(":5000", "peerA:5000", cfg)

The handshake uses a cookie contest to assign INITIATOR/RESPONDER roles automatically.

Connection Bonding

Groups manage multiple SRT connections for link redundancy. Two modes are supported:

Broadcast sends every packet on all links. The receiver deduplicates by sequence number:

g := srt.NewGroup(srt.GroupBroadcast)
g.Connect("server1:4200", cfg, 1, 100) // token=1, weight=100
g.Connect("server2:4200", cfg, 2, 50)  // token=2, weight=50
defer g.Close()

g.Write(payload) // sent on both links
n, err := g.Read(buf) // deduplicated

Backup uses one active link with automatic failover to standby links:

g := srt.NewGroup(srt.GroupBackup)
g.SetStabilityTimeout(2 * time.Second)
g.Connect("primary:4200", cfg, 1, 100)  // higher weight = preferred
g.Connect("fallback:4200", cfg, 2, 50)
defer g.Close()

g.Write(payload) // sent on active link only; buffered for failover

When the active link becomes unstable, the highest-weight standby is promoted and recent packets are replayed for seamless continuity.

Server Framework

The Server type provides a high-level callback-based framework for building SRT applications:

package main

import (
	"log"

	srt "github.com/zsiec/srtgo"
)

func main() {
	s := &srt.Server{
		Addr: ":6000",
		HandleConnect: func(req srt.ConnRequest) srt.ConnType {
			if req.StreamID == "live/feed" {
				return srt.Publish
			}
			if req.StreamID == "live/watch" {
				return srt.Subscribe
			}
			return srt.Reject
		},
		HandlePublish: func(conn *srt.Conn) {
			buf := make([]byte, 1500)
			for {
				n, err := conn.Read(buf)
				if err != nil {
					return
				}
				log.Printf("received %d bytes from publisher", n)
			}
		},
		HandleSubscribe: func(conn *srt.Conn) {
			// Send data to subscriber
			for {
				if _, err := conn.Write([]byte("data")); err != nil {
					return
				}
			}
		},
	}

	log.Fatal(s.ListenAndServe())
}

Call s.Shutdown() from another goroutine for graceful shutdown. Each handler runs in its own goroutine and the connection is closed when the handler returns.

Statistics

The Stats method on *Conn returns detailed connection metrics:

stats := conn.Stats(false) // false = cumulative totals; true = interval since last call

log.Printf("RTT: %v, Loss: %.2f%%, Bandwidth: %d pkt/s",
	stats.RTT, stats.SendLossRate, stats.EstimatedBandwidth)
log.Printf("Sent: %d pkts (%d bytes), Retransmits: %d",
	stats.SentPackets, stats.SentBytes, stats.Retransmits)
log.Printf("Recv: %d pkts (%d bytes), Dropped: %d",
	stats.RecvPackets, stats.RecvBytes, stats.RecvDropped)
log.Printf("Flight: %d pkts, SendBuf: %d pkts, RecvBuf: %d pkts",
	stats.FlightSize, stats.SendBufSize, stats.RecvBufSize)

The ConnStats struct includes counters for packets, bytes, loss, retransmits, drops, RTT, buffer state, bitrates, and key management state. Groups expose aggregate stats via g.Stats().

Architecture

Each SRT connection runs exactly 3 goroutines:

Goroutine Role
recvLoop Reads packets from the UDP mux, processes control packets (ACK, NAK, keepalive), inserts data packets into the receive buffer
timerLoop 10ms ticker drives periodic events: Full ACK, periodic NAK, keepalive, TSBPD delivery, EXP timeout
application User calls Read / Write on the connection

All connections sharing a listener multiplex over a single UDP socket. Packets are dispatched by DestinationSocketID in a single read goroutine.

Internal Package Layout
Package Description
internal/seq 31-bit wrapping sequence numbers with comparison and arithmetic
internal/clock Type-safe Microseconds / Timestamp types, Clock interface (real + mock for testing)
internal/packet Concrete Packet struct, SRT header marshal/unmarshal, CIF types for all control packets
internal/crypto AES-CTR/GCM encryption, RFC 3394 key wrap, PBKDF2 key derivation
internal/mux UDP multiplexer -- shared socket dispatching packets by socket ID
internal/buffer O(1) sequence-indexed send/receive ring buffers using power-of-2 bitmask
internal/tsbpd Timestamp-Based Packet Delivery with drift compensation and group synchronization
internal/congestion LiveCC (fixed-rate pacer) and FileCC (AIMD adaptive congestion control)
internal/handshake SYN cookie generation/validation, 4-step and rendezvous handshake builders
internal/filter FEC packet filter with row/column XOR encoding and recovery

Performance

Benchmarks on Apple M1 Pro (single core):

Operation Time Allocations
Packet parse 58 ns 1 alloc
Header marshal 2.4 ns 0 allocs
Sequence ops ~2 ns 0 allocs
Clock ops ~2 ns 0 allocs
Buffer push 72 ns 0 allocs
Buffer ACK 14 ns 0 allocs
Write throughput 164 MB/s 5 allocs/op
Dial + Accept 523 us 146 allocs
AES encrypt 293 ns 0 allocs
Key wrap 352 ns 0 allocs

Hot-path allocations are minimized through sync.Pool for packet buffers and concrete types (no interfaces on hot paths).

Examples

The examples/ directory contains runnable demos:

Example Description Run
loopback Zero-config self-test: transfers 10 MB over localhost, verifies SHA-256, prints stats go run ./examples/loopback
streaming Simulates live streaming with a real-time stats dashboard (throughput, RTT, loss) go run ./examples/streaming
sender Sends stdin or a test pattern to an SRT receiver go run ./examples/sender -addr 127.0.0.1:4200
receiver Listens for a connection and writes received data to stdout go run ./examples/receiver -addr :4200
filetransfer Reliable file transfer using file mode go run ./examples/filetransfer -mode send -file data.bin
server Server framework with publish/subscribe routing go run ./examples/server
interop Media relay for interop testing with FFmpeg, VLC, and C++ SRT tools go run ./examples/interop

Start with loopback to verify everything works — it requires no setup:

go run ./examples/loopback
srtgo loopback demo
====================

Listener ready on 127.0.0.1:53314
Connected (RTT: 0.08ms, mode: file)

Transferring 10.0 MB...
   10.0 / 10.0 MB  100%   105.8 MB/s

Transfer complete
  Duration:    94ms
  Throughput:  105.8 MB/s
  Sent:        7202 packets (10485760 bytes)
  Received:    7202 packets (10485760 bytes)
  Retransmits: 0
  Integrity:   SHA-256 verified

Testing

Unit Tests
go test -race -count=1 -timeout 120s ./...
Interop Tests

The interop test suite validates srtgo against the C++ reference implementation (srt-live-transmit). Tests cover live and file modes, encryption, FEC, stream IDs, payload sizes, statistics, and more across both Go-to-C++ and C++-to-Go directions.

Requires srt-tools to be installed:

# Ubuntu/Debian
sudo apt-get install srt-tools

# macOS
brew install srt

Run the interop tests:

go test -tags interop -run TestInterop -v -count=1 -timeout 600s

Interop tests run automatically in CI on both Ubuntu and macOS.

Benchmarks
go test -bench=. -benchmem ./...

Contributing

Contributions are welcome. Please see CONTRIBUTING.md for guidelines.

License

MIT

Documentation

Overview

Package srt implements the SRT (Secure Reliable Transport) protocol in pure Go.

SRT is a UDP-based protocol for low-latency, reliable transport of live media streams. This implementation supports live streaming and file transfer modes with caller-listener and rendezvous (P2P) connection models.

Architecture

Each SRT connection uses exactly 3 goroutines:

  • recvLoop: reads packets from the mux, processes control packets, inserts data packets into the receive buffer
  • timerLoop: 10ms ticker drives periodic events (ACK, NAK, keepalive, TSBPD)
  • application goroutine: calls Read/Write on the connection

All connections sharing a listener multiplex over a single UDP socket. Packets are dispatched by DestinationSocketID in a single read goroutine.

Usage

Listener (server):

l, err := srt.Listen("0.0.0.0:6000", srt.DefaultConfig())
if err != nil {
    log.Fatal(err)
}
defer l.Close()

l.SetAcceptFunc(func(req srt.ConnRequest) bool {
    return req.StreamID == "live/stream"
})

conn, err := l.Accept()
// conn implements net.Conn

Dialer (client):

cfg := srt.DefaultConfig()
cfg.StreamID = "live/stream"
cfg.Latency = 120 * time.Millisecond

conn, err := srt.Dial("server:6000", cfg)
// conn implements net.Conn

Rendezvous (P2P):

cfg := srt.DefaultConfig()
conn, err := srt.DialRendezvous(":6000", "peer:6000", cfg)
// conn implements net.Conn

Index

Examples

Constants

View Source
const (
	DefaultLatency         = 120 * time.Millisecond   // minimum TSBPD delay
	DefaultMSS             = 1500                     // maximum segment size
	DefaultFC              = 25600                    // flow control window (packets)
	DefaultSendBufSize     = 8192                     // send buffer size (packets)
	DefaultRecvBufSize     = 8192                     // receive buffer size (packets)
	DefaultMaxBW           = int64(1_000_000_000 / 8) // 1 Gbps = 125 MB/s
	DefaultOverheadBW      = 25                       // 25% overhead for retransmissions
	DefaultConnTimeout     = 3 * time.Second          // handshake timeout
	DefaultPeerIdleTimeout = 5 * time.Second          // peer inactivity timeout
	MaxLinger              = 180 * time.Second        // maximum linger duration (3 minutes)

	DefaultKMRefreshRate = uint64(1 << 24) // 16.7M packets before key switch
	DefaultKMPreAnnounce = uint64(1 << 16) // 64K packets before refresh to announce new key

	MinMSS     = 76 // minimum MSS (IP header + UDP header + SRT header)
	MaxMSS     = 1500
	MinPayload = 32 // minimum payload size after header overhead
	MinLatency = 20 * time.Millisecond

	MinBufSize = 32 // minimum send/recv buffer size (packets)
	MinFC      = 32 // minimum flow control window (packets)
)

Default configuration values.

View Source
const (
	CryptoModeAuto int = 0 // responder adopts initiator's mode
	CryptoModeCTR  int = 1 // AES-CTR (default for initiators)
	CryptoModeGCM  int = 2 // AES-GCM (authenticated encryption)
)

CryptoMode constants for Config.CryptoMode.

View Source
const (
	RejUnknown    = packet.HandshakeType(1000) // unknown reason
	RejSystem     = packet.HandshakeType(1001) // system function error
	RejPeer       = packet.HandshakeType(1002) // rejected by peer
	RejResource   = packet.HandshakeType(1003) // resource allocation problem
	RejRogue      = packet.HandshakeType(1004) // incorrect data in handshake
	RejBacklog    = packet.HandshakeType(1005) // listener's backlog exceeded
	RejIPE        = packet.HandshakeType(1006) // internal program error
	RejClose      = packet.HandshakeType(1007) // socket is closing
	RejVersion    = packet.HandshakeType(1008) // peer version too old
	RejRdvCookie  = packet.HandshakeType(1009) // rendezvous cookie collision (reserved)
	RejBadSecret  = packet.HandshakeType(1010) // wrong password
	RejUnsecure   = packet.HandshakeType(1011) // password required or unexpected
	RejMessageAPI = packet.HandshakeType(1012) // stream flag collision
	RejCongestion = packet.HandshakeType(1013) // incompatible congestion controller
	RejFilter     = packet.HandshakeType(1014) // incompatible packet filter
	RejGroup      = packet.HandshakeType(1015) // incompatible group
	RejTimeout    = packet.HandshakeType(1016) // connection timeout
	RejCrypto     = packet.HandshakeType(1017) // conflicting cryptographic configurations

	// RejUserDefined is the base for user-defined rejection codes.
	// Codes 2000+ are passed through unchanged in the rejection handshake.
	RejUserDefined = packet.HandshakeType(2000)

	// Extended rejection codes for access control (matching C++ access_control.h).
	// These are within the user-defined range (>= 1000) and pass through
	// the wire format unchanged.
	RejXBadRequest    = packet.HandshakeType(1400) // malformed stream ID
	RejXUnauthorized  = packet.HandshakeType(1401) // authentication required
	RejXOverloaded    = packet.HandshakeType(1402) // server overloaded
	RejXForbidden     = packet.HandshakeType(1403) // access denied
	RejXNotFound      = packet.HandshakeType(1404) // resource not found
	RejXBadMode       = packet.HandshakeType(1405) // unsupported mode
	RejXUnacceptable  = packet.HandshakeType(1406) // parameters unacceptable
	RejXConflict      = packet.HandshakeType(1409) // resource conflict
	RejXLocked        = packet.HandshakeType(1423) // resource locked
	RejXInternalError = packet.HandshakeType(1500) // server internal error
	RejXUnavailable   = packet.HandshakeType(1503) // service unavailable
)

Rejection reasons for handshake failures. These are sent in the HandshakeType field of a rejection response.

View Source
const (
	EventIn  = 0x1 // data available for reading
	EventOut = 0x4 // send buffer has space
	EventErr = 0x8 // connection error/broken
)

Poll event flags for SockOptEvent.

View Source
const (
	// PeerErrorFileSystem indicates a filesystem error on the peer (e.g. disk
	// write failure during file transfer). This is the only error code defined
	// in the SRT specification and the C++ reference implementation.
	// Matches C++ CUDTException::EFILE = MJ_FILESYSTEM * 1000 = 4000.
	PeerErrorFileSystem uint32 = 4000
)

Peer error codes sent via PEERERROR control packets (Section 3.2.10). The error code is carried in the TypeSpecific field of the control header.

Variables

View Source
var (
	// ErrWouldBlock is returned when a non-blocking send or receive cannot complete
	// immediately (SRTO_SNDSYN=false or SRTO_RCVSYN=false).
	ErrWouldBlock = errors.New("srt: operation would block")

	// ErrGroupClosed is returned when operating on a closed Group.
	ErrGroupClosed = errors.New("srt: group closed")

	// ErrListenerClosed is returned when Accept is called on a closed Listener.
	ErrListenerClosed = errors.New("srt: listener closed")

	// ErrNilConnection is returned when a nil Conn is passed to a group or watcher.
	ErrNilConnection = errors.New("srt: nil connection")

	// ErrPeerError is returned when the peer sends an error.
	ErrPeerError = errors.New("srt: peer error")

	// ErrConnectionTimeout is returned when the connection times out due to inactivity.
	ErrConnectionTimeout = errors.New("srt: connection timeout")

	// ErrPeerShutdown is returned when the peer sends a shutdown control packet.
	ErrPeerShutdown = errors.New("srt: peer shutdown")
)

Sentinel errors for common conditions.

View Source
var ErrAlreadyWatched = errors.New("srt: connection already watched")

ErrAlreadyWatched is returned when adding a connection that is already watched.

View Source
var ErrInvalidOption = errors.New("srt: invalid socket option")

ErrInvalidOption is returned when an unsupported SockOpt is used.

View Source
var ErrNotWatched = errors.New("srt: connection not watched")

ErrNotWatched is returned when removing a connection that is not watched.

View Source
var ErrPreConnectOnly = errors.New("srt: socket option can only be set before connecting")

ErrPreConnectOnly is returned when trying to Set a pre-connect-only option on a live connection.

View Source
var ErrReadOnlyOption = errors.New("srt: socket option is read-only")

ErrReadOnlyOption is returned when trying to Set a read-only option.

View Source
var ErrServerClosed = errors.New("srt: server closed")

ErrServerClosed is returned by Serve when the server is shut down.

View Source
var ErrWatcherClosed = errors.New("srt: watcher closed")

ErrWatcherClosed is returned when operating on a closed Watcher.

Functions

This section is empty.

Types

type AcceptFunc

type AcceptFunc func(req ConnRequest) bool

AcceptFunc is called for each incoming connection during the handshake. It receives the connection request with the stream ID and peer address, and returns whether to accept the connection.

type AcceptRejectFunc

type AcceptRejectFunc func(req ConnRequest) RejectReason

AcceptRejectFunc is called for each incoming connection during the handshake. It receives the connection request and returns a rejection reason. Return 0 to accept the connection. Return any non-zero HandshakeType to reject with that code (e.g., RejPeer, or user-defined codes >= RejUserDefined).

type BackupState

type BackupState int

BackupState tracks fine-grained state for backup mode members.

const (
	BackupStandby        BackupState = iota // Ready but not sending
	BackupActiveFresh                       // Recently activated, probing
	BackupActiveStable                      // Sending well
	BackupActiveUnstable                    // Degraded (no response > stability timeout)
	BackupActiveWary                        // Recovering from unstable
	BackupBroken                            // Disconnected
)

func (BackupState) String

func (s BackupState) String() string

String returns a human-readable name for the backup state.

type BindingTime

type BindingTime int

BindingTime describes when an option may be changed.

const (
	// BindPreBind means the option cannot change after the socket is bound.
	BindPreBind BindingTime = iota
	// BindPre means the option cannot change after connect/listen.
	BindPre
	// BindPost means the option can change while connected.
	BindPost
)

type Config

type Config struct {
	// Latency is the TSBPD latency (receive delay).
	// The actual latency used is max(local, remote) during negotiation.
	// Default: 120ms. Minimum: 20ms.
	// If RecvLatency or PeerLatency are set, they override this value
	// for their respective directions.
	Latency time.Duration

	// RecvLatency is the TSBPD latency for receiving data (SRTO_RCVLATENCY).
	// If zero, defaults to Latency.
	RecvLatency time.Duration

	// PeerLatency is the minimum TSBPD latency requested of the peer (SRTO_PEERLATENCY).
	// If zero, defaults to Latency.
	PeerLatency time.Duration

	// MSS is the Maximum Segment Size (MTU - IP - UDP headers).
	// Negotiated to the smaller of the two sides.
	// Default: 1500. Range: 76-1500.
	MSS int

	// FC is the flow control window in packets.
	// Default: 25600.
	FC int

	// MaxBW is the maximum sending bandwidth in bytes per second.
	// When > 0, used directly (no overhead applied).
	// When 0 and InputBW > 0, InputBW * (1 + OverheadBW/100) is used.
	// When 0 and InputBW == 0, defaults to 125 MB/s (1 Gbps).
	MaxBW int64

	// OverheadBW is the bandwidth overhead percentage for retransmissions.
	// Range: 5-100. Default: 25.
	OverheadBW int

	// SendBufSize is the send buffer size in packets.
	// Default: 8192.
	SendBufSize int

	// RecvBufSize is the receive buffer size in packets.
	// Default: 8192.
	RecvBufSize int

	// PayloadSize is the maximum payload size per packet (SRTO_PAYLOADSIZE).
	// When 0 (default), derived from MSS: MSS - 44 (IP 20 + UDP 8 + SRT 16).
	// When set, must be <= MSS - 44. Used for CC pacing and fragmentation limit.
	PayloadSize int

	// StreamID is the stream identifier sent during the handshake.
	// Maximum 512 bytes. Used by the listener to route/authorize connections.
	StreamID string

	// Passphrase enables encryption. Must be 10-80 bytes if set.
	Passphrase string

	// KeyLength is the AES key size in bytes: 16 (AES-128), 24 (AES-192), or 32 (AES-256).
	// Default: 16. Only used when Passphrase is set.
	KeyLength int

	// CryptoMode selects the encryption cipher mode.
	// 0 = auto (responder adopts initiator's mode), 1 = AES-CTR, 2 = AES-GCM.
	// Default: 0 (auto, which defaults to CTR for initiators).
	// SRTO_CRYPTOMODE: CIPHER_MODE_AUTO=0, CIPHER_MODE_AES_CTR=1, CIPHER_MODE_AES_GCM=2.
	CryptoMode int

	// ConnTimeout is the handshake timeout.
	// Default: 3s.
	ConnTimeout time.Duration

	// Linger is the maximum time Close() will wait for the send buffer
	// to drain before shutting down. Default: 0 (immediate close).
	// Maximum: 3s.
	Linger time.Duration

	// PeerIdleTimeout is the duration of peer inactivity (no packets received)
	// before the connection is considered timed out.
	// Default: 5s. Minimum: 1s.
	PeerIdleTimeout time.Duration

	// KMRefreshRate is the number of packets sent before switching to a new
	// encryption key. Set to 0 to disable key rotation.
	// Default: 2^24 (~16.7M packets).
	KMRefreshRate uint64

	// KMPreAnnounce is the number of packets before the refresh point at
	// which the new key is announced to the peer via KMREQ.
	// Must be less than KMRefreshRate/2. Default: 2^16 (65536 packets).
	KMPreAnnounce uint64

	// MessageAPI enables message-oriented delivery (default: true for live mode).
	// When true, each Write/Read preserves message boundaries.
	// When false, data is treated as a byte stream (FlagStream in handshake).
	MessageAPI *bool

	// TransType selects a bundle of settings. TransTypeFile overrides
	// Congestion to "file" and sets appropriate defaults.
	// Default: TransTypeLive.
	TransType TransType

	// Congestion selects the congestion control algorithm: "live" or "file".
	// Overridden by TransType if set to TransTypeFile.
	// Default: "live".
	Congestion CongestionType

	// MinVersion is the minimum SRT version required of the peer (SRTO_MINVERSION).
	// Connections from peers with a lower version are rejected.
	// Default: 0x010000 (1.0.0).
	MinVersion uint32

	// LossMaxTTL is the maximum reorder tolerance in packets (SRTO_LOSSMAXTTL).
	// When > 0, enables the FreshLoss mechanism: NAK is deferred for up to this
	// many received packets to allow out-of-order arrivals before reporting loss.
	// Default: 0 (immediate NAK, no reorder tolerance).
	LossMaxTTL int

	// SndDropDelay is extra sender drop delay in milliseconds (SRTO_SNDDROPDELAY).
	// Added to the TSBPD latency when computing the sender-side drop threshold.
	// Set to -1 to disable sender-side too-late drop entirely.
	// Default: 0.
	SndDropDelay int

	// EnforcedEncryption when true (default), requires both sides to use
	// matching encryption. When false, allows mixed encrypted/unencrypted
	// connections (SRTO_ENFORCEDENCRYPTION).
	EnforcedEncryption *bool

	// NAKReport when true (default for live mode), enables periodic NAK reports.
	// When false, only immediate NAKs are sent on gap detection.
	// Always false for file mode (SRTO_NAKREPORT).
	NAKReport *bool

	// RetransmitAlgo selects the retransmission algorithm (SRTO_RETRANSMITALGO).
	// 0 = always immediate retransmit on NAK (no timing gate).
	// 1 = timing gate: skip retransmit if packet was recently sent (default for live).
	// Default: 1 for live mode, 0 for file mode.
	RetransmitAlgo *int

	// DriftTracer when true (default), enables TSBPD drift correction.
	// When false, drift compensation is disabled (SRTO_DRIFTTRACER).
	DriftTracer *bool

	// IPTTL sets the IP Time-To-Live for outgoing packets (SRTO_IPTTL).
	// Default: -1 (use OS default). Range: 1-255.
	IPTTL int

	// IPTOS sets the IP Type-Of-Service / DiffServ field (SRTO_IPTOS).
	// Default: -1 (use OS default). Range: 0-255.
	IPTOS int

	// InputBW is the estimated input bandwidth in bytes per second (SRTO_INPUTBW).
	// When MaxBW is 0 (auto), InputBW * (1 + OverheadBW/100) is used as the
	// effective sending rate. Default: 0 (not used).
	InputBW int64

	// MinInputBW is the minimum input bandwidth estimate in bytes per second
	// (SRTO_MININPUTBW). When auto-input-rate sampling is active (MaxBW=0 and
	// InputBW=0), the sampled rate will not drop below this floor. Default: 0.
	MinInputBW int64

	// MaxRexmitBW is the maximum retransmission bandwidth in bytes per second
	// (SRTO_MAXREXMITBW). When > 0, retransmissions are rate-limited using a
	// token bucket. 0 = unlimited (default).
	MaxRexmitBW int64

	// SndSyn when true (default), Write blocks until send buffer has space.
	// When false, Write returns ErrWouldBlock if the send buffer is full.
	// SRTO_SNDSYN (default: true).
	SndSyn *bool

	// RcvSyn when true (default), Read blocks until data is available.
	// When false, Read returns ErrWouldBlock if no data is ready.
	// SRTO_RCVSYN (default: true).
	RcvSyn *bool

	// PacketFilter is the FEC filter configuration string (SRTO_PACKETFILTER).
	// Format: "fec,cols:N,rows:M,layout:staircase,arq:onreq"
	// Empty string disables FEC. Default: "" (disabled).
	PacketFilter string

	// GroupConnect enables accepting grouped connections on a listener.
	// When true, the listener recognizes the group handshake extension
	// and allows multiple connections to join the same group.
	// Default: false (group connections rejected). Maps to SRTO_GROUPCONNECT.
	GroupConnect bool

	// GroupStabTimeout is the minimum stability timeout for backup mode.
	// A link with no response for longer than this is considered unstable.
	// Only used in GroupBackup mode. Default: 1s.
	// Maps to SRTO_GROUPMINSTABLETIMEO.
	GroupStabTimeout time.Duration

	// UDPSendBufSize sets the UDP socket send buffer size in bytes (SO_SNDBUF).
	// When 0 (default), the OS default is used. Must be >= MSS when set.
	// Maps to SRTO_UDP_SNDBUF (PREBIND option, set before I/O).
	UDPSendBufSize int

	// UDPRecvBufSize sets the UDP socket receive buffer size in bytes (SO_RCVBUF).
	// When 0 (default), the OS default is used. Must be >= MSS when set.
	// Maps to SRTO_UDP_RCVBUF (PREBIND option, set before I/O).
	UDPRecvBufSize int

	// IPv6Only controls whether an IPv6 socket accepts IPv4 connections
	// via IPv4-mapped IPv6 addresses (dual-stack). When nil, the OS default
	// is used. When true, only IPv6 is allowed. When false, dual-stack is
	// enabled. Only meaningful for IPv6 listeners. Maps to IPV6_V6ONLY.
	IPv6Only *bool

	// BindToDevice binds the socket to a specific network interface.
	// Only supported on Linux (SO_BINDTODEVICE). Empty string disables.
	BindToDevice string

	// Sender determines the data direction role for HSv4 connections.
	// When non-nil and true, this side sends HSREQ first (data sender role).
	// When nil or false, this side is the responder (data receiver role).
	// Only meaningful for HSv4 connections; HSv5 is always bidirectional.
	Sender *bool

	// Logger receives diagnostic log messages. When nil (the default),
	// no logging occurs and there is zero performance overhead.
	Logger Logger
}

Config contains SRT connection configuration.

Example
package main

import (
	"time"

	srt "github.com/zsiec/srtgo"
)

func main() {
	// Basic live streaming configuration
	live := srt.DefaultConfig()
	live.Latency = 200 * time.Millisecond
	live.StreamID = "live/stream1"

	// Encrypted connection with AES-256
	encrypted := srt.DefaultConfig()
	encrypted.Passphrase = "my_secret_passphrase"
	encrypted.KeyLength = 32

	// File transfer mode
	file := srt.DefaultConfig()
	file.TransType = srt.TransTypeFile

	_ = live
	_ = encrypted
	_ = file
}

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a Config with default values.

type CongestionType

type CongestionType string

CongestionType selects the congestion control algorithm.

const (
	// CongestionLive selects fixed-rate pacing (default).
	CongestionLive CongestionType = "live"

	// CongestionFile selects CUBIC-like adaptive congestion control.
	CongestionFile CongestionType = "file"
)

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is an SRT connection that implements net.Conn.

Each connection runs exactly 3 goroutines:

  • recvLoop: reads packets from the mux channel, processes control packets, inserts data packets into the receive buffer
  • timerLoop: 10ms ticker drives periodic events (ACK, NAK, keepalive, TSBPD)
  • application goroutine: calls Read/Write on the connection

func Dial

func Dial(addr string, cfg Config) (*Conn, error)

Dial connects to an SRT listener at the given address.

The handshake follows a 4-step process:

  1. Caller sends INDUCTION (v4, no cookie)
  2. Listener responds with INDUCTION response (v5, SYN cookie, SRT magic)
  3. Caller sends CONCLUSION (v5, echoed cookie, extensions)
  4. Listener responds with CONCLUSION response (v5, negotiated parameters)

Each handshake step retransmits periodically until a response is received or the connection timeout expires.

Example
package main

import (
	"log"
	"time"

	srt "github.com/zsiec/srtgo"
)

func main() {
	cfg := srt.DefaultConfig()
	cfg.StreamID = "live/camera1"
	cfg.Latency = 120 * time.Millisecond

	conn, err := srt.Dial("127.0.0.1:4200", cfg)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	_, err = conn.Write([]byte("hello SRT"))
	if err != nil {
		log.Fatal(err)
	}
}

func DialPacketConn added in v0.2.2

func DialPacketConn(conn net.PacketConn, remoteAddr net.Addr, cfg Config) (*Conn, error)

DialPacketConn connects to an SRT listener using an existing PacketConn. This enables custom transports (WebRTC DataChannels, QUIC, etc.) instead of the default UDP socket created by Dial.

The remoteAddr specifies the address of the SRT listener. The caller is responsible for creating and managing the PacketConn lifetime until the SRT connection is established; after that, closing the SRT Conn will close the underlying PacketConn.

func DialRendezvous

func DialRendezvous(localAddr, remoteAddr string, cfg Config) (*Conn, error)

DialRendezvous connects to a peer using rendezvous mode. Both peers call DialRendezvous with the other's address. localAddr is the address to bind to; remoteAddr is the peer's address.

Example
package main

import (
	"log"

	srt "github.com/zsiec/srtgo"
)

func main() {
	cfg := srt.DefaultConfig()
	cfg.StreamID = "p2p/session1"

	conn, err := srt.DialRendezvous(":5000", "192.168.1.100:5000", cfg)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	_, err = conn.Write([]byte("peer-to-peer data"))
	if err != nil {
		log.Fatal(err)
	}
}

func DialRendezvousPacketConn added in v0.2.2

func DialRendezvousPacketConn(conn net.PacketConn, remoteAddr net.Addr, cfg Config) (*Conn, error)

DialRendezvousPacketConn connects to a peer using rendezvous mode over an existing PacketConn. Both peers call this with the other's address. This enables custom transports instead of the default UDP socket.

func (*Conn) ApplyGroupDrift

func (c *Conn) ApplyGroupDrift(tb tsbpd.GroupTimeBase)

ApplyGroupDrift synchronizes this connection's TSBPD drift with a group member's state. Used by Group to keep all members' delivery times aligned.

func (*Conn) ApplyGroupTime

func (c *Conn) ApplyGroupTime(tb tsbpd.GroupTimeBase)

ApplyGroupTime synchronizes this connection's full TSBPD state with the group. Used when a new member joins the group and needs to adopt the group's time reference.

func (*Conn) AvgRcvBufBytes

func (c *Conn) AvgRcvBufBytes() float64

AvgRcvBufBytes returns the IIR-8 smoothed receive buffer occupancy in bytes.

func (*Conn) AvgRcvBufSize

func (c *Conn) AvgRcvBufSize() float64

AvgRcvBufSize returns the IIR-8 smoothed receive buffer occupancy in packets.

func (*Conn) AvgSndBufBytes

func (c *Conn) AvgSndBufBytes() float64

AvgSndBufBytes returns the IIR-8 smoothed send buffer occupancy in bytes.

func (*Conn) AvgSndBufSize

func (c *Conn) AvgSndBufSize() float64

AvgSndBufSize returns the IIR-8 smoothed send buffer occupancy in packets. buffer_tools.h AvgBufSize.

func (*Conn) Close

func (c *Conn) Close() error

func (*Conn) CurrentSRTTimestamp

func (c *Conn) CurrentSRTTimestamp() uint32

CurrentSRTTimestamp returns the current SRT timestamp from this connection's clock. Used by Group to obtain a common source timestamp for all members.

func (*Conn) ExtendedStats

func (c *Conn) ExtendedStats(clear bool) ExtendedConnStats

ExtendedStats returns an ExtendedConnStats containing the base ConnStats plus additional buffer occupancy averages and send rate statistics. When clear is true, interval counters are reset (same as Stats).

func (*Conn) GetOption

func (c *Conn) GetOption(opt SockOpt) (any, error)

GetOption retrieves the current value of a runtime socket option. The returned value type depends on the option (see SockOpt documentation).

func (*Conn) GroupID

func (c *Conn) GroupID() uint32

GroupID returns the local group ID (0 if not part of a group).

func (*Conn) LastMsgNo

func (c *Conn) LastMsgNo() uint32

LastMsgNo returns the most recently assigned message number. Used by Group to record the message number for sender buffer entries.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

func (*Conn) OnStats

func (c *Conn) OnStats(interval time.Duration, fn func(ConnStats))

OnStats registers a callback invoked periodically with connection statistics. The callback receives interval stats (equivalent to Stats(true)). Pass 0 interval to use the default (1 second). Call with nil fn to unregister.

func (*Conn) OverrideSndSeqNo

func (c *Conn) OverrideSndSeqNo(nextSeq seq.Number) bool

OverrideSndSeqNo overrides the send sequence number to match the group's scheduling sequence. This aligns a newly-activated member's send sequence with the group so all members share the same sequence space.

seq is the next sequence number to be sent (the send buffer's nextSeq). Returns true if the override was applied.

func (*Conn) PeerGroupID

func (c *Conn) PeerGroupID() uint32

PeerGroupID returns the peer's group ID (0 if not part of a group).

func (*Conn) RcvBufEmpty

func (c *Conn) RcvBufEmpty() bool

RcvBufEmpty returns true if the receive buffer has no available packets. Used by Group to check if an idle link's recv buffer is empty before resetting its pointer.

func (*Conn) RcvBufStartSeq

func (c *Conn) RcvBufStartSeq() seq.Number

RcvBufStartSeq returns the receive buffer's oldest unread sequence number. Used by Group for idle link synchronization.

func (*Conn) Read

func (c *Conn) Read(b []byte) (int, error)

Read reads data from the connection. It blocks until data is available or the read deadline expires.

In message mode with multi-packet messages, Read returns a complete reassembled message (all packets from PP_FIRST through PP_LAST concatenated). In stream mode, Read returns data from the next available packet.

func (*Conn) ReadMessage

func (c *Conn) ReadMessage(b []byte) (int, error)

ReadMessage reads a single complete message from the connection. In live mode, returns a single packet's data. In file/message mode, reassembles multi-packet messages from PP_FIRST through PP_LAST.

func (*Conn) ReadMsgCtrl

func (c *Conn) ReadMsgCtrl(b []byte, mc *MsgCtrl) (int, error)

ReadMsgCtrl reads data and populates the MsgCtrl with message metadata. mc.Boundary, mc.PktSeq, and mc.MsgNo are filled from the received packet.

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

func (*Conn) ResetRecvState

func (c *Conn) ResetRecvState(newSeq seq.Number)

ResetRecvState resets the receiver to a new initial sequence number, discarding all buffered data and resetting ACK state. Used by Group to synchronize idle link receiver pointers with the active link.

func (*Conn) SchedSeqNo

func (c *Conn) SchedSeqNo() seq.Number

SchedSeqNo returns the next sequence number that would be used for sending. Used by the Group to synchronize sequence numbers across members.

func (*Conn) SendKeepAlive

func (c *Conn) SendKeepAlive()

SendKeepAlive sends an immediate keepalive to the peer. Used by Group to notify the peer when a link is silenced to standby. sendBackup_CheckIdleTime: sends KEEPALIVE after sender buffer drains on a silenced link.

func (*Conn) SendPeerError added in v0.2.2

func (c *Conn) SendPeerError(errorCode uint32)

SendPeerError sends a PEERERROR control packet to the peer, signaling an unrecoverable processing error. This unblocks the peer's send operations. The errorCode is carried in the TypeSpecific header field per the SRT specification (Section 3.2.10). Use PeerErrorFileSystem (4000) for filesystem errors during file transfer.

func (*Conn) SendRate

func (c *Conn) SendRate() (pktPerSec int64, bytesPerSec int64)

SendRate returns the current smoothed send rate as packets/sec and bytes/sec. This is the circular-buffer average over the last 1 second.

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

func (*Conn) SetMaxBW

func (c *Conn) SetMaxBW(bw int64)

SetMaxBW updates the maximum sending bandwidth in bytes/sec at runtime. SRTO_MAXBW is a POST option (can be changed after connection). When bw > 0, it is used directly. When bw == 0, the CC reverts to auto mode (InputBW + overhead, or sampling). When bw == -1, the max bandwidth is unlimited.

func (*Conn) SetOption

func (c *Conn) SetOption(opt SockOpt, val any) error

SetOption changes the value of a runtime socket option on a live connection. Only certain options support runtime changes (see SockOpt documentation).

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

func (*Conn) SocketID

func (c *Conn) SocketID() uint32

SocketID returns this connection's socket ID.

func (*Conn) Stats

func (c *Conn) Stats(clear bool) ConnStats

Stats returns connection statistics. If clear is true, the returned stats represent the interval since the last clear=true call, and internal interval counters are reset. If clear is false, cumulative totals are returned. This matches the srt_bistats(sock, &perf, clear, instantaneous) API.

func (*Conn) StreamID

func (c *Conn) StreamID() string

StreamID returns the stream ID from the handshake.

func (*Conn) TSBPDTimeBase

func (c *Conn) TSBPDTimeBase() *tsbpd.GroupTimeBase

TSBPDTimeBase returns the TSBPD timer's internal state for group synchronization. Returns nil GroupTimeBase fields if TSBPD is not enabled.

func (*Conn) Write

func (c *Conn) Write(b []byte) (int, error)

Write writes data to the connection. It blocks until the send buffer has space or the write deadline expires.

In live mode (TSBPD), the data must fit in a single packet (max payloadSize bytes); multi-packet messages are rejected in TSBPD mode. In file mode, large messages are automatically fragmented into multiple packets with PP_FIRST/PP_MIDDLE/PP_LAST boundaries sharing the same message number.

func (*Conn) WriteMessage

func (c *Conn) WriteMessage(b []byte) (int, error)

WriteMessage sends a single message. In live mode (TSBPD), the message must fit in a single packet. In file/message mode, messages are auto-fragmented. Returns an error if the message exceeds the maximum allowed size.

func (*Conn) WriteMsgCtrl

func (c *Conn) WriteMsgCtrl(b []byte, mc *MsgCtrl) (int, error)

WriteMsgCtrl sends data with per-message control options. mc.SrcTime overrides the packet timestamp (custom source timestamp). mc.MsgTTL sets a per-message time-to-live for sender-side drop.

type ConnConfig

type ConnConfig struct {
	LocalAddr    net.Addr
	RemoteAddr   net.Addr
	SocketID     uint32
	PeerSocketID uint32
	StreamID     string
	IsServer     bool

	Mux      *mux.Mux
	OwnsMux  bool // true for client-side connections (Dial creates its own mux)
	RecvChan <-chan packet.Packet
	Clock    clock.Clock

	SendISN seq.Number
	RecvISN seq.Number

	SendBufSize         int                     // packets
	RecvBufSize         int                     // packets
	MaxBW               int64                   // bytes/sec
	TsbpdDelay          time.Duration           // local TSBPD receive latency
	PeerTsbpdDelay      time.Duration           // peer's TSBPD receive latency (for sender-side drop)
	FC                  int                     // flow control window (packets)
	PayloadSize         int                     // max payload per packet (0 = default 1456)
	CryptoCtx           *crypto.Context         // encryption context (nil = unencrypted)
	ActiveKey           packet.PacketEncryption // which key slot to use for encryption
	Linger              time.Duration           // max wait for send buffer drain on Close
	PeerIdleTimeout     time.Duration           // peer inactivity timeout
	Passphrase          string                  // for key rotation (KMREQ/KMRSP)
	KMRefreshRate       uint64                  // packets before key switch (0 = disabled)
	KMPreAnnounce       uint64                  // packets before refresh to announce new key
	MessageAPI          bool                    // true = message boundaries preserved
	Congestion          CongestionType          // "live" or "file" (empty = "live")
	NAKReport           bool                    // true = enable periodic NAK reports
	PeerNakReport       bool                    // true if peer sends periodic NAK reports
	RetransmitAlgo      int                     // SRTO_RETRANSMITALGO: 0=always immediate, 1=timing gate
	LossMaxTTL          int                     // max reorder tolerance (0 = disabled)
	SndDropDelay        int                     // extra sender drop delay in ms (-1 = disable)
	InputBW             int64                   // estimated input bandwidth (bytes/sec, 0 = unused)
	MinInputBW          int64                   // minimum input bandwidth for auto-rate (bytes/sec)
	OverheadBW          int                     // bandwidth overhead percentage
	DriftTracer         bool                    // true = enable TSBPD drift correction (default true)
	PeerSRTVersion      uint32                  // peer's SRT version from handshake HSRSP
	PeerStartTime       uint32                  // peer's timestamp from handshake (for TSBPD timebase)
	PacketFilter        string                  // negotiated FEC filter config ("" = disabled)
	GroupID             uint32                  // local group ID (0 = not grouped)
	PeerGroupID         uint32                  // peer's group ID (0 = not grouped)
	GroupType           uint8                   // group type (1=broadcast, 2=backup)
	GroupWeight         uint16                  // member weight for group operations
	SndSyn              bool                    // true = blocking Write (default)
	RcvSyn              bool                    // true = blocking Read (default)
	MaxRexmitBW         int64                   // max retransmit bandwidth (bytes/sec, 0 = unlimited)
	MinVersion          uint32                  // minimum peer SRT version
	EnforcedEncryption  bool                    // true = encryption strictly enforced
	GroupConnectEnabled bool                    // true = listener accepts grouped connections
	Logger              Logger                  // diagnostic logger (nil = disabled)
}

ConnConfig contains the parameters for creating a new SRT connection.

type ConnRequest

type ConnRequest struct {
	// StreamID is the stream identifier from the caller's handshake.
	StreamID string
	// RemoteAddr is the caller's address.
	RemoteAddr net.Addr
	// HSVersion is the handshake version (4 or 5).
	HSVersion uint32
	// GroupID is the peer's group ID (0 = not a group connection).
	GroupID uint32
	// GroupType is the group type (1=broadcast, 2=backup).
	GroupType uint8
}

ConnRequest provides information about an incoming connection.

type ConnState

type ConnState int

ConnState represents the state of an SRT connection. Values start at 1.

const (
	StateInit       ConnState = 1 // initial, unbound
	StateOpened     ConnState = 2 // bound but not listening/connecting
	StateListening  ConnState = 3 // listening for connections
	StateConnecting ConnState = 4 // connection in progress
	StateConnected  ConnState = 5 // established
	StateBroken     ConnState = 6 // broken (timeout, error)
	StateClosing    ConnState = 7 // draining
	StateClosed     ConnState = 8 // cleanly closed
	StateNonExist   ConnState = 9 // socket removed
)

func (ConnState) String

func (s ConnState) String() string

String returns a human-readable name for the connection state.

type ConnStats

type ConnStats struct {
	// Timing
	StartTime time.Time     // connection creation time
	Duration  time.Duration // time since connection start

	// Sent packet/byte counters
	SentPackets       uint64 // total DATA packets sent (including retransmissions)
	SentBytes         uint64 // payload bytes sent
	SentUniquePackets uint64 // unique DATA packets sent (SentPackets - Retransmits)
	SentUniqueBytes   uint64 // payload bytes for unique sends
	Retransmits       uint64 // retransmitted packets sent
	RetransBytes      uint64 // payload bytes for retransmitted packets

	// Received packet/byte counters
	RecvPackets       uint64 // total DATA packets received (including retransmissions)
	RecvBytes         uint64 // payload bytes received
	RecvUniquePackets uint64 // unique DATA packets received (RecvPackets - RecvRetrans)
	RecvUniqueBytes   uint64 // payload bytes for unique receives
	RecvRetrans       uint64 // retransmitted packets received
	RecvRetransBytes  uint64 // payload bytes of retransmitted packets received

	// Loss
	LostPackets  uint64  // packets reported as lost at sender side (from NAKs)
	RecvLoss     uint64  // packets detected as missing at receiver side (gap detection)
	SendLossRate float64 // LostPackets / SentPackets * 100
	RecvLossRate float64 // RecvDropped / (RecvPackets + RecvDropped) * 100

	// Total bytes including IP/UDP/SRT header overhead (44 bytes per packet)
	// These match byteSentTotal/byteRecvTotal semantics.
	SentTotalBytes          uint64 // payload + headers for all sent packets
	RecvTotalBytes          uint64 // payload + headers for all received packets
	SentUniqueTotalBytes    uint64 // payload + headers for unique sent packets
	RecvUniqueTotalBytes    uint64 // payload + headers for unique received packets
	RecvLossBytes           uint64 // estimated bytes for lost packets (pkt count * avg payload + headers)
	RetransTotalBytes       uint64 // payload + headers for retransmitted packets
	RecvRetransTotalBytes   uint64 // payload + headers for received retransmissions
	SentDropTotalBytes      uint64 // payload + headers for sender-dropped packets
	RecvDropTotalBytes      uint64 // payload + headers for receiver-dropped packets
	RecvBelatedTotalBytes   uint64 // payload + headers for belated packets
	RecvUndecryptTotalBytes uint64 // payload + headers for undecrypted packets

	// Bitrates (interval mode: computed from interval bytes/duration)
	MbpsSendRate float64 // send bitrate in Mbps
	MbpsRecvRate float64 // receive bitrate in Mbps

	// RTT
	RTT       time.Duration
	RTTVar    time.Duration
	RTTFactor float64 // RTT / NegotiatedLatency

	// Flight and buffer state
	FlowWindow       int // flow window size in packets
	FlightSize       int // packets in flight (sent but not ACK'd)
	SendBufSize      int // packets in send buffer
	SendBufAvailable int // free slots in send buffer
	SendBufBytes     int // estimated payload bytes in send buffer
	RecvBufSize      int // packets in receive buffer
	RecvBufAvailable int // free slots in receive buffer
	RecvBufBytes     int // estimated payload bytes in receive buffer

	// Instantaneous measurements
	NegotiatedLatency  time.Duration // negotiated TSBPD delay
	PacketReceiveRate  uint32        // packets/sec
	EstimatedBandwidth uint32        // probe link capacity (packets/sec)
	UsPktSndPeriod     float64       // inter-packet send period in μs
	MbpsMaxBW          float64       // configured max bandwidth in Mbps
	MsSndBuf           time.Duration // age of oldest unacked packet in send buffer
	MsRcvBuf           time.Duration // timespan of data in receive buffer

	// Control packet counters
	SentACKs    uint64
	SentNAKs    uint64
	SentACKACKs uint64
	RecvACKs    uint64
	RecvNAKs    uint64
	RecvACKACKs uint64

	// Receiver-side counters
	RecvDropped        uint64 // packets dropped due to too-late arrival
	RecvDroppedBytes   uint64 // payload bytes of receiver-dropped packets
	RecvBelated        uint64 // packets arrived after already dropped/ACK'd
	RecvBelatedBytes   uint64 // payload bytes of belated packets
	RecvUndecrypt      uint64 // packets that failed decryption
	RecvUndecryptBytes uint64 // payload bytes of undecrypted packets

	// Sender-side counters
	SentDropped      uint64 // packets dropped from send buffer (too late)
	SentDroppedBytes uint64 // payload bytes of sender-dropped packets

	// Key management counters
	SentKM uint64 // KMREQ packets sent
	RecvKM uint64 // KMREQ/KMRSP packets received

	// Key management state (matches m_SndKmState / m_RcvKmState)
	// 0=unsecured, 1=securing, 2=secured, 3=nosecret, 4=badsecret, 5=badcryptomode
	SndKmState int
	RcvKmState int

	// Sender duration and congestion
	UsSndDuration    int64 // accumulated microseconds sender had data to transmit
	CongestionWindow int   // congestion window in packets (= FC for live mode)

	// Reorder tracking
	ReorderTolerance int32 // configured reorder tolerance (packets)
	ReorderDistance  int32 // maximum observed reorder distance (packets)

	// Belated arrival timing
	RcvAvgBelatedTime time.Duration // average lateness of belated packets

	// FEC statistics
	SndFilterExtra  uint64 // FEC control packets sent
	RcvFilterExtra  uint64 // FEC control packets received
	RcvFilterSupply uint64 // packets recovered by FEC
	RcvFilterLoss   uint64 // irrecoverable losses reported to ARQ

	// Negotiated parameters
	NegotiatedMSS   int           // negotiated maximum segment size
	NegotiatedFC    int           // negotiated flow control window
	MsSndTsbPdDelay time.Duration // peer's TSBPD delay (sender side)
	MsRcvTsbPdDelay time.Duration // local TSBPD delay (receiver side)
}

ConnStats contains connection statistics Byte fields suffixed with "Total" include IP/UDP/SRT header overhead (44 bytes/pkt). Payload-only byte fields omit headers.

type ConnType

type ConnType int

ConnType classifies how a connection should be handled.

const (
	// Reject refuses the connection.
	Reject ConnType = iota
	// Publish indicates the caller will send data (write-only).
	Publish
	// Subscribe indicates the caller will receive data (read-only).
	Subscribe
)

type ConnectFunc

type ConnectFunc func(req ConnRequest) ConnType

ConnectFunc is called for each incoming connection during the handshake. It receives a ConnRequest with the stream ID and peer address, and returns a ConnType to route the connection to the appropriate handler. Return Reject to refuse the connection.

type Event

type Event struct {
	// Conn is the connection that generated the event.
	Conn *Conn
	// Type indicates what kind of readiness triggered the event.
	Type EventType
	// Err is non-nil for EventError, describing why the connection failed.
	Err error
}

Event represents a readiness notification from a watched connection.

type EventType

type EventType int

EventType identifies the kind of readiness event.

const (
	// EventRead indicates data is available for reading.
	EventRead EventType = iota
	// EventWrite indicates send buffer space is available.
	EventWrite
	// EventError indicates the connection has encountered an error or closed.
	EventError
)

func (EventType) String

func (e EventType) String() string

String returns a human-readable name for the event type.

type ExtendedConnStats

type ExtendedConnStats struct {
	ConnStats

	// IIR-8 smoothed buffer occupancy
	AvgSndBufPkts  float64 // average send buffer occupancy in packets
	AvgSndBufBytes float64 // average send buffer occupancy in bytes
	AvgRcvBufPkts  float64 // average receive buffer occupancy in packets
	AvgRcvBufBytes float64 // average receive buffer occupancy in bytes

	// Send rate from circular buffer estimator
	SendRatePps int64 // smoothed send rate in packets/sec
	SendRateBps int64 // smoothed send rate in bytes/sec
}

ExtendedConnStats extends ConnStats with buffer IIR averages and send rate. These fields match C++ buffer_tools.h AvgBufSize and CSndRateEstimator.

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group manages multiple SRT connections for link redundancy. It provides a unified Read/Write interface that dispatches across member connections based on the group mode.

Usage:

g := srt.NewGroup(srt.GroupBackup)
g.Connect("server1:4200", cfg, 1, 100)
g.Connect("server2:4200", cfg, 2, 50)
defer g.Close()

g.Write(payload) // sends on active link
g.Read(buf)      // receives deduplicated data

func NewGroup

func NewGroup(mode GroupMode) *Group

NewGroup creates a new socket group with the specified mode.

func (*Group) AddConn

func (g *Group) AddConn(conn *Conn, token int, weight uint16) error

AddConn registers an already-connected *Conn as a member of the group and starts a receive goroutine that fans packets into the group's shared receive channel. token is a caller-chosen integer identifier that is stored with the member and returned in MemberInfo; it can be any value meaningful to the caller (e.g., a link index or path ID) and is not interpreted by the group. weight sets the member's priority for backup mode activation: when a standby link must be promoted, the highest-weight eligible member is chosen first.

On addition the new member's TSBPD time base is synchronized with the existing group members, and in GroupBackup or GroupBroadcast modes the sender sequence number is aligned so that all members share a single sequence space. If the group has no prior sequence, this member's ISN is adopted as the group's scheduling sequence.

Returns an error if the group is already closed or conn is nil. This method is safe for concurrent use.

func (*Group) AddPendingConn

func (g *Group) AddPendingConn(conn *Conn, token int, weight uint16) error

AddPendingConn registers a connection whose handshake is still in progress as a pending member of the group. Unlike Group.AddConn, which expects an already-connected *Conn, this method records the member in MemberPending status and lets the group's background monitor loop drive its lifecycle: once the handshake completes, the monitor promotes the member to MemberIdle and starts its receive goroutine; if the handshake does not complete within pendingTimeout (5 s), the member is marked MemberBroken and its connection is closed. token is a caller-chosen identifier for locating this member later, and weight sets its backup-mode activation priority (higher is preferred). Returns an error if the group is already closed or conn is nil. This method is safe for concurrent use.

func (*Group) Close

func (g *Group) Close() error

Close closes all member connections and stops the group.

func (*Group) Connect

func (g *Group) Connect(addr string, cfg Config, token int, weight uint16) error

Connect dials a new SRT connection to addr using Dial with the given Config, and on success adds the resulting *Conn to the group via Group.AddConn. This is a convenience method that combines dialing and group membership in a single call. If the dial fails, the error is returned and no member is added. token is a caller-chosen identifier that can be used to locate this member in Group.Members output. weight sets the member's priority for backup mode activation (higher values are preferred when promoting a standby link). This method is safe for concurrent use.

func (*Group) GroupID

func (g *Group) GroupID() uint32

GroupID returns the group's unique identifier.

func (*Group) Members

func (g *Group) Members() []MemberInfo

Members returns a snapshot of every member connection's current state as a slice of MemberInfo values. Each entry includes the caller-assigned token, the member's lifecycle status, its backup state (meaningful only in GroupBackup mode), its weight, local and remote addresses, and the most recent RTT measurement. The returned slice is a copy; callers may read or store it without synchronization. This method is safe for concurrent use.

func (*Group) Mode

func (g *Group) Mode() GroupMode

Mode returns the group's redundancy mode.

func (*Group) RTT

func (g *Group) RTT() time.Duration

RTT returns the minimum RTT across all running members.

func (*Group) Read

func (g *Group) Read(b []byte) (int, error)

Read receives data from the group, deduplicating across members. Packets already delivered via another link are silently dropped.

func (*Group) SetStabilityTimeout

func (g *Group) SetStabilityTimeout(d time.Duration)

SetStabilityTimeout configures the minimum duration of silence (no data or ACK received) before a backup-mode member is considered unstable. The effective stability threshold is max(d, 2*SRTT + 4*RTTVar) per member, so the value set here acts as a floor. When a member exceeds this threshold without a response, the group's monitor loop transitions it from BackupActiveStable to BackupActiveUnstable, which may trigger failover to a higher-weight standby link. The default is 1 second. This setting has no effect in GroupBroadcast mode. This method is not safe for concurrent use with Write; callers should set it before starting I/O.

func (*Group) Stats

func (g *Group) Stats() GroupStats

Stats returns aggregate statistics for the group as a GroupStats value. The returned struct includes the total member count, the number of members in Running state, cumulative packets sent and received across all members, and the number of duplicate packets discarded during receive deduplication. Packet counters are read atomically and the member counts are read under a read lock, so Stats is safe to call concurrently from any goroutine.

func (*Group) SynchronizeDrift

func (g *Group) SynchronizeDrift(src *Conn)

SynchronizeDrift propagates one member's TSBPD drift to all other members. Called when a member's drift is updated.

func (*Group) Write

func (g *Group) Write(b []byte) (int, error)

Write sends data across group members per the mode.

Broadcast: sends on all Running members; at least one must succeed. Backup: sends on the active link only; buffers for failover.

Returns the number of bytes written and an error if no member could send.

type GroupMemberData

type GroupMemberData struct {
	// State is the backup state of this member (e.g., ActiveStable, Standby).
	State BackupState
	// Weight is the member's priority weight (higher = preferred for backup).
	Weight uint16
	// RTT is the member's current smoothed round-trip time.
	RTT time.Duration
}

GroupMemberData reports the status of one member in a bonded connection group. SRT_MEMBER_STATUS equivalent.

type GroupMode

type GroupMode int

GroupMode specifies the redundancy strategy for a socket group.

const (
	// GroupBroadcast sends every packet on ALL member connections.
	// The receiver deduplicates by sequence number, delivering each
	// packet exactly once from whichever link arrives first.
	GroupBroadcast GroupMode = iota + 1

	// GroupBackup uses a single active link for sending, with one
	// or more standby links ready for automatic failover. When the
	// active link becomes unstable or broken, the highest-weight
	// standby is promoted and recent packets are replayed from
	// a sender buffer for seamless continuity.
	GroupBackup

	// GroupBalancing distributes packets across member connections
	// for load balancing. Not yet implemented — defined here for
	// wire protocol compatibility.
	GroupBalancing
)

func (GroupMode) String

func (m GroupMode) String() string

String returns a human-readable name for the group mode.

type GroupStats

type GroupStats struct {
	Members       int    // total member connections
	ActiveMembers int    // members in Running state
	SentPackets   uint64 // total packets sent across all members
	RecvPackets   uint64 // total packets received (before dedup)
	RecvDedups    uint64 // packets dropped as duplicates
}

GroupStats contains aggregate statistics for the group.

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

Listener accepts incoming SRT connections.

Incoming handshakes are processed through a two-phase state machine:

  • INDUCTION: Caller sends initial packet, listener responds with SYN cookie
  • CONCLUSION: Caller echoes cookie with extensions, listener validates and accepts

A context controls the listener lifecycle. Canceling the context closes the listener and all pending handshakes.

func Listen

func Listen(addr string, cfg Config) (*Listener, error)

Listen creates an SRT listener on the given address.

Example
package main

import (
	"log"
	"strings"
	"time"

	srt "github.com/zsiec/srtgo"
)

func main() {
	cfg := srt.DefaultConfig()
	cfg.Latency = 120 * time.Millisecond

	ln, err := srt.Listen(":4200", cfg)
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	ln.SetAcceptFunc(func(req srt.ConnRequest) bool {
		return strings.HasPrefix(req.StreamID, "live/")
	})

	conn, err := ln.Accept()
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	buf := make([]byte, 1456)
	n, err := conn.Read(buf)
	if err != nil {
		log.Fatal(err)
	}
	_ = n
}

func ListenPacketConn added in v0.2.2

func ListenPacketConn(conn net.PacketConn, cfg Config) (*Listener, error)

ListenPacketConn creates an SRT listener on an existing PacketConn. This enables custom transports (WebRTC DataChannels, QUIC, etc.) instead of the default UDP socket created by Listen.

The caller is responsible for creating and managing the PacketConn; closing the Listener will close the underlying PacketConn.

func (*Listener) Accept

func (l *Listener) Accept() (*Conn, error)

Accept waits for and returns the next incoming connection. It blocks until a connection is available or the listener is closed.

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

Addr returns the listener's network address.

func (*Listener) Close

func (l *Listener) Close() error

Close stops the listener and releases resources.

func (*Listener) SetAcceptFunc deprecated

func (l *Listener) SetAcceptFunc(fn AcceptFunc)

SetAcceptFunc sets a callback that is invoked for each incoming connection. If the callback returns false, the connection is rejected with RejPeer. Must be called before any connections arrive.

Deprecated: Use SetAcceptRejectFunc for finer-grained rejection codes.

func (*Listener) SetAcceptRejectFunc

func (l *Listener) SetAcceptRejectFunc(fn AcceptRejectFunc)

SetAcceptRejectFunc sets a callback for incoming connections that can return a specific rejection code. Return 0 to accept, or a rejection code (e.g., RejPeer, or user-defined codes >= RejUserDefined) to reject. Takes precedence over SetAcceptFunc if both are set.

type LogCategory

type LogCategory string

LogCategory identifies the subsystem that generated a log message. Categories match SRT_LOGFA_* facility areas.

const (
	LogGeneral    LogCategory = "general"
	LogConn       LogCategory = "conn"
	LogHandshake  LogCategory = "handshake"
	LogTSBPD      LogCategory = "tsbpd"
	LogCongestion LogCategory = "congestion"
	LogMux        LogCategory = "mux"
	LogCrypto     LogCategory = "crypto"
	LogGroup      LogCategory = "group"
	LogFilter     LogCategory = "filter"
)

type LogLevel

type LogLevel int

LogLevel represents the severity of a log message.

const (
	// LogDebug is for detailed diagnostic information.
	LogDebug LogLevel = iota
	// LogNote is for notable but normal events.
	LogNote
	// LogWarning is for unexpected but recoverable conditions.
	LogWarning
	// LogError is for error conditions that affect operation.
	LogError
)

func (LogLevel) String

func (l LogLevel) String() string

String returns a human-readable name for the log level.

type Logger

type Logger interface {
	// Log emits a log message. socketID is 0 for non-connection-scoped messages.
	// Implementations should not block or perform expensive operations.
	Log(level LogLevel, category LogCategory, socketID uint32, msg string)
}

Logger is the interface for SRT diagnostic log output. Implementations must be safe for concurrent use from multiple goroutines.

When Config.Logger is nil (the default), no logging occurs and there is zero performance overhead — the logf() helper returns immediately without formatting the message.

func SlogLogger added in v0.2.0

func SlogLogger(l *slog.Logger) Logger

SlogLogger returns a Logger that emits messages through a slog.Logger. Log levels are mapped as: LogDebug→Debug, LogNote→Info, LogWarning→Warn, LogError→Error. The category and socket ID are included as structured attributes.

Example:

cfg := srt.DefaultConfig()
cfg.Logger = srt.SlogLogger(slog.Default())

func StdLogger

func StdLogger(w io.Writer) Logger

StdLogger returns a Logger that writes timestamped messages to w. Output format: "2006-01-02T15:04:05.000Z07:00 [LEVEL] category [socketID] message\n"

Example:

cfg := srt.DefaultConfig()
cfg.Logger = srt.StdLogger(os.Stderr)

type MemberInfo

type MemberInfo struct {
	Token       int
	Status      MemberStatus
	BackupState BackupState // only meaningful in Backup mode
	Weight      uint16
	LocalAddr   net.Addr
	RemoteAddr  net.Addr
	RTT         time.Duration
}

MemberInfo describes a member connection's state. Returned by Group.Members() for external inspection.

type MemberStatus

type MemberStatus int

MemberStatus tracks a member connection's lifecycle within a group.

const (
	MemberPending MemberStatus = iota // Handshake in progress
	MemberIdle                        // Connected, not yet activated
	MemberRunning                     // Actively sending/receiving
	MemberBroken                      // Failed, disconnected, or closed
)

func (MemberStatus) String

func (s MemberStatus) String() string

String returns a human-readable name for the member status.

type MsgCtrl

type MsgCtrl struct {
	// SrcTime is a custom source timestamp for the message (send only).
	// When zero, the current time is used (default behavior).
	SrcTime time.Time

	// MsgTTL is a per-message time-to-live (send only). Packets older than
	// this are dropped from the send buffer before retransmission.
	// Zero means no per-message TTL (use the global TSBPD drop threshold).
	MsgTTL time.Duration

	// InOrder specifies whether this message must be delivered in order (send only).
	// When true, the receiver will only deliver this message after all
	// earlier messages have been delivered. When false, the receiver may
	// deliver this message out of order if it arrives before earlier ones.
	// Default true for live, false allowed for file.
	InOrder bool

	// Boundary indicates the packet position within a message (read only).
	// One of: packet.PositionSingle, PositionFirst, PositionMiddle, PositionLast.
	Boundary int

	// PktSeq is the first packet sequence number of the message (read only).
	PktSeq uint32

	// MsgNo is the message number (read only).
	MsgNo uint32

	// GroupData provides per-member status when reading from a bonded group.
	// Each entry corresponds to one group member connection and reports its
	// current state and RTT. Nil for non-group connections.
	GroupData []GroupMemberData
}

MsgCtrl provides per-message metadata for advanced send/receive operations. It allows setting a custom source timestamp and per-message TTL on send, and reading message boundary and sequence information on receive. SRT_MSGCTRL equivalent for per-message metadata.

type RejectReason

type RejectReason = packet.HandshakeType

RejectReason is a type alias for rejection codes used in AcceptRejectFunc.

type Server

type Server struct {
	// Addr is the address to listen on (e.g., ":6000").
	Addr string

	// Config is the SRT configuration. If nil, DefaultConfig() is used.
	Config *Config

	// HandleConnect is called during the handshake to classify and
	// authorize the connection. If nil, all connections are rejected.
	// This is called once per connection, during the handshake phase.
	HandleConnect ConnectFunc

	// HandlePublish is called for connections classified as Publish.
	// It blocks for the lifetime of the connection. The connection is
	// closed when the handler returns.
	HandlePublish func(conn *Conn)

	// HandleSubscribe is called for connections classified as Subscribe.
	// It blocks for the lifetime of the connection. The connection is
	// closed when the handler returns.
	HandleSubscribe func(conn *Conn)
	// contains filtered or unexported fields
}

Server is a high-level SRT server framework.

It wraps a Listener and provides callback-based routing:

  • HandleConnect classifies connections as Publish or Subscribe
  • HandlePublish is called for publishing (write) connections
  • HandleSubscribe is called for subscribing (read) connections

Each accepted connection is handled in its own goroutine. The handler callbacks block for the lifetime of the connection.

Example
package main

import (
	"log"
	"strings"
	"time"

	srt "github.com/zsiec/srtgo"
)

func main() {
	cfg := srt.DefaultConfig()

	srv := &srt.Server{
		Addr:   ":4200",
		Config: &cfg,
		HandleConnect: func(req srt.ConnRequest) srt.ConnType {
			if strings.HasPrefix(req.StreamID, "#!::r=") {
				return srt.Subscribe
			}
			if strings.HasPrefix(req.StreamID, "#!::m=publish") {
				return srt.Publish
			}
			return srt.Reject
		},
		HandlePublish: func(conn *srt.Conn) {
			buf := make([]byte, 1456)
			for {
				_, err := conn.Read(buf)
				if err != nil {
					return
				}
			}
		},
		HandleSubscribe: func(conn *srt.Conn) {
			data := []byte("test payload")
			for {
				_, err := conn.Write(data)
				if err != nil {
					return
				}
				time.Sleep(10 * time.Millisecond)
			}
		},
	}

	if err := srv.ListenAndServe(); err != nil && err != srt.ErrServerClosed {
		log.Fatal(err)
	}
}

func (*Server) Listen

func (s *Server) Listen() error

Listen opens the listener socket. Call Serve to start accepting connections.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe listens on the configured address and serves connections. It blocks until Shutdown is called or an unrecoverable error occurs.

func (*Server) Serve

func (s *Server) Serve() error

Serve accepts connections on the listener and dispatches them to handlers. It blocks until Shutdown is called. Returns ErrServerClosed on clean shutdown.

func (*Server) Shutdown

func (s *Server) Shutdown()

Shutdown gracefully stops the server. It stops accepting new connections, closes all active connections, and waits for handler goroutines to finish.

type SockOpt

type SockOpt int

SockOpt identifies a runtime socket option.

const (
	// SockOptMaxBW is the maximum sending bandwidth in bytes/sec.
	// Get returns int64. Set accepts int64. 0 = auto (DefaultMaxBW).
	SockOptMaxBW SockOpt = iota

	// SockOptPayloadSize is the negotiated maximum payload per packet.
	// Get only; returns int.
	SockOptPayloadSize

	// SockOptRcvLatency is the negotiated receive TSBPD latency.
	// Get only; returns time.Duration.
	SockOptRcvLatency

	// SockOptSndLatency is the peer's TSBPD latency used for sender-side drop.
	// Get only; returns time.Duration.
	SockOptSndLatency

	// SockOptState is the connection state. Get only; returns ConnState.
	SockOptState

	// SockOptPeerVersion is the peer's SRT version from the handshake.
	// Get only; returns uint32 (e.g., 0x010500 = v1.5.0).
	SockOptPeerVersion

	// SockOptStreamID is the stream identifier negotiated during handshake.
	// Get only; returns string.
	SockOptStreamID

	// SockOptMSS is the negotiated Maximum Segment Size.
	// Get only; returns int.
	SockOptMSS

	// SockOptFC is the negotiated flow control window in packets.
	// Get only; returns int.
	SockOptFC

	// SockOptInputBW is the estimated input bandwidth in bytes/sec.
	// Get/Set; accepts int64. When MaxBW=0, InputBW * (1 + overhead) is used.
	SockOptInputBW

	// SockOptISN is the local initial sequence number. Get only; returns uint32.
	SockOptISN

	// SockOptPeerISN is the peer's initial sequence number. Get only; returns uint32.
	SockOptPeerISN

	// SockOptSndKmState is the send-side key material state.
	// Get only; returns int32 (0=unsecured, 1=securing, 2=secured, 3=nosecret, 4=badsecret, 5=badcryptomode).
	SockOptSndKmState

	// SockOptRcvKmState is the recv-side key material state.
	// Get only; returns int32.
	SockOptRcvKmState

	// SockOptKmState is the combined key material state.
	// For senders returns SndKmState, for receivers returns RcvKmState.
	// Get only; returns int32.
	SockOptKmState

	// SockOptSndData is the number of unacknowledged packets in the send buffer.
	// Get only; returns int.
	SockOptSndData

	// SockOptRcvData is the number of available packets in the receive buffer.
	// Get only; returns int.
	SockOptRcvData

	// SockOptSndBuf is the send buffer capacity in packets.
	// Get only; returns int.
	SockOptSndBuf

	// SockOptRcvBuf is the receive buffer capacity in packets.
	// Get only; returns int.
	SockOptRcvBuf

	// SockOptFlightSize is the number of in-flight (unacknowledged) packets.
	// Get only; returns int.
	SockOptFlightSize

	// SockOptRTT is the smoothed round-trip time in microseconds.
	// Get only; returns int64.
	SockOptRTT

	// SockOptRTTVar is the RTT variance in microseconds.
	// Get only; returns int64.
	SockOptRTTVar

	// SockOptVersion is the local SRT version. Get only; returns uint32.
	SockOptVersion

	// SockOptCongestion is the congestion control type ("live" or "file").
	// Get only; returns string.
	SockOptCongestion

	// SockOptTransType is the transfer type. Get only; returns TransType.
	SockOptTransType

	// SockOptMessageAPI indicates whether message API mode is enabled.
	// Get only; returns bool.
	SockOptMessageAPI

	// SockOptTSBPDMode indicates whether TSBPD is enabled.
	// Get only; returns bool.
	SockOptTSBPDMode

	// SockOptTLPktDrop indicates whether too-late packet drop is enabled.
	// Get only; returns bool.
	SockOptTLPktDrop

	// SockOptNAKReport indicates whether periodic NAK reports are enabled.
	// Get only; returns bool.
	SockOptNAKReport

	// SockOptRetransmitAlgo is the retransmission algorithm (0=immediate, 1=timing gate).
	// Get only; returns int.
	SockOptRetransmitAlgo

	// SockOptPBKeyLen is the encryption key length in bytes (0, 16, 24, or 32).
	// Get only; returns int.
	SockOptPBKeyLen

	// SockOptCryptoMode is the encryption cipher mode (0=auto, 1=CTR, 2=GCM).
	// Get only; returns int.
	SockOptCryptoMode

	// SockOptPeerIdleTimeout is the peer inactivity timeout.
	// Get only; returns time.Duration.
	SockOptPeerIdleTimeout

	// SockOptLinger is the maximum time Close waits for send buffer drain.
	// Get/Set; accepts time.Duration.
	SockOptLinger

	// SockOptEvent returns poll-like event flags (SRT_EPOLL_IN/OUT/ERR).
	// Get only; returns int.
	SockOptEvent

	// SockOptDriftTracer indicates whether TSBPD drift correction is enabled.
	// Get only; returns bool.
	SockOptDriftTracer

	// SockOptPacketFilter is the negotiated FEC filter configuration string.
	// Get only; returns string.
	SockOptPacketFilter

	// SockOptMinVersion is the minimum SRT version required of the peer.
	// Get only (pre-connect option); returns uint32.
	SockOptMinVersion

	// SockOptEnforcedEncryption indicates whether encryption is enforced.
	// Get only (pre-connect option); returns bool.
	SockOptEnforcedEncryption

	// SockOptGroupConnect indicates whether the listener accepts grouped connections.
	// Get only (pre-connect option); returns bool.
	SockOptGroupConnect

	// SockOptMaxRexmitBW is the maximum retransmission bandwidth in bytes/sec.
	// Get only; returns int64.
	SockOptMaxRexmitBW

	// SockOptOverheadBW is the bandwidth overhead percentage for retransmissions.
	// Get/Set; accepts int (range 5-100).
	SockOptOverheadBW

	// SockOptMinInputBW is the minimum input bandwidth floor in bytes/sec.
	// Get/Set; accepts int64.
	SockOptMinInputBW

	// SockOptSndDropDelay is the extra sender drop delay in milliseconds.
	// Get/Set; accepts int. -1 disables sender drop.
	SockOptSndDropDelay

	// SockOptLossMaxTTL is the maximum reorder tolerance in packets.
	// Get/Set; accepts int.
	SockOptLossMaxTTL

	// SockOptSndSyn controls blocking mode for Write.
	// Get/Set; accepts bool. true = blocking (default).
	SockOptSndSyn

	// SockOptRcvSyn controls blocking mode for Read.
	// Get/Set; accepts bool. true = blocking (default).
	SockOptRcvSyn

	// SockOptSndTimeo is the send timeout for non-blocking mode.
	// Get/Set; accepts time.Duration.
	SockOptSndTimeo

	// SockOptRcvTimeo is the receive timeout for non-blocking mode.
	// Get/Set; accepts time.Duration.
	SockOptRcvTimeo
)

type StreamIDInfo

type StreamIDInfo struct {
	UserName     string            // "u" — user/application name
	ResourceName string            // "r" — resource path (e.g. "live/stream")
	HostName     string            // "h" — host name
	SessionID    string            // "s" — session identifier
	Type         StreamType        // "t" — session type
	Mode         StreamMode        // "m" — data direction
	Extra        map[string]string // any non-standard keys
}

StreamIDInfo holds the parsed fields of a structured SRT stream ID. See C++ SRT access control guidelines for the field definitions.

func ParseStreamID

func ParseStreamID(raw string) (StreamIDInfo, bool)

ParseStreamID parses a raw SRT stream ID string into structured fields.

Two formats are supported:

  • Bare path: the entire string becomes ResourceName (e.g. "live/stream").
  • Structured: starts with "#!::" followed by comma-separated key=value pairs (e.g. "#!::u=admin,r=live/stream,m=publish").

Returns the parsed info and true on success. Returns false only if the "#!::" prefix is present but zero valid pairs are found.

type StreamMode

type StreamMode string

StreamMode identifies the data direction for an SRT stream.

const (
	StreamModeRequest       StreamMode = "request"       // pull data from server
	StreamModePublish       StreamMode = "publish"       // push data to server
	StreamModeBidirectional StreamMode = "bidirectional" // both directions
)

type StreamType

type StreamType string

StreamType identifies the type of SRT stream session.

const (
	StreamTypeStream StreamType = "stream" // live media streaming
	StreamTypeFile   StreamType = "file"   // file transfer
	StreamTypeAuth   StreamType = "auth"   // authentication only
)

type TransType

type TransType int

TransType selects a bundle of settings optimized for a transfer pattern.

const (
	// TransTypeLive is the default: TSBPD=on, TLPKTDROP=on, LiveCC, MessageAPI=true.
	TransTypeLive TransType = iota

	// TransTypeFile disables TSBPD and TLPKTDROP, uses FileCC, MessageAPI=false.
	TransTypeFile
)

func (TransType) String added in v0.2.0

func (t TransType) String() string

String returns a human-readable name for the transfer type.

type WatchOpts

type WatchOpts struct {
	// EdgeTriggered enables edge-triggered mode (like epoll EPOLLET).
	// When true, events fire only on state transitions (e.g., not-readable -> readable),
	// not while the condition persists. After an ET event is delivered, it will not
	// fire again until the condition clears and re-triggers.
	// Default: false (level-triggered, matching standard epoll behavior).
	EdgeTriggered bool
}

WatchOpts configures per-connection options when adding to a Watcher.

type Watcher

type Watcher struct {
	// contains filtered or unexported fields
}

Watcher monitors multiple SRT connections for readiness events. It provides an epoll-like interface for event-driven I/O multiplexing.

Usage:

w := srt.NewWatcher()
defer w.Close()
w.Add(conn1)
w.Add(conn2)
for {
    event, err := w.Wait()
    if err != nil { break }
    switch event.Type {
    case srt.EventRead:
        event.Conn.Read(buf)
    case srt.EventError:
        event.Conn.Close()
    }
}

func NewWatcher

func NewWatcher() *Watcher

NewWatcher creates a Watcher ready to monitor connections.

func (*Watcher) Add

func (w *Watcher) Add(conn *Conn) error

Add registers a connection with the Watcher using default options (level-triggered mode). Events for this connection will be delivered via Wait(). A connection may only be added to one Watcher.

func (*Watcher) AddWithOpts

func (w *Watcher) AddWithOpts(conn *Conn, opts WatchOpts) error

AddWithOpts registers a connection with the Watcher using the specified options. When opts.EdgeTriggered is true, events fire only on state transitions (not-ready -> ready), matching epoll EPOLLET semantics.

func (*Watcher) ClearEvent

func (w *Watcher) ClearEvent(conn *Conn, eventType EventType)

ClearEvent resets the edge-triggered state for the specified event type on the given connection. After calling ClearEvent, the next occurrence of the event will fire again in edge-triggered mode. This is a no-op for level-triggered connections.

Typical usage: after processing a read event in ET mode, call ClearEvent(conn, EventRead) to re-arm the trigger.

func (*Watcher) Close

func (w *Watcher) Close() error

Close shuts down the Watcher and releases all resources. Any pending Wait() calls will return an error.

func (*Watcher) Remove

func (w *Watcher) Remove(conn *Conn) error

Remove unregisters a connection. No further events will be delivered for it.

func (*Watcher) Wait

func (w *Watcher) Wait() (Event, error)

Wait blocks until an event is available and returns it. Returns an error if the Watcher has been closed.

Directories

Path Synopsis
cmd
srt-bench command
Command srt-bench measures SRT throughput, latency, and resource usage.
Command srt-bench measures SRT throughput, latency, and resource usage.
examples
filetransfer command
Command filetransfer demonstrates SRT file transfer mode.
Command filetransfer demonstrates SRT file transfer mode.
interop command
Command interop is an SRT media relay for interoperability testing with FFmpeg, VLC, ffplay, and other SRT implementations.
Command interop is an SRT media relay for interoperability testing with FFmpeg, VLC, ffplay, and other SRT implementations.
loopback command
Command loopback is a zero-config demo that proves srtgo works.
Command loopback is a zero-config demo that proves srtgo works.
receiver command
Command receiver listens for an SRT connection and writes received data to stdout.
Command receiver listens for an SRT connection and writes received data to stdout.
sender command
Command sender connects to an SRT receiver and sends data from stdin or a generated test pattern.
Command sender connects to an SRT receiver and sends data from stdin or a generated test pattern.
server command
Command server demonstrates the srt.Server framework with callback-based connection routing.
Command server demonstrates the srt.Server framework with callback-based connection routing.
streaming command
Command streaming is a self-contained demo that simulates live streaming with a real-time stats dashboard.
Command streaming is a self-contained demo that simulates live streaming with a real-time stats dashboard.
internal
buffer
Package buffer provides ring-buffer-based send and receive buffers for SRT.
Package buffer provides ring-buffer-based send and receive buffers for SRT.
clock
Package clock provides type-safe time abstractions for SRT.
Package clock provides type-safe time abstractions for SRT.
congestion
Package congestion provides congestion control for SRT.
Package congestion provides congestion control for SRT.
crypto
Package crypto implements SRT encryption and decryption.
Package crypto implements SRT encryption and decryption.
filter
Package filter implements the SRT packet filter framework for Forward Error Correction (FEC).
Package filter implements the SRT packet filter framework for Forward Error Correction (FEC).
handshake
Package handshake implements the SRT connection handshake state machine.
Package handshake implements the SRT connection handshake state machine.
mux
Package mux provides a UDP multiplexer that allows multiple SRT connections to share a single UDP socket.
Package mux provides a UDP multiplexer that allows multiple SRT connections to share a single UDP socket.
packet
Package packet implements SRT packet parsing, serialization, and pooling.
Package packet implements SRT packet parsing, serialization, and pooling.
seq
Package seq implements 31-bit wrapping sequence number arithmetic for SRT.
Package seq implements 31-bit wrapping sequence number arithmetic for SRT.
tsbpd
Package tsbpd implements Timestamp-Based Packet Delivery for SRT.
Package tsbpd implements Timestamp-Based Packet Delivery for SRT.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL