move most errors into pkg/liberrors (#408)

This commit is contained in:
Alessandro Ros
2023-09-10 17:32:16 +02:00
committed by GitHub
parent 43e448d3fe
commit 4495e7d689
12 changed files with 178 additions and 131 deletions

View File

@@ -713,7 +713,7 @@ func (c *Client) checkState(allowed map[clientState]struct{}) error {
} }
func (c *Client) trySwitchingProtocol() error { func (c *Client) trySwitchingProtocol() error {
c.OnTransportSwitch(fmt.Errorf("no UDP packets received, switching to TCP")) c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP{})
prevConnURL := c.connURL prevConnURL := c.connURL
prevBaseURL := c.baseURL prevBaseURL := c.baseURL
@@ -752,7 +752,7 @@ func (c *Client) trySwitchingProtocol() error {
} }
func (c *Client) trySwitchingProtocol2(medi *description.Media, baseURL *url.URL) (*base.Response, error) { func (c *Client) trySwitchingProtocol2(medi *description.Media, baseURL *url.URL) (*base.Response, error) {
c.OnTransportSwitch(fmt.Errorf("switching to TCP because server requested it")) c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{})
prevConnURL := c.connURL prevConnURL := c.connURL
@@ -939,7 +939,7 @@ func (c *Client) do(req *base.Request, skipResponse bool) (*base.Response, error
sender, err := auth.NewSender(res.Header["WWW-Authenticate"], user, pass) sender, err := auth.NewSender(res.Header["WWW-Authenticate"], user, pass)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to setup authentication: %s", err) return nil, liberrors.ErrClientAuthSetup{Err: err}
} }
c.sender = sender c.sender = sender
@@ -1142,13 +1142,13 @@ func (c *Client) doDescribe(u *url.URL) (*description.Session, *base.Response, e
var ssd sdp.SessionDescription var ssd sdp.SessionDescription
err = ssd.Unmarshal(res.Body) err = ssd.Unmarshal(res.Body)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, liberrors.ErrClientSDPInvalid{Err: err}
} }
var desc description.Session var desc description.Session
err = desc.Unmarshal(&ssd) err = desc.Unmarshal(&ssd)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, liberrors.ErrClientSDPInvalid{Err: err}
} }
baseURL, err := findBaseURL(&ssd, res, u) baseURL, err := findBaseURL(&ssd, res, u)
@@ -1348,7 +1348,7 @@ func (c *Client) doSetup(
// switch transport automatically // switch transport automatically
if res.StatusCode == base.StatusUnsupportedTransport && if res.StatusCode == base.StatusUnsupportedTransport &&
c.effectiveTransport == nil { c.effectiveTransport == nil {
c.OnTransportSwitch(fmt.Errorf("switching to TCP because server requested it")) c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{})
v := TransportTCP v := TransportTCP
c.effectiveTransport = &v c.effectiveTransport = &v
return c.doSetup(baseURL, medi, 0, 0) return c.doSetup(baseURL, medi, 0, 0)

View File

@@ -1,7 +1,6 @@
package gortsplib package gortsplib
import ( import (
"fmt"
"time" "time"
"github.com/pion/rtcp" "github.com/pion/rtcp"
@@ -95,14 +94,7 @@ func (ct *clientFormat) writePacketRTP(byts []byte, pkt *rtp.Packet, ntp time.Ti
func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) { func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) {
packets, lost := ct.udpReorderer.Process(pkt) packets, lost := ct.udpReorderer.Process(pkt)
if lost != 0 { if lost != 0 {
ct.cm.c.OnPacketLost(fmt.Errorf("%d RTP %s lost", ct.cm.c.OnPacketLost(liberrors.ErrClientRTPPacketsLost{Lost: lost})
lost,
func() string {
if lost == 1 {
return "packet"
}
return "packets"
}()))
// do not return // do not return
} }
@@ -122,14 +114,7 @@ func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) {
func (ct *clientFormat) readRTPTCP(pkt *rtp.Packet) { func (ct *clientFormat) readRTPTCP(pkt *rtp.Packet) {
lost := ct.tcpLossDetector.Process(pkt) lost := ct.tcpLossDetector.Process(pkt)
if lost != 0 { if lost != 0 {
ct.cm.c.OnPacketLost(fmt.Errorf("%d RTP %s lost", ct.cm.c.OnPacketLost(liberrors.ErrClientRTPPacketsLost{Lost: lost})
lost,
func() string {
if lost == 1 {
return "packet"
}
return "packets"
}()))
// do not return // do not return
} }

View File

@@ -1,7 +1,6 @@
package gortsplib package gortsplib
import ( import (
"fmt"
"sync/atomic" "sync/atomic"
"time" "time"
@@ -193,7 +192,7 @@ func (cm *clientMedia) readRTPTCPPlay(payload []byte) {
forma, ok := cm.formats[pkt.PayloadType] forma, ok := cm.formats[pkt.PayloadType]
if !ok { if !ok {
cm.c.OnDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType)) cm.c.OnDecodeError(liberrors.ErrClientRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
return return
} }
@@ -205,8 +204,7 @@ func (cm *clientMedia) readRTCPTCPPlay(payload []byte) {
atomic.StoreInt64(cm.c.tcpLastFrameTime, now.Unix()) atomic.StoreInt64(cm.c.tcpLastFrameTime, now.Unix())
if len(payload) > udpMaxPayloadSize { if len(payload) > udpMaxPayloadSize {
cm.c.OnDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
len(payload), udpMaxPayloadSize))
return return
} }
@@ -233,8 +231,7 @@ func (cm *clientMedia) readRTPTCPRecord(_ []byte) {
func (cm *clientMedia) readRTCPTCPRecord(payload []byte) { func (cm *clientMedia) readRTCPTCPRecord(payload []byte) {
if len(payload) > udpMaxPayloadSize { if len(payload) > udpMaxPayloadSize {
cm.c.OnDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
len(payload), udpMaxPayloadSize))
return return
} }
@@ -255,7 +252,7 @@ func (cm *clientMedia) readRTPUDPPlay(payload []byte) {
atomic.AddUint64(cm.c.BytesReceived, uint64(plen)) atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
if plen == (udpMaxPayloadSize + 1) { if plen == (udpMaxPayloadSize + 1) {
cm.c.OnDecodeError(fmt.Errorf("RTP packet is too big to be read with UDP")) cm.c.OnDecodeError(liberrors.ErrClientRTPPacketTooBigUDP{})
return return
} }
@@ -268,7 +265,7 @@ func (cm *clientMedia) readRTPUDPPlay(payload []byte) {
forma, ok := cm.formats[pkt.PayloadType] forma, ok := cm.formats[pkt.PayloadType]
if !ok { if !ok {
cm.c.OnDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType)) cm.c.OnDecodeError(liberrors.ErrClientRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
return return
} }
@@ -282,7 +279,7 @@ func (cm *clientMedia) readRTCPUDPPlay(payload []byte) {
atomic.AddUint64(cm.c.BytesReceived, uint64(plen)) atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
if plen == (udpMaxPayloadSize + 1) { if plen == (udpMaxPayloadSize + 1) {
cm.c.OnDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP")) cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBigUDP{})
return return
} }
@@ -313,7 +310,7 @@ func (cm *clientMedia) readRTCPUDPRecord(payload []byte) {
atomic.AddUint64(cm.c.BytesReceived, uint64(plen)) atomic.AddUint64(cm.c.BytesReceived, uint64(plen))
if plen == (udpMaxPayloadSize + 1) { if plen == (udpMaxPayloadSize + 1) {
cm.c.OnDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP")) cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBigUDP{})
return return
} }

View File

@@ -2896,13 +2896,13 @@ func TestClientPlayDecodeErrors(t *testing.T) {
{"udp", "rtp invalid"}, {"udp", "rtp invalid"},
{"udp", "rtcp invalid"}, {"udp", "rtcp invalid"},
{"udp", "rtp packets lost"}, {"udp", "rtp packets lost"},
{"udp", "rtp unknown format"}, {"udp", "rtp unknown payload type"},
{"udp", "wrong ssrc"}, {"udp", "wrong ssrc"},
{"udp", "rtcp too big"}, {"udp", "rtcp too big"},
{"udp", "rtp too big"}, {"udp", "rtp too big"},
{"tcp", "rtp invalid"}, {"tcp", "rtp invalid"},
{"tcp", "rtcp invalid"}, {"tcp", "rtcp invalid"},
{"tcp", "rtp unknown format"}, {"tcp", "rtp unknown payload type"},
{"tcp", "wrong ssrc"}, {"tcp", "wrong ssrc"},
{"tcp", "rtcp too big"}, {"tcp", "rtcp too big"},
} { } {
@@ -3077,7 +3077,7 @@ func TestClientPlayDecodeErrors(t *testing.T) {
}, },
})) }))
case ca.name == "rtp unknown format": case ca.name == "rtp unknown payload type":
writeRTP(mustMarshalPacketRTP(&rtp.Packet{ writeRTP(mustMarshalPacketRTP(&rtp.Packet{
Header: rtp.Header{ Header: rtp.Header{
PayloadType: 111, PayloadType: 111,
@@ -3140,8 +3140,8 @@ func TestClientPlayDecodeErrors(t *testing.T) {
case ca.name == "rtcp invalid": case ca.name == "rtcp invalid":
require.EqualError(t, err, "rtcp: packet too short") require.EqualError(t, err, "rtcp: packet too short")
case ca.name == "rtp unknown format": case ca.name == "rtp unknown payload type":
require.EqualError(t, err, "received RTP packet with unknown format: 111") require.EqualError(t, err, "received RTP packet with unknown payload type: 111")
case ca.name == "wrong ssrc": case ca.name == "wrong ssrc":
require.EqualError(t, err, "received packet with wrong SSRC 456, expected 123") require.EqualError(t, err, "received packet with wrong SSRC 456, expected 123")

View File

@@ -256,3 +256,94 @@ type ErrClientWriteQueueFull struct{}
func (e ErrClientWriteQueueFull) Error() string { func (e ErrClientWriteQueueFull) Error() string {
return "write queue is full" return "write queue is full"
} }
// ErrClientRTPPacketsLost is an error that can be returned by a client.
type ErrClientRTPPacketsLost struct {
Lost int
}
// Error implements the error interface.
func (e ErrClientRTPPacketsLost) Error() string {
return fmt.Sprintf("%d RTP %s lost",
e.Lost,
func() string {
if e.Lost == 1 {
return "packet"
}
return "packets"
}())
}
// ErrClientRTPPacketUnknownPayloadType is an error that can be returned by a client.
type ErrClientRTPPacketUnknownPayloadType struct {
PayloadType uint8
}
// Error implements the error interface.
func (e ErrClientRTPPacketUnknownPayloadType) Error() string {
return fmt.Sprintf("received RTP packet with unknown payload type: %d", e.PayloadType)
}
// ErrClientRTCPPacketTooBig is an error that can be returned by a client.
type ErrClientRTCPPacketTooBig struct {
L int
Max int
}
// Error implements the error interface.
func (e ErrClientRTCPPacketTooBig) Error() string {
return fmt.Sprintf("RTCP packet size (%d) is greater than maximum allowed (%d)",
e.L, e.Max)
}
// ErrClientRTPPacketTooBigUDP is an error that can be returned by a client.
type ErrClientRTPPacketTooBigUDP struct{}
// Error implements the error interface.
func (e ErrClientRTPPacketTooBigUDP) Error() string {
return "RTP packet is too big to be read with UDP"
}
// ErrClientRTCPPacketTooBigUDP is an error that can be returned by a client.
type ErrClientRTCPPacketTooBigUDP struct{}
// Error implements the error interface.
func (e ErrClientRTCPPacketTooBigUDP) Error() string {
return "RTCP packet is too big to be read with UDP"
}
// ErrClientSwitchToTCP is an error that can be returned by a client.
type ErrClientSwitchToTCP struct{}
// Error implements the error interface.
func (e ErrClientSwitchToTCP) Error() string {
return "no UDP packets received, switching to TCP"
}
// ErrClientSwitchToTCP2 is an error that can be returned by a client.
type ErrClientSwitchToTCP2 struct{}
// Error implements the error interface.
func (e ErrClientSwitchToTCP2) Error() string {
return "switching to TCP because server requested it"
}
// ErrClientAuthSetup is an error that can be returned by a client.
type ErrClientAuthSetup struct {
Err error
}
// Error implements the error interface.
func (e ErrClientAuthSetup) Error() string {
return fmt.Sprintf("unable to setup authentication: %s", e.Err)
}
// ErrClientSDPInvalid is an error that can be returned by a client.
type ErrClientSDPInvalid struct {
Err error
}
// Error implements the error interface.
func (e ErrClientSDPInvalid) Error() string {
return fmt.Sprintf("invalid SDP: %v", e.Err)
}

View File

@@ -4,17 +4,11 @@ import (
"fmt" "fmt"
"net" "net"
"github.com/bluenviron/gortsplib/v4/pkg/base"
"github.com/bluenviron/gortsplib/v4/pkg/headers" "github.com/bluenviron/gortsplib/v4/pkg/headers"
) )
// ErrServerTerminated is an error that can be returned by a server. // ErrServerTerminated is an error that can be returned by a server.
type ErrServerTerminated struct{} type ErrServerTerminated = ErrClientTerminated
// Error implements the error interface.
func (e ErrServerTerminated) Error() string {
return "terminated"
}
// ErrServerSessionNotFound is an error that can be returned by a server. // ErrServerSessionNotFound is an error that can be returned by a server.
type ErrServerSessionNotFound struct{} type ErrServerSessionNotFound struct{}
@@ -61,42 +55,16 @@ func (e ErrServerInvalidPath) Error() string {
} }
// ErrServerContentTypeMissing is an error that can be returned by a server. // ErrServerContentTypeMissing is an error that can be returned by a server.
type ErrServerContentTypeMissing struct{} type ErrServerContentTypeMissing = ErrClientContentTypeMissing
// Error implements the error interface.
func (e ErrServerContentTypeMissing) Error() string {
return "Content-Type header is missing"
}
// ErrServerContentTypeUnsupported is an error that can be returned by a server. // ErrServerContentTypeUnsupported is an error that can be returned by a server.
type ErrServerContentTypeUnsupported struct { type ErrServerContentTypeUnsupported = ErrClientContentTypeUnsupported
CT base.HeaderValue
}
// Error implements the error interface.
func (e ErrServerContentTypeUnsupported) Error() string {
return fmt.Sprintf("unsupported Content-Type header '%v'", e.CT)
}
// ErrServerSDPInvalid is an error that can be returned by a server. // ErrServerSDPInvalid is an error that can be returned by a server.
type ErrServerSDPInvalid struct { type ErrServerSDPInvalid = ErrClientSDPInvalid
Err error
}
// Error implements the error interface.
func (e ErrServerSDPInvalid) Error() string {
return fmt.Sprintf("invalid SDP: %v", e.Err)
}
// ErrServerTransportHeaderInvalid is an error that can be returned by a server. // ErrServerTransportHeaderInvalid is an error that can be returned by a server.
type ErrServerTransportHeaderInvalid struct { type ErrServerTransportHeaderInvalid = ErrClientTransportHeaderInvalid
Err error
}
// Error implements the error interface.
func (e ErrServerTransportHeaderInvalid) Error() string {
return fmt.Sprintf("invalid transport header: %v", e.Err)
}
// ErrServerMediaAlreadySetup is an error that can be returned by a server. // ErrServerMediaAlreadySetup is an error that can be returned by a server.
type ErrServerMediaAlreadySetup struct{} type ErrServerMediaAlreadySetup struct{}
@@ -106,6 +74,14 @@ func (e ErrServerMediaAlreadySetup) Error() string {
return "media has already been setup" return "media has already been setup"
} }
// ErrServerMediaNotFound is an error that can be returned by a server.
type ErrServerMediaNotFound struct{}
// Error implements the error interface.
func (e ErrServerMediaNotFound) Error() string {
return "media not found"
}
// ErrServerTransportHeaderInvalidMode is an error that can be returned by a server. // ErrServerTransportHeaderInvalidMode is an error that can be returned by a server.
type ErrServerTransportHeaderInvalidMode struct { type ErrServerTransportHeaderInvalidMode struct {
Mode headers.TransportMode Mode headers.TransportMode
@@ -245,25 +221,43 @@ func (e ErrServerSessionNotInUse) Error() string {
} }
// ErrServerUnexpectedFrame is an error that can be returned by a server. // ErrServerUnexpectedFrame is an error that can be returned by a server.
type ErrServerUnexpectedFrame struct{} type ErrServerUnexpectedFrame = ErrClientUnexpectedFrame
// Error implements the error interface.
func (e ErrServerUnexpectedFrame) Error() string {
return "received unexpected interleaved frame"
}
// ErrServerUnexpectedResponse is an error that can be returned by a server. // ErrServerUnexpectedResponse is an error that can be returned by a server.
type ErrServerUnexpectedResponse struct{} type ErrServerUnexpectedResponse = ErrClientUnexpectedResponse
// Error implements the error interface.
func (e ErrServerUnexpectedResponse) Error() string {
return "received unexpected response"
}
// ErrServerWriteQueueFull is an error that can be returned by a server. // ErrServerWriteQueueFull is an error that can be returned by a server.
type ErrServerWriteQueueFull struct{} type ErrServerWriteQueueFull = ErrClientWriteQueueFull
// ErrServerRTPPacketsLost is an error that can be returned by a server.
type ErrServerRTPPacketsLost = ErrClientRTPPacketsLost
// ErrServerRTPPacketUnknownPayloadType is an error that can be returned by a server.
type ErrServerRTPPacketUnknownPayloadType = ErrClientRTPPacketUnknownPayloadType
// ErrServerRTCPPacketTooBig is an error that can be returned by a server.
type ErrServerRTCPPacketTooBig = ErrClientRTCPPacketTooBig
// ErrServerRTPPacketTooBigUDP is an error that can be returned by a server.
type ErrServerRTPPacketTooBigUDP = ErrClientRTPPacketTooBigUDP
// ErrServerRTCPPacketTooBigUDP is an error that can be returned by a server.
type ErrServerRTCPPacketTooBigUDP = ErrClientRTCPPacketTooBigUDP
// ErrServerStreamClosed is an error that can be returned by a server.
type ErrServerStreamClosed struct{}
// Error implements the error interface. // Error implements the error interface.
func (e ErrServerWriteQueueFull) Error() string { func (e ErrServerStreamClosed) Error() string {
return "write queue is full" return "stream is closed"
}
// ErrServerPathNoSlash is an error that can be returned by a server.
type ErrServerPathNoSlash struct{}
// Error implements the error interface.
func (ErrServerPathNoSlash) Error() string {
return "path of a SETUP request must end with a slash. " +
"This typically happens when VLC fails a request, and then switches to an " +
"unsupported RTSP dialect"
} }

View File

@@ -459,7 +459,7 @@ func (s *Server) getMulticastIP() (net.IP, error) {
return <-res, nil return <-res, nil
case <-s.ctx.Done(): case <-s.ctx.Done():
return nil, fmt.Errorf("terminated") return nil, liberrors.ErrServerTerminated{}
} }
} }

View File

@@ -1188,13 +1188,13 @@ func TestServerRecordDecodeErrors(t *testing.T) {
{"udp", "rtp invalid"}, {"udp", "rtp invalid"},
{"udp", "rtcp invalid"}, {"udp", "rtcp invalid"},
{"udp", "rtp packets lost"}, {"udp", "rtp packets lost"},
{"udp", "rtp unknown format"}, {"udp", "rtp unknown payload type"},
{"udp", "wrong ssrc"}, {"udp", "wrong ssrc"},
{"udp", "rtcp too big"}, {"udp", "rtcp too big"},
{"udp", "rtp too big"}, {"udp", "rtp too big"},
{"tcp", "rtcp invalid"}, {"tcp", "rtcp invalid"},
{"tcp", "rtp packets lost"}, {"tcp", "rtp packets lost"},
{"tcp", "rtp unknown format"}, {"tcp", "rtp unknown payload type"},
{"tcp", "wrong ssrc"}, {"tcp", "wrong ssrc"},
{"tcp", "rtcp too big"}, {"tcp", "rtcp too big"},
} { } {
@@ -1230,8 +1230,8 @@ func TestServerRecordDecodeErrors(t *testing.T) {
case ca.name == "rtcp invalid": case ca.name == "rtcp invalid":
require.EqualError(t, ctx.Error, "rtcp: packet too short") require.EqualError(t, ctx.Error, "rtcp: packet too short")
case ca.name == "rtp unknown format": case ca.name == "rtp unknown payload type":
require.EqualError(t, ctx.Error, "received RTP packet with unknown format: 111") require.EqualError(t, ctx.Error, "received RTP packet with unknown payload type: 111")
case ca.name == "wrong ssrc": case ca.name == "wrong ssrc":
require.EqualError(t, ctx.Error, "received packet with wrong SSRC 456, expected 123") require.EqualError(t, ctx.Error, "received packet with wrong SSRC 456, expected 123")
@@ -1375,7 +1375,7 @@ func TestServerRecordDecodeErrors(t *testing.T) {
}, },
})) }))
case ca.name == "rtp unknown format": case ca.name == "rtp unknown payload type":
writeRTP(mustMarshalPacketRTP(&rtp.Packet{ writeRTP(mustMarshalPacketRTP(&rtp.Packet{
Header: rtp.Header{ Header: rtp.Header{
PayloadType: 111, PayloadType: 111,

View File

@@ -44,9 +44,7 @@ func serverParseURLForPlay(u *url.URL) (string, string, string, error) {
i := stringsReverseIndex(pathAndQuery, "/trackID=") i := stringsReverseIndex(pathAndQuery, "/trackID=")
if i < 0 { if i < 0 {
if !strings.HasSuffix(pathAndQuery, "/") { if !strings.HasSuffix(pathAndQuery, "/") {
return "", "", "", fmt.Errorf("path of a SETUP request must end with a slash. " + return "", "", "", liberrors.ErrServerPathNoSlash{}
"This typically happens when VLC fails a request, and then switches to an " +
"unsupported RTSP dialect")
} }
path, query := url.PathSplitQuery(pathAndQuery[:len(pathAndQuery)-1]) path, query := url.PathSplitQuery(pathAndQuery[:len(pathAndQuery)-1])
@@ -775,7 +773,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) (
if medi == nil { if medi == nil {
return &base.Response{ return &base.Response{
StatusCode: base.StatusBadRequest, StatusCode: base.StatusBadRequest,
}, fmt.Errorf("media not found") }, liberrors.ErrServerMediaNotFound{}
} }
if _, ok := ss.setuppedMedias[medi]; ok { if _, ok := ss.setuppedMedias[medi]; ok {

View File

@@ -1,13 +1,13 @@
package gortsplib package gortsplib
import ( import (
"fmt"
"time" "time"
"github.com/pion/rtcp" "github.com/pion/rtcp"
"github.com/pion/rtp" "github.com/pion/rtp"
"github.com/bluenviron/gortsplib/v4/pkg/format" "github.com/bluenviron/gortsplib/v4/pkg/format"
"github.com/bluenviron/gortsplib/v4/pkg/liberrors"
"github.com/bluenviron/gortsplib/v4/pkg/rtcpreceiver" "github.com/bluenviron/gortsplib/v4/pkg/rtcpreceiver"
"github.com/bluenviron/gortsplib/v4/pkg/rtplossdetector" "github.com/bluenviron/gortsplib/v4/pkg/rtplossdetector"
"github.com/bluenviron/gortsplib/v4/pkg/rtpreorderer" "github.com/bluenviron/gortsplib/v4/pkg/rtpreorderer"
@@ -65,14 +65,7 @@ func (sf *serverSessionFormat) stop() {
func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) { func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) {
packets, lost := sf.udpReorderer.Process(pkt) packets, lost := sf.udpReorderer.Process(pkt)
if lost != 0 { if lost != 0 {
sf.sm.ss.onPacketLost(fmt.Errorf("%d RTP %s lost", sf.sm.ss.onPacketLost(liberrors.ErrServerRTPPacketsLost{Lost: lost})
lost,
func() string {
if lost == 1 {
return "packet"
}
return "packets"
}()))
// do not return // do not return
} }
@@ -90,14 +83,7 @@ func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) {
func (sf *serverSessionFormat) readRTPTCP(pkt *rtp.Packet) { func (sf *serverSessionFormat) readRTPTCP(pkt *rtp.Packet) {
lost := sf.tcpLossDetector.Process(pkt) lost := sf.tcpLossDetector.Process(pkt)
if lost != 0 { if lost != 0 {
sf.sm.ss.onPacketLost(fmt.Errorf("%d RTP %s lost", sf.sm.ss.onPacketLost(liberrors.ErrServerRTPPacketsLost{Lost: lost})
lost,
func() string {
if lost == 1 {
return "packet"
}
return "packets"
}()))
// do not return // do not return
} }

View File

@@ -1,7 +1,6 @@
package gortsplib package gortsplib
import ( import (
"fmt"
"net" "net"
"sync/atomic" "sync/atomic"
"time" "time"
@@ -171,7 +170,7 @@ func (sm *serverSessionMedia) readRTCPUDPPlay(payload []byte) {
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen)) atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
if plen == (udpMaxPayloadSize + 1) { if plen == (udpMaxPayloadSize + 1) {
sm.ss.onDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP")) sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBigUDP{})
return return
} }
@@ -195,7 +194,7 @@ func (sm *serverSessionMedia) readRTPUDPRecord(payload []byte) {
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen)) atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
if plen == (udpMaxPayloadSize + 1) { if plen == (udpMaxPayloadSize + 1) {
sm.ss.onDecodeError(fmt.Errorf("RTP packet is too big to be read with UDP")) sm.ss.onDecodeError(liberrors.ErrServerRTPPacketTooBigUDP{})
return return
} }
@@ -208,7 +207,7 @@ func (sm *serverSessionMedia) readRTPUDPRecord(payload []byte) {
forma, ok := sm.formats[pkt.PayloadType] forma, ok := sm.formats[pkt.PayloadType]
if !ok { if !ok {
sm.ss.onDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType)) sm.ss.onDecodeError(liberrors.ErrServerRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
return return
} }
@@ -224,7 +223,7 @@ func (sm *serverSessionMedia) readRTCPUDPRecord(payload []byte) {
atomic.AddUint64(sm.ss.bytesReceived, uint64(plen)) atomic.AddUint64(sm.ss.bytesReceived, uint64(plen))
if plen == (udpMaxPayloadSize + 1) { if plen == (udpMaxPayloadSize + 1) {
sm.ss.onDecodeError(fmt.Errorf("RTCP packet is too big to be read with UDP")) sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBigUDP{})
return return
} }
@@ -254,8 +253,7 @@ func (sm *serverSessionMedia) readRTPTCPPlay(_ []byte) {
func (sm *serverSessionMedia) readRTCPTCPPlay(payload []byte) { func (sm *serverSessionMedia) readRTCPTCPPlay(payload []byte) {
if len(payload) > udpMaxPayloadSize { if len(payload) > udpMaxPayloadSize {
sm.ss.onDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
len(payload), udpMaxPayloadSize))
return return
} }
@@ -280,7 +278,7 @@ func (sm *serverSessionMedia) readRTPTCPRecord(payload []byte) {
forma, ok := sm.formats[pkt.PayloadType] forma, ok := sm.formats[pkt.PayloadType]
if !ok { if !ok {
sm.ss.onDecodeError(fmt.Errorf("received RTP packet with unknown format: %d", pkt.PayloadType)) sm.ss.onDecodeError(liberrors.ErrServerRTPPacketUnknownPayloadType{PayloadType: pkt.PayloadType})
return return
} }
@@ -289,8 +287,7 @@ func (sm *serverSessionMedia) readRTPTCPRecord(payload []byte) {
func (sm *serverSessionMedia) readRTCPTCPRecord(payload []byte) { func (sm *serverSessionMedia) readRTCPTCPRecord(payload []byte) {
if len(payload) > udpMaxPayloadSize { if len(payload) > udpMaxPayloadSize {
sm.ss.onDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize})
len(payload), udpMaxPayloadSize))
return return
} }

View File

@@ -1,7 +1,6 @@
package gortsplib package gortsplib
import ( import (
"fmt"
"sync" "sync"
"time" "time"
@@ -142,7 +141,7 @@ func (st *ServerStream) readerAdd(
defer st.mutex.Unlock() defer st.mutex.Unlock()
if st.closed { if st.closed {
return fmt.Errorf("stream is closed") return liberrors.ErrServerStreamClosed{}
} }
switch transport { switch transport {
@@ -251,7 +250,7 @@ func (st *ServerStream) WritePacketRTPWithNTP(medi *description.Media, pkt *rtp.
defer st.mutex.RUnlock() defer st.mutex.RUnlock()
if st.closed { if st.closed {
return fmt.Errorf("stream is closed") return liberrors.ErrServerStreamClosed{}
} }
sm := st.streamMedias[medi] sm := st.streamMedias[medi]
@@ -270,7 +269,7 @@ func (st *ServerStream) WritePacketRTCP(medi *description.Media, pkt rtcp.Packet
defer st.mutex.RUnlock() defer st.mutex.RUnlock()
if st.closed { if st.closed {
return fmt.Errorf("stream is closed") return liberrors.ErrServerStreamClosed{}
} }
sm := st.streamMedias[medi] sm := st.streamMedias[medi]