mirror of
https://github.com/pion/ice.git
synced 2025-10-04 07:06:31 +08:00
Move URL type to pion/stun.URI
This commit is contained in:
2
agent.go
2
agent.go
@@ -105,7 +105,7 @@ type Agent struct {
|
|||||||
|
|
||||||
selectedPair atomic.Value // *CandidatePair
|
selectedPair atomic.Value // *CandidatePair
|
||||||
|
|
||||||
urls []*URL
|
urls []*stun.URI
|
||||||
networkTypes []NetworkType
|
networkTypes []NetworkType
|
||||||
|
|
||||||
buf *packetio.Buffer
|
buf *packetio.Buffer
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pion/logging"
|
"github.com/pion/logging"
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/v2"
|
"github.com/pion/transport/v2"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
@@ -54,7 +55,7 @@ func defaultCandidateTypes() []CandidateType {
|
|||||||
// AgentConfig collects the arguments to ice.Agent construction into
|
// AgentConfig collects the arguments to ice.Agent construction into
|
||||||
// a single structure, for future-proofness of the interface
|
// a single structure, for future-proofness of the interface
|
||||||
type AgentConfig struct {
|
type AgentConfig struct {
|
||||||
Urls []*URL
|
Urls []*stun.URI
|
||||||
|
|
||||||
// PortMin and PortMax are optional. Leave them 0 for the default UDP port allocation strategy.
|
// PortMin and PortMax are optional. Leave them 0 for the default UDP port allocation strategy.
|
||||||
PortMin uint16
|
PortMin uint16
|
||||||
|
@@ -301,11 +301,11 @@ func TestConnectivityLite(t *testing.T) {
|
|||||||
lim := test.TimeOut(time.Second * 30)
|
lim := test.TimeOut(time.Second * 30)
|
||||||
defer lim.Stop()
|
defer lim.Stop()
|
||||||
|
|
||||||
stunServerURL := &URL{
|
stunServerURL := &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: SchemeTypeSTUN,
|
||||||
Host: "1.2.3.4",
|
Host: "1.2.3.4",
|
||||||
Port: 3478,
|
Port: 3478,
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
natType := &vnet.NATType{
|
natType := &vnet.NATType{
|
||||||
@@ -320,7 +320,7 @@ func TestConnectivityLite(t *testing.T) {
|
|||||||
bNotifier, bConnected := onConnected()
|
bNotifier, bConnected := onConnected()
|
||||||
|
|
||||||
cfg0 := &AgentConfig{
|
cfg0 := &AgentConfig{
|
||||||
Urls: []*URL{stunServerURL},
|
Urls: []*stun.URI{stunServerURL},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
MulticastDNSMode: MulticastDNSModeDisabled,
|
MulticastDNSMode: MulticastDNSModeDisabled,
|
||||||
Net: v.net0,
|
Net: v.net0,
|
||||||
@@ -331,7 +331,7 @@ func TestConnectivityLite(t *testing.T) {
|
|||||||
require.NoError(t, aAgent.OnConnectionStateChange(aNotifier))
|
require.NoError(t, aAgent.OnConnectionStateChange(aNotifier))
|
||||||
|
|
||||||
cfg1 := &AgentConfig{
|
cfg1 := &AgentConfig{
|
||||||
Urls: []*URL{},
|
Urls: []*stun.URI{},
|
||||||
Lite: true,
|
Lite: true,
|
||||||
CandidateTypes: []CandidateType{CandidateTypeHost},
|
CandidateTypes: []CandidateType{CandidateTypeHost},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
@@ -548,7 +548,7 @@ func TestConnectionStateCallback(t *testing.T) {
|
|||||||
KeepaliveInterval := time.Duration(0)
|
KeepaliveInterval := time.Duration(0)
|
||||||
|
|
||||||
cfg := &AgentConfig{
|
cfg := &AgentConfig{
|
||||||
Urls: []*URL{},
|
Urls: []*stun.URI{},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
DisconnectedTimeout: &disconnectedDuration,
|
DisconnectedTimeout: &disconnectedDuration,
|
||||||
FailedTimeout: &failedDuration,
|
FailedTimeout: &failedDuration,
|
||||||
@@ -1330,7 +1330,7 @@ func TestCloseInConnectionStateCallback(t *testing.T) {
|
|||||||
CheckInterval := 500 * time.Millisecond
|
CheckInterval := 500 * time.Millisecond
|
||||||
|
|
||||||
cfg := &AgentConfig{
|
cfg := &AgentConfig{
|
||||||
Urls: []*URL{},
|
Urls: []*stun.URI{},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
DisconnectedTimeout: &disconnectedDuration,
|
DisconnectedTimeout: &disconnectedDuration,
|
||||||
FailedTimeout: &failedDuration,
|
FailedTimeout: &failedDuration,
|
||||||
@@ -1382,7 +1382,7 @@ func TestRunTaskInConnectionStateCallback(t *testing.T) {
|
|||||||
CheckInterval := 50 * time.Millisecond
|
CheckInterval := 50 * time.Millisecond
|
||||||
|
|
||||||
cfg := &AgentConfig{
|
cfg := &AgentConfig{
|
||||||
Urls: []*URL{},
|
Urls: []*stun.URI{},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
DisconnectedTimeout: &oneSecond,
|
DisconnectedTimeout: &oneSecond,
|
||||||
FailedTimeout: &oneSecond,
|
FailedTimeout: &oneSecond,
|
||||||
@@ -1427,7 +1427,7 @@ func TestRunTaskInSelectedCandidatePairChangeCallback(t *testing.T) {
|
|||||||
CheckInterval := 50 * time.Millisecond
|
CheckInterval := 50 * time.Millisecond
|
||||||
|
|
||||||
cfg := &AgentConfig{
|
cfg := &AgentConfig{
|
||||||
Urls: []*URL{},
|
Urls: []*stun.URI{},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
DisconnectedTimeout: &oneSecond,
|
DisconnectedTimeout: &oneSecond,
|
||||||
FailedTimeout: &oneSecond,
|
FailedTimeout: &oneSecond,
|
||||||
|
@@ -12,6 +12,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/v2/test"
|
"github.com/pion/transport/v2/test"
|
||||||
"github.com/pion/turn/v2"
|
"github.com/pion/turn/v2"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -47,14 +48,14 @@ func TestRelayOnlyConnection(t *testing.T) {
|
|||||||
|
|
||||||
cfg := &AgentConfig{
|
cfg := &AgentConfig{
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
Urls: []*URL{
|
Urls: []*stun.URI{
|
||||||
{
|
{
|
||||||
Scheme: SchemeTypeTURN,
|
Scheme: stun.SchemeTypeTURN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Username: "username",
|
Username: "username",
|
||||||
Password: "password",
|
Password: "password",
|
||||||
Port: serverPort,
|
Port: serverPort,
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CandidateTypes: []CandidateType{CandidateTypeRelay},
|
CandidateTypes: []CandidateType{CandidateTypeRelay},
|
||||||
|
@@ -12,6 +12,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/v2/test"
|
"github.com/pion/transport/v2/test"
|
||||||
"github.com/pion/turn/v2"
|
"github.com/pion/turn/v2"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -43,7 +44,7 @@ func TestServerReflexiveOnlyConnection(t *testing.T) {
|
|||||||
|
|
||||||
cfg := &AgentConfig{
|
cfg := &AgentConfig{
|
||||||
NetworkTypes: []NetworkType{NetworkTypeUDP4},
|
NetworkTypes: []NetworkType{NetworkTypeUDP4},
|
||||||
Urls: []*URL{
|
Urls: []*stun.URI{
|
||||||
{
|
{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: SchemeTypeSTUN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
|
@@ -226,7 +226,7 @@ func connectWithVNet(aAgent, bAgent *Agent) (*Conn, *Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type agentTestConfig struct {
|
type agentTestConfig struct {
|
||||||
urls []*URL
|
urls []*stun.URI
|
||||||
nat1To1IPCandidateType CandidateType
|
nat1To1IPCandidateType CandidateType
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,20 +305,20 @@ func TestConnectivityVNet(t *testing.T) {
|
|||||||
report := test.CheckRoutines(t)
|
report := test.CheckRoutines(t)
|
||||||
defer report()
|
defer report()
|
||||||
|
|
||||||
stunServerURL := &URL{
|
stunServerURL := &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: stun.SchemeTypeSTUN,
|
||||||
Host: vnetSTUNServerIP,
|
Host: vnetSTUNServerIP,
|
||||||
Port: vnetSTUNServerPort,
|
Port: vnetSTUNServerPort,
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
turnServerURL := &URL{
|
turnServerURL := &stun.URI{
|
||||||
Scheme: SchemeTypeTURN,
|
Scheme: stun.SchemeTypeTURN,
|
||||||
Host: vnetSTUNServerIP,
|
Host: vnetSTUNServerIP,
|
||||||
Port: vnetSTUNServerPort,
|
Port: vnetSTUNServerPort,
|
||||||
Username: "user",
|
Username: "user",
|
||||||
Password: "pass",
|
Password: "pass",
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("Full-cone NATs on both ends", func(t *testing.T) {
|
t.Run("Full-cone NATs on both ends", func(t *testing.T) {
|
||||||
@@ -339,12 +339,12 @@ func TestConnectivityVNet(t *testing.T) {
|
|||||||
|
|
||||||
log.Debug("Connecting...")
|
log.Debug("Connecting...")
|
||||||
a0TestConfig := &agentTestConfig{
|
a0TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{
|
urls: []*stun.URI{
|
||||||
stunServerURL,
|
stunServerURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
a1TestConfig := &agentTestConfig{
|
a1TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{
|
urls: []*stun.URI{
|
||||||
stunServerURL,
|
stunServerURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -376,13 +376,13 @@ func TestConnectivityVNet(t *testing.T) {
|
|||||||
|
|
||||||
log.Debug("Connecting...")
|
log.Debug("Connecting...")
|
||||||
a0TestConfig := &agentTestConfig{
|
a0TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{
|
urls: []*stun.URI{
|
||||||
stunServerURL,
|
stunServerURL,
|
||||||
turnServerURL,
|
turnServerURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
a1TestConfig := &agentTestConfig{
|
a1TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{
|
urls: []*stun.URI{
|
||||||
stunServerURL,
|
stunServerURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -416,11 +416,11 @@ func TestConnectivityVNet(t *testing.T) {
|
|||||||
|
|
||||||
log.Debug("Connecting...")
|
log.Debug("Connecting...")
|
||||||
a0TestConfig := &agentTestConfig{
|
a0TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{},
|
urls: []*stun.URI{},
|
||||||
nat1To1IPCandidateType: CandidateTypeHost, // Use 1:1 NAT IP as a host candidate
|
nat1To1IPCandidateType: CandidateTypeHost, // Use 1:1 NAT IP as a host candidate
|
||||||
}
|
}
|
||||||
a1TestConfig := &agentTestConfig{
|
a1TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{},
|
urls: []*stun.URI{},
|
||||||
}
|
}
|
||||||
ca, cb := pipeWithVNet(v, a0TestConfig, a1TestConfig)
|
ca, cb := pipeWithVNet(v, a0TestConfig, a1TestConfig)
|
||||||
|
|
||||||
@@ -452,11 +452,11 @@ func TestConnectivityVNet(t *testing.T) {
|
|||||||
|
|
||||||
log.Debug("Connecting...")
|
log.Debug("Connecting...")
|
||||||
a0TestConfig := &agentTestConfig{
|
a0TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{},
|
urls: []*stun.URI{},
|
||||||
nat1To1IPCandidateType: CandidateTypeServerReflexive, // Use 1:1 NAT IP as a srflx candidate
|
nat1To1IPCandidateType: CandidateTypeServerReflexive, // Use 1:1 NAT IP as a srflx candidate
|
||||||
}
|
}
|
||||||
a1TestConfig := &agentTestConfig{
|
a1TestConfig := &agentTestConfig{
|
||||||
urls: []*URL{},
|
urls: []*stun.URI{},
|
||||||
}
|
}
|
||||||
ca, cb := pipeWithVNet(v, a0TestConfig, a1TestConfig)
|
ca, cb := pipeWithVNet(v, a0TestConfig, a1TestConfig)
|
||||||
|
|
||||||
|
@@ -124,8 +124,6 @@ var (
|
|||||||
errReadingStreamingPacket = errors.New("error reading streaming packet")
|
errReadingStreamingPacket = errors.New("error reading streaming packet")
|
||||||
errWriting = errors.New("error writing to")
|
errWriting = errors.New("error writing to")
|
||||||
errClosingConnection = errors.New("error closing connection")
|
errClosingConnection = errors.New("error closing connection")
|
||||||
errMissingProtocolScheme = errors.New("missing protocol scheme")
|
|
||||||
errTooManyColonsAddr = errors.New("too many colons in address")
|
|
||||||
errRead = errors.New("unexpected error trying to read")
|
errRead = errors.New("unexpected error trying to read")
|
||||||
errUnknownRole = errors.New("unknown role")
|
errUnknownRole = errors.New("unknown role")
|
||||||
errICEWriteSTUNMessage = errors.New("the ICE conn can't write STUN messages")
|
errICEWriteSTUNMessage = errors.New("the ICE conn can't write STUN messages")
|
||||||
|
31
gather.go
31
gather.go
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/pion/ice/v2/internal/fakenet"
|
"github.com/pion/ice/v2/internal/fakenet"
|
||||||
stunx "github.com/pion/ice/v2/internal/stun"
|
stunx "github.com/pion/ice/v2/internal/stun"
|
||||||
"github.com/pion/logging"
|
"github.com/pion/logging"
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/turn/v2"
|
"github.com/pion/turn/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -376,7 +377,7 @@ func (a *Agent) gatherCandidatesSrflxMapped(ctx context.Context, networkTypes []
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*URL, networkTypes []NetworkType) { //nolint:gocognit
|
func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*stun.URI, networkTypes []NetworkType) { //nolint:gocognit
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
defer wg.Wait()
|
defer wg.Wait()
|
||||||
|
|
||||||
@@ -393,7 +394,7 @@ func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*URL, ne
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(url URL, network string, localAddr *net.UDPAddr) {
|
go func(url stun.URI, network string, localAddr *net.UDPAddr) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
hostPort := fmt.Sprintf("%s:%d", url.Host, url.Port)
|
hostPort := fmt.Sprintf("%s:%d", url.Host, url.Port)
|
||||||
@@ -444,7 +445,7 @@ func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*URL, ne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*URL, networkTypes []NetworkType) { //nolint:gocognit
|
func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*stun.URI, networkTypes []NetworkType) { //nolint:gocognit
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
defer wg.Wait()
|
defer wg.Wait()
|
||||||
|
|
||||||
@@ -455,7 +456,7 @@ func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*URL, networkT
|
|||||||
|
|
||||||
for i := range urls {
|
for i := range urls {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(url URL, network string) {
|
go func(url stun.URI, network string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
hostPort := fmt.Sprintf("%s:%d", url.Host, url.Port)
|
hostPort := fmt.Sprintf("%s:%d", url.Host, url.Port)
|
||||||
@@ -518,14 +519,14 @@ func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*URL, networkT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //nolint:gocognit
|
func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*stun.URI) { //nolint:gocognit
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
defer wg.Wait()
|
defer wg.Wait()
|
||||||
|
|
||||||
network := NetworkTypeUDP4.String()
|
network := NetworkTypeUDP4.String()
|
||||||
for i := range urls {
|
for i := range urls {
|
||||||
switch {
|
switch {
|
||||||
case urls[i].Scheme != SchemeTypeTURN && urls[i].Scheme != SchemeTypeTURNS:
|
case urls[i].Scheme != stun.SchemeTypeTURN && urls[i].Scheme != stun.SchemeTypeTURNS:
|
||||||
continue
|
continue
|
||||||
case urls[i].Username == "":
|
case urls[i].Username == "":
|
||||||
a.log.Errorf("Failed to gather relay candidates: %v", ErrUsernameEmpty)
|
a.log.Errorf("Failed to gather relay candidates: %v", ErrUsernameEmpty)
|
||||||
@@ -536,7 +537,7 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli
|
|||||||
}
|
}
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(url URL) {
|
go func(url stun.URI) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
turnServerAddr := fmt.Sprintf("%s:%d", url.Host, url.Port)
|
turnServerAddr := fmt.Sprintf("%s:%d", url.Host, url.Port)
|
||||||
var (
|
var (
|
||||||
@@ -548,7 +549,7 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli
|
|||||||
)
|
)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case url.Proto == ProtoTypeUDP && url.Scheme == SchemeTypeTURN:
|
case url.Proto == stun.ProtoTypeUDP && url.Scheme == stun.SchemeTypeTURN:
|
||||||
if locConn, err = a.net.ListenPacket(network, "0.0.0.0:0"); err != nil {
|
if locConn, err = a.net.ListenPacket(network, "0.0.0.0:0"); err != nil {
|
||||||
a.log.Warnf("Failed to listen %s: %v", network, err)
|
a.log.Warnf("Failed to listen %s: %v", network, err)
|
||||||
return
|
return
|
||||||
@@ -557,8 +558,8 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli
|
|||||||
relAddr = locConn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert
|
relAddr = locConn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert
|
||||||
relPort = locConn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert
|
relPort = locConn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert
|
||||||
relayProtocol = udp
|
relayProtocol = udp
|
||||||
case a.proxyDialer != nil && url.Proto == ProtoTypeTCP &&
|
case a.proxyDialer != nil && url.Proto == stun.ProtoTypeTCP &&
|
||||||
(url.Scheme == SchemeTypeTURN || url.Scheme == SchemeTypeTURNS):
|
(url.Scheme == stun.SchemeTypeTURN || url.Scheme == stun.SchemeTypeTURNS):
|
||||||
conn, connectErr := a.proxyDialer.Dial(NetworkTypeTCP4.String(), turnServerAddr)
|
conn, connectErr := a.proxyDialer.Dial(NetworkTypeTCP4.String(), turnServerAddr)
|
||||||
if connectErr != nil {
|
if connectErr != nil {
|
||||||
a.log.Warnf("Failed to dial TCP address %s via proxy dialer: %v", turnServerAddr, connectErr)
|
a.log.Warnf("Failed to dial TCP address %s via proxy dialer: %v", turnServerAddr, connectErr)
|
||||||
@@ -567,14 +568,14 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli
|
|||||||
|
|
||||||
relAddr = conn.LocalAddr().(*net.TCPAddr).IP.String() //nolint:forcetypeassert
|
relAddr = conn.LocalAddr().(*net.TCPAddr).IP.String() //nolint:forcetypeassert
|
||||||
relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert
|
relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert
|
||||||
if url.Scheme == SchemeTypeTURN {
|
if url.Scheme == stun.SchemeTypeTURN {
|
||||||
relayProtocol = tcp
|
relayProtocol = tcp
|
||||||
} else if url.Scheme == SchemeTypeTURNS {
|
} else if url.Scheme == stun.SchemeTypeTURNS {
|
||||||
relayProtocol = "tls"
|
relayProtocol = "tls"
|
||||||
}
|
}
|
||||||
locConn = turn.NewSTUNConn(conn)
|
locConn = turn.NewSTUNConn(conn)
|
||||||
|
|
||||||
case url.Proto == ProtoTypeTCP && url.Scheme == SchemeTypeTURN:
|
case url.Proto == stun.ProtoTypeTCP && url.Scheme == stun.SchemeTypeTURN:
|
||||||
tcpAddr, connectErr := a.net.ResolveTCPAddr(NetworkTypeTCP4.String(), turnServerAddr)
|
tcpAddr, connectErr := a.net.ResolveTCPAddr(NetworkTypeTCP4.String(), turnServerAddr)
|
||||||
if connectErr != nil {
|
if connectErr != nil {
|
||||||
a.log.Warnf("Failed to resolve TCP address %s: %v", turnServerAddr, connectErr)
|
a.log.Warnf("Failed to resolve TCP address %s: %v", turnServerAddr, connectErr)
|
||||||
@@ -591,7 +592,7 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli
|
|||||||
relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert
|
relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert
|
||||||
relayProtocol = tcp
|
relayProtocol = tcp
|
||||||
locConn = turn.NewSTUNConn(conn)
|
locConn = turn.NewSTUNConn(conn)
|
||||||
case url.Proto == ProtoTypeUDP && url.Scheme == SchemeTypeTURNS:
|
case url.Proto == stun.ProtoTypeUDP && url.Scheme == stun.SchemeTypeTURNS:
|
||||||
udpAddr, connectErr := a.net.ResolveUDPAddr(network, turnServerAddr)
|
udpAddr, connectErr := a.net.ResolveUDPAddr(network, turnServerAddr)
|
||||||
if connectErr != nil {
|
if connectErr != nil {
|
||||||
a.log.Warnf("Failed to resolve UDP address %s: %v", turnServerAddr, connectErr)
|
a.log.Warnf("Failed to resolve UDP address %s: %v", turnServerAddr, connectErr)
|
||||||
@@ -617,7 +618,7 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli
|
|||||||
relPort = conn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert
|
relPort = conn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert
|
||||||
relayProtocol = "dtls"
|
relayProtocol = "dtls"
|
||||||
locConn = &fakenet.PacketConn{Conn: conn}
|
locConn = &fakenet.PacketConn{Conn: conn}
|
||||||
case url.Proto == ProtoTypeTCP && url.Scheme == SchemeTypeTURNS:
|
case url.Proto == stun.ProtoTypeTCP && url.Scheme == stun.SchemeTypeTURNS:
|
||||||
tcpAddr, resolvErr := a.net.ResolveTCPAddr(NetworkTypeTCP4.String(), turnServerAddr)
|
tcpAddr, resolvErr := a.net.ResolveTCPAddr(NetworkTypeTCP4.String(), turnServerAddr)
|
||||||
if resolvErr != nil {
|
if resolvErr != nil {
|
||||||
a.log.Warnf("Failed to resolve relay address %s: %v", turnServerAddr, resolvErr)
|
a.log.Warnf("Failed to resolve relay address %s: %v", turnServerAddr, resolvErr)
|
||||||
|
@@ -224,16 +224,16 @@ func TestSTUNConcurrency(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
urls := []*URL{}
|
urls := []*stun.URI{}
|
||||||
for i := 0; i <= 10; i++ {
|
for i := 0; i <= 10; i++ {
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: stun.SchemeTypeSTUN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: serverPort + 1,
|
Port: serverPort + 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: stun.SchemeTypeSTUN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: serverPort,
|
Port: serverPort,
|
||||||
})
|
})
|
||||||
@@ -284,7 +284,7 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
lim := test.TimeOut(time.Second * 30)
|
lim := test.TimeOut(time.Second * 30)
|
||||||
defer lim.Stop()
|
defer lim.Stop()
|
||||||
|
|
||||||
runTest := func(protocol ProtoType, scheme SchemeType, packetConn net.PacketConn, listener net.Listener, serverPort int) {
|
runTest := func(protocol stun.ProtoType, scheme stun.SchemeType, packetConn net.PacketConn, listener net.Listener, serverPort int) {
|
||||||
packetConnConfigs := []turn.PacketConnConfig{}
|
packetConnConfigs := []turn.PacketConnConfig{}
|
||||||
if packetConn != nil {
|
if packetConn != nil {
|
||||||
packetConnConfigs = append(packetConnConfigs, turn.PacketConnConfig{
|
packetConnConfigs = append(packetConnConfigs, turn.PacketConnConfig{
|
||||||
@@ -309,9 +309,9 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
urls := []*URL{}
|
urls := []*stun.URI{}
|
||||||
for i := 0; i <= 10; i++ {
|
for i := 0; i <= 10; i++ {
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: scheme,
|
Scheme: scheme,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Username: "username",
|
Username: "username",
|
||||||
@@ -320,7 +320,7 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
Port: serverPort + 1 + i,
|
Port: serverPort + 1 + i,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: scheme,
|
Scheme: scheme,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Username: "username",
|
Username: "username",
|
||||||
@@ -356,7 +356,7 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
serverListener, err := net.ListenPacket("udp", "127.0.0.1:"+strconv.Itoa(serverPort))
|
serverListener, err := net.ListenPacket("udp", "127.0.0.1:"+strconv.Itoa(serverPort))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
runTest(ProtoTypeUDP, SchemeTypeTURN, serverListener, nil, serverPort)
|
runTest(stun.ProtoTypeUDP, stun.SchemeTypeTURN, serverListener, nil, serverPort)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("TCP Relay", func(t *testing.T) {
|
t.Run("TCP Relay", func(t *testing.T) {
|
||||||
@@ -364,7 +364,7 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
serverListener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(serverPort))
|
serverListener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(serverPort))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
runTest(ProtoTypeTCP, SchemeTypeTURN, nil, serverListener, serverPort)
|
runTest(stun.ProtoTypeTCP, stun.SchemeTypeTURN, nil, serverListener, serverPort)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("TLS Relay", func(t *testing.T) {
|
t.Run("TLS Relay", func(t *testing.T) {
|
||||||
@@ -377,7 +377,7 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
runTest(ProtoTypeTCP, SchemeTypeTURNS, nil, serverListener, serverPort)
|
runTest(stun.ProtoTypeTCP, stun.SchemeTypeTURNS, nil, serverListener, serverPort)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("DTLS Relay", func(t *testing.T) {
|
t.Run("DTLS Relay", func(t *testing.T) {
|
||||||
@@ -390,7 +390,7 @@ func TestTURNConcurrency(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
runTest(ProtoTypeUDP, SchemeTypeTURNS, nil, serverListener, serverPort)
|
runTest(stun.ProtoTypeUDP, stun.SchemeTypeTURNS, nil, serverListener, serverPort)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,17 +418,17 @@ func TestSTUNTURNConcurrency(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
urls := []*URL{}
|
urls := []*stun.URI{}
|
||||||
for i := 0; i <= 10; i++ {
|
for i := 0; i <= 10; i++ {
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: stun.SchemeTypeSTUN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: serverPort + 1,
|
Port: serverPort + 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: SchemeTypeTURN,
|
Scheme: stun.SchemeTypeTURN,
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: serverPort,
|
Port: serverPort,
|
||||||
Username: "username",
|
Username: "username",
|
||||||
@@ -490,9 +490,9 @@ func TestTURNSrflx(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
urls := []*URL{{
|
urls := []*stun.URI{{
|
||||||
Scheme: SchemeTypeTURN,
|
Scheme: stun.SchemeTypeTURN,
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: serverPort,
|
Port: serverPort,
|
||||||
Username: "username",
|
Username: "username",
|
||||||
@@ -574,13 +574,13 @@ func TestTURNProxyDialer(t *testing.T) {
|
|||||||
a, err := NewAgent(&AgentConfig{
|
a, err := NewAgent(&AgentConfig{
|
||||||
CandidateTypes: []CandidateType{CandidateTypeRelay},
|
CandidateTypes: []CandidateType{CandidateTypeRelay},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
Urls: []*URL{
|
Urls: []*stun.URI{
|
||||||
{
|
{
|
||||||
Scheme: SchemeTypeTURN,
|
Scheme: stun.SchemeTypeTURN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Username: "username",
|
Username: "username",
|
||||||
Password: "password",
|
Password: "password",
|
||||||
Proto: ProtoTypeTCP,
|
Proto: stun.ProtoTypeTCP,
|
||||||
Port: 5000,
|
Port: 5000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -782,9 +782,9 @@ func TestUniversalUDPMuxUsage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numSTUNS := 3
|
numSTUNS := 3
|
||||||
urls := []*URL{}
|
urls := []*stun.URI{}
|
||||||
for i := 0; i < numSTUNS; i++ {
|
for i := 0; i < numSTUNS; i++ {
|
||||||
urls = append(urls, &URL{
|
urls = append(urls, &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: SchemeTypeSTUN,
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: 3478 + i,
|
Port: 3478 + i,
|
||||||
|
@@ -14,6 +14,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pion/logging"
|
"github.com/pion/logging"
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/v2/test"
|
"github.com/pion/transport/v2/test"
|
||||||
"github.com/pion/transport/v2/vnet"
|
"github.com/pion/transport/v2/vnet"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -445,13 +446,13 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) {
|
|||||||
report := test.CheckRoutines(t)
|
report := test.CheckRoutines(t)
|
||||||
defer report()
|
defer report()
|
||||||
|
|
||||||
turnServerURL := &URL{
|
turnServerURL := &stun.URI{
|
||||||
Scheme: SchemeTypeTURN,
|
Scheme: stun.SchemeTypeTURN,
|
||||||
Host: vnetSTUNServerIP,
|
Host: vnetSTUNServerIP,
|
||||||
Port: vnetSTUNServerPort,
|
Port: vnetSTUNServerPort,
|
||||||
Username: "user",
|
Username: "user",
|
||||||
Password: "pass",
|
Password: "pass",
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildVNet with a Symmetric NATs for both LANs
|
// buildVNet with a Symmetric NATs for both LANs
|
||||||
@@ -467,7 +468,7 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) {
|
|||||||
defer v.close()
|
defer v.close()
|
||||||
|
|
||||||
cfg0 := &AgentConfig{
|
cfg0 := &AgentConfig{
|
||||||
Urls: []*URL{
|
Urls: []*stun.URI{
|
||||||
turnServerURL,
|
turnServerURL,
|
||||||
},
|
},
|
||||||
NetworkTypes: supportedNetworkTypes(),
|
NetworkTypes: supportedNetworkTypes(),
|
||||||
@@ -480,7 +481,7 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
aAgent.gatherCandidatesRelay(context.Background(), []*URL{turnServerURL})
|
aAgent.gatherCandidatesRelay(context.Background(), []*stun.URI{turnServerURL})
|
||||||
// Assert relay conn leak on close.
|
// Assert relay conn leak on close.
|
||||||
assert.NoError(t, aAgent.Close())
|
assert.NoError(t, aAgent.Close())
|
||||||
}
|
}
|
||||||
|
10
ice.go
10
ice.go
@@ -8,8 +8,11 @@ type ConnectionState int
|
|||||||
|
|
||||||
// List of supported States
|
// List of supported States
|
||||||
const (
|
const (
|
||||||
|
// ConnectionStateUnknown represents an unknown state
|
||||||
|
ConnectionStateUnknown = iota
|
||||||
|
|
||||||
// ConnectionStateNew ICE agent is gathering addresses
|
// ConnectionStateNew ICE agent is gathering addresses
|
||||||
ConnectionStateNew = iota + 1
|
ConnectionStateNew
|
||||||
|
|
||||||
// ConnectionStateChecking ICE agent has been given local and remote candidates, and is attempting to find a match
|
// ConnectionStateChecking ICE agent has been given local and remote candidates, and is attempting to find a match
|
||||||
ConnectionStateChecking
|
ConnectionStateChecking
|
||||||
@@ -55,8 +58,11 @@ func (c ConnectionState) String() string {
|
|||||||
type GatheringState int
|
type GatheringState int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// GatheringStateUnknown represents an unknown state
|
||||||
|
GatheringStateUnknown GatheringState = iota
|
||||||
|
|
||||||
// GatheringStateNew indicates candidate gathering is not yet started
|
// GatheringStateNew indicates candidate gathering is not yet started
|
||||||
GatheringStateNew GatheringState = iota + 1
|
GatheringStateNew
|
||||||
|
|
||||||
// GatheringStateGathering indicates candidate gathering is ongoing
|
// GatheringStateGathering indicates candidate gathering is ongoing
|
||||||
GatheringStateGathering
|
GatheringStateGathering
|
||||||
|
@@ -14,7 +14,7 @@ func TestConnectedState_String(t *testing.T) {
|
|||||||
connectionState ConnectionState
|
connectionState ConnectionState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{ConnectionState(Unknown), "Invalid"},
|
{ConnectionStateUnknown, "Invalid"},
|
||||||
{ConnectionStateNew, "New"},
|
{ConnectionStateNew, "New"},
|
||||||
{ConnectionStateChecking, "Checking"},
|
{ConnectionStateChecking, "Checking"},
|
||||||
{ConnectionStateConnected, "Connected"},
|
{ConnectionStateConnected, "Connected"},
|
||||||
@@ -38,7 +38,7 @@ func TestGatheringState_String(t *testing.T) {
|
|||||||
gatheringState GatheringState
|
gatheringState GatheringState
|
||||||
expectedString string
|
expectedString string
|
||||||
}{
|
}{
|
||||||
{GatheringState(Unknown), ErrUnknownType.Error()},
|
{GatheringStateUnknown, ErrUnknownType.Error()},
|
||||||
{GatheringStateNew, "new"},
|
{GatheringStateNew, "new"},
|
||||||
{GatheringStateGathering, "gathering"},
|
{GatheringStateGathering, "gathering"},
|
||||||
{GatheringStateComplete, "complete"},
|
{GatheringStateComplete, "complete"},
|
||||||
|
@@ -13,6 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/v2/test"
|
"github.com/pion/transport/v2/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ func connect(aAgent, bAgent *Agent) (*Conn, *Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func pipe(defaultConfig *AgentConfig) (*Conn, *Conn) {
|
func pipe(defaultConfig *AgentConfig) (*Conn, *Conn) {
|
||||||
var urls []*URL
|
var urls []*stun.URI
|
||||||
|
|
||||||
aNotifier, aConnected := onConnected()
|
aNotifier, aConnected := onConnected()
|
||||||
bNotifier, bConnected := onConnected()
|
bNotifier, bConnected := onConnected()
|
||||||
@@ -261,7 +262,7 @@ func pipe(defaultConfig *AgentConfig) (*Conn, *Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func pipeWithTimeout(disconnectTimeout time.Duration, iceKeepalive time.Duration) (*Conn, *Conn) {
|
func pipeWithTimeout(disconnectTimeout time.Duration, iceKeepalive time.Duration) (*Conn, *Conn) {
|
||||||
var urls []*URL
|
var urls []*stun.URI
|
||||||
|
|
||||||
aNotifier, aConnected := onConnected()
|
aNotifier, aConnected := onConnected()
|
||||||
bNotifier, bConnected := onConnected()
|
bNotifier, bConnected := onConnected()
|
||||||
|
@@ -12,6 +12,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/v2/test"
|
"github.com/pion/transport/v2/test"
|
||||||
"github.com/pion/transport/v2/vnet"
|
"github.com/pion/transport/v2/vnet"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -37,11 +38,11 @@ func TestRemoteLocalAddr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer v.close()
|
defer v.close()
|
||||||
|
|
||||||
stunServerURL := &URL{
|
stunServerURL := &stun.URI{
|
||||||
Scheme: SchemeTypeSTUN,
|
Scheme: stun.SchemeTypeSTUN,
|
||||||
Host: vnetSTUNServerIP,
|
Host: vnetSTUNServerIP,
|
||||||
Port: vnetSTUNServerPort,
|
Port: vnetSTUNServerPort,
|
||||||
Proto: ProtoTypeUDP,
|
Proto: stun.ProtoTypeUDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("Disconnected Returns nil", func(t *testing.T) {
|
t.Run("Disconnected Returns nil", func(t *testing.T) {
|
||||||
@@ -58,10 +59,10 @@ func TestRemoteLocalAddr(t *testing.T) {
|
|||||||
t.Run("Remote/Local Pair Match between Agents", func(t *testing.T) {
|
t.Run("Remote/Local Pair Match between Agents", func(t *testing.T) {
|
||||||
ca, cb := pipeWithVNet(v,
|
ca, cb := pipeWithVNet(v,
|
||||||
&agentTestConfig{
|
&agentTestConfig{
|
||||||
urls: []*URL{stunServerURL},
|
urls: []*stun.URI{stunServerURL},
|
||||||
},
|
},
|
||||||
&agentTestConfig{
|
&agentTestConfig{
|
||||||
urls: []*URL{stunServerURL},
|
urls: []*stun.URI{stunServerURL},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
254
url.go
254
url.go
@@ -3,228 +3,80 @@
|
|||||||
|
|
||||||
package ice
|
package ice
|
||||||
|
|
||||||
import (
|
import "github.com/pion/stun"
|
||||||
"errors"
|
|
||||||
"net"
|
type (
|
||||||
"net/url"
|
// URL represents a STUN (rfc7064) or TURN (rfc7065) URI
|
||||||
"strconv"
|
//
|
||||||
|
// Deprecated: Please use pion/stun.URI
|
||||||
|
URL = stun.URI
|
||||||
|
|
||||||
|
// ProtoType indicates the transport protocol type that is used in the ice.URL
|
||||||
|
// structure.
|
||||||
|
//
|
||||||
|
// Deprecated: TPlease use pion/stun.ProtoType
|
||||||
|
ProtoType = stun.ProtoType
|
||||||
|
|
||||||
|
// SchemeType indicates the type of server used in the ice.URL structure.
|
||||||
|
//
|
||||||
|
// Deprecated: Please use pion/stun.SchemeType
|
||||||
|
SchemeType = stun.SchemeType
|
||||||
)
|
)
|
||||||
|
|
||||||
// SchemeType indicates the type of server used in the ice.URL structure.
|
|
||||||
type SchemeType int
|
|
||||||
|
|
||||||
// Unknown defines default public constant to use for "enum" like struct
|
|
||||||
// comparisons when no value was defined.
|
|
||||||
const Unknown = iota
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SchemeTypeSTUN indicates the URL represents a STUN server.
|
// SchemeTypeSTUN indicates the URL represents a STUN server.
|
||||||
SchemeTypeSTUN SchemeType = iota + 1
|
//
|
||||||
|
// Deprecated: Please use pion/stun.SchemeTypeSTUN
|
||||||
|
SchemeTypeSTUN = stun.SchemeTypeSTUN
|
||||||
|
|
||||||
// SchemeTypeSTUNS indicates the URL represents a STUNS (secure) server.
|
// SchemeTypeSTUNS indicates the URL represents a STUNS (secure) server.
|
||||||
SchemeTypeSTUNS
|
//
|
||||||
|
// Deprecated: Please use pion/stun.SchemeTypeSTUNS
|
||||||
|
SchemeTypeSTUNS = stun.SchemeTypeSTUNS
|
||||||
|
|
||||||
// SchemeTypeTURN indicates the URL represents a TURN server.
|
// SchemeTypeTURN indicates the URL represents a TURN server.
|
||||||
SchemeTypeTURN
|
//
|
||||||
|
// Deprecated: Please use pion/stun.SchemeTypeTURN
|
||||||
|
SchemeTypeTURN = stun.SchemeTypeTURN
|
||||||
|
|
||||||
// SchemeTypeTURNS indicates the URL represents a TURNS (secure) server.
|
// SchemeTypeTURNS indicates the URL represents a TURNS (secure) server.
|
||||||
SchemeTypeTURNS
|
//
|
||||||
|
// Deprecated: Please use pion/stun.SchemeTypeTURNS
|
||||||
|
SchemeTypeTURNS = stun.SchemeTypeTURNS
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewSchemeType defines a procedure for creating a new SchemeType from a raw
|
|
||||||
// string naming the scheme type.
|
|
||||||
func NewSchemeType(raw string) SchemeType {
|
|
||||||
switch raw {
|
|
||||||
case "stun":
|
|
||||||
return SchemeTypeSTUN
|
|
||||||
case "stuns":
|
|
||||||
return SchemeTypeSTUNS
|
|
||||||
case "turn":
|
|
||||||
return SchemeTypeTURN
|
|
||||||
case "turns":
|
|
||||||
return SchemeTypeTURNS
|
|
||||||
default:
|
|
||||||
return SchemeType(Unknown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t SchemeType) String() string {
|
|
||||||
switch t {
|
|
||||||
case SchemeTypeSTUN:
|
|
||||||
return "stun"
|
|
||||||
case SchemeTypeSTUNS:
|
|
||||||
return "stuns"
|
|
||||||
case SchemeTypeTURN:
|
|
||||||
return "turn"
|
|
||||||
case SchemeTypeTURNS:
|
|
||||||
return "turns"
|
|
||||||
default:
|
|
||||||
return ErrUnknownType.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProtoType indicates the transport protocol type that is used in the ice.URL
|
|
||||||
// structure.
|
|
||||||
type ProtoType int
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ProtoTypeUDP indicates the URL uses a UDP transport.
|
// ProtoTypeUDP indicates the URL uses a UDP transport.
|
||||||
ProtoTypeUDP ProtoType = iota + 1
|
//
|
||||||
|
// Deprecated: Please use pion/stun.ProtoTypeUDP
|
||||||
|
ProtoTypeUDP = stun.ProtoTypeUDP
|
||||||
|
|
||||||
// ProtoTypeTCP indicates the URL uses a TCP transport.
|
// ProtoTypeTCP indicates the URL uses a TCP transport.
|
||||||
ProtoTypeTCP
|
//
|
||||||
|
// Deprecated: Please use pion/stun.ProtoTypeTCP
|
||||||
|
ProtoTypeTCP = stun.ProtoTypeTCP
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewProtoType defines a procedure for creating a new ProtoType from a raw
|
// Unknown represents and unknown ProtoType or SchemeType
|
||||||
// string naming the transport protocol type.
|
//
|
||||||
func NewProtoType(raw string) ProtoType {
|
// Deprecated: Please use pion/stun.SchemeTypeUnknown or pion/stun.ProtoTypeUnknown
|
||||||
switch raw {
|
const Unknown = 0
|
||||||
case "udp":
|
|
||||||
return ProtoTypeUDP
|
|
||||||
case "tcp":
|
|
||||||
return ProtoTypeTCP
|
|
||||||
default:
|
|
||||||
return ProtoType(Unknown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t ProtoType) String() string {
|
|
||||||
switch t {
|
|
||||||
case ProtoTypeUDP:
|
|
||||||
return "udp"
|
|
||||||
case ProtoTypeTCP:
|
|
||||||
return "tcp"
|
|
||||||
default:
|
|
||||||
return ErrUnknownType.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// URL represents a STUN (rfc7064) or TURN (rfc7065) URL
|
|
||||||
type URL struct {
|
|
||||||
Scheme SchemeType
|
|
||||||
Host string
|
|
||||||
Port int
|
|
||||||
Username string
|
|
||||||
Password string
|
|
||||||
Proto ProtoType
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseURL parses a STUN or TURN urls following the ABNF syntax described in
|
// ParseURL parses a STUN or TURN urls following the ABNF syntax described in
|
||||||
// https://tools.ietf.org/html/rfc7064 and https://tools.ietf.org/html/rfc7065
|
// https://tools.ietf.org/html/rfc7064 and https://tools.ietf.org/html/rfc7065
|
||||||
// respectively.
|
// respectively.
|
||||||
func ParseURL(raw string) (*URL, error) { //nolint:gocognit
|
//
|
||||||
rawParts, err := url.Parse(raw)
|
// Deprecated: Please use pion/stun.ParseURI
|
||||||
if err != nil {
|
var ParseURL = stun.ParseURI //nolint:gochecknoglobals
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var u URL
|
// NewSchemeType defines a procedure for creating a new SchemeType from a raw
|
||||||
u.Scheme = NewSchemeType(rawParts.Scheme)
|
// string naming the scheme type.
|
||||||
if u.Scheme == SchemeType(Unknown) {
|
//
|
||||||
return nil, ErrSchemeType
|
// Deprecated: Please use pion/stun.NewSchemeType
|
||||||
}
|
var NewSchemeType = stun.NewSchemeType //nolint:gochecknoglobals
|
||||||
|
|
||||||
var rawPort string
|
// NewProtoType defines a procedure for creating a new ProtoType from a raw
|
||||||
if u.Host, rawPort, err = net.SplitHostPort(rawParts.Opaque); err != nil {
|
// string naming the transport protocol type.
|
||||||
var e *net.AddrError
|
//
|
||||||
if errors.As(err, &e) {
|
// Deprecated: Please use pion/stun.NewProtoType
|
||||||
if e.Err == "missing port in address" {
|
var NewProtoType = stun.NewProtoType //nolint:gochecknoglobals
|
||||||
nextRawURL := u.Scheme.String() + ":" + rawParts.Opaque
|
|
||||||
switch {
|
|
||||||
case u.Scheme == SchemeTypeSTUN || u.Scheme == SchemeTypeTURN:
|
|
||||||
nextRawURL += ":3478"
|
|
||||||
if rawParts.RawQuery != "" {
|
|
||||||
nextRawURL += "?" + rawParts.RawQuery
|
|
||||||
}
|
|
||||||
return ParseURL(nextRawURL)
|
|
||||||
case u.Scheme == SchemeTypeSTUNS || u.Scheme == SchemeTypeTURNS:
|
|
||||||
nextRawURL += ":5349"
|
|
||||||
if rawParts.RawQuery != "" {
|
|
||||||
nextRawURL += "?" + rawParts.RawQuery
|
|
||||||
}
|
|
||||||
return ParseURL(nextRawURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if u.Host == "" {
|
|
||||||
return nil, ErrHost
|
|
||||||
}
|
|
||||||
|
|
||||||
if u.Port, err = strconv.Atoi(rawPort); err != nil {
|
|
||||||
return nil, ErrPort
|
|
||||||
}
|
|
||||||
|
|
||||||
switch u.Scheme {
|
|
||||||
case SchemeTypeSTUN:
|
|
||||||
qArgs, err := url.ParseQuery(rawParts.RawQuery)
|
|
||||||
if err != nil || len(qArgs) > 0 {
|
|
||||||
return nil, ErrSTUNQuery
|
|
||||||
}
|
|
||||||
u.Proto = ProtoTypeUDP
|
|
||||||
case SchemeTypeSTUNS:
|
|
||||||
qArgs, err := url.ParseQuery(rawParts.RawQuery)
|
|
||||||
if err != nil || len(qArgs) > 0 {
|
|
||||||
return nil, ErrSTUNQuery
|
|
||||||
}
|
|
||||||
u.Proto = ProtoTypeTCP
|
|
||||||
case SchemeTypeTURN:
|
|
||||||
proto, err := parseProto(rawParts.RawQuery)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
u.Proto = proto
|
|
||||||
if u.Proto == ProtoType(Unknown) {
|
|
||||||
u.Proto = ProtoTypeUDP
|
|
||||||
}
|
|
||||||
case SchemeTypeTURNS:
|
|
||||||
proto, err := parseProto(rawParts.RawQuery)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
u.Proto = proto
|
|
||||||
if u.Proto == ProtoType(Unknown) {
|
|
||||||
u.Proto = ProtoTypeTCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &u, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseProto(raw string) (ProtoType, error) {
|
|
||||||
qArgs, err := url.ParseQuery(raw)
|
|
||||||
if err != nil || len(qArgs) > 1 {
|
|
||||||
return ProtoType(Unknown), ErrInvalidQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
var proto ProtoType
|
|
||||||
if rawProto := qArgs.Get("transport"); rawProto != "" {
|
|
||||||
if proto = NewProtoType(rawProto); proto == ProtoType(0) {
|
|
||||||
return ProtoType(Unknown), ErrProtoType
|
|
||||||
}
|
|
||||||
return proto, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(qArgs) > 0 {
|
|
||||||
return ProtoType(Unknown), ErrInvalidQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
return proto, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u URL) String() string {
|
|
||||||
rawURL := u.Scheme.String() + ":" + net.JoinHostPort(u.Host, strconv.Itoa(u.Port))
|
|
||||||
if u.Scheme == SchemeTypeTURN || u.Scheme == SchemeTypeTURNS {
|
|
||||||
rawURL += "?transport=" + u.Proto.String()
|
|
||||||
}
|
|
||||||
return rawURL
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSecure returns whether the this URL's scheme describes secure scheme or not.
|
|
||||||
func (u URL) IsSecure() bool {
|
|
||||||
return u.Scheme == SchemeTypeSTUNS || u.Scheme == SchemeTypeTURNS
|
|
||||||
}
|
|
||||||
|
87
url_test.go
87
url_test.go
@@ -1,87 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package ice
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseURL(t *testing.T) {
|
|
||||||
t.Run("Success", func(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
rawURL string
|
|
||||||
expectedURLString string
|
|
||||||
expectedScheme SchemeType
|
|
||||||
expectedSecure bool
|
|
||||||
expectedHost string
|
|
||||||
expectedPort int
|
|
||||||
expectedProto ProtoType
|
|
||||||
}{
|
|
||||||
{"stun:google.de", "stun:google.de:3478", SchemeTypeSTUN, false, "google.de", 3478, ProtoTypeUDP},
|
|
||||||
{"stun:google.de:1234", "stun:google.de:1234", SchemeTypeSTUN, false, "google.de", 1234, ProtoTypeUDP},
|
|
||||||
{"stuns:google.de", "stuns:google.de:5349", SchemeTypeSTUNS, true, "google.de", 5349, ProtoTypeTCP},
|
|
||||||
{"stun:[::1]:123", "stun:[::1]:123", SchemeTypeSTUN, false, "::1", 123, ProtoTypeUDP},
|
|
||||||
{"turn:google.de", "turn:google.de:3478?transport=udp", SchemeTypeTURN, false, "google.de", 3478, ProtoTypeUDP},
|
|
||||||
{"turns:google.de", "turns:google.de:5349?transport=tcp", SchemeTypeTURNS, true, "google.de", 5349, ProtoTypeTCP},
|
|
||||||
{"turn:google.de?transport=udp", "turn:google.de:3478?transport=udp", SchemeTypeTURN, false, "google.de", 3478, ProtoTypeUDP},
|
|
||||||
{"turns:google.de?transport=tcp", "turns:google.de:5349?transport=tcp", SchemeTypeTURNS, true, "google.de", 5349, ProtoTypeTCP},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
|
||||||
url, err := ParseURL(testCase.rawURL)
|
|
||||||
assert.Nil(t, err, "testCase: %d %v", i, testCase)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, testCase.expectedScheme, url.Scheme, "testCase: %d %v", i, testCase)
|
|
||||||
assert.Equal(t, testCase.expectedURLString, url.String(), "testCase: %d %v", i, testCase)
|
|
||||||
assert.Equal(t, testCase.expectedSecure, url.IsSecure(), "testCase: %d %v", i, testCase)
|
|
||||||
assert.Equal(t, testCase.expectedHost, url.Host, "testCase: %d %v", i, testCase)
|
|
||||||
assert.Equal(t, testCase.expectedPort, url.Port, "testCase: %d %v", i, testCase)
|
|
||||||
assert.Equal(t, testCase.expectedProto, url.Proto, "testCase: %d %v", i, testCase)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("Failure", func(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
rawURL string
|
|
||||||
expectedErr error
|
|
||||||
}{
|
|
||||||
{"", ErrSchemeType},
|
|
||||||
{":::", errMissingProtocolScheme},
|
|
||||||
{"stun:[::1]:123:", errTooManyColonsAddr},
|
|
||||||
{"stun:[::1]:123a", ErrPort},
|
|
||||||
{"google.de", ErrSchemeType},
|
|
||||||
{"stun:", ErrHost},
|
|
||||||
{"stun:google.de:abc", ErrPort},
|
|
||||||
{"stun:google.de?transport=udp", ErrSTUNQuery},
|
|
||||||
{"stuns:google.de?transport=udp", ErrSTUNQuery},
|
|
||||||
{"turn:google.de?trans=udp", ErrInvalidQuery},
|
|
||||||
{"turns:google.de?trans=udp", ErrInvalidQuery},
|
|
||||||
{"turns:google.de?transport=udp&another=1", ErrInvalidQuery},
|
|
||||||
{"turn:google.de?transport=ip", ErrProtoType},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
|
||||||
_, err := ParseURL(testCase.rawURL)
|
|
||||||
var (
|
|
||||||
urlError *url.Error
|
|
||||||
addrError *net.AddrError
|
|
||||||
)
|
|
||||||
switch {
|
|
||||||
case errors.As(err, &urlError):
|
|
||||||
err = urlError.Err
|
|
||||||
case errors.As(err, &addrError):
|
|
||||||
err = fmt.Errorf(addrError.Err) //nolint:goerr113
|
|
||||||
}
|
|
||||||
assert.EqualError(t, err, testCase.expectedErr.Error(), "testCase: %d %v", i, testCase)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
Reference in New Issue
Block a user