From 29f7f1a57d8b4366d68c20eec090a7a5c641ff38 Mon Sep 17 00:00:00 2001 From: fmcloudconsulting <170678386+fmcloudconsulting@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:50:35 +0100 Subject: [PATCH 1/6] feat: accept rtsp client without interleaved parameter --- pkg/rtsp/server.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index c96125a2..b59d9abf 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -148,25 +148,30 @@ func (c *Conn) Accept() error { Request: req, } - const transport = "RTP/AVP/TCP;unicast;interleaved=" - if tr = core.Between(tr, "interleaved=", ";"); tr != "" { - c.session = core.RandString(8, 10) - c.state = StateSetup + const transport = "RTP/AVP/TCP;unicast" - if c.mode == core.ModePassiveConsumer { - if i := reqTrackID(req); i >= 0 && i < len(c.Senders) { - // mark sender as SETUP - c.Senders[i].Media.ID = MethodSetup - tr = fmt.Sprintf("%d-%d", i*2, i*2+1) - res.Header.Set("Transport", transport+tr) + c.session = core.RandString(8, 10) + c.state = StateSetup + + if c.mode == core.ModePassiveConsumer { + if i := reqTrackID(req); i >= 0 && i < len(c.Senders) { + // mark sender as SETUP + c.Senders[i].Media.ID = MethodSetup + interleaved := fmt.Sprintf("%d-%d", i*2, i*2+1) + + // Check if transport already contains the 'interleaved' parameter + if strings.Contains(transport, "interleaved=") { + // If so, just update the interleaved value + res.Header.Set("Transport", strings.Replace(transport, "interleaved=[^;]*", "interleaved="+interleaved, 1)) } else { - res.Status = "400 Bad Request" + // Otherwise, append the interleaved parameter + res.Header.Set("Transport", transport+";interleaved="+interleaved) } } else { - res.Header.Set("Transport", transport+tr) + res.Status = "400 Bad Request" } } else { - res.Status = "461 Unsupported transport" + res.Header.Set("Transport", tr) } if err = c.WriteResponse(res); err != nil { From fd125ecc683daf8f526673aca3ead91e53540e37 Mon Sep 17 00:00:00 2001 From: fmcloudconsulting <170678386+fmcloudconsulting@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:28:13 +0100 Subject: [PATCH 2/6] fix: return 461 if client requested an invalid transport method --- pkg/rtsp/server.go | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index b59d9abf..f5967c5a 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -150,28 +150,35 @@ func (c *Conn) Accept() error { const transport = "RTP/AVP/TCP;unicast" - c.session = core.RandString(8, 10) - c.state = StateSetup + // Test if client requests unicast with TCP transport, otherwise return 461 Transport not supported + // This allows smart clients who initially requested UDP to fall back on TCP transport. + if strings.HasPrefix(tr, transport) { + + c.session = core.RandString(8, 10) + c.state = StateSetup - if c.mode == core.ModePassiveConsumer { - if i := reqTrackID(req); i >= 0 && i < len(c.Senders) { - // mark sender as SETUP - c.Senders[i].Media.ID = MethodSetup - interleaved := fmt.Sprintf("%d-%d", i*2, i*2+1) - - // Check if transport already contains the 'interleaved' parameter - if strings.Contains(transport, "interleaved=") { - // If so, just update the interleaved value - res.Header.Set("Transport", strings.Replace(transport, "interleaved=[^;]*", "interleaved="+interleaved, 1)) + if c.mode == core.ModePassiveConsumer { + if i := reqTrackID(req); i >= 0 && i < len(c.Senders) { + // mark sender as SETUP + c.Senders[i].Media.ID = MethodSetup + interleaved := fmt.Sprintf("%d-%d", i*2, i*2+1) + + // Check if transport already contains the 'interleaved' parameter + if strings.Contains(transport, "interleaved=") { + // If so, just update the interleaved value + res.Header.Set("Transport", strings.Replace(transport, "interleaved=[^;]*", "interleaved="+interleaved, 1)) + } else { + // Otherwise, append the interleaved parameter + res.Header.Set("Transport", transport+";interleaved="+interleaved) + } } else { - // Otherwise, append the interleaved parameter - res.Header.Set("Transport", transport+";interleaved="+interleaved) + res.Status = "400 Bad Request" } } else { - res.Status = "400 Bad Request" + res.Header.Set("Transport", tr) } - } else { - res.Header.Set("Transport", tr) + else { + res.Status = "461 Unsupported transport" } if err = c.WriteResponse(res); err != nil { From d881755503b4c30b338fd3924fd51cdeb1b460c7 Mon Sep 17 00:00:00 2001 From: fmcloudconsulting <170678386+fmcloudconsulting@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:30:10 +0100 Subject: [PATCH 3/6] chore: lint --- pkg/rtsp/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index f5967c5a..d9a40881 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -156,7 +156,7 @@ func (c *Conn) Accept() error { c.session = core.RandString(8, 10) c.state = StateSetup - + if c.mode == core.ModePassiveConsumer { if i := reqTrackID(req); i >= 0 && i < len(c.Senders) { // mark sender as SETUP From 4b80b2c233be089fb8ced21bc05f2c493cc9a3d9 Mon Sep 17 00:00:00 2001 From: fmcloudconsulting <170678386+fmcloudconsulting@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:36:18 +0100 Subject: [PATCH 4/6] fix: typo --- pkg/rtsp/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index d9a40881..88d24e27 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -177,7 +177,7 @@ func (c *Conn) Accept() error { } else { res.Header.Set("Transport", tr) } - else { + } else { res.Status = "461 Unsupported transport" } From 6fa352f407c3466edafeffab1e56b0e84740f2d3 Mon Sep 17 00:00:00 2001 From: fmcloudconsulting <170678386+fmcloudconsulting@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:06:15 +0100 Subject: [PATCH 5/6] fix: don't require unicast param and fix typo (tr instead of transport) --- pkg/rtsp/server.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index 88d24e27..cefaef1d 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -148,11 +148,9 @@ func (c *Conn) Accept() error { Request: req, } - const transport = "RTP/AVP/TCP;unicast" - - // Test if client requests unicast with TCP transport, otherwise return 461 Transport not supported + // Test if client requests TCP transport, otherwise return 461 Transport not supported // This allows smart clients who initially requested UDP to fall back on TCP transport. - if strings.HasPrefix(tr, transport) { + if strings.HasPrefix(tr, "RTP/AVP/TCP") { c.session = core.RandString(8, 10) c.state = StateSetup @@ -163,13 +161,13 @@ func (c *Conn) Accept() error { c.Senders[i].Media.ID = MethodSetup interleaved := fmt.Sprintf("%d-%d", i*2, i*2+1) - // Check if transport already contains the 'interleaved' parameter - if strings.Contains(transport, "interleaved=") { + // Check if tr already contains the 'interleaved' parameter + if strings.Contains(tr, "interleaved=") { // If so, just update the interleaved value - res.Header.Set("Transport", strings.Replace(transport, "interleaved=[^;]*", "interleaved="+interleaved, 1)) + res.Header.Set("Transport", strings.Replace(tr, "interleaved=[^;]*", "interleaved="+interleaved, 1)) } else { // Otherwise, append the interleaved parameter - res.Header.Set("Transport", transport+";interleaved="+interleaved) + res.Header.Set("Transport", tr+";interleaved="+interleaved) } } else { res.Status = "400 Bad Request" From 637e65e5a059defcdb9ce80eaffec00a01ae3d5d Mon Sep 17 00:00:00 2001 From: Alex X Date: Tue, 18 Feb 2025 12:49:33 +0300 Subject: [PATCH 6/6] Code refactoring for RTSP transport header processing --- pkg/rtsp/server.go | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index cefaef1d..29f97b5c 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -141,17 +141,14 @@ func (c *Conn) Accept() error { } case MethodSetup: - tr := req.Header.Get("Transport") - res := &tcp.Response{ Header: map[string][]string{}, Request: req, } // Test if client requests TCP transport, otherwise return 461 Transport not supported - // This allows smart clients who initially requested UDP to fall back on TCP transport. - if strings.HasPrefix(tr, "RTP/AVP/TCP") { - + // This allows smart clients who initially requested UDP to fall back on TCP transport + if tr := req.Header.Get("Transport"); strings.HasPrefix(tr, "RTP/AVP/TCP") { c.session = core.RandString(8, 10) c.state = StateSetup @@ -159,16 +156,8 @@ func (c *Conn) Accept() error { if i := reqTrackID(req); i >= 0 && i < len(c.Senders) { // mark sender as SETUP c.Senders[i].Media.ID = MethodSetup - interleaved := fmt.Sprintf("%d-%d", i*2, i*2+1) - - // Check if tr already contains the 'interleaved' parameter - if strings.Contains(tr, "interleaved=") { - // If so, just update the interleaved value - res.Header.Set("Transport", strings.Replace(tr, "interleaved=[^;]*", "interleaved="+interleaved, 1)) - } else { - // Otherwise, append the interleaved parameter - res.Header.Set("Transport", tr+";interleaved="+interleaved) - } + tr = fmt.Sprintf("RTP/AVP/TCP;unicast;interleaved=%d-%d", i*2, i*2+1) + res.Header.Set("Transport", tr) } else { res.Status = "400 Bad Request" }