client: support servers which don't provide UDP ports (#21)

This commit is contained in:
aler9
2021-01-20 23:23:35 +01:00
parent c6e0294e1c
commit b9dfe1b310
4 changed files with 50 additions and 10 deletions

View File

@@ -39,6 +39,15 @@ type ClientConf struct {
// It defaults to &tls.Config{InsecureSkipVerify:true} // It defaults to &tls.Config{InsecureSkipVerify:true}
TLSConfig *tls.Config TLSConfig *tls.Config
// disable being redirected to other servers, that can happen during Describe().
// It defaults to false.
RedirectDisable bool
// enable communication with servers which don't provide server ports.
// this can be a security issue.
// It defaults to false.
AnyPortEnable bool
// timeout of read operations. // timeout of read operations.
// It defaults to 10 seconds. // It defaults to 10 seconds.
ReadTimeout time.Duration ReadTimeout time.Duration
@@ -47,10 +56,6 @@ type ClientConf struct {
// It defaults to 10 seconds. // It defaults to 10 seconds.
WriteTimeout time.Duration WriteTimeout time.Duration
// disable being redirected to other servers, that can happen during Describe().
// It defaults to false.
RedirectDisable bool
// read buffer count. // read buffer count.
// If greater than 1, allows to pass buffers to routines different than the one // If greater than 1, allows to pass buffers to routines different than the one
// that is reading frames. // that is reading frames.

View File

@@ -220,10 +220,43 @@ func TestClientDialReadZeroServerPorts(t *testing.T) {
}, },
}.Write(bconn.Writer) }.Write(bconn.Writer)
require.NoError(t, err) require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Play, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
}.Write(bconn.Writer)
require.NoError(t, err)
time.Sleep(1 * time.Second)
l1, err := net.ListenPacket("udp", "localhost:0")
require.NoError(t, err)
defer l1.Close()
l1.WriteTo([]byte("\x00\x00\x00\x00"), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[0],
})
}() }()
_, err = DialRead("rtsp://localhost:8554/teststream") conf := ClientConf{
require.Equal(t, "server ports are zero", err.Error()) AnyPortEnable: true,
}
conn, err := conf.DialRead("rtsp://localhost:8554/teststream")
require.NoError(t, err)
frameRecv := make(chan struct{})
done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) {
close(frameRecv)
})
<-frameRecv
conn.Close()
<-done
} }
func TestClientDialReadAutomaticProtocol(t *testing.T) { func TestClientDialReadAutomaticProtocol(t *testing.T) {

View File

@@ -578,7 +578,7 @@ func (c *ClientConn) Setup(mode headers.TransportMode, track *Track,
if thRes.ServerPorts == nil { if thRes.ServerPorts == nil {
rtpListener.close() rtpListener.close()
rtcpListener.close() rtcpListener.close()
return nil, fmt.Errorf("server ports not provided") return nil, fmt.Errorf("server ports have not been provided. Use AnyPortEnable to communicate with this server")
} }
if (thRes.ServerPorts[0] == 0 && thRes.ServerPorts[1] != 0) || if (thRes.ServerPorts[0] == 0 && thRes.ServerPorts[1] != 0) ||
@@ -588,8 +588,10 @@ func (c *ClientConn) Setup(mode headers.TransportMode, track *Track,
return nil, fmt.Errorf("server ports must be both zero or both not zero") return nil, fmt.Errorf("server ports must be both zero or both not zero")
} }
if !c.conf.AnyPortEnable {
if thRes.ServerPorts[0] == 0 && thRes.ServerPorts[1] == 0 { if thRes.ServerPorts[0] == 0 && thRes.ServerPorts[1] == 0 {
return nil, fmt.Errorf("server ports are zero") return nil, fmt.Errorf("server ports have not been provided. Use AnyPortEnable to communicate with this server")
}
} }
} else { } else {

View File

@@ -79,7 +79,7 @@ func (l *clientConnUDPListener) run() {
uaddr := addr.(*net.UDPAddr) uaddr := addr.(*net.UDPAddr)
if !l.remoteIP.Equal(uaddr.IP) || l.remotePort != uaddr.Port { if !l.remoteIP.Equal(uaddr.IP) || (l.remotePort != 0 && l.remotePort != uaddr.Port) {
continue continue
} }