diff --git a/go.mod b/go.mod index d305fa0a..5509dcf5 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/asticode/go-astits v1.10.1-0.20220319093903-4abe66a9b757 github.com/fsnotify/fsnotify v1.4.9 github.com/gin-gonic/gin v1.8.1 + github.com/google/uuid v1.1.2 github.com/gookit/color v1.4.2 github.com/grafov/m3u8 v0.11.1 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 @@ -31,7 +32,6 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/goccy/go-json v0.9.7 // indirect - github.com/google/uuid v1.1.2 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect diff --git a/internal/core/rtmp_conn.go b/internal/core/rtmp_conn.go index 8641a316..b927ff07 100644 --- a/internal/core/rtmp_conn.go +++ b/internal/core/rtmp_conn.go @@ -14,6 +14,7 @@ import ( "github.com/aler9/gortsplib/pkg/h264" "github.com/aler9/gortsplib/pkg/mpeg4audio" "github.com/aler9/gortsplib/pkg/ringbuffer" + "github.com/google/uuid" "github.com/notedit/rtmp/format/flv/flvio" "github.com/aler9/rtsp-simple-server/internal/conf" @@ -56,7 +57,6 @@ type rtmpConnParent interface { type rtmpConn struct { isTLS bool - id string externalAuthenticationURL string rtspAddress string readTimeout conf.StringDuration @@ -73,6 +73,7 @@ type rtmpConn struct { ctx context.Context ctxCancel func() + uuid uuid.UUID created time.Time path *path ringBuffer *ringbuffer.RingBuffer // read @@ -83,7 +84,6 @@ type rtmpConn struct { func newRTMPConn( parentCtx context.Context, isTLS bool, - id string, externalAuthenticationURL string, rtspAddress string, readTimeout conf.StringDuration, @@ -101,7 +101,6 @@ func newRTMPConn( c := &rtmpConn{ isTLS: isTLS, - id: id, externalAuthenticationURL: externalAuthenticationURL, rtspAddress: rtspAddress, readTimeout: readTimeout, @@ -117,6 +116,7 @@ func newRTMPConn( parent: parent, ctx: ctx, ctxCancel: ctxCancel, + uuid: uuid.New(), created: time.Now(), } @@ -683,7 +683,7 @@ func (c *rtmpConn) apiReaderDescribe() interface{} { return struct { Type string `json:"type"` ID string `json:"id"` - }{"rtmpConn", c.id} + }{"rtmpConn", c.uuid.String()} } // apiSourceDescribe implements source. @@ -698,5 +698,5 @@ func (c *rtmpConn) apiSourceDescribe() interface{} { return struct { Type string `json:"type"` ID string `json:"id"` - }{typ, c.id} + }{typ, c.uuid.String()} } diff --git a/internal/core/rtmp_server.go b/internal/core/rtmp_server.go index 9d518c0d..d0f020f7 100644 --- a/internal/core/rtmp_server.go +++ b/internal/core/rtmp_server.go @@ -2,11 +2,9 @@ package core import ( "context" - "crypto/rand" "crypto/tls" "fmt" "net" - "strconv" "sync" "time" @@ -196,12 +194,9 @@ outer: break outer case nconn := <-connNew: - id, _ := s.newConnID() - c := newRTMPConn( s.ctx, s.isTLS, - id, s.externalAuthenticationURL, s.rtspAddress, s.readTimeout, @@ -228,7 +223,7 @@ outer: } for c := range s.conns { - data.Items[c.id] = rtmpServerAPIConnsListItem{ + data.Items[c.uuid.String()] = rtmpServerAPIConnsListItem{ Created: c.created, RemoteAddr: c.remoteAddr().String(), State: func() string { @@ -249,7 +244,7 @@ outer: case req := <-s.chAPIConnsKick: res := func() bool { for c := range s.conns { - if c.id == req.id { + if c.uuid.String() == req.id { delete(s.conns, c) c.close() return true @@ -277,34 +272,6 @@ outer: } } -func (s *rtmpServer) newConnID() (string, error) { - for { - b := make([]byte, 4) - _, err := rand.Read(b) - if err != nil { - return "", err - } - - u := uint32(b[3])<<24 | uint32(b[2])<<16 | uint32(b[1])<<8 | uint32(b[0]) - u %= 899999999 - u += 100000000 - - id := strconv.FormatUint(uint64(u), 10) - - alreadyPresent := func() bool { - for c := range s.conns { - if c.id == id { - return true - } - } - return false - }() - if !alreadyPresent { - return id, nil - } - } -} - // connClose is called by rtmpConn. func (s *rtmpServer) connClose(c *rtmpConn) { select { diff --git a/internal/core/rtsp_conn.go b/internal/core/rtsp_conn.go index 91569079..953f05b9 100644 --- a/internal/core/rtsp_conn.go +++ b/internal/core/rtsp_conn.go @@ -10,6 +10,7 @@ import ( "github.com/aler9/gortsplib/pkg/auth" "github.com/aler9/gortsplib/pkg/base" "github.com/aler9/gortsplib/pkg/headers" + "github.com/google/uuid" "github.com/aler9/rtsp-simple-server/internal/conf" "github.com/aler9/rtsp-simple-server/internal/externalcmd" @@ -25,7 +26,6 @@ type rtspConnParent interface { } type rtspConn struct { - id string externalAuthenticationURL string rtspAddress string authMethods []headers.AuthMethod @@ -37,6 +37,7 @@ type rtspConn struct { conn *gortsplib.ServerConn parent rtspConnParent + uuid uuid.UUID created time.Time onConnectCmd *externalcmd.Cmd authUser string @@ -46,7 +47,6 @@ type rtspConn struct { } func newRTSPConn( - id string, externalAuthenticationURL string, rtspAddress string, authMethods []headers.AuthMethod, @@ -59,7 +59,6 @@ func newRTSPConn( parent rtspConnParent, ) *rtspConn { c := &rtspConn{ - id: id, externalAuthenticationURL: externalAuthenticationURL, rtspAddress: rtspAddress, authMethods: authMethods, @@ -70,6 +69,7 @@ func newRTSPConn( pathManager: pathManager, conn: conn, parent: parent, + uuid: uuid.New(), created: time.Now(), } diff --git a/internal/core/rtsp_server.go b/internal/core/rtsp_server.go index c3ea69ff..912ba001 100644 --- a/internal/core/rtsp_server.go +++ b/internal/core/rtsp_server.go @@ -2,10 +2,8 @@ package core import ( "context" - "crypto/rand" "crypto/tls" "fmt" - "strconv" "strings" "sync" "time" @@ -239,68 +237,9 @@ outer: } } -func (s *rtspServer) newSessionID() (string, error) { - for { - b := make([]byte, 4) - _, err := rand.Read(b) - if err != nil { - return "", err - } - - u := uint32(b[3])<<24 | uint32(b[2])<<16 | uint32(b[1])<<8 | uint32(b[0]) - u %= 899999999 - u += 100000000 - - id := strconv.FormatUint(uint64(u), 10) - - alreadyPresent := func() bool { - for _, s := range s.sessions { - if s.id == id { - return true - } - } - return false - }() - if !alreadyPresent { - return id, nil - } - } -} - -func (s *rtspServer) newConnID() (string, error) { - for { - b := make([]byte, 4) - _, err := rand.Read(b) - if err != nil { - return "", err - } - - u := uint32(b[3])<<24 | uint32(b[2])<<16 | uint32(b[1])<<8 | uint32(b[0]) - u %= 899999999 - u += 100000000 - - id := strconv.FormatUint(uint64(u), 10) - - alreadyPresent := func() bool { - for _, c := range s.conns { - if c.id == id { - return true - } - } - return false - }() - if !alreadyPresent { - return id, nil - } - } -} - // OnConnOpen implements gortsplib.ServerHandlerOnConnOpen. func (s *rtspServer) OnConnOpen(ctx *gortsplib.ServerHandlerOnConnOpenCtx) { - s.mutex.Lock() - id, _ := s.newConnID() c := newRTSPConn( - id, s.externalAuthenticationURL, s.rtspAddress, s.authMethods, @@ -311,6 +250,7 @@ func (s *rtspServer) OnConnOpen(ctx *gortsplib.ServerHandlerOnConnOpenCtx) { s.pathManager, ctx.Conn, s) + s.mutex.Lock() s.conns[ctx.Conn] = c s.mutex.Unlock() @@ -340,17 +280,15 @@ func (s *rtspServer) OnResponse(sc *gortsplib.ServerConn, res *base.Response) { // OnSessionOpen implements gortsplib.ServerHandlerOnSessionOpen. func (s *rtspServer) OnSessionOpen(ctx *gortsplib.ServerHandlerOnSessionOpenCtx) { - s.mutex.Lock() - id, _ := s.newSessionID() se := newRTSPSession( s.isTLS, s.protocols, - id, ctx.Session, ctx.Conn, s.externalCmdPool, s.pathManager, s) + s.mutex.Lock() s.sessions[ctx.Session] = se s.mutex.Unlock() ctx.Session.SetUserData(se) @@ -435,7 +373,7 @@ func (s *rtspServer) apiConnsList() rtspServerAPIConnsListRes { } for _, c := range s.conns { - data.Items[c.id] = rtspServerAPIConnsListItem{ + data.Items[c.uuid.String()] = rtspServerAPIConnsListItem{ Created: c.created, RemoteAddr: c.remoteAddr().String(), } @@ -460,7 +398,7 @@ func (s *rtspServer) apiSessionsList() rtspServerAPISessionsListRes { } for _, s := range s.sessions { - data.Items[s.id] = rtspServerAPISessionsListItem{ + data.Items[s.uuid.String()] = rtspServerAPISessionsListItem{ Created: s.created, RemoteAddr: s.remoteAddr().String(), State: func() string { @@ -493,7 +431,7 @@ func (s *rtspServer) apiSessionsKick(id string) rtspServerAPISessionsKickRes { defer s.mutex.RUnlock() for key, se := range s.sessions { - if se.id == id { + if se.uuid.String() == id { se.close() delete(s.sessions, key) se.onClose(liberrors.ErrServerTerminated{}) diff --git a/internal/core/rtsp_session.go b/internal/core/rtsp_session.go index 497e4828..6cac8631 100644 --- a/internal/core/rtsp_session.go +++ b/internal/core/rtsp_session.go @@ -1,6 +1,7 @@ package core import ( + "encoding/hex" "errors" "fmt" "net" @@ -9,6 +10,7 @@ import ( "github.com/aler9/gortsplib" "github.com/aler9/gortsplib/pkg/base" + "github.com/google/uuid" "github.com/pion/rtp" "github.com/aler9/rtsp-simple-server/internal/conf" @@ -32,13 +34,13 @@ type rtspSessionParent interface { type rtspSession struct { isTLS bool protocols map[conf.Protocol]struct{} - id string ss *gortsplib.ServerSession author *gortsplib.ServerConn externalCmdPool *externalcmd.Pool pathManager rtspSessionPathManager parent rtspSessionParent + uuid uuid.UUID created time.Time path *path stream *stream @@ -50,7 +52,6 @@ type rtspSession struct { func newRTSPSession( isTLS bool, protocols map[conf.Protocol]struct{}, - id string, ss *gortsplib.ServerSession, sc *gortsplib.ServerConn, externalCmdPool *externalcmd.Pool, @@ -60,12 +61,12 @@ func newRTSPSession( s := &rtspSession{ isTLS: isTLS, protocols: protocols, - id: id, ss: ss, author: sc, externalCmdPool: externalCmdPool, pathManager: pathManager, parent: parent, + uuid: uuid.New(), created: time.Now(), } @@ -93,7 +94,8 @@ func (s *rtspSession) remoteAddr() net.Addr { } func (s *rtspSession) log(level logger.Level, format string, args ...interface{}) { - s.parent.log(level, "[session %s] "+format, append([]interface{}{s.id}, args...)...) + id := hex.EncodeToString(s.uuid[:4]) + s.parent.log(level, "[session %s] "+format, append([]interface{}{id}, args...)...) } // onClose is called by rtspServer. @@ -357,7 +359,7 @@ func (s *rtspSession) apiReaderDescribe() interface{} { return struct { Type string `json:"type"` ID string `json:"id"` - }{typ, s.id} + }{typ, s.uuid.String()} } // apiSourceDescribe implements source. @@ -372,7 +374,7 @@ func (s *rtspSession) apiSourceDescribe() interface{} { return struct { Type string `json:"type"` ID string `json:"id"` - }{typ, s.id} + }{typ, s.uuid.String()} } // onPacketRTP is called by rtspServer.