Make ephemeral udp ports configurable

This commit is contained in:
Torjus Håkestad 2023-12-05 01:25:17 +01:00
parent fd18ba6527
commit 4b171b849f
5 changed files with 55 additions and 8 deletions

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"os" "os"
@ -33,6 +34,7 @@ func main() {
srv := server.NewServer(cfg) srv := server.NewServer(cfg)
srv.Addr = cfg.HTTP.ListenAddr srv.Addr = cfg.HTTP.ListenAddr
slog.Info("Starting HTTP-server", "addr", srv.Addr, "cfg", cfg)
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
return err return err
} }

View File

@ -7,4 +7,15 @@ SiteName = "stream.example.org"
# HTTPListenAddr is which port the HTTP server will listen on. # HTTPListenAddr is which port the HTTP server will listen on.
# Default: ":8080" # Default: ":8080"
# Env: MINISTREAM_HTTP_LISTENADDR # Env: MINISTREAM_HTTP_LISTENADDR
HTTPListenAddr = ":8080" ListenAddr = ":8080"
[WebRTC]
# UDPMin is the minimum used for ephemeral ports.
# Default: 50000
# Env: MINISTREAM_WEBRTC_UDPMIN
UDPMin = 50000
# UDPMax is the maximum used for ephemeral ports.
# Default: 50050
# Env: MINISTREAM_WEBRTC_UDPMAX
UDPMAX = 50050

View File

@ -3,25 +3,36 @@ package server
import ( import (
"io" "io"
"os" "os"
"strconv"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
) )
type Config struct { type Config struct {
SiteName string `toml:"siteName"` SiteName string `toml:"siteName"`
HTTP ConfigHTTP `toml:"http"` HTTP ConfigHTTP `toml:"http"`
WebRTC ConfigWebRTC `toml:"WebRTC"`
} }
type ConfigHTTP struct { type ConfigHTTP struct {
ListenAddr string `json:"ListenAddr" toml:"ListenAddr"` ListenAddr string `json:"ListenAddr" toml:"ListenAddr"`
} }
type ConfigWebRTC struct {
UDPMin int `toml:"UDPMin"`
UDPMax int `toml:"UDPMax"`
}
func DefaultConfig() *Config { func DefaultConfig() *Config {
return &Config{ return &Config{
SiteName: "ministream", SiteName: "ministream",
HTTP: ConfigHTTP{ HTTP: ConfigHTTP{
ListenAddr: ":8080", ListenAddr: ":8080",
}, },
WebRTC: ConfigWebRTC{
UDPMin: 50000,
UDPMax: 50050,
},
} }
} }
@ -33,6 +44,21 @@ func (c *Config) OverrideFromEnv() {
if httpAddr, ok := os.LookupEnv("MINISTREAM_HTTP_LISTENADDR"); ok { if httpAddr, ok := os.LookupEnv("MINISTREAM_HTTP_LISTENADDR"); ok {
c.HTTP.ListenAddr = httpAddr c.HTTP.ListenAddr = httpAddr
} }
if value, ok := os.LookupEnv("MINISTREAM_WEBRTC_UDPMIN"); ok {
min, err := strconv.Atoi(value)
if err != nil {
panic("MINISTREAM_WEBRTC_UDPMIN is invalid")
}
c.WebRTC.UDPMin = min
}
if value, ok := os.LookupEnv("MINISTREAM_WEBRTC_UDPMAX"); ok {
max, err := strconv.Atoi(value)
if err != nil {
panic("MINISTREAM_WEBRTC_UDPMAX is invalid")
}
c.WebRTC.UDPMin = max
}
} }
func ConfigFromReader(r io.Reader) (*Config, error) { func ConfigFromReader(r io.Reader) (*Config, error) {

View File

@ -26,7 +26,7 @@ type Server struct {
func NewServer(config *Config) *Server { func NewServer(config *Config) *Server {
srv := &Server{ srv := &Server{
streams: NewStreamStore(), streams: NewStreamStore(config),
config: config, config: config,
} }

View File

@ -19,20 +19,24 @@ import (
var ErrNoSuchStream error = fmt.Errorf("no such stream") var ErrNoSuchStream error = fmt.Errorf("no such stream")
type StreamStore struct { type StreamStore struct {
Streams map[string]*Stream Streams map[string]*Stream
config *Config
webRTCConfig webrtc.Configuration webRTCConfig webrtc.Configuration
mu sync.Mutex mu sync.Mutex
} }
func NewStreamStore() *StreamStore { func NewStreamStore(config *Config) *StreamStore {
s := &StreamStore{ s := &StreamStore{
Streams: make(map[string]*Stream), Streams: make(map[string]*Stream),
config: config,
} }
return s return s
} }
type Stream struct { type Stream struct {
store *StreamStore
peerConnection *webrtc.PeerConnection peerConnection *webrtc.PeerConnection
peerConnectionStats map[string]*stats.Stats peerConnectionStats map[string]*stats.Stats
peerConnectionStatsMu sync.Mutex peerConnectionStatsMu sync.Mutex
@ -96,7 +100,10 @@ func (s *Stream) AddListener(sd *webrtc.SessionDescription) (*webrtc.SessionDesc
//i.Add(statsInterceptorFactory) //i.Add(statsInterceptorFactory)
se := webrtc.SettingEngine{} se := webrtc.SettingEngine{}
_ = se.SetEphemeralUDPPortRange(50000, 50050) _ = se.SetEphemeralUDPPortRange(
uint16(s.store.config.WebRTC.UDPMin),
uint16(s.store.config.WebRTC.UDPMax),
)
webRTCConfig := webrtc.Configuration{ webRTCConfig := webrtc.Configuration{
ICEServers: []webrtc.ICEServer{ ICEServers: []webrtc.ICEServer{
@ -179,6 +186,7 @@ func (s *StreamStore) Add(streamKey string, sd *webrtc.SessionDescription) (*web
go func() { go func() {
stream := &Stream{ stream := &Stream{
store: s,
lastUpdate: time.Now(), lastUpdate: time.Now(),
peerConnectionStats: make(map[string]*stats.Stats), peerConnectionStats: make(map[string]*stats.Stats),
} }
@ -226,7 +234,7 @@ func (s *StreamStore) Add(streamKey string, sd *webrtc.SessionDescription) (*web
}, },
} }
se := webrtc.SettingEngine{} se := webrtc.SettingEngine{}
_ = se.SetEphemeralUDPPortRange(50000, 50050) _ = se.SetEphemeralUDPPortRange(uint16(s.config.WebRTC.UDPMin), uint16(s.config.WebRTC.UDPMax))
// se.BufferFactory = func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser { // se.BufferFactory = func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser {
// buf := packetio.NewBuffer() // buf := packetio.NewBuffer()