From 4495e7d6892ef5dc002eb188601839f861a55135 Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Sun, 10 Sep 2023 17:32:16 +0200 Subject: [PATCH] move most errors into pkg/liberrors (#408) --- client.go | 12 ++--- client_format.go | 19 +------- client_media.go | 17 +++---- client_play_test.go | 10 ++-- pkg/liberrors/client.go | 91 +++++++++++++++++++++++++++++++++++++ pkg/liberrors/server.go | 98 +++++++++++++++++++--------------------- server.go | 2 +- server_record_test.go | 10 ++-- server_session.go | 6 +-- server_session_format.go | 20 ++------ server_session_media.go | 17 +++---- server_stream.go | 7 ++- 12 files changed, 178 insertions(+), 131 deletions(-) diff --git a/client.go b/client.go index e97f4ec6..e4226626 100644 --- a/client.go +++ b/client.go @@ -713,7 +713,7 @@ func (c *Client) checkState(allowed map[clientState]struct{}) error { } func (c *Client) trySwitchingProtocol() error { - c.OnTransportSwitch(fmt.Errorf("no UDP packets received, switching to TCP")) + c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP{}) prevConnURL := c.connURL 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) { - c.OnTransportSwitch(fmt.Errorf("switching to TCP because server requested it")) + c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{}) 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) if err != nil { - return nil, fmt.Errorf("unable to setup authentication: %s", err) + return nil, liberrors.ErrClientAuthSetup{Err: err} } c.sender = sender @@ -1142,13 +1142,13 @@ func (c *Client) doDescribe(u *url.URL) (*description.Session, *base.Response, e var ssd sdp.SessionDescription err = ssd.Unmarshal(res.Body) if err != nil { - return nil, nil, err + return nil, nil, liberrors.ErrClientSDPInvalid{Err: err} } var desc description.Session err = desc.Unmarshal(&ssd) if err != nil { - return nil, nil, err + return nil, nil, liberrors.ErrClientSDPInvalid{Err: err} } baseURL, err := findBaseURL(&ssd, res, u) @@ -1348,7 +1348,7 @@ func (c *Client) doSetup( // switch transport automatically if res.StatusCode == base.StatusUnsupportedTransport && c.effectiveTransport == nil { - c.OnTransportSwitch(fmt.Errorf("switching to TCP because server requested it")) + c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{}) v := TransportTCP c.effectiveTransport = &v return c.doSetup(baseURL, medi, 0, 0) diff --git a/client_format.go b/client_format.go index d07b4b88..922093fe 100644 --- a/client_format.go +++ b/client_format.go @@ -1,7 +1,6 @@ package gortsplib import ( - "fmt" "time" "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) { packets, lost := ct.udpReorderer.Process(pkt) if lost != 0 { - ct.cm.c.OnPacketLost(fmt.Errorf("%d RTP %s lost", - lost, - func() string { - if lost == 1 { - return "packet" - } - return "packets" - }())) + ct.cm.c.OnPacketLost(liberrors.ErrClientRTPPacketsLost{Lost: lost}) // do not return } @@ -122,14 +114,7 @@ func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) { func (ct *clientFormat) readRTPTCP(pkt *rtp.Packet) { lost := ct.tcpLossDetector.Process(pkt) if lost != 0 { - ct.cm.c.OnPacketLost(fmt.Errorf("%d RTP %s lost", - lost, - func() string { - if lost == 1 { - return "packet" - } - return "packets" - }())) + ct.cm.c.OnPacketLost(liberrors.ErrClientRTPPacketsLost{Lost: lost}) // do not return } diff --git a/client_media.go b/client_media.go index e2eca9fd..a10dc9fb 100644 --- a/client_media.go +++ b/client_media.go @@ -1,7 +1,6 @@ package gortsplib import ( - "fmt" "sync/atomic" "time" @@ -193,7 +192,7 @@ func (cm *clientMedia) readRTPTCPPlay(payload []byte) { forma, ok := cm.formats[pkt.PayloadType] 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 } @@ -205,8 +204,7 @@ func (cm *clientMedia) readRTCPTCPPlay(payload []byte) { atomic.StoreInt64(cm.c.tcpLastFrameTime, now.Unix()) if len(payload) > udpMaxPayloadSize { - cm.c.OnDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", - len(payload), udpMaxPayloadSize)) + cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize}) return } @@ -233,8 +231,7 @@ func (cm *clientMedia) readRTPTCPRecord(_ []byte) { func (cm *clientMedia) readRTCPTCPRecord(payload []byte) { if len(payload) > udpMaxPayloadSize { - cm.c.OnDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", - len(payload), udpMaxPayloadSize)) + cm.c.OnDecodeError(liberrors.ErrClientRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize}) return } @@ -255,7 +252,7 @@ func (cm *clientMedia) readRTPUDPPlay(payload []byte) { atomic.AddUint64(cm.c.BytesReceived, uint64(plen)) 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 } @@ -268,7 +265,7 @@ func (cm *clientMedia) readRTPUDPPlay(payload []byte) { forma, ok := cm.formats[pkt.PayloadType] 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 } @@ -282,7 +279,7 @@ func (cm *clientMedia) readRTCPUDPPlay(payload []byte) { atomic.AddUint64(cm.c.BytesReceived, uint64(plen)) 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 } @@ -313,7 +310,7 @@ func (cm *clientMedia) readRTCPUDPRecord(payload []byte) { atomic.AddUint64(cm.c.BytesReceived, uint64(plen)) 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 } diff --git a/client_play_test.go b/client_play_test.go index 759b91c6..0cc64bdb 100644 --- a/client_play_test.go +++ b/client_play_test.go @@ -2896,13 +2896,13 @@ func TestClientPlayDecodeErrors(t *testing.T) { {"udp", "rtp invalid"}, {"udp", "rtcp invalid"}, {"udp", "rtp packets lost"}, - {"udp", "rtp unknown format"}, + {"udp", "rtp unknown payload type"}, {"udp", "wrong ssrc"}, {"udp", "rtcp too big"}, {"udp", "rtp too big"}, {"tcp", "rtp invalid"}, {"tcp", "rtcp invalid"}, - {"tcp", "rtp unknown format"}, + {"tcp", "rtp unknown payload type"}, {"tcp", "wrong ssrc"}, {"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{ Header: rtp.Header{ PayloadType: 111, @@ -3140,8 +3140,8 @@ func TestClientPlayDecodeErrors(t *testing.T) { case ca.name == "rtcp invalid": require.EqualError(t, err, "rtcp: packet too short") - case ca.name == "rtp unknown format": - require.EqualError(t, err, "received RTP packet with unknown format: 111") + case ca.name == "rtp unknown payload type": + require.EqualError(t, err, "received RTP packet with unknown payload type: 111") case ca.name == "wrong ssrc": require.EqualError(t, err, "received packet with wrong SSRC 456, expected 123") diff --git a/pkg/liberrors/client.go b/pkg/liberrors/client.go index 471d6f83..521eb335 100644 --- a/pkg/liberrors/client.go +++ b/pkg/liberrors/client.go @@ -256,3 +256,94 @@ type ErrClientWriteQueueFull struct{} func (e ErrClientWriteQueueFull) Error() string { 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) +} diff --git a/pkg/liberrors/server.go b/pkg/liberrors/server.go index 4fd602bd..20b60023 100644 --- a/pkg/liberrors/server.go +++ b/pkg/liberrors/server.go @@ -4,17 +4,11 @@ import ( "fmt" "net" - "github.com/bluenviron/gortsplib/v4/pkg/base" "github.com/bluenviron/gortsplib/v4/pkg/headers" ) // ErrServerTerminated is an error that can be returned by a server. -type ErrServerTerminated struct{} - -// Error implements the error interface. -func (e ErrServerTerminated) Error() string { - return "terminated" -} +type ErrServerTerminated = ErrClientTerminated // ErrServerSessionNotFound is an error that can be returned by a server. type ErrServerSessionNotFound struct{} @@ -61,42 +55,16 @@ func (e ErrServerInvalidPath) Error() string { } // ErrServerContentTypeMissing is an error that can be returned by a server. -type ErrServerContentTypeMissing struct{} - -// Error implements the error interface. -func (e ErrServerContentTypeMissing) Error() string { - return "Content-Type header is missing" -} +type ErrServerContentTypeMissing = ErrClientContentTypeMissing // ErrServerContentTypeUnsupported is an error that can be returned by a server. -type ErrServerContentTypeUnsupported struct { - CT base.HeaderValue -} - -// Error implements the error interface. -func (e ErrServerContentTypeUnsupported) Error() string { - return fmt.Sprintf("unsupported Content-Type header '%v'", e.CT) -} +type ErrServerContentTypeUnsupported = ErrClientContentTypeUnsupported // ErrServerSDPInvalid is an error that can be returned by a server. -type ErrServerSDPInvalid struct { - Err error -} - -// Error implements the error interface. -func (e ErrServerSDPInvalid) Error() string { - return fmt.Sprintf("invalid SDP: %v", e.Err) -} +type ErrServerSDPInvalid = ErrClientSDPInvalid // ErrServerTransportHeaderInvalid is an error that can be returned by a server. -type ErrServerTransportHeaderInvalid struct { - Err error -} - -// Error implements the error interface. -func (e ErrServerTransportHeaderInvalid) Error() string { - return fmt.Sprintf("invalid transport header: %v", e.Err) -} +type ErrServerTransportHeaderInvalid = ErrClientTransportHeaderInvalid // ErrServerMediaAlreadySetup is an error that can be returned by a server. type ErrServerMediaAlreadySetup struct{} @@ -106,6 +74,14 @@ func (e ErrServerMediaAlreadySetup) Error() string { 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. type ErrServerTransportHeaderInvalidMode struct { Mode headers.TransportMode @@ -245,25 +221,43 @@ func (e ErrServerSessionNotInUse) Error() string { } // ErrServerUnexpectedFrame is an error that can be returned by a server. -type ErrServerUnexpectedFrame struct{} - -// Error implements the error interface. -func (e ErrServerUnexpectedFrame) Error() string { - return "received unexpected interleaved frame" -} +type ErrServerUnexpectedFrame = ErrClientUnexpectedFrame // ErrServerUnexpectedResponse is an error that can be returned by a server. -type ErrServerUnexpectedResponse struct{} - -// Error implements the error interface. -func (e ErrServerUnexpectedResponse) Error() string { - return "received unexpected response" -} +type ErrServerUnexpectedResponse = ErrClientUnexpectedResponse // 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. -func (e ErrServerWriteQueueFull) Error() string { - return "write queue is full" +func (e ErrServerStreamClosed) Error() string { + 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" } diff --git a/server.go b/server.go index cfed1296..05e88617 100644 --- a/server.go +++ b/server.go @@ -459,7 +459,7 @@ func (s *Server) getMulticastIP() (net.IP, error) { return <-res, nil case <-s.ctx.Done(): - return nil, fmt.Errorf("terminated") + return nil, liberrors.ErrServerTerminated{} } } diff --git a/server_record_test.go b/server_record_test.go index fd05cabb..fe85f606 100644 --- a/server_record_test.go +++ b/server_record_test.go @@ -1188,13 +1188,13 @@ func TestServerRecordDecodeErrors(t *testing.T) { {"udp", "rtp invalid"}, {"udp", "rtcp invalid"}, {"udp", "rtp packets lost"}, - {"udp", "rtp unknown format"}, + {"udp", "rtp unknown payload type"}, {"udp", "wrong ssrc"}, {"udp", "rtcp too big"}, {"udp", "rtp too big"}, {"tcp", "rtcp invalid"}, {"tcp", "rtp packets lost"}, - {"tcp", "rtp unknown format"}, + {"tcp", "rtp unknown payload type"}, {"tcp", "wrong ssrc"}, {"tcp", "rtcp too big"}, } { @@ -1230,8 +1230,8 @@ func TestServerRecordDecodeErrors(t *testing.T) { case ca.name == "rtcp invalid": require.EqualError(t, ctx.Error, "rtcp: packet too short") - case ca.name == "rtp unknown format": - require.EqualError(t, ctx.Error, "received RTP packet with unknown format: 111") + case ca.name == "rtp unknown payload type": + require.EqualError(t, ctx.Error, "received RTP packet with unknown payload type: 111") case ca.name == "wrong ssrc": 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{ Header: rtp.Header{ PayloadType: 111, diff --git a/server_session.go b/server_session.go index 308cee8f..615579eb 100644 --- a/server_session.go +++ b/server_session.go @@ -44,9 +44,7 @@ func serverParseURLForPlay(u *url.URL) (string, string, string, error) { i := stringsReverseIndex(pathAndQuery, "/trackID=") if i < 0 { if !strings.HasSuffix(pathAndQuery, "/") { - return "", "", "", fmt.Errorf("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") + return "", "", "", liberrors.ErrServerPathNoSlash{} } path, query := url.PathSplitQuery(pathAndQuery[:len(pathAndQuery)-1]) @@ -775,7 +773,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( if medi == nil { return &base.Response{ StatusCode: base.StatusBadRequest, - }, fmt.Errorf("media not found") + }, liberrors.ErrServerMediaNotFound{} } if _, ok := ss.setuppedMedias[medi]; ok { diff --git a/server_session_format.go b/server_session_format.go index 58251ad4..658683f4 100644 --- a/server_session_format.go +++ b/server_session_format.go @@ -1,13 +1,13 @@ package gortsplib import ( - "fmt" "time" "github.com/pion/rtcp" "github.com/pion/rtp" "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/rtplossdetector" "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) { packets, lost := sf.udpReorderer.Process(pkt) if lost != 0 { - sf.sm.ss.onPacketLost(fmt.Errorf("%d RTP %s lost", - lost, - func() string { - if lost == 1 { - return "packet" - } - return "packets" - }())) + sf.sm.ss.onPacketLost(liberrors.ErrServerRTPPacketsLost{Lost: lost}) // do not return } @@ -90,14 +83,7 @@ func (sf *serverSessionFormat) readRTPUDP(pkt *rtp.Packet, now time.Time) { func (sf *serverSessionFormat) readRTPTCP(pkt *rtp.Packet) { lost := sf.tcpLossDetector.Process(pkt) if lost != 0 { - sf.sm.ss.onPacketLost(fmt.Errorf("%d RTP %s lost", - lost, - func() string { - if lost == 1 { - return "packet" - } - return "packets" - }())) + sf.sm.ss.onPacketLost(liberrors.ErrServerRTPPacketsLost{Lost: lost}) // do not return } diff --git a/server_session_media.go b/server_session_media.go index a7bdc03a..3e5a2f74 100644 --- a/server_session_media.go +++ b/server_session_media.go @@ -1,7 +1,6 @@ package gortsplib import ( - "fmt" "net" "sync/atomic" "time" @@ -171,7 +170,7 @@ func (sm *serverSessionMedia) readRTCPUDPPlay(payload []byte) { atomic.AddUint64(sm.ss.bytesReceived, uint64(plen)) 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 } @@ -195,7 +194,7 @@ func (sm *serverSessionMedia) readRTPUDPRecord(payload []byte) { atomic.AddUint64(sm.ss.bytesReceived, uint64(plen)) 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 } @@ -208,7 +207,7 @@ func (sm *serverSessionMedia) readRTPUDPRecord(payload []byte) { forma, ok := sm.formats[pkt.PayloadType] 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 } @@ -224,7 +223,7 @@ func (sm *serverSessionMedia) readRTCPUDPRecord(payload []byte) { atomic.AddUint64(sm.ss.bytesReceived, uint64(plen)) 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 } @@ -254,8 +253,7 @@ func (sm *serverSessionMedia) readRTPTCPPlay(_ []byte) { func (sm *serverSessionMedia) readRTCPTCPPlay(payload []byte) { if len(payload) > udpMaxPayloadSize { - sm.ss.onDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", - len(payload), udpMaxPayloadSize)) + sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize}) return } @@ -280,7 +278,7 @@ func (sm *serverSessionMedia) readRTPTCPRecord(payload []byte) { forma, ok := sm.formats[pkt.PayloadType] 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 } @@ -289,8 +287,7 @@ func (sm *serverSessionMedia) readRTPTCPRecord(payload []byte) { func (sm *serverSessionMedia) readRTCPTCPRecord(payload []byte) { if len(payload) > udpMaxPayloadSize { - sm.ss.onDecodeError(fmt.Errorf("RTCP packet size (%d) is greater than maximum allowed (%d)", - len(payload), udpMaxPayloadSize)) + sm.ss.onDecodeError(liberrors.ErrServerRTCPPacketTooBig{L: len(payload), Max: udpMaxPayloadSize}) return } diff --git a/server_stream.go b/server_stream.go index 2d58f5af..507a2484 100644 --- a/server_stream.go +++ b/server_stream.go @@ -1,7 +1,6 @@ package gortsplib import ( - "fmt" "sync" "time" @@ -142,7 +141,7 @@ func (st *ServerStream) readerAdd( defer st.mutex.Unlock() if st.closed { - return fmt.Errorf("stream is closed") + return liberrors.ErrServerStreamClosed{} } switch transport { @@ -251,7 +250,7 @@ func (st *ServerStream) WritePacketRTPWithNTP(medi *description.Media, pkt *rtp. defer st.mutex.RUnlock() if st.closed { - return fmt.Errorf("stream is closed") + return liberrors.ErrServerStreamClosed{} } sm := st.streamMedias[medi] @@ -270,7 +269,7 @@ func (st *ServerStream) WritePacketRTCP(medi *description.Media, pkt rtcp.Packet defer st.mutex.RUnlock() if st.closed { - return fmt.Errorf("stream is closed") + return liberrors.ErrServerStreamClosed{} } sm := st.streamMedias[medi]