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 ¶
- Constants
- Variables
- type AcceptFunc
- type AcceptRejectFunc
- type BackupState
- type BindingTime
- type Config
- type CongestionType
- type Conn
- func Dial(addr string, cfg Config) (*Conn, error)
- func DialPacketConn(conn net.PacketConn, remoteAddr net.Addr, cfg Config) (*Conn, error)
- func DialRendezvous(localAddr, remoteAddr string, cfg Config) (*Conn, error)
- func DialRendezvousPacketConn(conn net.PacketConn, remoteAddr net.Addr, cfg Config) (*Conn, error)
- func (c *Conn) ApplyGroupDrift(tb tsbpd.GroupTimeBase)
- func (c *Conn) ApplyGroupTime(tb tsbpd.GroupTimeBase)
- func (c *Conn) AvgRcvBufBytes() float64
- func (c *Conn) AvgRcvBufSize() float64
- func (c *Conn) AvgSndBufBytes() float64
- func (c *Conn) AvgSndBufSize() float64
- func (c *Conn) Close() error
- func (c *Conn) CurrentSRTTimestamp() uint32
- func (c *Conn) ExtendedStats(clear bool) ExtendedConnStats
- func (c *Conn) GetOption(opt SockOpt) (any, error)
- func (c *Conn) GroupID() uint32
- func (c *Conn) LastMsgNo() uint32
- func (c *Conn) LocalAddr() net.Addr
- func (c *Conn) OnStats(interval time.Duration, fn func(ConnStats))
- func (c *Conn) OverrideSndSeqNo(nextSeq seq.Number) bool
- func (c *Conn) PeerGroupID() uint32
- func (c *Conn) RcvBufEmpty() bool
- func (c *Conn) RcvBufStartSeq() seq.Number
- func (c *Conn) Read(b []byte) (int, error)
- func (c *Conn) ReadMessage(b []byte) (int, error)
- func (c *Conn) ReadMsgCtrl(b []byte, mc *MsgCtrl) (int, error)
- func (c *Conn) RemoteAddr() net.Addr
- func (c *Conn) ResetRecvState(newSeq seq.Number)
- func (c *Conn) SchedSeqNo() seq.Number
- func (c *Conn) SendKeepAlive()
- func (c *Conn) SendPeerError(errorCode uint32)
- func (c *Conn) SendRate() (pktPerSec int64, bytesPerSec int64)
- func (c *Conn) SetDeadline(t time.Time) error
- func (c *Conn) SetMaxBW(bw int64)
- func (c *Conn) SetOption(opt SockOpt, val any) error
- func (c *Conn) SetReadDeadline(t time.Time) error
- func (c *Conn) SetWriteDeadline(t time.Time) error
- func (c *Conn) SocketID() uint32
- func (c *Conn) Stats(clear bool) ConnStats
- func (c *Conn) StreamID() string
- func (c *Conn) TSBPDTimeBase() *tsbpd.GroupTimeBase
- func (c *Conn) Write(b []byte) (int, error)
- func (c *Conn) WriteMessage(b []byte) (int, error)
- func (c *Conn) WriteMsgCtrl(b []byte, mc *MsgCtrl) (int, error)
- type ConnConfig
- type ConnRequest
- type ConnState
- type ConnStats
- type ConnType
- type ConnectFunc
- type Event
- type EventType
- type ExtendedConnStats
- type Group
- func (g *Group) AddConn(conn *Conn, token int, weight uint16) error
- func (g *Group) AddPendingConn(conn *Conn, token int, weight uint16) error
- func (g *Group) Close() error
- func (g *Group) Connect(addr string, cfg Config, token int, weight uint16) error
- func (g *Group) GroupID() uint32
- func (g *Group) Members() []MemberInfo
- func (g *Group) Mode() GroupMode
- func (g *Group) RTT() time.Duration
- func (g *Group) Read(b []byte) (int, error)
- func (g *Group) SetStabilityTimeout(d time.Duration)
- func (g *Group) Stats() GroupStats
- func (g *Group) SynchronizeDrift(src *Conn)
- func (g *Group) Write(b []byte) (int, error)
- type GroupMemberData
- type GroupMode
- type GroupStats
- type Listener
- type LogCategory
- type LogLevel
- type Logger
- type MemberInfo
- type MemberStatus
- type MsgCtrl
- type RejectReason
- type Server
- type SockOpt
- type StreamIDInfo
- type StreamMode
- type StreamType
- type TransType
- type WatchOpts
- type Watcher
Examples ¶
Constants ¶
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.
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.
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 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 )
Rejection reasons for handshake failures. These are sent in the HandshakeType field of a rejection response.
const ( EventIn = 0x1 // data available for reading EventOut = 0x4 // send buffer has space EventErr = 0x8 // connection error/broken )
Poll event flags for SockOptEvent.
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 ¶
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.
var ErrAlreadyWatched = errors.New("srt: connection already watched")
ErrAlreadyWatched is returned when adding a connection that is already watched.
var ErrInvalidOption = errors.New("srt: invalid socket option")
ErrInvalidOption is returned when an unsupported SockOpt is used.
var ErrNotWatched = errors.New("srt: connection not watched")
ErrNotWatched is returned when removing a connection that is not watched.
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.
var ErrReadOnlyOption = errors.New("srt: socket option is read-only")
ErrReadOnlyOption is returned when trying to Set a read-only option.
var ErrServerClosed = errors.New("srt: server closed")
ErrServerClosed is returned by Serve when the server is shut down.
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 ¶
Dial connects to an SRT listener at the given address.
The handshake follows a 4-step process:
- Caller sends INDUCTION (v4, no cookie)
- Listener responds with INDUCTION response (v5, SYN cookie, SRT magic)
- Caller sends CONCLUSION (v5, echoed cookie, extensions)
- 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
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 ¶
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
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 ¶
AvgRcvBufBytes returns the IIR-8 smoothed receive buffer occupancy in bytes.
func (*Conn) AvgRcvBufSize ¶
AvgRcvBufSize returns the IIR-8 smoothed receive buffer occupancy in packets.
func (*Conn) AvgSndBufBytes ¶
AvgSndBufBytes returns the IIR-8 smoothed send buffer occupancy in bytes.
func (*Conn) AvgSndBufSize ¶
AvgSndBufSize returns the IIR-8 smoothed send buffer occupancy in packets. buffer_tools.h AvgBufSize.
func (*Conn) CurrentSRTTimestamp ¶
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 ¶
GetOption retrieves the current value of a runtime socket option. The returned value type depends on the option (see SockOpt documentation).
func (*Conn) LastMsgNo ¶
LastMsgNo returns the most recently assigned message number. Used by Group to record the message number for sender buffer entries.
func (*Conn) OnStats ¶
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 ¶
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 ¶
PeerGroupID returns the peer's group ID (0 if not part of a group).
func (*Conn) RcvBufEmpty ¶
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 ¶
RcvBufStartSeq returns the receive buffer's oldest unread sequence number. Used by Group for idle link synchronization.
func (*Conn) Read ¶
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 ¶
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 ¶
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 (*Conn) ResetRecvState ¶
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 ¶
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
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 ¶
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) SetMaxBW ¶
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 ¶
SetOption changes the value of a runtime socket option on a live connection. Only certain options support runtime changes (see SockOpt documentation).
func (*Conn) Stats ¶
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) 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 ¶
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 ¶
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.
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 )
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 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 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 (*Group) AddConn ¶
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 ¶
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) Connect ¶
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) 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) Read ¶
Read receives data from the group, deduplicating across members. Packets already delivered via another link are silently dropped.
func (*Group) SetStabilityTimeout ¶
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 ¶
SynchronizeDrift propagates one member's TSBPD drift to all other members. Called when a member's drift is updated.
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 )
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 ¶
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 ¶
Accept waits for and returns the next incoming connection. It blocks until a connection is available or the listener is closed.
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 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
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())
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 ¶
Listen opens the listener socket. Call Serve to start accepting connections.
func (*Server) ListenAndServe ¶
ListenAndServe listens on the configured address and serves connections. It blocks until Shutdown is called or an unrecoverable error occurs.
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.
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 ¶
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 ¶
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 ¶
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 ¶
Close shuts down the Watcher and releases all resources. Any pending Wait() calls will return an error.
Source Files
¶
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. |