improve coverage

This commit is contained in:
aler9
2022-12-09 12:31:18 +01:00
parent 8515d62735
commit e6e7f11ee1
4 changed files with 405 additions and 54 deletions

View File

@@ -1,6 +1,7 @@
package gortsplib package gortsplib
import ( import (
"bytes"
"crypto/tls" "crypto/tls"
"net" "net"
"strings" "strings"
@@ -838,6 +839,183 @@ func TestClientPublishAutomaticProtocol(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
} }
func TestClientPublishDecodeErrors(t *testing.T) {
for _, ca := range []struct {
proto string
name string
}{
{"udp", "rtcp invalid"},
{"udp", "rtcp too big"},
{"tcp", "rtcp too big"},
} {
t.Run(ca.proto+" "+ca.name, func(t *testing.T) {
errorRecv := make(chan struct{})
l, err := net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
nconn, err := l.Accept()
require.NoError(t, err)
defer nconn.Close()
conn := conn.NewConn(nconn)
req, err := conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Announce),
string(base.Setup),
string(base.Record),
}, ", ")},
},
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Announce, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Setup, req.Method)
var inTH headers.Transport
err = inTH.Unmarshal(req.Header["Transport"])
require.NoError(t, err)
th := headers.Transport{
Delivery: func() *headers.TransportDelivery {
v := headers.TransportDeliveryUnicast
return &v
}(),
}
if ca.proto == "udp" {
th.Protocol = headers.TransportProtocolUDP
th.ClientPorts = inTH.ClientPorts
th.ServerPorts = &[2]int{34556, 34557}
} else {
th.Protocol = headers.TransportProtocolTCP
th.InterleavedIDs = inTH.InterleavedIDs
}
var l1 net.PacketConn
var l2 net.PacketConn
if ca.proto == "udp" {
l1, err = net.ListenPacket("udp", "127.0.0.1:34556")
require.NoError(t, err)
defer l1.Close()
l2, err = net.ListenPacket("udp", "127.0.0.1:34557")
require.NoError(t, err)
defer l2.Close()
}
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Transport": th.Marshal(),
},
})
require.NoError(t, err)
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Record, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
})
require.NoError(t, err)
switch {
case ca.proto == "udp" && ca.name == "rtcp invalid":
l2.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[1],
})
case ca.proto == "udp" && ca.name == "rtcp too big":
l2.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[1],
})
case ca.proto == "tcp" && ca.name == "rtcp too big":
err = conn.WriteInterleavedFrame(&base.InterleavedFrame{
Channel: 1,
Payload: bytes.Repeat([]byte{0x01, 0x02}, 2000/2),
}, make([]byte, 2048))
require.NoError(t, err)
}
req, err = conn.ReadRequest()
require.NoError(t, err)
require.Equal(t, base.Teardown, req.Method)
err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK,
})
require.NoError(t, err)
}()
c := Client{
Transport: func() *Transport {
if ca.proto == "udp" {
v := TransportUDP
return &v
}
v := TransportTCP
return &v
}(),
OnDecodeError: func(err error) {
switch {
case ca.proto == "udp" && ca.name == "rtcp invalid":
require.EqualError(t, err, "rtcp: packet too short")
case ca.proto == "udp" && ca.name == "rtcp too big":
require.EqualError(t, err, "RTCP packet is too big to be read with UDP")
case ca.proto == "tcp" && ca.name == "rtcp too big":
require.EqualError(t, err, "RTCP packet size (2000) is greater than maximum allowed (1472)")
}
close(errorRecv)
},
}
track := &TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
PacketizationMode: 1,
}
err = c.StartPublishing("rtsp://localhost:8554/stream",
Tracks{track})
require.NoError(t, err)
defer c.Close()
<-errorRecv
})
}
}
func TestClientPublishRTCPReport(t *testing.T) { func TestClientPublishRTCPReport(t *testing.T) {
for _, ca := range []string{"udp", "tcp"} { for _, ca := range []string{"udp", "tcp"} {
t.Run(ca, func(t *testing.T) { t.Run(ca, func(t *testing.T) {

View File

@@ -2730,15 +2730,19 @@ func TestClientReadDifferentSource(t *testing.T) {
} }
func TestClientReadDecodeErrors(t *testing.T) { func TestClientReadDecodeErrors(t *testing.T) {
for _, ca := range []string{ for _, ca := range []struct {
"rtp invalid", proto string
"rtcp invalid", name string
"rtp packets lost", }{
"rtp too big", {"udp", "rtp invalid"},
"rtcp too big", {"udp", "rtcp invalid"},
"rtcp too big tcp", {"udp", "rtp packets lost"},
{"udp", "rtp too big"},
{"udp", "rtcp too big"},
{"tcp", "rtcp invalid"},
{"tcp", "rtcp too big"},
} { } {
t.Run(ca, func(t *testing.T) { t.Run(ca.proto+" "+ca.name, func(t *testing.T) {
errorRecv := make(chan struct{}) errorRecv := make(chan struct{})
l, err := net.Listen("tcp", "localhost:8554") l, err := net.Listen("tcp", "localhost:8554")
@@ -2758,7 +2762,6 @@ func TestClientReadDecodeErrors(t *testing.T) {
req, err := conn.ReadRequest() req, err := conn.ReadRequest()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Options, req.Method) require.Equal(t, base.Options, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/stream"), req.URL)
err = conn.WriteResponse(&base.Response{ err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
@@ -2775,7 +2778,6 @@ func TestClientReadDecodeErrors(t *testing.T) {
req, err = conn.ReadRequest() req, err = conn.ReadRequest()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Describe, req.Method) require.Equal(t, base.Describe, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/stream"), req.URL)
tracks := Tracks{&TrackGeneric{ tracks := Tracks{&TrackGeneric{
Media: "application", Media: "application",
@@ -2799,7 +2801,6 @@ func TestClientReadDecodeErrors(t *testing.T) {
req, err = conn.ReadRequest() req, err = conn.ReadRequest()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Setup, req.Method) require.Equal(t, base.Setup, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/stream/trackID=0"), req.URL)
var inTH headers.Transport var inTH headers.Transport
err = inTH.Unmarshal(req.Header["Transport"]) err = inTH.Unmarshal(req.Header["Transport"])
@@ -2812,7 +2813,7 @@ func TestClientReadDecodeErrors(t *testing.T) {
}(), }(),
} }
if ca != "rtcp too big tcp" { if ca.proto == "udp" {
th.Protocol = headers.TransportProtocolUDP th.Protocol = headers.TransportProtocolUDP
th.ClientPorts = inTH.ClientPorts th.ClientPorts = inTH.ClientPorts
th.ServerPorts = &[2]int{34556, 34557} th.ServerPorts = &[2]int{34556, 34557}
@@ -2824,7 +2825,7 @@ func TestClientReadDecodeErrors(t *testing.T) {
var l1 net.PacketConn var l1 net.PacketConn
var l2 net.PacketConn var l2 net.PacketConn
if ca != "rtcp too big tcp" { if ca.proto == "udp" {
l1, err = net.ListenPacket("udp", "127.0.0.1:34556") l1, err = net.ListenPacket("udp", "127.0.0.1:34556")
require.NoError(t, err) require.NoError(t, err)
defer l1.Close() defer l1.Close()
@@ -2845,27 +2846,26 @@ func TestClientReadDecodeErrors(t *testing.T) {
req, err = conn.ReadRequest() req, err = conn.ReadRequest()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Play, req.Method) require.Equal(t, base.Play, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/stream/"), req.URL)
err = conn.WriteResponse(&base.Response{ err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
}) })
require.NoError(t, err) require.NoError(t, err)
switch ca { //nolint:dupl switch { //nolint:dupl
case "rtp invalid": case ca.proto == "udp" && ca.name == "rtp invalid":
l1.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{ l1.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[0], Port: th.ClientPorts[0],
}) })
case "rtcp invalid": case ca.proto == "udp" && ca.name == "rtcp invalid":
l2.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{ l2.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[1], Port: th.ClientPorts[1],
}) })
case "rtp packets lost": case ca.proto == "udp" && ca.name == "rtp packets lost":
byts, _ := rtp.Packet{ byts, _ := rtp.Packet{
Header: rtp.Header{ Header: rtp.Header{
SequenceNumber: 30, SequenceNumber: 30,
@@ -2886,19 +2886,26 @@ func TestClientReadDecodeErrors(t *testing.T) {
Port: th.ClientPorts[0], Port: th.ClientPorts[0],
}) })
case "rtp too big": case ca.proto == "udp" && ca.name == "rtp too big":
l1.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{ l1.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[0], Port: th.ClientPorts[0],
}) })
case "rtcp too big": case ca.proto == "udp" && ca.name == "rtcp too big":
l2.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{ l2.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[1], Port: th.ClientPorts[1],
}) })
case "rtcp too big tcp": case ca.proto == "tcp" && ca.name == "rtcp invalid":
err = conn.WriteInterleavedFrame(&base.InterleavedFrame{
Channel: 1,
Payload: []byte{0x01, 0x02},
}, make([]byte, 2048))
require.NoError(t, err)
case ca.proto == "tcp" && ca.name == "rtcp too big":
err = conn.WriteInterleavedFrame(&base.InterleavedFrame{ err = conn.WriteInterleavedFrame(&base.InterleavedFrame{
Channel: 1, Channel: 1,
Payload: bytes.Repeat([]byte{0x01, 0x02}, 2000/2), Payload: bytes.Repeat([]byte{0x01, 0x02}, 2000/2),
@@ -2909,7 +2916,6 @@ func TestClientReadDecodeErrors(t *testing.T) {
req, err = conn.ReadRequest() req, err = conn.ReadRequest()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Teardown, req.Method) require.Equal(t, base.Teardown, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/stream/"), req.URL)
err = conn.WriteResponse(&base.Response{ err = conn.WriteResponse(&base.Response{
StatusCode: base.StatusOK, StatusCode: base.StatusOK,
@@ -2919,7 +2925,7 @@ func TestClientReadDecodeErrors(t *testing.T) {
c := Client{ c := Client{
Transport: func() *Transport { Transport: func() *Transport {
if ca != "rtcp too big tcp" { if ca.proto == "udp" {
v := TransportUDP v := TransportUDP
return &v return &v
} }
@@ -2927,18 +2933,26 @@ func TestClientReadDecodeErrors(t *testing.T) {
return &v return &v
}(), }(),
OnDecodeError: func(err error) { OnDecodeError: func(err error) {
switch ca { switch {
case "rtp invalid": case ca.proto == "udp" && ca.name == "rtp invalid":
require.EqualError(t, err, "RTP header size insufficient: 2 < 4") require.EqualError(t, err, "RTP header size insufficient: 2 < 4")
case "rtcp invalid":
case ca.proto == "udp" && ca.name == "rtcp invalid":
require.EqualError(t, err, "rtcp: packet too short") require.EqualError(t, err, "rtcp: packet too short")
case "rtp packets lost":
case ca.proto == "udp" && ca.name == "rtp packets lost":
require.EqualError(t, err, "69 RTP packet(s) lost") require.EqualError(t, err, "69 RTP packet(s) lost")
case "rtp too big":
case ca.proto == "udp" && ca.name == "rtp too big":
require.EqualError(t, err, "RTP packet is too big to be read with UDP") require.EqualError(t, err, "RTP packet is too big to be read with UDP")
case "rtcp too big":
case ca.proto == "udp" && ca.name == "rtcp too big":
require.EqualError(t, err, "RTCP packet is too big to be read with UDP") require.EqualError(t, err, "RTCP packet is too big to be read with UDP")
case "rtcp too big tcp":
case ca.proto == "tcp" && ca.name == "rtcp invalid":
require.EqualError(t, err, "rtcp: packet too short")
case ca.proto == "tcp" && ca.name == "rtcp too big":
require.EqualError(t, err, "RTCP packet size (2000) is greater than maximum allowed (1472)") require.EqualError(t, err, "RTCP packet size (2000) is greater than maximum allowed (1472)")
} }
close(errorRecv) close(errorRecv)

View File

@@ -1485,15 +1485,18 @@ func TestServerPublishUDPChangeConn(t *testing.T) {
} }
func TestServerPublishDecodeErrors(t *testing.T) { func TestServerPublishDecodeErrors(t *testing.T) {
for _, ca := range []string{ for _, ca := range []struct {
"rtp invalid", proto string
"rtcp invalid", name string
"rtp packets lost", }{
"rtp too big", {"udp", "rtp invalid"},
"rtcp too big", {"udp", "rtcp invalid"},
"rtcp too big tcp", {"udp", "rtp packets lost"},
{"udp", "rtp too big"},
{"udp", "rtcp too big"},
{"tcp", "rtcp too big"},
} { } {
t.Run(ca, func(t *testing.T) { t.Run(ca.proto+" "+ca.name, func(t *testing.T) {
errorRecv := make(chan struct{}) errorRecv := make(chan struct{})
s := &Server{ s := &Server{
@@ -1514,18 +1517,23 @@ func TestServerPublishDecodeErrors(t *testing.T) {
}, nil }, nil
}, },
onDecodeError: func(ctx *ServerHandlerOnDecodeErrorCtx) { onDecodeError: func(ctx *ServerHandlerOnDecodeErrorCtx) {
switch ca { switch {
case "rtp invalid": case ca.proto == "udp" && ca.name == "rtp invalid":
require.EqualError(t, ctx.Error, "RTP header size insufficient: 2 < 4") require.EqualError(t, ctx.Error, "RTP header size insufficient: 2 < 4")
case "rtcp invalid":
case ca.proto == "udp" && ca.name == "rtcp invalid":
require.EqualError(t, ctx.Error, "rtcp: packet too short") require.EqualError(t, ctx.Error, "rtcp: packet too short")
case "rtp packets lost":
case ca.proto == "udp" && ca.name == "rtp packets lost":
require.EqualError(t, ctx.Error, "69 RTP packet(s) lost") require.EqualError(t, ctx.Error, "69 RTP packet(s) lost")
case "rtp too big":
case ca.proto == "udp" && ca.name == "rtp too big":
require.EqualError(t, ctx.Error, "RTP packet is too big to be read with UDP") require.EqualError(t, ctx.Error, "RTP packet is too big to be read with UDP")
case "rtcp too big":
case ca.proto == "udp" && ca.name == "rtcp too big":
require.EqualError(t, ctx.Error, "RTCP packet is too big to be read with UDP") require.EqualError(t, ctx.Error, "RTCP packet is too big to be read with UDP")
case "rtcp too big tcp":
case ca.proto == "tcp" && ca.name == "rtcp too big":
require.EqualError(t, ctx.Error, "RTCP packet size (2000) is greater than maximum allowed (1472)") require.EqualError(t, ctx.Error, "RTCP packet size (2000) is greater than maximum allowed (1472)")
} }
close(errorRecv) close(errorRecv)
@@ -1577,7 +1585,7 @@ func TestServerPublishDecodeErrors(t *testing.T) {
}(), }(),
} }
if ca != "rtcp too big tcp" { if ca.proto == "udp" {
inTH.Protocol = headers.TransportProtocolUDP inTH.Protocol = headers.TransportProtocolUDP
inTH.ClientPorts = &[2]int{35466, 35467} inTH.ClientPorts = &[2]int{35466, 35467}
} else { } else {
@@ -1588,7 +1596,7 @@ func TestServerPublishDecodeErrors(t *testing.T) {
var l1 net.PacketConn var l1 net.PacketConn
var l2 net.PacketConn var l2 net.PacketConn
if ca != "rtcp too big tcp" { if ca.proto == "udp" {
l1, err = net.ListenPacket("udp", "127.0.0.1:35466") l1, err = net.ListenPacket("udp", "127.0.0.1:35466")
require.NoError(t, err) require.NoError(t, err)
defer l1.Close() defer l1.Close()
@@ -1628,20 +1636,20 @@ func TestServerPublishDecodeErrors(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode) require.Equal(t, base.StatusOK, res.StatusCode)
switch ca { //nolint:dupl switch { //nolint:dupl
case "rtp invalid": case ca.proto == "udp" && ca.name == "rtp invalid":
l1.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{ l1.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: resTH.ServerPorts[0], Port: resTH.ServerPorts[0],
}) })
case "rtcp invalid": case ca.proto == "udp" && ca.name == "rtcp invalid":
l2.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{ l2.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: resTH.ServerPorts[1], Port: resTH.ServerPorts[1],
}) })
case "rtp packets lost": case ca.proto == "udp" && ca.name == "rtp packets lost":
byts, _ := rtp.Packet{ byts, _ := rtp.Packet{
Header: rtp.Header{ Header: rtp.Header{
SequenceNumber: 30, SequenceNumber: 30,
@@ -1662,19 +1670,19 @@ func TestServerPublishDecodeErrors(t *testing.T) {
Port: resTH.ServerPorts[0], Port: resTH.ServerPorts[0],
}) })
case "rtp too big": case ca.proto == "udp" && ca.name == "rtp too big":
l1.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{ l1.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: resTH.ServerPorts[0], Port: resTH.ServerPorts[0],
}) })
case "rtcp too big": case ca.proto == "udp" && ca.name == "rtcp too big":
l2.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{ l2.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"), IP: net.ParseIP("127.0.0.1"),
Port: resTH.ServerPorts[1], Port: resTH.ServerPorts[1],
}) })
case "rtcp too big tcp": case ca.proto == "tcp" && ca.name == "rtcp too big":
err = conn.WriteInterleavedFrame(&base.InterleavedFrame{ err = conn.WriteInterleavedFrame(&base.InterleavedFrame{
Channel: 1, Channel: 1,
Payload: bytes.Repeat([]byte{0x01, 0x02}, 2000/2), Payload: bytes.Repeat([]byte{0x01, 0x02}, 2000/2),

View File

@@ -1,6 +1,7 @@
package gortsplib package gortsplib
import ( import (
"bytes"
"crypto/tls" "crypto/tls"
"net" "net"
"strconv" "strconv"
@@ -716,6 +717,156 @@ func TestServerRead(t *testing.T) {
} }
} }
func TestServerReadDecodeErrors(t *testing.T) {
for _, ca := range []struct {
proto string
name string
}{
{"udp", "rtcp invalid"},
{"udp", "rtcp too big"},
{"tcp", "rtcp too big"},
} {
t.Run(ca.proto+" "+ca.name, func(t *testing.T) {
errorRecv := make(chan struct{})
track := &TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
PacketizationMode: 1,
}
stream := NewServerStream(Tracks{track})
defer stream.Close()
s := &Server{
Handler: &testServerHandler{
onSetup: func(ctx *ServerHandlerOnSetupCtx) (*base.Response, *ServerStream, error) {
return &base.Response{
StatusCode: base.StatusOK,
}, stream, nil
},
onPlay: func(ctx *ServerHandlerOnPlayCtx) (*base.Response, error) {
return &base.Response{
StatusCode: base.StatusOK,
}, nil
},
onDecodeError: func(ctx *ServerHandlerOnDecodeErrorCtx) {
switch {
case ca.proto == "udp" && ca.name == "rtcp invalid":
require.EqualError(t, ctx.Error, "rtcp: packet too short")
case ca.proto == "udp" && ca.name == "rtcp too big":
require.EqualError(t, ctx.Error, "RTCP packet is too big to be read with UDP")
case ca.proto == "tcp" && ca.name == "rtcp too big":
require.EqualError(t, ctx.Error, "RTCP packet size (2000) is greater than maximum allowed (1472)")
}
close(errorRecv)
},
},
UDPRTPAddress: "127.0.0.1:8000",
UDPRTCPAddress: "127.0.0.1:8001",
RTSPAddress: "localhost:8554",
}
err := s.Start()
require.NoError(t, err)
defer s.Close()
nconn, err := net.Dial("tcp", "localhost:8554")
require.NoError(t, err)
defer nconn.Close()
conn := conn.NewConn(nconn)
inTH := &headers.Transport{
Mode: func() *headers.TransportMode {
v := headers.TransportModePlay
return &v
}(),
Delivery: func() *headers.TransportDelivery {
v := headers.TransportDeliveryUnicast
return &v
}(),
}
if ca.proto == "udp" {
inTH.Protocol = headers.TransportProtocolUDP
inTH.ClientPorts = &[2]int{35466, 35467}
} else {
inTH.Protocol = headers.TransportProtocolTCP
inTH.InterleavedIDs = &[2]int{0, 1}
}
res, err := writeReqReadRes(conn, base.Request{
Method: base.Setup,
URL: mustParseURL("rtsp://localhost:8554/teststream/trackID=0"),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
"Transport": inTH.Marshal(),
},
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
var resTH headers.Transport
err = resTH.Unmarshal(res.Header["Transport"])
require.NoError(t, err)
var l1 net.PacketConn
var l2 net.PacketConn
if ca.proto == "udp" {
l1, err = net.ListenPacket("udp", "127.0.0.1:35466")
require.NoError(t, err)
defer l1.Close()
l2, err = net.ListenPacket("udp", "127.0.0.1:35467")
require.NoError(t, err)
defer l2.Close()
}
var sx headers.Session
err = sx.Unmarshal(res.Header["Session"])
require.NoError(t, err)
res, err = writeReqReadRes(conn, base.Request{
Method: base.Play,
URL: mustParseURL("rtsp://localhost:8554/teststream"),
Header: base.Header{
"CSeq": base.HeaderValue{"2"},
"Session": base.HeaderValue{sx.Session},
},
})
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
switch { //nolint:dupl
case ca.proto == "udp" && ca.name == "rtcp invalid":
l2.WriteTo([]byte{0x01, 0x02}, &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: resTH.ServerPorts[1],
})
case ca.proto == "udp" && ca.name == "rtcp too big":
l2.WriteTo(bytes.Repeat([]byte{0x01, 0x02}, 2000/2), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: resTH.ServerPorts[1],
})
case ca.proto == "tcp" && ca.name == "rtcp too big":
err = conn.WriteInterleavedFrame(&base.InterleavedFrame{
Channel: 1,
Payload: bytes.Repeat([]byte{0x01, 0x02}, 2000/2),
}, make([]byte, 2048))
require.NoError(t, err)
}
<-errorRecv
})
}
}
func TestServerReadRTCPReport(t *testing.T) { func TestServerReadRTCPReport(t *testing.T) {
for _, ca := range []string{"udp", "tcp"} { for _, ca := range []string{"udp", "tcp"} {
t.Run(ca, func(t *testing.T) { t.Run(ca, func(t *testing.T) {