Allow RTCP packets for keepalive also in state PLAY (#185) (#186)

* Allow RTCP packets for keepalive also in state PLAY (#185)

* use sessionTimeout instead of ReadTimeout

* reset udpLastPacketTime before PLAY and RECORD

* change error message in case of timeouts

* fix comment

---------

Co-authored-by: aler9 <46489434+aler9@users.noreply.github.com>
This commit is contained in:
Nils Zottmann
2023-02-13 13:22:38 +01:00
committed by GitHub
parent d75c8e4788
commit 1c50779598
3 changed files with 20 additions and 19 deletions

View File

@@ -24,20 +24,12 @@ func (e ErrServerSessionNotFound) Error() string {
return "session not found" return "session not found"
} }
// ErrServerNoUDPPacketsInAWhile is an error that can be returned by a server. // ErrServerSessionTimedOut is an error that can be returned by a server.
type ErrServerNoUDPPacketsInAWhile struct{} type ErrServerSessionTimedOut struct{}
// Error implements the error interface. // Error implements the error interface.
func (e ErrServerNoUDPPacketsInAWhile) Error() string { func (e ErrServerSessionTimedOut) Error() string {
return "no UDP packets received in a while" return "session timed out"
}
// ErrServerNoRTSPRequestsInAWhile is an error that can be returned by a server.
type ErrServerNoRTSPRequestsInAWhile struct{}
// Error implements the error interface.
func (e ErrServerNoRTSPRequestsInAWhile) Error() string {
return "no RTSP requests received in a while"
} }
// ErrServerCSeqMissing is an error that can be returned by a server. // ErrServerCSeqMissing is an error that can be returned by a server.

View File

@@ -412,16 +412,18 @@ func (ss *ServerSession) runInner() error {
case <-ss.udpCheckStreamTimer.C: case <-ss.udpCheckStreamTimer.C:
now := time.Now() now := time.Now()
lft := atomic.LoadInt64(ss.udpLastPacketTime)
// in case of RECORD, timeout happens when no RTP or RTCP packets are being received // in case of RECORD, timeout happens when no RTP or RTCP packets are being received
if ss.state == ServerSessionStateRecord { if ss.state == ServerSessionStateRecord {
lft := atomic.LoadInt64(ss.udpLastPacketTime)
if now.Sub(time.Unix(lft, 0)) >= ss.s.ReadTimeout { if now.Sub(time.Unix(lft, 0)) >= ss.s.ReadTimeout {
return liberrors.ErrServerNoUDPPacketsInAWhile{} return liberrors.ErrServerSessionTimedOut{}
} }
// in case of PLAY, timeout happens when no RTSP keepalives are being received // in case of PLAY, timeout happens when no RTSP keepalives and no RTCP packets are being received
} else if now.Sub(ss.lastRequestTime) >= ss.s.sessionTimeout { } else if now.Sub(ss.lastRequestTime) >= ss.s.sessionTimeout &&
return liberrors.ErrServerNoRTSPRequestsInAWhile{} now.Sub(time.Unix(lft, 0)) >= ss.s.sessionTimeout {
return liberrors.ErrServerSessionTimedOut{}
} }
ss.udpCheckStreamTimer = time.NewTimer(ss.s.checkStreamPeriod) ss.udpCheckStreamTimer = time.NewTimer(ss.s.checkStreamPeriod)
@@ -573,8 +575,6 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
ss.setuppedQuery = query ss.setuppedQuery = query
ss.announcedMedias = medias ss.announcedMedias = medias
v := time.Now().Unix()
ss.udpLastPacketTime = &v
return res, err return res, err
case base.Setup: case base.Setup:
@@ -860,6 +860,9 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
ss.state = ServerSessionStatePlay ss.state = ServerSessionStatePlay
v := time.Now().Unix()
ss.udpLastPacketTime = &v
for _, sm := range ss.setuppedMedias { for _, sm := range ss.setuppedMedias {
sm.start() sm.start()
} }
@@ -949,6 +952,9 @@ func (ss *ServerSession) handleRequest(sc *ServerConn, req *base.Request) (*base
ss.state = ServerSessionStateRecord ss.state = ServerSessionStateRecord
v := time.Now().Unix()
ss.udpLastPacketTime = &v
for _, sm := range ss.setuppedMedias { for _, sm := range ss.setuppedMedias {
sm.start() sm.start()
} }

View File

@@ -165,6 +165,9 @@ func (sm *serverSessionMedia) readRTCPUDPPlay(payload []byte) error {
return nil return nil
} }
now := time.Now()
atomic.StoreInt64(sm.ss.udpLastPacketTime, now.Unix())
for _, pkt := range packets { for _, pkt := range packets {
sm.onPacketRTCP(pkt) sm.onPacketRTCP(pkt)
} }