diff --git a/agent.go b/agent.go index e896756..fa688b4 100644 --- a/agent.go +++ b/agent.go @@ -105,7 +105,7 @@ type Agent struct { selectedPair atomic.Value // *CandidatePair - urls []*URL + urls []*stun.URI networkTypes []NetworkType buf *packetio.Buffer diff --git a/agent_config.go b/agent_config.go index 04d74b1..f5897cd 100644 --- a/agent_config.go +++ b/agent_config.go @@ -8,6 +8,7 @@ import ( "time" "github.com/pion/logging" + "github.com/pion/stun" "github.com/pion/transport/v2" "golang.org/x/net/proxy" ) @@ -54,7 +55,7 @@ func defaultCandidateTypes() []CandidateType { // AgentConfig collects the arguments to ice.Agent construction into // a single structure, for future-proofness of the interface type AgentConfig struct { - Urls []*URL + Urls []*stun.URI // PortMin and PortMax are optional. Leave them 0 for the default UDP port allocation strategy. PortMin uint16 diff --git a/agent_test.go b/agent_test.go index b7d6dea..e6e07c4 100644 --- a/agent_test.go +++ b/agent_test.go @@ -301,11 +301,11 @@ func TestConnectivityLite(t *testing.T) { lim := test.TimeOut(time.Second * 30) defer lim.Stop() - stunServerURL := &URL{ + stunServerURL := &stun.URI{ Scheme: SchemeTypeSTUN, Host: "1.2.3.4", Port: 3478, - Proto: ProtoTypeUDP, + Proto: stun.ProtoTypeUDP, } natType := &vnet.NATType{ @@ -320,7 +320,7 @@ func TestConnectivityLite(t *testing.T) { bNotifier, bConnected := onConnected() cfg0 := &AgentConfig{ - Urls: []*URL{stunServerURL}, + Urls: []*stun.URI{stunServerURL}, NetworkTypes: supportedNetworkTypes(), MulticastDNSMode: MulticastDNSModeDisabled, Net: v.net0, @@ -331,7 +331,7 @@ func TestConnectivityLite(t *testing.T) { require.NoError(t, aAgent.OnConnectionStateChange(aNotifier)) cfg1 := &AgentConfig{ - Urls: []*URL{}, + Urls: []*stun.URI{}, Lite: true, CandidateTypes: []CandidateType{CandidateTypeHost}, NetworkTypes: supportedNetworkTypes(), @@ -548,7 +548,7 @@ func TestConnectionStateCallback(t *testing.T) { KeepaliveInterval := time.Duration(0) cfg := &AgentConfig{ - Urls: []*URL{}, + Urls: []*stun.URI{}, NetworkTypes: supportedNetworkTypes(), DisconnectedTimeout: &disconnectedDuration, FailedTimeout: &failedDuration, @@ -1330,7 +1330,7 @@ func TestCloseInConnectionStateCallback(t *testing.T) { CheckInterval := 500 * time.Millisecond cfg := &AgentConfig{ - Urls: []*URL{}, + Urls: []*stun.URI{}, NetworkTypes: supportedNetworkTypes(), DisconnectedTimeout: &disconnectedDuration, FailedTimeout: &failedDuration, @@ -1382,7 +1382,7 @@ func TestRunTaskInConnectionStateCallback(t *testing.T) { CheckInterval := 50 * time.Millisecond cfg := &AgentConfig{ - Urls: []*URL{}, + Urls: []*stun.URI{}, NetworkTypes: supportedNetworkTypes(), DisconnectedTimeout: &oneSecond, FailedTimeout: &oneSecond, @@ -1427,7 +1427,7 @@ func TestRunTaskInSelectedCandidatePairChangeCallback(t *testing.T) { CheckInterval := 50 * time.Millisecond cfg := &AgentConfig{ - Urls: []*URL{}, + Urls: []*stun.URI{}, NetworkTypes: supportedNetworkTypes(), DisconnectedTimeout: &oneSecond, FailedTimeout: &oneSecond, diff --git a/candidate_relay_test.go b/candidate_relay_test.go index 76054a1..870f76a 100644 --- a/candidate_relay_test.go +++ b/candidate_relay_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/pion/stun" "github.com/pion/transport/v2/test" "github.com/pion/turn/v2" "github.com/stretchr/testify/assert" @@ -47,14 +48,14 @@ func TestRelayOnlyConnection(t *testing.T) { cfg := &AgentConfig{ NetworkTypes: supportedNetworkTypes(), - Urls: []*URL{ + Urls: []*stun.URI{ { - Scheme: SchemeTypeTURN, + Scheme: stun.SchemeTypeTURN, Host: "127.0.0.1", Username: "username", Password: "password", Port: serverPort, - Proto: ProtoTypeUDP, + Proto: stun.ProtoTypeUDP, }, }, CandidateTypes: []CandidateType{CandidateTypeRelay}, diff --git a/candidate_server_reflexive_test.go b/candidate_server_reflexive_test.go index c226f93..953d84a 100644 --- a/candidate_server_reflexive_test.go +++ b/candidate_server_reflexive_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/pion/stun" "github.com/pion/transport/v2/test" "github.com/pion/turn/v2" "github.com/stretchr/testify/assert" @@ -43,7 +44,7 @@ func TestServerReflexiveOnlyConnection(t *testing.T) { cfg := &AgentConfig{ NetworkTypes: []NetworkType{NetworkTypeUDP4}, - Urls: []*URL{ + Urls: []*stun.URI{ { Scheme: SchemeTypeSTUN, Host: "127.0.0.1", diff --git a/connectivity_vnet_test.go b/connectivity_vnet_test.go index a9e993f..b8f8dd3 100644 --- a/connectivity_vnet_test.go +++ b/connectivity_vnet_test.go @@ -226,7 +226,7 @@ func connectWithVNet(aAgent, bAgent *Agent) (*Conn, *Conn) { } type agentTestConfig struct { - urls []*URL + urls []*stun.URI nat1To1IPCandidateType CandidateType } @@ -305,20 +305,20 @@ func TestConnectivityVNet(t *testing.T) { report := test.CheckRoutines(t) defer report() - stunServerURL := &URL{ - Scheme: SchemeTypeSTUN, + stunServerURL := &stun.URI{ + Scheme: stun.SchemeTypeSTUN, Host: vnetSTUNServerIP, Port: vnetSTUNServerPort, - Proto: ProtoTypeUDP, + Proto: stun.ProtoTypeUDP, } - turnServerURL := &URL{ - Scheme: SchemeTypeTURN, + turnServerURL := &stun.URI{ + Scheme: stun.SchemeTypeTURN, Host: vnetSTUNServerIP, Port: vnetSTUNServerPort, Username: "user", Password: "pass", - Proto: ProtoTypeUDP, + Proto: stun.ProtoTypeUDP, } t.Run("Full-cone NATs on both ends", func(t *testing.T) { @@ -339,12 +339,12 @@ func TestConnectivityVNet(t *testing.T) { log.Debug("Connecting...") a0TestConfig := &agentTestConfig{ - urls: []*URL{ + urls: []*stun.URI{ stunServerURL, }, } a1TestConfig := &agentTestConfig{ - urls: []*URL{ + urls: []*stun.URI{ stunServerURL, }, } @@ -376,13 +376,13 @@ func TestConnectivityVNet(t *testing.T) { log.Debug("Connecting...") a0TestConfig := &agentTestConfig{ - urls: []*URL{ + urls: []*stun.URI{ stunServerURL, turnServerURL, }, } a1TestConfig := &agentTestConfig{ - urls: []*URL{ + urls: []*stun.URI{ stunServerURL, }, } @@ -416,11 +416,11 @@ func TestConnectivityVNet(t *testing.T) { log.Debug("Connecting...") a0TestConfig := &agentTestConfig{ - urls: []*URL{}, + urls: []*stun.URI{}, nat1To1IPCandidateType: CandidateTypeHost, // Use 1:1 NAT IP as a host candidate } a1TestConfig := &agentTestConfig{ - urls: []*URL{}, + urls: []*stun.URI{}, } ca, cb := pipeWithVNet(v, a0TestConfig, a1TestConfig) @@ -452,11 +452,11 @@ func TestConnectivityVNet(t *testing.T) { log.Debug("Connecting...") a0TestConfig := &agentTestConfig{ - urls: []*URL{}, + urls: []*stun.URI{}, nat1To1IPCandidateType: CandidateTypeServerReflexive, // Use 1:1 NAT IP as a srflx candidate } a1TestConfig := &agentTestConfig{ - urls: []*URL{}, + urls: []*stun.URI{}, } ca, cb := pipeWithVNet(v, a0TestConfig, a1TestConfig) diff --git a/errors.go b/errors.go index eaae591..e05cce8 100644 --- a/errors.go +++ b/errors.go @@ -124,8 +124,6 @@ var ( errReadingStreamingPacket = errors.New("error reading streaming packet") errWriting = errors.New("error writing to") 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") errUnknownRole = errors.New("unknown role") errICEWriteSTUNMessage = errors.New("the ICE conn can't write STUN messages") diff --git a/gather.go b/gather.go index eab5ca7..15e2da1 100644 --- a/gather.go +++ b/gather.go @@ -17,6 +17,7 @@ import ( "github.com/pion/ice/v2/internal/fakenet" stunx "github.com/pion/ice/v2/internal/stun" "github.com/pion/logging" + "github.com/pion/stun" "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 defer wg.Wait() @@ -393,7 +394,7 @@ func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*URL, ne continue } 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() 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 defer wg.Wait() @@ -455,7 +456,7 @@ func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*URL, networkT for i := range urls { wg.Add(1) - go func(url URL, network string) { + go func(url stun.URI, network string) { defer wg.Done() 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 defer wg.Wait() network := NetworkTypeUDP4.String() for i := range urls { switch { - case urls[i].Scheme != SchemeTypeTURN && urls[i].Scheme != SchemeTypeTURNS: + case urls[i].Scheme != stun.SchemeTypeTURN && urls[i].Scheme != stun.SchemeTypeTURNS: continue case urls[i].Username == "": 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) - go func(url URL) { + go func(url stun.URI) { defer wg.Done() turnServerAddr := fmt.Sprintf("%s:%d", url.Host, url.Port) var ( @@ -548,7 +549,7 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli ) 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 { a.log.Warnf("Failed to listen %s: %v", network, err) return @@ -557,8 +558,8 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) { //noli relAddr = locConn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert relPort = locConn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert relayProtocol = udp - case a.proxyDialer != nil && url.Proto == ProtoTypeTCP && - (url.Scheme == SchemeTypeTURN || url.Scheme == SchemeTypeTURNS): + case a.proxyDialer != nil && url.Proto == stun.ProtoTypeTCP && + (url.Scheme == stun.SchemeTypeTURN || url.Scheme == stun.SchemeTypeTURNS): conn, connectErr := a.proxyDialer.Dial(NetworkTypeTCP4.String(), turnServerAddr) if connectErr != nil { 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 relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert - if url.Scheme == SchemeTypeTURN { + if url.Scheme == stun.SchemeTypeTURN { relayProtocol = tcp - } else if url.Scheme == SchemeTypeTURNS { + } else if url.Scheme == stun.SchemeTypeTURNS { relayProtocol = "tls" } 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) if connectErr != nil { 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 relayProtocol = tcp 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) if connectErr != nil { 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 relayProtocol = "dtls" 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) if resolvErr != nil { a.log.Warnf("Failed to resolve relay address %s: %v", turnServerAddr, resolvErr) diff --git a/gather_test.go b/gather_test.go index 14583c2..9baf11b 100644 --- a/gather_test.go +++ b/gather_test.go @@ -224,16 +224,16 @@ func TestSTUNConcurrency(t *testing.T) { }) assert.NoError(t, err) - urls := []*URL{} + urls := []*stun.URI{} for i := 0; i <= 10; i++ { - urls = append(urls, &URL{ - Scheme: SchemeTypeSTUN, + urls = append(urls, &stun.URI{ + Scheme: stun.SchemeTypeSTUN, Host: "127.0.0.1", Port: serverPort + 1, }) } - urls = append(urls, &URL{ - Scheme: SchemeTypeSTUN, + urls = append(urls, &stun.URI{ + Scheme: stun.SchemeTypeSTUN, Host: "127.0.0.1", Port: serverPort, }) @@ -284,7 +284,7 @@ func TestTURNConcurrency(t *testing.T) { lim := test.TimeOut(time.Second * 30) 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{} if packetConn != nil { packetConnConfigs = append(packetConnConfigs, turn.PacketConnConfig{ @@ -309,9 +309,9 @@ func TestTURNConcurrency(t *testing.T) { }) assert.NoError(t, err) - urls := []*URL{} + urls := []*stun.URI{} for i := 0; i <= 10; i++ { - urls = append(urls, &URL{ + urls = append(urls, &stun.URI{ Scheme: scheme, Host: "127.0.0.1", Username: "username", @@ -320,7 +320,7 @@ func TestTURNConcurrency(t *testing.T) { Port: serverPort + 1 + i, }) } - urls = append(urls, &URL{ + urls = append(urls, &stun.URI{ Scheme: scheme, Host: "127.0.0.1", Username: "username", @@ -356,7 +356,7 @@ func TestTURNConcurrency(t *testing.T) { serverListener, err := net.ListenPacket("udp", "127.0.0.1:"+strconv.Itoa(serverPort)) 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) { @@ -364,7 +364,7 @@ func TestTURNConcurrency(t *testing.T) { serverListener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(serverPort)) 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) { @@ -377,7 +377,7 @@ func TestTURNConcurrency(t *testing.T) { }) 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) { @@ -390,7 +390,7 @@ func TestTURNConcurrency(t *testing.T) { }) 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) - urls := []*URL{} + urls := []*stun.URI{} for i := 0; i <= 10; i++ { - urls = append(urls, &URL{ - Scheme: SchemeTypeSTUN, + urls = append(urls, &stun.URI{ + Scheme: stun.SchemeTypeSTUN, Host: "127.0.0.1", Port: serverPort + 1, }) } - urls = append(urls, &URL{ - Scheme: SchemeTypeTURN, - Proto: ProtoTypeUDP, + urls = append(urls, &stun.URI{ + Scheme: stun.SchemeTypeTURN, + Proto: stun.ProtoTypeUDP, Host: "127.0.0.1", Port: serverPort, Username: "username", @@ -490,9 +490,9 @@ func TestTURNSrflx(t *testing.T) { }) assert.NoError(t, err) - urls := []*URL{{ - Scheme: SchemeTypeTURN, - Proto: ProtoTypeUDP, + urls := []*stun.URI{{ + Scheme: stun.SchemeTypeTURN, + Proto: stun.ProtoTypeUDP, Host: "127.0.0.1", Port: serverPort, Username: "username", @@ -574,13 +574,13 @@ func TestTURNProxyDialer(t *testing.T) { a, err := NewAgent(&AgentConfig{ CandidateTypes: []CandidateType{CandidateTypeRelay}, NetworkTypes: supportedNetworkTypes(), - Urls: []*URL{ + Urls: []*stun.URI{ { - Scheme: SchemeTypeTURN, + Scheme: stun.SchemeTypeTURN, Host: "127.0.0.1", Username: "username", Password: "password", - Proto: ProtoTypeTCP, + Proto: stun.ProtoTypeTCP, Port: 5000, }, }, @@ -782,9 +782,9 @@ func TestUniversalUDPMuxUsage(t *testing.T) { } numSTUNS := 3 - urls := []*URL{} + urls := []*stun.URI{} for i := 0; i < numSTUNS; i++ { - urls = append(urls, &URL{ + urls = append(urls, &stun.URI{ Scheme: SchemeTypeSTUN, Host: "127.0.0.1", Port: 3478 + i, diff --git a/gather_vnet_test.go b/gather_vnet_test.go index 084d279..3f344bd 100644 --- a/gather_vnet_test.go +++ b/gather_vnet_test.go @@ -14,6 +14,7 @@ import ( "testing" "github.com/pion/logging" + "github.com/pion/stun" "github.com/pion/transport/v2/test" "github.com/pion/transport/v2/vnet" "github.com/stretchr/testify/assert" @@ -445,13 +446,13 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) { report := test.CheckRoutines(t) defer report() - turnServerURL := &URL{ - Scheme: SchemeTypeTURN, + turnServerURL := &stun.URI{ + Scheme: stun.SchemeTypeTURN, Host: vnetSTUNServerIP, Port: vnetSTUNServerPort, Username: "user", Password: "pass", - Proto: ProtoTypeUDP, + Proto: stun.ProtoTypeUDP, } // buildVNet with a Symmetric NATs for both LANs @@ -467,7 +468,7 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) { defer v.close() cfg0 := &AgentConfig{ - Urls: []*URL{ + Urls: []*stun.URI{ turnServerURL, }, NetworkTypes: supportedNetworkTypes(), @@ -480,7 +481,7 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) { return } - aAgent.gatherCandidatesRelay(context.Background(), []*URL{turnServerURL}) + aAgent.gatherCandidatesRelay(context.Background(), []*stun.URI{turnServerURL}) // Assert relay conn leak on close. assert.NoError(t, aAgent.Close()) } diff --git a/ice.go b/ice.go index 9769ae1..441420b 100644 --- a/ice.go +++ b/ice.go @@ -8,8 +8,11 @@ type ConnectionState int // List of supported States const ( + // ConnectionStateUnknown represents an unknown state + ConnectionStateUnknown = iota + // 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 @@ -55,8 +58,11 @@ func (c ConnectionState) String() string { type GatheringState int const ( + // GatheringStateUnknown represents an unknown state + GatheringStateUnknown GatheringState = iota + // GatheringStateNew indicates candidate gathering is not yet started - GatheringStateNew GatheringState = iota + 1 + GatheringStateNew // GatheringStateGathering indicates candidate gathering is ongoing GatheringStateGathering diff --git a/ice_test.go b/ice_test.go index d203d09..5740cd1 100644 --- a/ice_test.go +++ b/ice_test.go @@ -14,7 +14,7 @@ func TestConnectedState_String(t *testing.T) { connectionState ConnectionState expectedString string }{ - {ConnectionState(Unknown), "Invalid"}, + {ConnectionStateUnknown, "Invalid"}, {ConnectionStateNew, "New"}, {ConnectionStateChecking, "Checking"}, {ConnectionStateConnected, "Connected"}, @@ -38,7 +38,7 @@ func TestGatheringState_String(t *testing.T) { gatheringState GatheringState expectedString string }{ - {GatheringState(Unknown), ErrUnknownType.Error()}, + {GatheringStateUnknown, ErrUnknownType.Error()}, {GatheringStateNew, "new"}, {GatheringStateGathering, "gathering"}, {GatheringStateComplete, "complete"}, diff --git a/transport_test.go b/transport_test.go index b47287d..c9861a7 100644 --- a/transport_test.go +++ b/transport_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "github.com/pion/stun" "github.com/pion/transport/v2/test" ) @@ -228,7 +229,7 @@ func connect(aAgent, bAgent *Agent) (*Conn, *Conn) { } func pipe(defaultConfig *AgentConfig) (*Conn, *Conn) { - var urls []*URL + var urls []*stun.URI aNotifier, aConnected := onConnected() bNotifier, bConnected := onConnected() @@ -261,7 +262,7 @@ func pipe(defaultConfig *AgentConfig) (*Conn, *Conn) { } func pipeWithTimeout(disconnectTimeout time.Duration, iceKeepalive time.Duration) (*Conn, *Conn) { - var urls []*URL + var urls []*stun.URI aNotifier, aConnected := onConnected() bNotifier, bConnected := onConnected() diff --git a/transport_vnet_test.go b/transport_vnet_test.go index ffdfd38..976cf73 100644 --- a/transport_vnet_test.go +++ b/transport_vnet_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/pion/stun" "github.com/pion/transport/v2/test" "github.com/pion/transport/v2/vnet" "github.com/stretchr/testify/assert" @@ -37,11 +38,11 @@ func TestRemoteLocalAddr(t *testing.T) { } defer v.close() - stunServerURL := &URL{ - Scheme: SchemeTypeSTUN, + stunServerURL := &stun.URI{ + Scheme: stun.SchemeTypeSTUN, Host: vnetSTUNServerIP, Port: vnetSTUNServerPort, - Proto: ProtoTypeUDP, + Proto: stun.ProtoTypeUDP, } 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) { ca, cb := pipeWithVNet(v, &agentTestConfig{ - urls: []*URL{stunServerURL}, + urls: []*stun.URI{stunServerURL}, }, &agentTestConfig{ - urls: []*URL{stunServerURL}, + urls: []*stun.URI{stunServerURL}, }, ) diff --git a/url.go b/url.go index 747379e..b2b9f8b 100644 --- a/url.go +++ b/url.go @@ -3,228 +3,80 @@ package ice -import ( - "errors" - "net" - "net/url" - "strconv" +import "github.com/pion/stun" + +type ( + // URL represents a STUN (rfc7064) or TURN (rfc7065) URI + // + // 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 ( // 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 + // + // Deprecated: Please use pion/stun.SchemeTypeSTUNS + SchemeTypeSTUNS = stun.SchemeTypeSTUNS // 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 + // + // 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 ( // 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 + // + // Deprecated: Please use pion/stun.ProtoTypeTCP + ProtoTypeTCP = stun.ProtoTypeTCP ) -// NewProtoType defines a procedure for creating a new ProtoType from a raw -// string naming the transport protocol type. -func NewProtoType(raw string) ProtoType { - switch raw { - 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 -} +// Unknown represents and unknown ProtoType or SchemeType +// +// Deprecated: Please use pion/stun.SchemeTypeUnknown or pion/stun.ProtoTypeUnknown +const Unknown = 0 // 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 // respectively. -func ParseURL(raw string) (*URL, error) { //nolint:gocognit - rawParts, err := url.Parse(raw) - if err != nil { - return nil, err - } +// +// Deprecated: Please use pion/stun.ParseURI +var ParseURL = stun.ParseURI //nolint:gochecknoglobals - var u URL - u.Scheme = NewSchemeType(rawParts.Scheme) - if u.Scheme == SchemeType(Unknown) { - return nil, ErrSchemeType - } +// NewSchemeType defines a procedure for creating a new SchemeType from a raw +// string naming the scheme type. +// +// Deprecated: Please use pion/stun.NewSchemeType +var NewSchemeType = stun.NewSchemeType //nolint:gochecknoglobals - var rawPort string - if u.Host, rawPort, err = net.SplitHostPort(rawParts.Opaque); err != nil { - var e *net.AddrError - if errors.As(err, &e) { - if e.Err == "missing port in address" { - 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 -} +// NewProtoType defines a procedure for creating a new ProtoType from a raw +// string naming the transport protocol type. +// +// Deprecated: Please use pion/stun.NewProtoType +var NewProtoType = stun.NewProtoType //nolint:gochecknoglobals diff --git a/url_test.go b/url_test.go deleted file mode 100644 index 9c010c5..0000000 --- a/url_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// 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) - } - }) -}