mirror of
https://github.com/datarhei/core.git
synced 2025-10-07 08:51:04 +08:00
Add GoSRT & improvements (repo-merge)
Commits (Ingo Oppermann): - Add experimental SRT connection stats and logs - Hide /config/reload endpoint in reade-only mode - Add SRT server - Create v16 in go.mod - Fix data races, tests, lint, and update dependencies - Add trailing slash for routed directories (datarhei/restreamer#340) - Allow relative URLs in content in static routes Co-Authored-By: Ingo Oppermann <57445+ioppermann@users.noreply.github.com>
This commit is contained in:
742
vendor/github.com/datarhei/gosrt/config.go
generated
vendored
Normal file
742
vendor/github.com/datarhei/gosrt/config.go
generated
vendored
Normal file
@@ -0,0 +1,742 @@
|
||||
package srt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
UDP_HEADER_SIZE = 28
|
||||
SRT_HEADER_SIZE = 16
|
||||
MIN_MSS_SIZE = 76
|
||||
MAX_MSS_SIZE = 1500
|
||||
MIN_PAYLOAD_SIZE = MIN_MSS_SIZE - UDP_HEADER_SIZE - SRT_HEADER_SIZE
|
||||
MAX_PAYLOAD_SIZE = MAX_MSS_SIZE - UDP_HEADER_SIZE - SRT_HEADER_SIZE
|
||||
MIN_PASSPHRASE_SIZE = 10
|
||||
MAX_PASSPHRASE_SIZE = 79
|
||||
MAX_STREAMID_SIZE = 512
|
||||
SRT_VERSION = 0x010401
|
||||
)
|
||||
|
||||
// Config is the configuration for a SRT connection
|
||||
type Config struct {
|
||||
// Type of congestion control. 'live' or 'file'
|
||||
// SRTO_CONGESTION
|
||||
Congestion string
|
||||
|
||||
// Connection timeout.
|
||||
// SRTO_CONNTIMEO
|
||||
ConnectionTimeout time.Duration
|
||||
|
||||
// Enable drift tracer.
|
||||
// SRTO_DRIFTTRACER
|
||||
DriftTracer bool
|
||||
|
||||
// Reject connection if parties set different passphrase.
|
||||
// SRTO_ENFORCEDENCRYPTION
|
||||
EnforcedEncryption bool
|
||||
|
||||
// Flow control window size. Packets.
|
||||
// SRTO_FC
|
||||
FC uint32
|
||||
|
||||
// Accept group connections.
|
||||
// SRTO_GROUPCONNECT
|
||||
GroupConnect bool
|
||||
|
||||
// Group stability timeout.
|
||||
// SRTO_GROUPSTABTIMEO
|
||||
GroupStabilityTimeout time.Duration
|
||||
|
||||
// Input bandwidth. Bytes.
|
||||
// SRTO_INPUTBW
|
||||
InputBW int64
|
||||
|
||||
// IP socket type of service
|
||||
// SRTO_IPTOS
|
||||
IPTOS int
|
||||
|
||||
// Defines IP socket "time to live" option.
|
||||
// SRTO_IPTTL
|
||||
IPTTL int
|
||||
|
||||
// Allow only IPv6.
|
||||
// SRTO_IPV6ONLY
|
||||
IPv6Only int
|
||||
|
||||
// Duration of Stream Encryption key switchover. Packets.
|
||||
// SRTO_KMPREANNOUNCE
|
||||
KMPreAnnounce uint64
|
||||
|
||||
// Stream encryption key refresh rate. Packets.
|
||||
// SRTO_KMREFRESHRATE
|
||||
KMRefreshRate uint64
|
||||
|
||||
// Defines the maximum accepted transmission latency.
|
||||
// SRTO_LATENCY
|
||||
Latency time.Duration
|
||||
|
||||
// Packet reorder tolerance.
|
||||
// SRTO_LOSSMAXTTL
|
||||
LossMaxTTL uint32
|
||||
|
||||
// Bandwidth limit in bytes/s.
|
||||
// SRTO_MAXBW
|
||||
MaxBW int64
|
||||
|
||||
// Enable SRT message mode.
|
||||
// SRTO_MESSAGEAPI
|
||||
MessageAPI bool
|
||||
|
||||
// Minimum input bandwidth
|
||||
// This option is effective only if both SRTO_MAXBW and SRTO_INPUTBW are set to 0. It controls the minimum allowed value of the input bitrate estimate.
|
||||
// SRTO_MININPUTBW
|
||||
MinInputBW int64
|
||||
|
||||
// Minimum SRT library version of a peer.
|
||||
// SRTO_MINVERSION
|
||||
MinVersion uint32
|
||||
|
||||
// MTU size
|
||||
// SRTO_MSS
|
||||
MSS uint32
|
||||
|
||||
// Enable periodic NAK reports
|
||||
// SRTO_NAKREPORT
|
||||
NAKReport bool
|
||||
|
||||
// Limit bandwidth overhead, percents
|
||||
// SRTO_OHEADBW
|
||||
OverheadBW int64
|
||||
|
||||
// Set up the packet filter.
|
||||
// SRTO_PACKETFILTER
|
||||
PacketFilter string
|
||||
|
||||
// Password for the encrypted transmission.
|
||||
// SRTO_PASSPHRASE
|
||||
Passphrase string
|
||||
|
||||
// Maximum payload size. Bytes.
|
||||
// SRTO_PAYLOADSIZE
|
||||
PayloadSize uint32
|
||||
|
||||
// Crypto key length in bytes.
|
||||
// SRTO_PBKEYLEN
|
||||
PBKeylen int
|
||||
|
||||
// Peer idle timeout.
|
||||
// SRTO_PEERIDLETIMEO
|
||||
PeerIdleTimeout time.Duration
|
||||
|
||||
// Minimum receiver latency to be requested by sender.
|
||||
// SRTO_PEERLATENCY
|
||||
PeerLatency time.Duration
|
||||
|
||||
// Receiver buffer size. Bytes.
|
||||
// SRTO_RCVBUF
|
||||
ReceiverBufferSize uint32
|
||||
|
||||
// Receiver-side latency.
|
||||
// SRTO_RCVLATENCY
|
||||
ReceiverLatency time.Duration
|
||||
|
||||
// Sender buffer size. Bytes.
|
||||
// SRTO_SNDBUF
|
||||
SendBufferSize uint32
|
||||
|
||||
// Sender's delay before dropping packets.
|
||||
// SRTO_SNDDROPDELAY
|
||||
SendDropDelay time.Duration
|
||||
|
||||
// Stream ID (settable in caller mode only, visible on the listener peer)
|
||||
// SRTO_STREAMID
|
||||
StreamId string
|
||||
|
||||
// Drop too late packets.
|
||||
// SRTO_TLPKTDROP
|
||||
TooLatePacketDrop bool
|
||||
|
||||
// Transmission type. 'live' or 'file'.
|
||||
// SRTO_TRANSTYPE
|
||||
TransmissionType string
|
||||
|
||||
// Timestamp-based packet delivery mode.
|
||||
// SRTO_TSBPDMODE
|
||||
TSBPDMode bool
|
||||
|
||||
// An implementation of the Logger interface
|
||||
Logger Logger
|
||||
}
|
||||
|
||||
// DefaultConfig is the default configuration for a SRT connection
|
||||
// if no individual configuration has been provided.
|
||||
var defaultConfig Config = Config{
|
||||
Congestion: "live",
|
||||
ConnectionTimeout: 3 * time.Second,
|
||||
DriftTracer: true,
|
||||
EnforcedEncryption: true,
|
||||
FC: 25600,
|
||||
GroupConnect: false,
|
||||
GroupStabilityTimeout: 0,
|
||||
InputBW: 0,
|
||||
IPTOS: 0,
|
||||
IPTTL: 0,
|
||||
IPv6Only: -1,
|
||||
KMPreAnnounce: 1 << 12,
|
||||
KMRefreshRate: 1 << 24,
|
||||
Latency: -1,
|
||||
LossMaxTTL: 0,
|
||||
MaxBW: -1,
|
||||
MessageAPI: false,
|
||||
MinVersion: SRT_VERSION,
|
||||
MSS: MAX_MSS_SIZE,
|
||||
NAKReport: true,
|
||||
OverheadBW: 25,
|
||||
PacketFilter: "",
|
||||
Passphrase: "",
|
||||
PayloadSize: MAX_PAYLOAD_SIZE,
|
||||
PBKeylen: 16,
|
||||
PeerIdleTimeout: 2 * time.Second,
|
||||
PeerLatency: 120 * time.Millisecond,
|
||||
ReceiverBufferSize: 0,
|
||||
ReceiverLatency: 120 * time.Millisecond,
|
||||
SendBufferSize: 0,
|
||||
SendDropDelay: 1 * time.Second,
|
||||
StreamId: "",
|
||||
TooLatePacketDrop: true,
|
||||
TransmissionType: "live",
|
||||
TSBPDMode: true,
|
||||
}
|
||||
|
||||
// DefaultConfig returns the default configuration for Dial and Listen.
|
||||
func DefaultConfig() Config {
|
||||
return defaultConfig
|
||||
}
|
||||
|
||||
// UnmarshalURL takes a SRT URL and parses out the configuration. A SRT URL is
|
||||
// srt://[host]:[port]?[key1]=[value1]&[key2]=[value2]...
|
||||
func (c *Config) UnmarshalURL(addr string) error {
|
||||
u, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if u.Scheme != "srt" {
|
||||
return fmt.Errorf("the URL doesn't seem to be an srt:// URL")
|
||||
}
|
||||
|
||||
return c.UnmarshalQuery(u.RawQuery)
|
||||
}
|
||||
|
||||
// UnmarshalQuery parses a query string and interprets it as a configuration
|
||||
// for a SRT connection. The key in each key/value pair corresponds to the
|
||||
// respective field in the Config type, but with only lower case letters. Bool
|
||||
// values can be represented as "true"/"false", "on"/"off", "yes"/"no", or "0"/"1".
|
||||
func (c *Config) UnmarshalQuery(query string) error {
|
||||
v, err := url.ParseQuery(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// https://github.com/Haivision/srt/blob/master/docs/apps/srt-live-transmit.md
|
||||
|
||||
if s := v.Get("congestion"); len(s) != 0 {
|
||||
c.Congestion = s
|
||||
}
|
||||
|
||||
if s := v.Get("conntimeo"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.ConnectionTimeout = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("drifttracer"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.DriftTracer = true
|
||||
case "no", "off", "false", "0":
|
||||
c.DriftTracer = false
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("enforcedencryption"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.EnforcedEncryption = true
|
||||
case "no", "off", "false", "0":
|
||||
c.EnforcedEncryption = false
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("fc"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 32); err == nil {
|
||||
c.FC = uint32(d)
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("groupconnect"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.GroupConnect = true
|
||||
case "no", "off", "false", "0":
|
||||
c.GroupConnect = false
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("groupstabtimeo"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.GroupStabilityTimeout = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("inputbw"); len(s) != 0 {
|
||||
if d, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||
c.InputBW = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("iptos"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.IPTOS = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("ipttl"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.IPTTL = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("ipv6only"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.IPv6Only = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("kmpreannounce"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 64); err == nil {
|
||||
c.KMPreAnnounce = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("kmrefreshrate"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 64); err == nil {
|
||||
c.KMRefreshRate = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("latency"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.Latency = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("lossmaxttl"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 32); err == nil {
|
||||
c.LossMaxTTL = uint32(d)
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("maxbw"); len(s) != 0 {
|
||||
if d, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||
c.MaxBW = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("mininputbw"); len(s) != 0 {
|
||||
if d, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||
c.MinInputBW = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("messageapi"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.MessageAPI = true
|
||||
case "no", "off", "false", "0":
|
||||
c.MessageAPI = false
|
||||
}
|
||||
}
|
||||
|
||||
// minversion is ignored
|
||||
|
||||
if s := v.Get("mss"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 32); err == nil {
|
||||
c.MSS = uint32(d)
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("nakreport"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.NAKReport = true
|
||||
case "no", "off", "false", "0":
|
||||
c.NAKReport = false
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("oheadbw"); len(s) != 0 {
|
||||
if d, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||
c.OverheadBW = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("packetfilter"); len(s) != 0 {
|
||||
c.PacketFilter = s
|
||||
}
|
||||
|
||||
if s := v.Get("passphrase"); len(s) != 0 {
|
||||
c.Passphrase = s
|
||||
}
|
||||
|
||||
if s := v.Get("payloadsize"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 32); err == nil {
|
||||
c.PayloadSize = uint32(d)
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("pbkeylen"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.PBKeylen = d
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("peeridletimeo"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.PeerIdleTimeout = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("peerlatency"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.PeerLatency = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("rcvbuf"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 32); err == nil {
|
||||
c.ReceiverBufferSize = uint32(d)
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("rcvlatency"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.ReceiverLatency = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
// retransmitalgo not implemented (there's only one)
|
||||
|
||||
if s := v.Get("sndbuf"); len(s) != 0 {
|
||||
if d, err := strconv.ParseUint(s, 10, 32); err == nil {
|
||||
c.SendBufferSize = uint32(d)
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("snddropdelay"); len(s) != 0 {
|
||||
if d, err := strconv.Atoi(s); err == nil {
|
||||
c.SendDropDelay = time.Duration(d) * time.Millisecond
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("streamid"); len(s) != 0 {
|
||||
c.StreamId = s
|
||||
}
|
||||
|
||||
if s := v.Get("tlpktdrop"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.TooLatePacketDrop = true
|
||||
case "no", "off", "false", "0":
|
||||
c.TooLatePacketDrop = false
|
||||
}
|
||||
}
|
||||
|
||||
if s := v.Get("transtype"); len(s) != 0 {
|
||||
c.TransmissionType = s
|
||||
}
|
||||
|
||||
if s := v.Get("tsbpdmode"); len(s) != 0 {
|
||||
switch s {
|
||||
case "yes", "on", "true", "1":
|
||||
c.TSBPDMode = true
|
||||
case "no", "off", "false", "0":
|
||||
c.TSBPDMode = false
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalURL returns the SRT URL for this config and the given host and port.
|
||||
func (c *Config) MarshalURL(host string, port uint) string {
|
||||
return "srt://" + host + ":" + strconv.FormatUint(uint64(port), 10) + "?" + c.MarshalQuery()
|
||||
}
|
||||
|
||||
// MarshalQuery returns the corresponding query string for a configuration.
|
||||
func (c *Config) MarshalQuery() string {
|
||||
q := url.Values{}
|
||||
|
||||
if c.Congestion != defaultConfig.Congestion {
|
||||
q.Set("congestion", c.Congestion)
|
||||
}
|
||||
|
||||
if c.ConnectionTimeout != defaultConfig.ConnectionTimeout {
|
||||
q.Set("conntimeo", strconv.FormatInt(c.ConnectionTimeout.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if c.DriftTracer != defaultConfig.DriftTracer {
|
||||
q.Set("drifttracer", strconv.FormatBool(c.DriftTracer))
|
||||
}
|
||||
|
||||
if c.EnforcedEncryption != defaultConfig.EnforcedEncryption {
|
||||
q.Set("enforcedencryption", strconv.FormatBool(c.EnforcedEncryption))
|
||||
}
|
||||
|
||||
if c.FC != defaultConfig.FC {
|
||||
q.Set("fc", strconv.FormatUint(uint64(c.FC), 10))
|
||||
}
|
||||
|
||||
if c.GroupConnect != defaultConfig.GroupConnect {
|
||||
q.Set("groupconnect", strconv.FormatBool(c.GroupConnect))
|
||||
}
|
||||
|
||||
if c.GroupStabilityTimeout != defaultConfig.GroupStabilityTimeout {
|
||||
q.Set("groupstabtimeo", strconv.FormatInt(c.GroupStabilityTimeout.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if c.InputBW != defaultConfig.InputBW {
|
||||
q.Set("inputbw", strconv.FormatInt(c.InputBW, 10))
|
||||
}
|
||||
|
||||
if c.IPTOS != defaultConfig.IPTOS {
|
||||
q.Set("iptos", strconv.FormatInt(int64(c.IPTOS), 10))
|
||||
}
|
||||
|
||||
if c.IPTTL != defaultConfig.IPTTL {
|
||||
q.Set("ipttl", strconv.FormatInt(int64(c.IPTTL), 10))
|
||||
}
|
||||
|
||||
if c.IPv6Only != defaultConfig.IPv6Only {
|
||||
q.Set("ipv6only", strconv.FormatInt(int64(c.IPv6Only), 10))
|
||||
}
|
||||
|
||||
if len(c.Passphrase) != 0 {
|
||||
if c.KMPreAnnounce != defaultConfig.KMPreAnnounce {
|
||||
q.Set("kmpreannounce", strconv.FormatUint(c.KMPreAnnounce, 10))
|
||||
}
|
||||
|
||||
if c.KMRefreshRate != defaultConfig.KMRefreshRate {
|
||||
q.Set("kmrefreshrate", strconv.FormatUint(c.KMRefreshRate, 10))
|
||||
}
|
||||
}
|
||||
|
||||
if c.Latency != defaultConfig.Latency {
|
||||
q.Set("latency", strconv.FormatInt(c.Latency.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if c.LossMaxTTL != defaultConfig.LossMaxTTL {
|
||||
q.Set("lossmaxttl", strconv.FormatInt(int64(c.LossMaxTTL), 10))
|
||||
}
|
||||
|
||||
if c.MaxBW != defaultConfig.MaxBW {
|
||||
q.Set("maxbw", strconv.FormatInt(c.MaxBW, 10))
|
||||
}
|
||||
|
||||
if c.MinInputBW != defaultConfig.InputBW {
|
||||
q.Set("mininputbw", strconv.FormatInt(c.MinInputBW, 10))
|
||||
}
|
||||
|
||||
if c.MessageAPI != defaultConfig.MessageAPI {
|
||||
q.Set("messageapi", strconv.FormatBool(c.MessageAPI))
|
||||
}
|
||||
|
||||
if c.MSS != defaultConfig.MSS {
|
||||
q.Set("mss", strconv.FormatUint(uint64(c.MSS), 10))
|
||||
}
|
||||
|
||||
if c.NAKReport != defaultConfig.NAKReport {
|
||||
q.Set("nakreport", strconv.FormatBool(c.NAKReport))
|
||||
}
|
||||
|
||||
if c.OverheadBW != defaultConfig.OverheadBW {
|
||||
q.Set("oheadbw", strconv.FormatInt(c.OverheadBW, 10))
|
||||
}
|
||||
|
||||
if c.PacketFilter != defaultConfig.PacketFilter {
|
||||
q.Set("packetfilter", c.PacketFilter)
|
||||
}
|
||||
|
||||
if len(c.Passphrase) != 0 {
|
||||
q.Set("passphrase", c.Passphrase)
|
||||
}
|
||||
|
||||
if c.PayloadSize != defaultConfig.PayloadSize {
|
||||
q.Set("payloadsize", strconv.FormatUint(uint64(c.PayloadSize), 10))
|
||||
}
|
||||
|
||||
if c.PBKeylen != defaultConfig.PBKeylen {
|
||||
q.Set("pbkeylen", strconv.FormatInt(int64(c.PBKeylen), 10))
|
||||
}
|
||||
|
||||
if c.PeerIdleTimeout != defaultConfig.PeerIdleTimeout {
|
||||
q.Set("peeridletimeo", strconv.FormatInt(c.PeerIdleTimeout.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if c.PeerLatency != defaultConfig.PeerLatency {
|
||||
q.Set("peerlatency", strconv.FormatInt(c.PeerLatency.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if c.ReceiverBufferSize != defaultConfig.ReceiverBufferSize {
|
||||
q.Set("rcvbuf", strconv.FormatInt(int64(c.ReceiverBufferSize), 10))
|
||||
}
|
||||
|
||||
if c.ReceiverLatency != defaultConfig.ReceiverLatency {
|
||||
q.Set("rcvlatency", strconv.FormatInt(c.ReceiverLatency.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if c.SendBufferSize != defaultConfig.SendBufferSize {
|
||||
q.Set("sndbuf", strconv.FormatInt(int64(c.SendBufferSize), 10))
|
||||
}
|
||||
|
||||
if c.SendDropDelay != defaultConfig.SendDropDelay {
|
||||
q.Set("snddropdelay", strconv.FormatInt(c.SendDropDelay.Milliseconds(), 10))
|
||||
}
|
||||
|
||||
if len(c.StreamId) != 0 {
|
||||
q.Set("streamid", c.StreamId)
|
||||
}
|
||||
|
||||
if c.TooLatePacketDrop != defaultConfig.TooLatePacketDrop {
|
||||
q.Set("tlpktdrop", strconv.FormatBool(c.TooLatePacketDrop))
|
||||
}
|
||||
|
||||
if c.TransmissionType != defaultConfig.TransmissionType {
|
||||
q.Set("transtype", c.TransmissionType)
|
||||
}
|
||||
|
||||
if c.TSBPDMode != defaultConfig.TSBPDMode {
|
||||
q.Set("tsbpdmode", strconv.FormatBool(c.TSBPDMode))
|
||||
}
|
||||
|
||||
return q.Encode()
|
||||
}
|
||||
|
||||
// Validate validates a configuration or returns an error if a field
|
||||
// has an invalid value.
|
||||
func (c Config) Validate() error {
|
||||
if c.TransmissionType != "live" {
|
||||
return fmt.Errorf("config: TransmissionType must be 'live'")
|
||||
}
|
||||
|
||||
c.Congestion = "live"
|
||||
c.NAKReport = true
|
||||
c.TooLatePacketDrop = true
|
||||
c.TSBPDMode = true
|
||||
|
||||
if c.Congestion != "live" {
|
||||
return fmt.Errorf("config: Congestion mode must be 'live'")
|
||||
}
|
||||
|
||||
if c.ConnectionTimeout <= 0 {
|
||||
return fmt.Errorf("config: ConnectionTimeout must be greater than 0")
|
||||
}
|
||||
|
||||
if c.GroupConnect {
|
||||
return fmt.Errorf("config: GroupConnect is not supported")
|
||||
}
|
||||
|
||||
if c.IPTOS > 0 && c.IPTOS > 255 {
|
||||
return fmt.Errorf("config: IPTOS must be lower than 255")
|
||||
}
|
||||
|
||||
if c.IPTTL > 0 && c.IPTTL > 255 {
|
||||
return fmt.Errorf("config: IPTTL must be between 1 and 255")
|
||||
}
|
||||
|
||||
if c.IPv6Only > 0 {
|
||||
return fmt.Errorf("config: IPv6Only is not supported")
|
||||
}
|
||||
|
||||
if c.KMRefreshRate != 0 {
|
||||
if c.KMPreAnnounce < 1 || c.KMPreAnnounce > c.KMRefreshRate/2 {
|
||||
return fmt.Errorf("config: KMPreAnnounce must be greater than 1 and smaller than KMRefreshRate/2")
|
||||
}
|
||||
}
|
||||
|
||||
if c.Latency >= 0 {
|
||||
c.PeerLatency = c.Latency
|
||||
c.ReceiverLatency = c.Latency
|
||||
}
|
||||
|
||||
if c.MinVersion != SRT_VERSION {
|
||||
return fmt.Errorf("config: MinVersion must be %#06x", SRT_VERSION)
|
||||
}
|
||||
|
||||
if c.MSS < MIN_MSS_SIZE || c.MSS > MAX_MSS_SIZE {
|
||||
return fmt.Errorf("config: MSS must be between %d and %d (both inclusive)", MIN_MSS_SIZE, MAX_MSS_SIZE)
|
||||
}
|
||||
|
||||
if !c.NAKReport {
|
||||
return fmt.Errorf("config: NAKReport must be enabled")
|
||||
}
|
||||
|
||||
if c.OverheadBW < 10 || c.OverheadBW > 100 {
|
||||
return fmt.Errorf("config: OverheadBW must be between 10 and 100")
|
||||
}
|
||||
|
||||
if len(c.PacketFilter) != 0 {
|
||||
return fmt.Errorf("config: PacketFilter are not supported")
|
||||
}
|
||||
|
||||
if len(c.Passphrase) != 0 {
|
||||
if len(c.Passphrase) < MIN_PASSPHRASE_SIZE || len(c.Passphrase) > MAX_PASSPHRASE_SIZE {
|
||||
return fmt.Errorf("config: Passphrase must be between %d and %d bytes long", MIN_PASSPHRASE_SIZE, MAX_PASSPHRASE_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
if c.PayloadSize < MIN_PAYLOAD_SIZE || c.PayloadSize > MAX_PAYLOAD_SIZE {
|
||||
return fmt.Errorf("config: PayloadSize must be between %d and %d (both inclusive)", MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE)
|
||||
}
|
||||
|
||||
if c.PayloadSize > c.MSS-uint32(SRT_HEADER_SIZE+UDP_HEADER_SIZE) {
|
||||
return fmt.Errorf("config: PayloadSize must not be larger than %d (MSS - %d)", c.MSS-uint32(SRT_HEADER_SIZE+UDP_HEADER_SIZE), SRT_HEADER_SIZE-UDP_HEADER_SIZE)
|
||||
}
|
||||
|
||||
if c.PBKeylen != 16 && c.PBKeylen != 24 && c.PBKeylen != 32 {
|
||||
return fmt.Errorf("config: PBKeylen must be 16, 24, or 32 bytes")
|
||||
}
|
||||
|
||||
if c.PeerLatency < 0 {
|
||||
return fmt.Errorf("config: PeerLatency must be greater than 0")
|
||||
}
|
||||
|
||||
if c.ReceiverLatency < 0 {
|
||||
return fmt.Errorf("config: ReceiverLatency must be greater than 0")
|
||||
}
|
||||
|
||||
if c.SendDropDelay < 0 {
|
||||
return fmt.Errorf("config: SendDropDelay must be greater than 0")
|
||||
}
|
||||
|
||||
if len(c.StreamId) > MAX_STREAMID_SIZE {
|
||||
return fmt.Errorf("config: StreamId must be shorter than or equal to %d bytes", MAX_STREAMID_SIZE)
|
||||
}
|
||||
|
||||
if !c.TooLatePacketDrop {
|
||||
return fmt.Errorf("config: TooLatePacketDrop must be enabled")
|
||||
}
|
||||
|
||||
if c.TransmissionType != "live" {
|
||||
return fmt.Errorf("config: TransmissionType must be 'live'")
|
||||
}
|
||||
|
||||
if !c.TSBPDMode {
|
||||
return fmt.Errorf("config: TSBPDMode must be enabled")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user