diff --git a/client.go b/client.go index d75c6839..76f473d8 100644 --- a/client.go +++ b/client.go @@ -202,9 +202,9 @@ func prepareForAnnounce( ) error { for i, m := range desc.Medias { m.Control = "trackID=" + strconv.FormatInt(int64(i), 10) - m.Secure = secure if secure { + m.Profile = headers.TransportProfileSAVP announceDataMedia := announceData[m] ssrcs := make([]uint32, len(m.Formats)) @@ -232,6 +232,8 @@ func prepareForAnnounce( } m.KeyMgmtMikey = mikeyMsg + } else { + m.Profile = headers.TransportProfileAVP } } @@ -512,8 +514,8 @@ type Client struct { lastDescribeDesc *description.Session baseURL *base.URL announceData map[*description.Media]*clientAnnounceDataMedia // record - effectiveTransport *Transport - effectiveSecure bool + setuppedTransport *Transport + setuppedProfile headers.TransportProfile backChannelSetupped bool stdChannelSetupped bool setuppedMedias map[*description.Media]*clientMedia @@ -973,7 +975,7 @@ func (c *Client) reset() { c.optionsSent = false c.useGetParameter = false c.baseURL = nil - c.effectiveTransport = nil + c.setuppedTransport = nil c.backChannelSetupped = false c.stdChannelSetupped = false c.setuppedMedias = nil @@ -1004,7 +1006,7 @@ func (c *Client) trySwitchingProtocol() error { c.reset() v := TransportTCP - c.effectiveTransport = &v + c.setuppedTransport = &v // some Hikvision cameras require a describe before a setup _, _, err := c.doDescribe(c.lastDescribeURL) @@ -1040,18 +1042,18 @@ func (c *Client) startTransportRoutines() { cm.start() } - if *c.effectiveTransport == TransportTCP { + if *c.setuppedTransport == TransportTCP { c.tcpFrame = &base.InterleavedFrame{} c.tcpBuffer = make([]byte, c.MaxPacketSize+4) } // always enable keepalives unless we are recording with TCP - if c.state == clientStatePlay || *c.effectiveTransport != TransportTCP { + if c.state == clientStatePlay || *c.setuppedTransport != TransportTCP { c.keepAliveTimer = time.NewTimer(c.keepAlivePeriod) } if c.state == clientStatePlay && c.stdChannelSetupped { - switch *c.effectiveTransport { + switch *c.setuppedTransport { case TransportUDP: c.checkTimeoutTimer = time.NewTimer(c.InitialUDPReadTimeout) c.checkTimeoutInitial = true @@ -1066,7 +1068,7 @@ func (c *Client) startTransportRoutines() { } } - if *c.effectiveTransport == TransportTCP { + if *c.setuppedTransport == TransportTCP { c.reader.setAllowInterleavedFrames(true) } } @@ -1281,8 +1283,8 @@ func (c *Client) isInTCPTimeout() bool { } func (c *Client) doCheckTimeout() error { - if *c.effectiveTransport == TransportUDP || - *c.effectiveTransport == TransportUDPMulticast { + if *c.setuppedTransport == TransportUDP || + *c.setuppedTransport == TransportUDPMulticast { if c.checkTimeoutInitial && !c.backChannelSetupped && c.Transport == nil { c.checkTimeoutInitial = false @@ -1586,20 +1588,30 @@ func (c *Client) doSetup( switch { // use transport from previous SETUP calls - case c.effectiveTransport != nil: - transport = *c.effectiveTransport - th.Secure = c.effectiveSecure + case c.setuppedTransport != nil: + transport = *c.setuppedTransport + th.Profile = c.setuppedProfile // use transport from config, secure flag from server case c.Transport != nil: transport = *c.Transport - th.Secure = medi.Secure && c.Scheme == "rtsps" + if isSecure(medi.Profile) && c.Scheme == "rtsps" { + th.Profile = headers.TransportProfileSAVP + } else { + th.Profile = headers.TransportProfileAVP + } - // try UDP if unencrypted or secure is supported by server, otherwise try TCP + // try + // - UDP if unencrypted or secure is supported by server + // - otherwise, TCP default: - th.Secure = medi.Secure && c.Scheme == "rtsps" + if isSecure(medi.Profile) && c.Scheme == "rtsps" { + th.Profile = headers.TransportProfileSAVP + } else { + th.Profile = headers.TransportProfileAVP + } - if th.Secure || c.Scheme == "rtsp" { + if th.Profile == headers.TransportProfileSAVP || c.Scheme == "rtsp" { transport = TransportUDP } else { transport = TransportTCP @@ -1609,7 +1621,7 @@ func (c *Client) doSetup( cm := &clientMedia{ c: c, media: medi, - secure: th.Secure, + secure: isSecure(th.Profile), } err = cm.initialize() if err != nil { @@ -1618,7 +1630,7 @@ func (c *Client) doSetup( switch transport { case TransportUDP, TransportUDPMulticast: - if c.Scheme == "rtsps" && !th.Secure { + if c.Scheme == "rtsps" && !isSecure(th.Profile) { cm.close() return nil, fmt.Errorf("unable to setup secure UDP") } @@ -1683,7 +1695,7 @@ func (c *Client) doSetup( header["Require"] = base.HeaderValue{"www.onvif.org/ver20/backchannel"} } - if th.Secure { + if isSecure(th.Profile) { ssrcs := make([]uint32, len(cm.formats)) n := 0 for _, cf := range cm.formats { @@ -1726,11 +1738,11 @@ func (c *Client) doSetup( // switch transport automatically if res.StatusCode == base.StatusUnsupportedTransport && - c.effectiveTransport == nil && c.Transport == nil { + c.setuppedTransport == nil && c.Transport == nil { c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{}) v := TransportTCP - c.effectiveTransport = &v - c.effectiveSecure = th.Secure + c.setuppedTransport = &v + c.setuppedProfile = th.Profile return c.doSetup(baseURL, medi, 0, 0) } @@ -1751,7 +1763,7 @@ func (c *Client) doSetup( cm.close() // switch transport automatically - if c.effectiveTransport == nil && c.Transport == nil { + if c.setuppedTransport == nil && c.Transport == nil { c.OnTransportSwitch(liberrors.ErrClientSwitchToTCP2{}) c.baseURL = baseURL @@ -1759,8 +1771,8 @@ func (c *Client) doSetup( c.reset() v := TransportTCP - c.effectiveTransport = &v - c.effectiveSecure = th.Secure + c.setuppedTransport = &v + c.setuppedProfile = th.Profile // some Hikvision cameras require a describe before a setup _, _, err = c.doDescribe(c.lastDescribeURL) @@ -1906,12 +1918,12 @@ func (c *Client) doSetup( cm.tcpChannel = thRes.InterleavedIDs[0] } - if cm.secure { - if !thRes.Secure { - cm.close() - return nil, fmt.Errorf("transport was not setupped securely") - } + if thRes.Profile != th.Profile { + cm.close() + return nil, fmt.Errorf("returned profile does not match requested profile") + } + if cm.secure { var mikeyMsg *mikey.Message // extract key-mgmt from (in order of priority): @@ -1943,9 +1955,6 @@ func (c *Client) doSetup( cm.close() return nil, err } - } else if thRes.Secure { - cm.close() - return nil, fmt.Errorf("received unexpected secure profile") } if c.setuppedMedias == nil { @@ -1955,8 +1964,8 @@ func (c *Client) doSetup( c.setuppedMedias[medi] = cm c.baseURL = baseURL - c.effectiveTransport = &transport - c.effectiveSecure = th.Secure + c.setuppedTransport = &transport + c.setuppedProfile = th.Profile if medi.IsBackChannel { c.backChannelSetupped = true @@ -2057,7 +2066,7 @@ func (c *Client) doPlay(ra *headers.Range) (*base.Response, error) { // when protocol is UDP, // open the firewall by sending empty packets to the remote part. // do this before sending the PLAY request. - if *c.effectiveTransport == TransportUDP { + if *c.setuppedTransport == TransportUDP { for _, cm := range c.setuppedMedias { if !cm.media.IsBackChannel && cm.udpRTPListener.writeAddr != nil { buf, _ := (&rtp.Packet{Header: rtp.Header{Version: 2}}).Marshal() diff --git a/client_play_test.go b/client_play_test.go index 78655669..fb1c43f4 100644 --- a/client_play_test.go +++ b/client_play_test.go @@ -399,11 +399,11 @@ func TestClientPlay(t *testing.T) { h := base.Header{} th := headers.Transport{ - Secure: inTH.Secure, + Profile: inTH.Profile, } if ca.secure == "secure" { - require.True(t, inTH.Secure) + require.Equal(t, headers.TransportProfileSAVP, inTH.Profile) var keyMgmt headers.KeyMgmt err2 = keyMgmt.Unmarshal(req.Header["KeyMgmt"]) diff --git a/client_record_test.go b/client_record_test.go index cd64dc1c..5f6166a1 100644 --- a/client_record_test.go +++ b/client_record_test.go @@ -213,7 +213,7 @@ func TestClientRecord(t *testing.T) { require.NoError(t, err2) if ca.secure == "secure" { - require.True(t, desc2.Medias[0].Secure) + require.Equal(t, headers.TransportProfileSAVP, desc2.Medias[0].Profile) _, err = mikeyToContext(desc2.Medias[0].KeyMgmtMikey) require.NoError(t, err) @@ -257,16 +257,14 @@ func TestClientRecord(t *testing.T) { th := headers.Transport{ Delivery: deliveryPtr(headers.TransportDeliveryUnicast), - Secure: inTH.Secure, + Profile: inTH.Profile, } var srtpInCtx *wrappedSRTPContext var srtpOutCtx *wrappedSRTPContext if ca.secure == "secure" { - th.Secure = true - - require.True(t, th.Secure) + require.Equal(t, inTH.Profile, headers.TransportProfileSAVP) var keyMgmt headers.KeyMgmt err = keyMgmt.Unmarshal(req.Header["KeyMgmt"]) diff --git a/pkg/description/media.go b/pkg/description/media.go index 1979ef1c..f2292812 100644 --- a/pkg/description/media.go +++ b/pkg/description/media.go @@ -15,6 +15,7 @@ import ( "github.com/bluenviron/gortsplib/v4/pkg/base" "github.com/bluenviron/gortsplib/v4/pkg/format" + "github.com/bluenviron/gortsplib/v4/pkg/headers" "github.com/bluenviron/gortsplib/v4/pkg/mikey" ) @@ -78,15 +79,20 @@ type Media struct { // Whether this media is a back channel. IsBackChannel bool - // Control attribute. - Control string - // Whether the transport is secure. + // + // Deprecated: replaced by Profile Secure bool + // RTP Profile. + Profile headers.TransportProfile + // key-mgmt attribute. KeyMgmtMikey *mikey.Message + // Control attribute. + Control string + // Formats contained into the media. Formats []format.Format } @@ -101,8 +107,14 @@ func (m *Media) Unmarshal(md *psdp.MediaDescription) error { } m.IsBackChannel = isBackChannel(md.Attributes) - m.Control = getAttribute(md.Attributes, "control") - m.Secure = slices.Contains(md.MediaName.Protos, "SAVP") + + if slices.Contains(md.MediaName.Protos, "SAVP") { + m.Secure = true + m.Profile = headers.TransportProfileSAVP + } else { + m.Secure = false + m.Profile = headers.TransportProfileAVP + } if enc := getAttribute(md.Attributes, "key-mgmt"); enc != "" { if !strings.HasPrefix(enc, "mikey ") { @@ -121,6 +133,8 @@ func (m *Media) Unmarshal(md *psdp.MediaDescription) error { } } + m.Control = getAttribute(md.Attributes, "control") + m.Formats = nil for _, payloadType := range md.MediaName.Formats { @@ -152,11 +166,16 @@ func (m Media) Marshal() *psdp.MediaDescription { // Marshal2 encodes the media in SDP format. func (m Media) Marshal2() (*psdp.MediaDescription, error) { + if m.Secure { + m.Profile = headers.TransportProfileSAVP + } + var protos []string - if !m.Secure { - protos = []string{"RTP", "AVP"} - } else { + + if m.Profile == headers.TransportProfileSAVP { protos = []string{"RTP", "SAVP"} + } else { + protos = []string{"RTP", "AVP"} } md := &psdp.MediaDescription{ diff --git a/pkg/description/session_test.go b/pkg/description/session_test.go index 713260f6..d5e5875f 100644 --- a/pkg/description/session_test.go +++ b/pkg/description/session_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/bluenviron/gortsplib/v4/pkg/format" + "github.com/bluenviron/gortsplib/v4/pkg/headers" "github.com/bluenviron/gortsplib/v4/pkg/mikey" "github.com/bluenviron/gortsplib/v4/pkg/sdp" ) @@ -726,6 +727,7 @@ var casesSession = []struct { Type: "video", Control: "trackID=0", Secure: true, + Profile: headers.TransportProfileSAVP, Formats: []format.Format{&format.H264{ PayloadTyp: 96, }}, @@ -762,6 +764,7 @@ var casesSession = []struct { Type: "video", Control: "trackID=0", Secure: true, + Profile: headers.TransportProfileSAVP, KeyMgmtMikey: &mikey.Message{ //nolint:dupl Header: mikey.Header{ Version: 1, diff --git a/pkg/headers/transport.go b/pkg/headers/transport.go index 3721ff96..9cfafd44 100644 --- a/pkg/headers/transport.go +++ b/pkg/headers/transport.go @@ -38,6 +38,15 @@ func parsePorts(val string) (*[2]int, error) { return &[2]int{0, 0}, fmt.Errorf("invalid ports (%v)", val) } +// TransportProfile is a transport profile. +type TransportProfile int + +// transport profiles. +const ( + TransportProfileAVP TransportProfile = iota + TransportProfileSAVP +) + // TransportProtocol is a transport protocol. type TransportProtocol int @@ -116,13 +125,18 @@ func (m TransportMode) String() string { // Transport is a Transport header. type Transport struct { - // protocol of the stream. - Protocol TransportProtocol - // Whether the secure variant is active. + // + // Deprecated: replaced by Profile. Secure bool - // (optional) delivery method of the stream. + // profile. + Profile TransportProfile + + // protocol. + Protocol TransportProtocol + + // (optional) delivery method. Delivery *TransportDelivery // (optional) Source IP. @@ -146,7 +160,7 @@ type Transport struct { // (optional) server ports. ServerPorts *[2]int - // (optional) SSRC of the packets of the stream. + // (optional) SSRC of packets. SSRC *uint32 // (optional) mode. @@ -175,21 +189,25 @@ func (h *Transport) Unmarshal(v base.HeaderValue) error { switch k { case "RTP/AVP", "RTP/AVP/UDP": + h.Profile = TransportProfileAVP h.Protocol = TransportProtocolUDP profileFound = true case "RTP/AVP/TCP": + h.Profile = TransportProfileAVP h.Protocol = TransportProtocolTCP profileFound = true case "RTP/SAVP", "RTP/SAVP/UDP": h.Protocol = TransportProtocolUDP h.Secure = true + h.Profile = TransportProfileSAVP profileFound = true case "RTP/SAVP/TCP": - h.Protocol = TransportProtocolTCP h.Secure = true + h.Profile = TransportProfileSAVP + h.Protocol = TransportProtocolTCP profileFound = true case "unicast": @@ -299,16 +317,20 @@ func (h *Transport) Unmarshal(v base.HeaderValue) error { func (h Transport) Marshal() base.HeaderValue { var rets []string + if h.Secure { + h.Profile = TransportProfileSAVP + } + var profile string switch { - case h.Protocol == TransportProtocolUDP && !h.Secure: + case h.Protocol == TransportProtocolUDP && h.Profile == TransportProfileAVP: profile = "RTP/AVP" - case h.Protocol == TransportProtocolTCP && !h.Secure: + case h.Protocol == TransportProtocolTCP && h.Profile == TransportProfileAVP: profile = "RTP/AVP/TCP" - case h.Protocol == TransportProtocolUDP && h.Secure: + case h.Protocol == TransportProtocolUDP && h.Profile == TransportProfileSAVP: profile = "RTP/SAVP" - case h.Protocol == TransportProtocolTCP && h.Secure: + case h.Protocol == TransportProtocolTCP && h.Profile == TransportProfileSAVP: profile = "RTP/SAVP/TCP" } diff --git a/pkg/headers/transport_test.go b/pkg/headers/transport_test.go index d537ba03..fa1fdcbe 100644 --- a/pkg/headers/transport_test.go +++ b/pkg/headers/transport_test.go @@ -175,6 +175,7 @@ var casesTransport = []struct { Transport{ Protocol: TransportProtocolUDP, Secure: true, + Profile: TransportProfileSAVP, Delivery: deliveryPtr(TransportDeliveryUnicast), ClientPorts: &[2]int{3456, 3457}, Mode: transportModePtr(TransportModePlay), @@ -187,6 +188,7 @@ var casesTransport = []struct { Transport{ Protocol: TransportProtocolTCP, Secure: true, + Profile: TransportProfileSAVP, InterleavedIDs: &[2]int{0, 1}, }, }, diff --git a/server_play_test.go b/server_play_test.go index 20a5412d..0cb572ca 100644 --- a/server_play_test.go +++ b/server_play_test.go @@ -777,7 +777,7 @@ func TestServerPlay(t *testing.T) { desc := doDescribe(t, conn, false) if ca.secure == "secure" { - require.True(t, desc.Medias[0].Secure) + require.Equal(t, headers.TransportProfileSAVP, desc.Medias[0].Profile) require.NotEmpty(t, desc.Medias[0].KeyMgmtMikey) } @@ -811,7 +811,7 @@ func TestServerPlay(t *testing.T) { var srtpOutCtx *wrappedSRTPContext if ca.secure == "secure" { - inTH.Secure = true + inTH.Profile = headers.TransportProfileSAVP key := make([]byte, srtpKeyLength) _, err = rand.Read(key) @@ -854,7 +854,7 @@ func TestServerPlay(t *testing.T) { var srtpInCtx *wrappedSRTPContext if ca.secure == "secure" { - require.True(t, th.Secure) + require.Equal(t, headers.TransportProfileSAVP, th.Profile) var keyMgmt headers.KeyMgmt err = keyMgmt.Unmarshal(res.Header["KeyMgmt"]) diff --git a/server_record_test.go b/server_record_test.go index af8a603b..193eb560 100644 --- a/server_record_test.go +++ b/server_record_test.go @@ -752,7 +752,7 @@ func TestServerRecord(t *testing.T) { } if ca.secure == "secure" { - inTH.Secure = true + inTH.Profile = headers.TransportProfileSAVP key := make([]byte, srtpKeyLength) _, err = rand.Read(key) @@ -800,7 +800,7 @@ func TestServerRecord(t *testing.T) { } if ca.secure == "secure" { - require.True(t, th.Secure) + require.Equal(t, headers.TransportProfileSAVP, th.Profile) var keyMgmt headers.KeyMgmt err = keyMgmt.Unmarshal(res.Header["KeyMgmt"]) diff --git a/server_session.go b/server_session.go index 8f192308..65d29f96 100644 --- a/server_session.go +++ b/server_session.go @@ -31,6 +31,10 @@ import ( type readFunc func([]byte) bool +func isSecure(profile headers.TransportProfile) bool { + return profile == headers.TransportProfileSAVP +} + func stringsReverseIndex(s, substr string) int { for i := len(s) - 1 - len(substr); i >= 0; i-- { if s[i:i+len(substr)] == substr { @@ -181,12 +185,12 @@ func isTransportSupported(s *Server, tr *headers.Transport) bool { } // prevent using unsecure UDP with RTSPS - if tr.Protocol == headers.TransportProtocolUDP && !tr.Secure && s.TLSConfig != nil { + if tr.Protocol == headers.TransportProtocolUDP && !isSecure(tr.Profile) && s.TLSConfig != nil { return false } // prevent using secure profiles with plain RTSP, since keys are in plain - if tr.Secure && s.TLSConfig == nil { + if isSecure(tr.Profile) && s.TLSConfig == nil { return false } @@ -420,7 +424,7 @@ type ServerSession struct { setuppedMediasOrdered []*serverSessionMedia tcpCallbackByChannel map[int]readFunc setuppedTransport *Transport - setuppedSecure bool + setuppedProfile headers.TransportProfile setuppedStream *ServerStream // play setuppedPath string setuppedQuery string @@ -503,7 +507,7 @@ func (ss *ServerSession) SetuppedTransport() *Transport { // If this is false, it does not mean that the stream is not secure, since // there are some combinations that are secure nonetheless, like RTSPS+TCP+unsecure. func (ss *ServerSession) SetuppedSecure() bool { - return ss.setuppedSecure + return isSecure(ss.setuppedProfile) } // SetuppedStream returns the stream associated with the session. @@ -1126,7 +1130,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( var srtpInCtx *wrappedSRTPContext - if inTH.Secure { + if isSecure(inTH.Profile) { var keyMgmt headers.KeyMgmt err = keyMgmt.Unmarshal(req.Header["KeyMgmt"]) if err != nil { @@ -1143,7 +1147,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( } } - if ss.setuppedTransport != nil && (*ss.setuppedTransport != transport || ss.setuppedSecure != inTH.Secure) { + if ss.setuppedTransport != nil && (*ss.setuppedTransport != transport || ss.setuppedProfile != inTH.Profile) { return &base.Response{ StatusCode: base.StatusBadRequest, }, liberrors.ErrServerMediasDifferentTransports{} @@ -1247,7 +1251,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( } ss.setuppedTransport = &transport - ss.setuppedSecure = inTH.Secure + ss.setuppedProfile = inTH.Profile if ss.state == ServerSessionStateInitial { err = stream.readerAdd(ss, @@ -1266,7 +1270,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( } th := headers.Transport{ - Secure: inTH.Secure, + Profile: inTH.Profile, } if ss.state == ServerSessionStatePrePlay { @@ -1355,7 +1359,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) ( res.Header["Transport"] = th.Marshal() - if inTH.Secure { + if isSecure(inTH.Profile) { ssrcs := make([]uint32, len(sm.formats)) n := 0 for _, sf := range sm.formats { diff --git a/server_session_format.go b/server_session_format.go index e7ac367f..a3339f68 100644 --- a/server_session_format.go +++ b/server_session_format.go @@ -159,7 +159,7 @@ func (sf *serverSessionFormat) writePacketRTP(pkt *rtp.Packet) error { pkt.SSRC = sf.localSSRC maxPlainPacketSize := sf.sm.ss.s.MaxPacketSize - if sf.sm.ss.setuppedSecure { + if isSecure(sf.sm.ss.setuppedProfile) { maxPlainPacketSize -= srtpOverhead } @@ -171,7 +171,7 @@ func (sf *serverSessionFormat) writePacketRTP(pkt *rtp.Packet) error { plain = plain[:n] var encr []byte - if sf.sm.ss.setuppedSecure { + if isSecure(sf.sm.ss.setuppedProfile) { encr = make([]byte, sf.sm.ss.s.MaxPacketSize) encr, err = sf.sm.srtpOutCtx.encryptRTP(encr, plain, &pkt.Header) if err != nil { @@ -179,7 +179,7 @@ func (sf *serverSessionFormat) writePacketRTP(pkt *rtp.Packet) error { } } - if sf.sm.ss.setuppedSecure { + if isSecure(sf.sm.ss.setuppedProfile) { return sf.writePacketRTPEncoded(encr) } return sf.writePacketRTPEncoded(plain) diff --git a/server_session_media.go b/server_session_media.go index d2d2f805..ecd82880 100644 --- a/server_session_media.go +++ b/server_session_media.go @@ -459,7 +459,7 @@ func (sm *serverSessionMedia) writePacketRTCP(pkt rtcp.Packet) error { } maxPlainPacketSize := sm.ss.s.MaxPacketSize - if sm.ss.setuppedSecure { + if isSecure(sm.ss.setuppedProfile) { maxPlainPacketSize -= srtcpOverhead } @@ -468,7 +468,7 @@ func (sm *serverSessionMedia) writePacketRTCP(pkt rtcp.Packet) error { } var encr []byte - if sm.ss.setuppedSecure { + if isSecure(sm.ss.setuppedProfile) { encr = make([]byte, sm.ss.s.MaxPacketSize) encr, err = sm.srtpOutCtx.encryptRTCP(encr, plain, nil) if err != nil { @@ -476,7 +476,7 @@ func (sm *serverSessionMedia) writePacketRTCP(pkt rtcp.Packet) error { } } - if sm.ss.setuppedSecure { + if isSecure(sm.ss.setuppedProfile) { return sm.writePacketRTCPEncoded(encr) } return sm.writePacketRTCPEncoded(plain) diff --git a/server_stream_format.go b/server_stream_format.go index 8d3667a2..607e6a43 100644 --- a/server_stream_format.go +++ b/server_stream_format.go @@ -120,7 +120,7 @@ func (sf *serverStreamFormat) writePacketRTP(pkt *rtp.Packet, ntp time.Time) err if rsm, ok := r.setuppedMedias[sf.sm.media]; ok { rsf := rsm.formats[pkt.PayloadType] - if r.setuppedSecure { + if isSecure(r.setuppedProfile) { err = rsf.writePacketRTPEncoded(encr) if err != nil { r.onStreamWriteError(err) diff --git a/server_stream_media.go b/server_stream_media.go index d87dd3a9..ae4bef16 100644 --- a/server_stream_media.go +++ b/server_stream_media.go @@ -110,7 +110,7 @@ func (sm *serverStreamMedia) writePacketRTCP(pkt rtcp.Packet) error { // send unicast for r := range sm.st.activeUnicastReaders { if sm, ok := r.setuppedMedias[sm.media]; ok { - if r.setuppedSecure { + if isSecure(r.setuppedProfile) { err = sm.writePacketRTCPEncoded(encr) if err != nil { r.onStreamWriteError(err)