diff --git a/internal/client/client.go b/internal/client/client.go index ee8d00d6..97aadffa 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -136,6 +136,7 @@ type Client interface { IsClient() IsSource() Close() + CloseRequest() Authenticate([]headers.AuthMethod, string, []interface{}, string, string, interface{}) error diff --git a/internal/clienthls/client.go b/internal/clienthls/client.go index ce9816c3..45c74bc6 100644 --- a/internal/clienthls/client.go +++ b/internal/clienthls/client.go @@ -181,6 +181,11 @@ func (c *Client) Close() { close(c.terminate) } +// CloseRequest closes a Client. +func (c *Client) CloseRequest() { + c.parent.OnClientClose(c) +} + // IsClient implements client.Client. func (c *Client) IsClient() {} diff --git a/internal/clientman/clientman.go b/internal/clientman/clientman.go index b25c4ae5..5573e797 100644 --- a/internal/clientman/clientman.go +++ b/internal/clientman/clientman.go @@ -5,23 +5,19 @@ import ( "sync" "time" - "github.com/aler9/gortsplib" "github.com/aler9/gortsplib/pkg/base" "github.com/aler9/rtsp-simple-server/internal/client" "github.com/aler9/rtsp-simple-server/internal/clienthls" "github.com/aler9/rtsp-simple-server/internal/clientrtmp" - "github.com/aler9/rtsp-simple-server/internal/clientrtsp" "github.com/aler9/rtsp-simple-server/internal/logger" "github.com/aler9/rtsp-simple-server/internal/serverhls" "github.com/aler9/rtsp-simple-server/internal/serverrtmp" - "github.com/aler9/rtsp-simple-server/internal/serverrtsp" "github.com/aler9/rtsp-simple-server/internal/stats" ) // PathManager is implemented by pathman.PathManager. type PathManager interface { - ClientClose() chan client.Client OnClientDescribe(client.DescribeReq) OnClientAnnounce(client.AnnounceReq) OnClientSetupPlay(client.SetupPlayReq) @@ -45,8 +41,6 @@ type ClientManager struct { protocols map[base.StreamProtocol]struct{} stats *stats.Stats pathMan PathManager - serverPlain *serverrtsp.Server - serverTLS *serverrtsp.Server serverRTMP *serverrtmp.Server serverHLS *serverhls.Server parent Parent @@ -76,8 +70,6 @@ func New( protocols map[base.StreamProtocol]struct{}, stats *stats.Stats, pathMan PathManager, - serverPlain *serverrtsp.Server, - serverTLS *serverrtsp.Server, serverRTMP *serverrtmp.Server, serverHLS *serverhls.Server, parent Parent) *ClientManager { @@ -94,8 +86,6 @@ func New( protocols: protocols, stats: stats, pathMan: pathMan, - serverPlain: serverPlain, - serverTLS: serverTLS, serverRTMP: serverRTMP, serverHLS: serverHLS, parent: parent, @@ -125,20 +115,6 @@ func (cm *ClientManager) Log(level logger.Level, format string, args ...interfac func (cm *ClientManager) run() { defer close(cm.done) - tcpAccept := func() chan *gortsplib.ServerConn { - if cm.serverPlain != nil { - return cm.serverPlain.Accept() - } - return make(chan *gortsplib.ServerConn) - }() - - tlsAccept := func() chan *gortsplib.ServerConn { - if cm.serverTLS != nil { - return cm.serverTLS.Accept() - } - return make(chan *gortsplib.ServerConn) - }() - rtmpAccept := func() chan net.Conn { if cm.serverRTMP != nil { return cm.serverRTMP.Accept() @@ -156,36 +132,6 @@ func (cm *ClientManager) run() { outer: for { select { - case conn := <-tcpAccept: - c := clientrtsp.New( - false, - cm.rtspAddress, - cm.readTimeout, - cm.runOnConnect, - cm.runOnConnectRestart, - cm.protocols, - &cm.wg, - cm.stats, - conn, - cm.pathMan, - cm) - cm.clients[c] = struct{}{} - - case conn := <-tlsAccept: - c := clientrtsp.New( - true, - cm.rtspAddress, - cm.readTimeout, - cm.runOnConnect, - cm.runOnConnectRestart, - cm.protocols, - &cm.wg, - cm.stats, - conn, - cm.pathMan, - cm) - cm.clients[c] = struct{}{} - case nconn := <-rtmpAccept: c := clientrtmp.New( cm.rtspAddress, @@ -218,12 +164,6 @@ outer: } c.OnRequest(req) - case c := <-cm.pathMan.ClientClose(): - if _, ok := cm.clients[c]; !ok { - continue - } - cm.onClientClose(c) - case c := <-cm.clientClose: if _, ok := cm.clients[c]; !ok { continue @@ -236,15 +176,7 @@ outer: } go func() { - for { - select { - case _, ok := <-cm.clientClose: - if !ok { - return - } - - case <-cm.pathMan.ClientClose(): - } + for range cm.clientClose { } }() diff --git a/internal/clientrtmp/client.go b/internal/clientrtmp/client.go index 540f2e41..781a377a 100644 --- a/internal/clientrtmp/client.go +++ b/internal/clientrtmp/client.go @@ -143,6 +143,11 @@ func (c *Client) Close() { close(c.terminate) } +// CloseRequest closes a Client. +func (c *Client) CloseRequest() { + c.parent.OnClientClose(c) +} + // IsClient implements client.Client. func (c *Client) IsClient() {} diff --git a/internal/clientrtsp/client.go b/internal/clientrtsp/client.go index d62f20de..e25a762c 100644 --- a/internal/clientrtsp/client.go +++ b/internal/clientrtsp/client.go @@ -55,7 +55,7 @@ type PathMan interface { // Parent is implemented by clientman.ClientMan. type Parent interface { Log(logger.Level, string, ...interface{}) - OnClientClose(client.Client) + OnClientClose(*Client) } // Client is a RTSP client. @@ -118,12 +118,7 @@ func New( } atomic.AddInt64(c.stats.CountClients, 1) - c.log(logger.Info, "connected (%s)", func() string { - if isTLS { - return "RTSP/TLS" - } - return "RTSP/TCP" - }()) + c.log(logger.Info, "connected") c.wg.Add(1) go c.run() @@ -134,9 +129,15 @@ func New( // Close closes a Client. func (c *Client) Close() { atomic.AddInt64(c.stats.CountClients, -1) + c.log(logger.Info, "disconnected") close(c.terminate) } +// CloseRequest closes a Client. +func (c *Client) CloseRequest() { + c.parent.OnClientClose(c) +} + // IsClient implements client.Client. func (c *Client) IsClient() {} @@ -155,7 +156,6 @@ var errTerminated = errors.New("terminated") func (c *Client) run() { defer c.wg.Done() - defer c.log(logger.Info, "disconnected") if c.runOnConnect != "" { _, port, _ := net.SplitHostPort(c.rtspAddress) diff --git a/internal/path/path.go b/internal/path/path.go index b3f33ffb..171a2ca7 100644 --- a/internal/path/path.go +++ b/internal/path/path.go @@ -32,7 +32,6 @@ func newEmptyTimer() *time.Timer { type Parent interface { Log(logger.Level, string, ...interface{}) OnPathClose(*Path) - OnPathClientClose(client.Client) } type sourceRedirect struct{} @@ -310,7 +309,7 @@ outer: case clientStateRecord: atomic.AddInt64(pa.stats.CountPublishers, -1) } - pa.parent.OnPathClientClose(c) + c.CloseRequest() } } pa.clientsWg.Wait() @@ -471,7 +470,7 @@ func (pa *Path) removeClient(c client.Client) { for oc, state := range pa.clients { if state != clientStatePreRemove { pa.removeClient(oc) - pa.parent.OnPathClientClose(oc) + oc.CloseRequest() } } } @@ -511,7 +510,7 @@ func (pa *Path) onSourceSetNotReady() { for c, state := range pa.clients { if c != pa.source && state != clientStatePreRemove { pa.removeClient(c) - pa.parent.OnPathClientClose(c) + c.CloseRequest() } } } @@ -670,7 +669,7 @@ func (pa *Path) onClientAnnounce(req client.AnnounceReq) { pa.Log(logger.Info, "disconnecting existing publisher") curPublisher := pa.source.(client.Client) pa.removeClient(curPublisher) - pa.parent.OnPathClientClose(curPublisher) + curPublisher.CloseRequest() // prevent path closure if pa.closeTimerStarted { diff --git a/internal/pathman/pathman.go b/internal/pathman/pathman.go index 5eff1e38..1431c251 100644 --- a/internal/pathman/pathman.go +++ b/internal/pathman/pathman.go @@ -43,8 +43,7 @@ type PathManager struct { terminate chan struct{} // out - clientClose chan client.Client - done chan struct{} + done chan struct{} } // New allocates a PathManager. @@ -76,7 +75,6 @@ func New( clientSetupPlay: make(chan client.SetupPlayReq), clientAnnounce: make(chan client.AnnounceReq), terminate: make(chan struct{}), - clientClose: make(chan client.Client), done: make(chan struct{}), } @@ -88,10 +86,6 @@ func New( // Close closes a PathManager. func (pm *PathManager) Close() { - go func() { - for range pm.clientClose { - } - }() close(pm.terminate) <-pm.done } @@ -271,7 +265,6 @@ outer: pm.wg.Wait() close(pm.confReload) - close(pm.clientClose) close(pm.pathClose) close(pm.clientDescribe) close(pm.clientSetupPlay) @@ -332,11 +325,6 @@ func (pm *PathManager) OnPathClose(pa *path.Path) { pm.pathClose <- pa } -// OnPathClientClose is called by path.Path. -func (pm *PathManager) OnPathClientClose(c client.Client) { - pm.clientClose <- c -} - // OnClientDescribe is called by clientman.ClientMan. func (pm *PathManager) OnClientDescribe(req client.DescribeReq) { pm.clientDescribe <- req @@ -351,8 +339,3 @@ func (pm *PathManager) OnClientAnnounce(req client.AnnounceReq) { func (pm *PathManager) OnClientSetupPlay(req client.SetupPlayReq) { pm.clientSetupPlay <- req } - -// ClientClose is called by clientman.ClientMan. -func (pm *PathManager) ClientClose() chan client.Client { - return pm.clientClose -} diff --git a/internal/serverrtsp/server.go b/internal/serverrtsp/server.go index e472a62c..33af3c41 100644 --- a/internal/serverrtsp/server.go +++ b/internal/serverrtsp/server.go @@ -2,12 +2,16 @@ package serverrtsp import ( "crypto/tls" - "sync/atomic" + "sync" "time" "github.com/aler9/gortsplib" + "github.com/aler9/gortsplib/pkg/base" + "github.com/aler9/rtsp-simple-server/internal/clientrtsp" "github.com/aler9/rtsp-simple-server/internal/logger" + "github.com/aler9/rtsp-simple-server/internal/pathman" + "github.com/aler9/rtsp-simple-server/internal/stats" ) // Parent is implemented by program. @@ -17,15 +21,26 @@ type Parent interface { // Server is a RTSP listener. type Server struct { - useTLS bool - parent Parent + readTimeout time.Duration + isTLS bool + rtspAddress string + protocols map[base.StreamProtocol]struct{} + runOnConnect string + runOnConnectRestart bool + stats *stats.Stats + pathMan *pathman.PathManager + parent Parent - srv *gortsplib.Server - closed uint32 + srv *gortsplib.Server + wg sync.WaitGroup + clients map[*clientrtsp.Client]struct{} + + // in + clientClose chan *clientrtsp.Client + terminate chan struct{} // out - accept chan *gortsplib.ServerConn - done chan struct{} + done chan struct{} } // New allocates a Server. @@ -38,9 +53,15 @@ func New( useUDP bool, rtpAddress string, rtcpAddress string, - useTLS bool, + isTLS bool, serverCert string, serverKey string, + rtspAddress string, + protocols map[base.StreamProtocol]struct{}, + runOnConnect string, + runOnConnectRestart bool, + stats *stats.Stats, + pathMan *pathman.PathManager, parent Parent) (*Server, error) { conf := gortsplib.ServerConf{ @@ -55,7 +76,7 @@ func New( conf.UDPRTCPAddress = rtcpAddress } - if useTLS { + if isTLS { cert, err := tls.LoadX509KeyPair(serverCert, serverKey) if err != nil { return nil, err @@ -70,70 +91,146 @@ func New( } s := &Server{ - useTLS: useTLS, - parent: parent, - srv: srv, - accept: make(chan *gortsplib.ServerConn), - done: make(chan struct{}), + readTimeout: readTimeout, + isTLS: isTLS, + rtspAddress: rtspAddress, + protocols: protocols, + stats: stats, + pathMan: pathMan, + parent: parent, + srv: srv, + clients: make(map[*clientrtsp.Client]struct{}), + clientClose: make(chan *clientrtsp.Client), + terminate: make(chan struct{}), + done: make(chan struct{}), } if conf.UDPRTPAddress != "" { - parent.Log(logger.Info, "[RTSP/UDP/RTP listener] opened on %s", conf.UDPRTPAddress) + s.Log(logger.Info, "UDP/RTP listener opened on %s", conf.UDPRTPAddress) } if conf.UDPRTCPAddress != "" { - parent.Log(logger.Info, "[RTSP/UDP/RTCP listener] opened on %s", conf.UDPRTCPAddress) + s.Log(logger.Info, "UDP/RTCP listener opened on %s", conf.UDPRTCPAddress) } - s.log(logger.Info, "opened on %s", address) + s.Log(logger.Info, "TCP listener opened on %s", address) go s.run() return s, nil } -func (s *Server) log(level logger.Level, format string, args ...interface{}) { +// Log is the main logging function. +func (s *Server) Log(level logger.Level, format string, args ...interface{}) { label := func() string { - if s.useTLS { - return "RTSP/TLS" + if s.isTLS { + return "RTSPS" } - return "RTSP/TCP" + return "RTSP" }() - s.parent.Log(level, "[%s listener] "+format, append([]interface{}{label}, args...)...) + s.parent.Log(level, "[%s] "+format, append([]interface{}{label}, args...)...) } // Close closes a Server. func (s *Server) Close() { - go func() { - for co := range s.accept { - co.Close() - } - }() - atomic.StoreUint32(&s.closed, 1) - s.srv.Close() + close(s.terminate) <-s.done } func (s *Server) run() { defer close(s.done) - for { - conn, err := s.srv.Accept() - if err != nil { - if atomic.LoadUint32(&s.closed) == 1 { - break - } - s.log(logger.Warn, "ERR: %s", err) - continue - } + s.wg.Add(1) + clientNew := make(chan *gortsplib.ServerConn) + acceptErr := make(chan error) + go func() { + defer s.wg.Done() + acceptErr <- func() error { + for { + conn, err := s.srv.Accept() + if err != nil { + return err + } - s.accept <- conn + clientNew <- conn + } + }() + }() + +outer: + for { + select { + case err := <-acceptErr: + s.Log(logger.Warn, "ERR: %s", err) + break outer + + case conn := <-clientNew: + c := clientrtsp.New( + s.isTLS, + s.rtspAddress, + s.readTimeout, + s.runOnConnect, + s.runOnConnectRestart, + s.protocols, + &s.wg, + s.stats, + conn, + s.pathMan, + s) + s.clients[c] = struct{}{} + + case c := <-s.clientClose: + if _, ok := s.clients[c]; !ok { + continue + } + s.doClientClose(c) + + case <-s.terminate: + break outer + } } - close(s.accept) + go func() { + for { + select { + case _, ok := <-acceptErr: + if !ok { + return + } + + case conn, ok := <-clientNew: + if !ok { + return + } + conn.Close() + + case _, ok := <-s.clientClose: + if !ok { + return + } + } + } + }() + + s.srv.Close() + + for c := range s.clients { + s.doClientClose(c) + } + + s.wg.Wait() + + close(acceptErr) + close(clientNew) + close(s.clientClose) } -// Accept returns a channel to accept incoming connections. -func (s *Server) Accept() chan *gortsplib.ServerConn { - return s.accept +func (s *Server) doClientClose(c *clientrtsp.Client) { + delete(s.clients, c) + c.Close() +} + +// OnClientClose is called by a client. +func (s *Server) OnClientClose(c *clientrtsp.Client) { + s.clientClose <- c } diff --git a/main.go b/main.go index 40defea7..94ec17f4 100644 --- a/main.go +++ b/main.go @@ -191,53 +191,6 @@ func (p *program) createResources(initial bool) error { } } - if !p.conf.RTSPDisable && - (p.conf.EncryptionParsed == conf.EncryptionNo || - p.conf.EncryptionParsed == conf.EncryptionOptional) { - if p.serverRTSPPlain == nil { - _, useUDP := p.conf.ProtocolsParsed[gortsplib.StreamProtocolUDP] - p.serverRTSPPlain, err = serverrtsp.New( - p.conf.RTSPAddress, - p.conf.ReadTimeout, - p.conf.WriteTimeout, - p.conf.ReadBufferCount, - p.conf.ReadBufferSize, - useUDP, - p.conf.RTPAddress, - p.conf.RTCPAddress, - false, - "", - "", - p) - if err != nil { - return err - } - } - } - - if !p.conf.RTSPDisable && - (p.conf.EncryptionParsed == conf.EncryptionStrict || - p.conf.EncryptionParsed == conf.EncryptionOptional) { - if p.serverRTSPTLS == nil { - p.serverRTSPTLS, err = serverrtsp.New( - p.conf.RTSPSAddress, - p.conf.ReadTimeout, - p.conf.WriteTimeout, - p.conf.ReadBufferCount, - p.conf.ReadBufferSize, - false, - "", - "", - true, - p.conf.ServerCert, - p.conf.ServerKey, - p) - if err != nil { - return err - } - } - } - if !p.conf.RTMPDisable { if p.serverRTMP == nil { p.serverRTMP, err = serverrtmp.New( @@ -286,17 +239,79 @@ func (p *program) createResources(initial bool) error { p.conf.ProtocolsParsed, p.stats, p.pathMan, - p.serverRTSPPlain, - p.serverRTSPTLS, p.serverRTMP, p.serverHLS, p) } + if !p.conf.RTSPDisable && + (p.conf.EncryptionParsed == conf.EncryptionNo || + p.conf.EncryptionParsed == conf.EncryptionOptional) { + if p.serverRTSPPlain == nil { + _, useUDP := p.conf.ProtocolsParsed[gortsplib.StreamProtocolUDP] + p.serverRTSPPlain, err = serverrtsp.New( + p.conf.RTSPAddress, + p.conf.ReadTimeout, + p.conf.WriteTimeout, + p.conf.ReadBufferCount, + p.conf.ReadBufferSize, + useUDP, + p.conf.RTPAddress, + p.conf.RTCPAddress, + false, + "", + "", + p.conf.RTSPAddress, + p.conf.ProtocolsParsed, + p.conf.RunOnConnect, + p.conf.RunOnConnectRestart, + p.stats, + p.pathMan, + p) + if err != nil { + return err + } + } + } + + if !p.conf.RTSPDisable && + (p.conf.EncryptionParsed == conf.EncryptionStrict || + p.conf.EncryptionParsed == conf.EncryptionOptional) { + if p.serverRTSPTLS == nil { + p.serverRTSPTLS, err = serverrtsp.New( + p.conf.RTSPSAddress, + p.conf.ReadTimeout, + p.conf.WriteTimeout, + p.conf.ReadBufferCount, + p.conf.ReadBufferSize, + false, + "", + "", + true, + p.conf.ServerCert, + p.conf.ServerKey, + p.conf.RTSPAddress, + p.conf.ProtocolsParsed, + p.conf.RunOnConnect, + p.conf.RunOnConnectRestart, + p.stats, + p.pathMan, + p) + if err != nil { + return err + } + } + } + return nil } func (p *program) closeResources(newConf *conf.Conf) { + closeStats := false + if newConf == nil { + closeStats = true + } + closeLogger := false if newConf == nil || !reflect.DeepEqual(newConf.LogDestinationsParsed, p.conf.LogDestinationsParsed) || @@ -307,17 +322,68 @@ func (p *program) closeResources(newConf *conf.Conf) { closeMetrics := false if newConf == nil || newConf.Metrics != p.conf.Metrics || - newConf.MetricsAddress != p.conf.MetricsAddress { + newConf.MetricsAddress != p.conf.MetricsAddress || + closeStats { closeMetrics = true } closePPROF := false if newConf == nil || newConf.PPROF != p.conf.PPROF || - newConf.PPROFAddress != p.conf.PPROFAddress { + newConf.PPROFAddress != p.conf.PPROFAddress || + closeStats { closePPROF = true } + closeServerRTMP := false + if newConf == nil || + newConf.RTMPDisable != p.conf.RTMPDisable || + newConf.RTMPAddress != p.conf.RTMPAddress || + newConf.ReadTimeout != p.conf.ReadTimeout || + closeStats { + closeServerRTMP = true + } + + closeServerHLS := false + if newConf == nil || + newConf.HLSDisable != p.conf.HLSDisable || + newConf.HLSAddress != p.conf.HLSAddress || + closeStats { + closeServerHLS = true + } + + closePathMan := false + if newConf == nil || + newConf.RTSPAddress != p.conf.RTSPAddress || + newConf.ReadTimeout != p.conf.ReadTimeout || + newConf.WriteTimeout != p.conf.WriteTimeout || + newConf.ReadBufferCount != p.conf.ReadBufferCount || + newConf.ReadBufferSize != p.conf.ReadBufferSize || + !reflect.DeepEqual(newConf.AuthMethodsParsed, p.conf.AuthMethodsParsed) || + closeStats { + closePathMan = true + } else if !reflect.DeepEqual(newConf.Paths, p.conf.Paths) { + p.pathMan.OnProgramConfReload(newConf.Paths) + } + + closeClientMan := false + if newConf == nil || + closeServerRTMP || + closeServerHLS || + closePathMan || + newConf.HLSSegmentCount != p.conf.HLSSegmentCount || + newConf.HLSSegmentDuration != p.conf.HLSSegmentDuration || + newConf.RTSPAddress != p.conf.RTSPAddress || + newConf.ReadTimeout != p.conf.ReadTimeout || + newConf.WriteTimeout != p.conf.WriteTimeout || + newConf.ReadBufferCount != p.conf.ReadBufferCount || + newConf.RunOnConnect != p.conf.RunOnConnect || + newConf.RunOnConnectRestart != p.conf.RunOnConnectRestart || + !reflect.DeepEqual(newConf.ProtocolsParsed, p.conf.ProtocolsParsed) || + closeStats { + closeClientMan = true + } + closeServerPlain := false if newConf == nil || newConf.RTSPDisable != p.conf.RTSPDisable || @@ -328,7 +394,13 @@ func (p *program) closeResources(newConf *conf.Conf) { newConf.ReadBufferCount != p.conf.ReadBufferCount || !reflect.DeepEqual(newConf.ProtocolsParsed, p.conf.ProtocolsParsed) || newConf.RTPAddress != p.conf.RTPAddress || - newConf.RTCPAddress != p.conf.RTCPAddress { + newConf.RTCPAddress != p.conf.RTCPAddress || + newConf.RTSPAddress != p.conf.RTSPAddress || + !reflect.DeepEqual(newConf.ProtocolsParsed, p.conf.ProtocolsParsed) || + newConf.RunOnConnect != p.conf.RunOnConnect || + newConf.RunOnConnectRestart != p.conf.RunOnConnectRestart || + closeStats || + closePathMan { closeServerPlain = true } @@ -341,60 +413,24 @@ func (p *program) closeResources(newConf *conf.Conf) { newConf.WriteTimeout != p.conf.WriteTimeout || newConf.ReadBufferCount != p.conf.ReadBufferCount || newConf.ServerCert != p.conf.ServerCert || - newConf.ServerKey != p.conf.ServerKey { + newConf.ServerKey != p.conf.ServerKey || + newConf.RTSPAddress != p.conf.RTSPAddress || + !reflect.DeepEqual(newConf.ProtocolsParsed, p.conf.ProtocolsParsed) || + newConf.RunOnConnect != p.conf.RunOnConnect || + newConf.RunOnConnectRestart != p.conf.RunOnConnectRestart || + closeStats || + closePathMan { closeServerTLS = true } - closeServerRTMP := false - if newConf == nil || - newConf.RTMPDisable != p.conf.RTMPDisable || - newConf.RTMPAddress != p.conf.RTMPAddress || - newConf.ReadTimeout != p.conf.ReadTimeout { - closeServerRTMP = true + if closeServerTLS && p.serverRTSPTLS != nil { + p.serverRTSPTLS.Close() + p.serverRTSPTLS = nil } - closeServerHLS := false - if newConf == nil || - newConf.HLSDisable != p.conf.HLSDisable || - newConf.HLSAddress != p.conf.HLSAddress { - closeServerHLS = true - } - - closePathMan := false - if newConf == nil || - newConf.RTSPAddress != p.conf.RTSPAddress || - newConf.ReadTimeout != p.conf.ReadTimeout || - newConf.WriteTimeout != p.conf.WriteTimeout || - newConf.ReadBufferCount != p.conf.ReadBufferCount || - newConf.ReadBufferSize != p.conf.ReadBufferSize || - !reflect.DeepEqual(newConf.AuthMethodsParsed, p.conf.AuthMethodsParsed) { - closePathMan = true - } else if !reflect.DeepEqual(newConf.Paths, p.conf.Paths) { - p.pathMan.OnProgramConfReload(newConf.Paths) - } - - closeClientMan := false - if newConf == nil || - closeServerPlain || - closeServerTLS || - closeServerRTMP || - closeServerHLS || - closePathMan || - newConf.HLSSegmentCount != p.conf.HLSSegmentCount || - newConf.HLSSegmentDuration != p.conf.HLSSegmentDuration || - newConf.RTSPAddress != p.conf.RTSPAddress || - newConf.ReadTimeout != p.conf.ReadTimeout || - newConf.WriteTimeout != p.conf.WriteTimeout || - newConf.ReadBufferCount != p.conf.ReadBufferCount || - newConf.RunOnConnect != p.conf.RunOnConnect || - newConf.RunOnConnectRestart != p.conf.RunOnConnectRestart || - !reflect.DeepEqual(newConf.ProtocolsParsed, p.conf.ProtocolsParsed) { - closeClientMan = true - } - - closeStats := false - if newConf == nil { - closeStats = true + if closeServerPlain && p.serverRTSPPlain != nil { + p.serverRTSPPlain.Close() + p.serverRTSPPlain = nil } if closeClientMan && p.clientMan != nil { @@ -417,16 +453,6 @@ func (p *program) closeResources(newConf *conf.Conf) { p.serverRTMP = nil } - if closeServerTLS && p.serverRTSPTLS != nil { - p.serverRTSPTLS.Close() - p.serverRTSPTLS = nil - } - - if closeServerPlain && p.serverRTSPPlain != nil { - p.serverRTSPPlain.Close() - p.serverRTSPPlain = nil - } - if closePPROF && p.pprof != nil { p.pprof.Close() p.pprof = nil