update gortsplib (#2126)

This commit is contained in:
Alessandro Ros 2023-07-30 23:39:24 +02:00 committed by GitHub
parent 83484b1e82
commit e3d4856b4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 81 additions and 83 deletions

2
go.mod
View File

@ -8,7 +8,7 @@ require (
github.com/alecthomas/kong v0.8.0
github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87
github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072
github.com/bluenviron/gortsplib/v3 v3.9.0
github.com/bluenviron/gortsplib/v3 v3.9.1-0.20230730204034-8b8b52e689d9
github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda
github.com/fsnotify/fsnotify v1.6.0
github.com/gin-gonic/gin v1.9.1

4
go.sum
View File

@ -12,8 +12,8 @@ github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87 h1:SCAqalLhg
github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072 h1:pAbC7frXsTMxP7Ck3E50hl7oFeSeD2dgc2lWjmHXztQ=
github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072/go.mod h1:rK4b161qErs82QqvBEl84vpi2xhdZBUT0yubXuytZ7E=
github.com/bluenviron/gortsplib/v3 v3.9.0 h1:aAHV6MhsDtgBF6yKaNBBCdvtSpLB8ne4kyUfLQlN7nM=
github.com/bluenviron/gortsplib/v3 v3.9.0/go.mod h1:5h3Zu7jkzwDknYrf+89q2saab//oioKgM9mgvBEX3pg=
github.com/bluenviron/gortsplib/v3 v3.9.1-0.20230730204034-8b8b52e689d9 h1:QBdUlT/taEG0b8dxguJ6GYT7r6vJFRhvwlhs1LGWYlQ=
github.com/bluenviron/gortsplib/v3 v3.9.1-0.20230730204034-8b8b52e689d9/go.mod h1:vBmCYjtox2pXWSvU+r9ROpEbwSOhh5lVWd+t9Sj8glc=
github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda h1:+ungCWRNDjsy/CVL1l/UjAj4vYL4+NIJQoJJWbR3Xw8=
github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda/go.mod h1:tfk0qGPhqnOxVCrElu8ct3LKQn6Cj4Tpu3zbbJBTKj4=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=

View File

@ -115,7 +115,7 @@ type pathReaderAddReq struct {
res chan pathReaderSetupPlayRes
}
type pathPublisherAnnounceRes struct {
type pathPublisherAddRes struct {
path *path
err error
}
@ -125,7 +125,7 @@ type pathPublisherAddReq struct {
pathName string
skipAuth bool
credentials authCredentials
res chan pathPublisherAnnounceRes
res chan pathPublisherAddRes
}
type pathPublisherRecordRes struct {
@ -743,7 +743,7 @@ func (pa *path) handlePublisherRemove(req pathPublisherRemoveReq) {
func (pa *path) handlePublisherAdd(req pathPublisherAddReq) {
if pa.conf.Source != "publisher" {
req.res <- pathPublisherAnnounceRes{
req.res <- pathPublisherAddRes{
err: fmt.Errorf("can't publish to path '%s' since 'source' is not 'publisher'", pa.name),
}
return
@ -751,7 +751,7 @@ func (pa *path) handlePublisherAdd(req pathPublisherAddReq) {
if pa.source != nil {
if pa.conf.DisablePublisherOverride {
req.res <- pathPublisherAnnounceRes{err: fmt.Errorf("someone is already publishing to path '%s'", pa.name)}
req.res <- pathPublisherAddRes{err: fmt.Errorf("someone is already publishing to path '%s'", pa.name)}
return
}
@ -762,7 +762,7 @@ func (pa *path) handlePublisherAdd(req pathPublisherAddReq) {
pa.source = req.author
req.res <- pathPublisherAnnounceRes{path: pa}
req.res <- pathPublisherAddRes{path: pa}
}
func (pa *path) handlePublisherStart(req pathPublisherStartReq) {
@ -973,12 +973,12 @@ func (pa *path) publisherRemove(req pathPublisherRemoveReq) {
}
// publisherAdd is called by a publisher through pathManager.
func (pa *path) publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes {
func (pa *path) publisherAdd(req pathPublisherAddReq) pathPublisherAddRes {
select {
case pa.chPublisherAdd <- req:
return <-req.res
case <-pa.ctx.Done():
return pathPublisherAnnounceRes{err: fmt.Errorf("terminated")}
return pathPublisherAddRes{err: fmt.Errorf("terminated")}
}
}

View File

@ -289,14 +289,14 @@ outer:
case req := <-pm.chPublisherAdd:
pathConfName, pathConf, pathMatches, err := getConfForPath(pm.pathConfs, req.pathName)
if err != nil {
req.res <- pathPublisherAnnounceRes{err: err}
req.res <- pathPublisherAddRes{err: err}
continue
}
if !req.skipAuth {
err = doAuthentication(pm.externalAuthenticationURL, pm.authMethods, req.pathName, pathConf, true, req.credentials)
if err != nil {
req.res <- pathPublisherAnnounceRes{err: err}
req.res <- pathPublisherAddRes{err: err}
continue
}
}
@ -306,7 +306,7 @@ outer:
pm.createPath(pathConfName, pathConf, req.pathName, pathMatches)
}
req.res <- pathPublisherAnnounceRes{path: pm.paths[req.pathName]}
req.res <- pathPublisherAddRes{path: pm.paths[req.pathName]}
case s := <-pm.chHLSManagerSet:
pm.hlsManager = s
@ -449,8 +449,8 @@ func (pm *pathManager) describe(req pathDescribeReq) pathDescribeRes {
}
// publisherAnnounce is called by a publisher.
func (pm *pathManager) publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes {
req.res = make(chan pathPublisherAnnounceRes)
func (pm *pathManager) publisherAdd(req pathPublisherAddReq) pathPublisherAddRes {
req.res = make(chan pathPublisherAddRes)
select {
case pm.chPublisherAdd <- req:
res := <-req.res
@ -461,7 +461,7 @@ func (pm *pathManager) publisherAdd(req pathPublisherAddReq) pathPublisherAnnoun
return res.path.publisherAdd(req)
case <-pm.ctx.Done():
return pathPublisherAnnounceRes{err: fmt.Errorf("terminated")}
return pathPublisherAddRes{err: fmt.Errorf("terminated")}
}
}

View File

@ -48,7 +48,7 @@ const (
type rtmpConnPathManager interface {
readerAdd(req pathReaderAddReq) pathReaderSetupPlayRes
publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes
publisherAdd(req pathPublisherAddReq) pathPublisherAddRes
}
type rtmpConnParent interface {

View File

@ -137,7 +137,13 @@ func (c *rtspConn) onDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx,
ctx.Path = ctx.Path[1:]
if c.authNonce == "" {
c.authNonce = auth.GenerateNonce()
var err error
c.authNonce, err = auth.GenerateNonce()
if err != nil {
return &base.Response{
StatusCode: base.StatusInternalServerError,
}, nil, err
}
}
res := c.pathManager.describe(pathDescribeReq{

View File

@ -21,7 +21,7 @@ import (
)
type rtspSessionPathManager interface {
publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes
publisherAdd(req pathPublisherAddReq) pathPublisherAddRes
readerAdd(req pathReaderAddReq) pathReaderSetupPlayRes
}
@ -122,7 +122,13 @@ func (s *rtspSession) onAnnounce(c *rtspConn, ctx *gortsplib.ServerHandlerOnAnno
ctx.Path = ctx.Path[1:]
if c.authNonce == "" {
c.authNonce = auth.GenerateNonce()
var err error
c.authNonce, err = auth.GenerateNonce()
if err != nil {
return &base.Response{
StatusCode: base.StatusInternalServerError,
}, err
}
}
res := s.pathManager.publisherAdd(pathPublisherAddReq{
@ -201,7 +207,13 @@ func (s *rtspSession) onSetup(c *rtspConn, ctx *gortsplib.ServerHandlerOnSetupCt
}
if c.authNonce == "" {
c.authNonce = auth.GenerateNonce()
var err error
c.authNonce, err = auth.GenerateNonce()
if err != nil {
return &base.Response{
StatusCode: base.StatusInternalServerError,
}, nil, err
}
}
res := s.pathManager.readerAdd(pathReaderAddReq{

View File

@ -2,11 +2,6 @@ package core
import (
"context"
"crypto/sha256"
"crypto/tls"
"encoding/hex"
"fmt"
"strings"
"time"
"github.com/bluenviron/gortsplib/v3"
@ -19,37 +14,6 @@ import (
"github.com/bluenviron/mediamtx/internal/logger"
)
type rtspSourceParent interface {
logger.Writer
sourceStaticImplSetReady(req pathSourceStaticSetReadyReq) pathSourceStaticSetReadyRes
sourceStaticImplSetNotReady(req pathSourceStaticSetNotReadyReq)
}
type rtspSource struct {
readTimeout conf.StringDuration
writeTimeout conf.StringDuration
readBufferCount int
parent rtspSourceParent
}
func newRTSPSource(
readTimeout conf.StringDuration,
writeTimeout conf.StringDuration,
readBufferCount int,
parent rtspSourceParent,
) *rtspSource {
return &rtspSource{
readTimeout: readTimeout,
writeTimeout: writeTimeout,
readBufferCount: readBufferCount,
parent: parent,
}
}
func (s *rtspSource) Log(level logger.Level, format string, args ...interface{}) {
s.parent.Log(level, "[rtsp source] "+format, args...)
}
func createRangeHeader(cnf *conf.PathConf) (*headers.Range, error) {
switch cnf.RtspRangeType {
case conf.RtspRangeTypeClock:
@ -95,33 +59,44 @@ func createRangeHeader(cnf *conf.PathConf) (*headers.Range, error) {
}
}
type rtspSourceParent interface {
logger.Writer
sourceStaticImplSetReady(req pathSourceStaticSetReadyReq) pathSourceStaticSetReadyRes
sourceStaticImplSetNotReady(req pathSourceStaticSetNotReadyReq)
}
type rtspSource struct {
readTimeout conf.StringDuration
writeTimeout conf.StringDuration
readBufferCount int
parent rtspSourceParent
}
func newRTSPSource(
readTimeout conf.StringDuration,
writeTimeout conf.StringDuration,
readBufferCount int,
parent rtspSourceParent,
) *rtspSource {
return &rtspSource{
readTimeout: readTimeout,
writeTimeout: writeTimeout,
readBufferCount: readBufferCount,
parent: parent,
}
}
func (s *rtspSource) Log(level logger.Level, format string, args ...interface{}) {
s.parent.Log(level, "[rtsp source] "+format, args...)
}
// run implements sourceStaticImpl.
func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan *conf.PathConf) error {
s.Log(logger.Debug, "connecting")
var tlsConfig *tls.Config
if cnf.SourceFingerprint != "" {
tlsConfig = &tls.Config{
InsecureSkipVerify: true,
VerifyConnection: func(cs tls.ConnectionState) error {
h := sha256.New()
h.Write(cs.PeerCertificates[0].Raw)
hstr := hex.EncodeToString(h.Sum(nil))
fingerprintLower := strings.ToLower(cnf.SourceFingerprint)
if hstr != fingerprintLower {
return fmt.Errorf("server fingerprint do not match: expected %s, got %s",
fingerprintLower, hstr)
}
return nil
},
}
}
c := &gortsplib.Client{
Transport: cnf.SourceProtocol.Transport,
TLSConfig: tlsConfig,
TLSConfig: tlsConfigForFingerprint(cnf.SourceFingerprint),
ReadTimeout: time.Duration(s.readTimeout),
WriteTimeout: time.Duration(s.writeTimeout),
ReadBufferCount: s.readBufferCount,

View File

@ -43,7 +43,9 @@ func TestRTSPSource(t *testing.T) {
t.Run(source, func(t *testing.T) {
medi := testMediaH264
stream := gortsplib.NewServerStream(media.Medias{medi})
nonce := auth.GenerateNonce()
nonce, err := auth.GenerateNonce()
require.NoError(t, err)
s := gortsplib.Server{
Handler: &testServer{
@ -112,7 +114,7 @@ func TestRTSPSource(t *testing.T) {
s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
}
err := s.Start()
err = s.Start()
require.NoError(t, err)
defer s.Wait()
defer s.Close()
@ -167,7 +169,10 @@ func TestRTSPSource(t *testing.T) {
func TestRTSPSourceNoPassword(t *testing.T) {
stream := gortsplib.NewServerStream(media.Medias{testMediaH264})
nonce := auth.GenerateNonce()
nonce, err := auth.GenerateNonce()
require.NoError(t, err)
done := make(chan struct{})
s := gortsplib.Server{
@ -201,7 +206,7 @@ func TestRTSPSourceNoPassword(t *testing.T) {
},
RTSPAddress: "127.0.0.1:8555",
}
err := s.Start()
err = s.Start()
require.NoError(t, err)
defer s.Wait()
defer s.Close()

View File

@ -131,7 +131,7 @@ func gatherIncomingTracks(
}
type webRTCSessionPathManager interface {
publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes
publisherAdd(req pathPublisherAddReq) pathPublisherAddRes
readerAdd(req pathReaderAddReq) pathReaderSetupPlayRes
}