// SPDX-FileCopyrightText: 2023 The Pion community // SPDX-License-Identifier: MIT //go:build !js // +build !js package ice import ( "context" "regexp" "testing" "time" "github.com/pion/transport/v3/test" "github.com/stretchr/testify/require" ) func TestMulticastDNSOnlyConnection(t *testing.T) { defer test.CheckRoutines(t)() // Limit runtime in case of deadlocks defer test.TimeOut(time.Second * 30).Stop() type testCase struct { Name string NetworkTypes []NetworkType } testCases := []testCase{ {Name: "UDP4", NetworkTypes: []NetworkType{NetworkTypeUDP4}}, } if ipv6Available(t) { testCases = append(testCases, testCase{Name: "UDP6", NetworkTypes: []NetworkType{NetworkTypeUDP6}}, testCase{Name: "UDP46", NetworkTypes: []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6}}, ) } for _, tc := range testCases { t.Run(tc.Name, func(t *testing.T) { cfg := &AgentConfig{ NetworkTypes: tc.NetworkTypes, CandidateTypes: []CandidateType{CandidateTypeHost}, MulticastDNSMode: MulticastDNSModeQueryAndGather, InterfaceFilter: problematicNetworkInterfaces, } aAgent, err := NewAgent(cfg) require.NoError(t, err) defer func() { require.NoError(t, aAgent.Close()) }() aNotifier, aConnected := onConnected() require.NoError(t, aAgent.OnConnectionStateChange(aNotifier)) bAgent, err := NewAgent(cfg) require.NoError(t, err) defer func() { require.NoError(t, bAgent.Close()) }() bNotifier, bConnected := onConnected() require.NoError(t, bAgent.OnConnectionStateChange(bNotifier)) connect(t, aAgent, bAgent) <-aConnected <-bConnected }) } } func TestMulticastDNSMixedConnection(t *testing.T) { defer test.CheckRoutines(t)() // Limit runtime in case of deadlocks defer test.TimeOut(time.Second * 30).Stop() type testCase struct { Name string NetworkTypes []NetworkType } testCases := []testCase{ {Name: "UDP4", NetworkTypes: []NetworkType{NetworkTypeUDP4}}, } if ipv6Available(t) { testCases = append(testCases, testCase{Name: "UDP6", NetworkTypes: []NetworkType{NetworkTypeUDP6}}, testCase{Name: "UDP46", NetworkTypes: []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6}}, ) } for _, tc := range testCases { t.Run(tc.Name, func(t *testing.T) { aAgent, err := NewAgent(&AgentConfig{ NetworkTypes: tc.NetworkTypes, CandidateTypes: []CandidateType{CandidateTypeHost}, MulticastDNSMode: MulticastDNSModeQueryAndGather, InterfaceFilter: problematicNetworkInterfaces, }) require.NoError(t, err) defer func() { require.NoError(t, aAgent.Close()) }() aNotifier, aConnected := onConnected() require.NoError(t, aAgent.OnConnectionStateChange(aNotifier)) bAgent, err := NewAgent(&AgentConfig{ NetworkTypes: tc.NetworkTypes, CandidateTypes: []CandidateType{CandidateTypeHost}, MulticastDNSMode: MulticastDNSModeQueryOnly, InterfaceFilter: problematicNetworkInterfaces, }) require.NoError(t, err) defer func() { require.NoError(t, bAgent.Close()) }() bNotifier, bConnected := onConnected() require.NoError(t, bAgent.OnConnectionStateChange(bNotifier)) connect(t, aAgent, bAgent) <-aConnected <-bConnected }) } } func TestMulticastDNSStaticHostName(t *testing.T) { defer test.CheckRoutines(t)() defer test.TimeOut(time.Second * 30).Stop() type testCase struct { Name string NetworkTypes []NetworkType } testCases := []testCase{ {Name: "UDP4", NetworkTypes: []NetworkType{NetworkTypeUDP4}}, } if ipv6Available(t) { testCases = append(testCases, testCase{Name: "UDP6", NetworkTypes: []NetworkType{NetworkTypeUDP6}}, testCase{Name: "UDP46", NetworkTypes: []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6}}, ) } for _, tc := range testCases { t.Run(tc.Name, func(t *testing.T) { _, err := NewAgent(&AgentConfig{ NetworkTypes: tc.NetworkTypes, CandidateTypes: []CandidateType{CandidateTypeHost}, MulticastDNSMode: MulticastDNSModeQueryAndGather, MulticastDNSHostName: "invalidHostName", InterfaceFilter: problematicNetworkInterfaces, }) require.Equal(t, err, ErrInvalidMulticastDNSHostName) agent, err := NewAgent(&AgentConfig{ NetworkTypes: tc.NetworkTypes, CandidateTypes: []CandidateType{CandidateTypeHost}, MulticastDNSMode: MulticastDNSModeQueryAndGather, MulticastDNSHostName: "validName.local", InterfaceFilter: problematicNetworkInterfaces, }) require.NoError(t, err) defer func() { require.NoError(t, agent.Close()) }() correctHostName, resolveFunc := context.WithCancel(context.Background()) require.NoError(t, agent.OnCandidate(func(c Candidate) { if c != nil && c.Address() == "validName.local" { resolveFunc() } })) require.NoError(t, agent.GatherCandidates()) <-correctHostName.Done() }) } } func TestGenerateMulticastDNSName(t *testing.T) { name, err := generateMulticastDNSName() require.NoError(t, err) isMDNSName := regexp.MustCompile( `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}.local+$`, ).MatchString require.True(t, isMDNSName(name)) }