Files
ice/external_ip_mapper_test.go
Joe Turki cad1676659 Upgrade golangci-lint, more linters
Introduces new linters, upgrade golangci-lint to version (v1.63.4)
2025-01-17 08:21:15 -06:00

310 lines
10 KiB
Go

// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
package ice
import (
"net"
"testing"
"github.com/stretchr/testify/require"
)
func TestExternalIPMapper(t *testing.T) { //nolint:maintidx
t.Run("validateIPString", func(t *testing.T) {
var ip net.IP
var isIPv4 bool
var err error
ip, isIPv4, err = validateIPString("1.2.3.4")
require.NoError(t, err, "should succeed")
require.True(t, isIPv4, "should be true")
require.Equal(t, "1.2.3.4", ip.String(), "should be true")
ip, isIPv4, err = validateIPString("2601:4567::5678")
require.NoError(t, err, "should succeed")
require.False(t, isIPv4, "should be false")
require.Equal(t, "2601:4567::5678", ip.String(), "should be true")
_, _, err = validateIPString("bad.6.6.6")
require.Error(t, err, "should fail")
})
t.Run("newExternalIPMapper", func(t *testing.T) {
var mapper *externalIPMapper
var err error
// ips being nil should succeed but mapper will be nil also
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, nil)
require.NoError(t, err, "should succeed")
require.Nil(t, mapper, "should be nil")
// ips being empty should succeed but mapper will still be nil
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{})
require.NoError(t, err, "should succeed")
require.Nil(t, mapper, "should be nil")
// IPv4 with no explicit local IP, defaults to CandidateTypeHost
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
require.Equal(t, CandidateTypeHost, mapper.candidateType, "should match")
require.NotNil(t, mapper.ipv4Mapping.ipSole)
require.Nil(t, mapper.ipv6Mapping.ipSole)
require.Equal(t, 0, len(mapper.ipv4Mapping.ipMap), "should match")
require.Equal(t, 0, len(mapper.ipv6Mapping.ipMap), "should match")
// IPv4 with no explicit local IP, using CandidateTypeServerReflexive
mapper, err = newExternalIPMapper(CandidateTypeServerReflexive, []string{
"1.2.3.4",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
require.Equal(t, CandidateTypeServerReflexive, mapper.candidateType, "should match")
require.NotNil(t, mapper.ipv4Mapping.ipSole)
require.Nil(t, mapper.ipv6Mapping.ipSole)
require.Equal(t, 0, len(mapper.ipv4Mapping.ipMap), "should match")
require.Equal(t, 0, len(mapper.ipv6Mapping.ipMap), "should match")
// IPv4 with no explicit local IP, defaults to CandidateTypeHost
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"2601:4567::5678",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
require.Equal(t, CandidateTypeHost, mapper.candidateType, "should match")
require.Nil(t, mapper.ipv4Mapping.ipSole)
require.NotNil(t, mapper.ipv6Mapping.ipSole)
require.Equal(t, 0, len(mapper.ipv4Mapping.ipMap), "should match")
require.Equal(t, 0, len(mapper.ipv6Mapping.ipMap), "should match")
// IPv4 and IPv6 in the mix
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4",
"2601:4567::5678",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
require.Equal(t, CandidateTypeHost, mapper.candidateType, "should match")
require.NotNil(t, mapper.ipv4Mapping.ipSole)
require.NotNil(t, mapper.ipv6Mapping.ipSole)
require.Equal(t, 0, len(mapper.ipv4Mapping.ipMap), "should match")
require.Equal(t, 0, len(mapper.ipv6Mapping.ipMap), "should match")
// Unsupported candidate type - CandidateTypePeerReflexive
mapper, err = newExternalIPMapper(CandidateTypePeerReflexive, []string{
"1.2.3.4",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Unsupported candidate type - CandidateTypeRelay
mapper, err = newExternalIPMapper(CandidateTypePeerReflexive, []string{
"1.2.3.4",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Cannot duplicate mapping IPv4 family
mapper, err = newExternalIPMapper(CandidateTypeServerReflexive, []string{
"1.2.3.4",
"5.6.7.8",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Cannot duplicate mapping IPv6 family
mapper, err = newExternalIPMapper(CandidateTypeServerReflexive, []string{
"2201::1",
"2201::0002",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Invalide external IP string
mapper, err = newExternalIPMapper(CandidateTypeServerReflexive, []string{
"bad.2.3.4",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Invalide local IP string
mapper, err = newExternalIPMapper(CandidateTypeServerReflexive, []string{
"1.2.3.4/10.0.0.bad",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
})
t.Run("newExternalIPMapper with explicit local IP", func(t *testing.T) {
var mapper *externalIPMapper
var err error
// IPv4 with explicit local IP, defaults to CandidateTypeHost
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4/10.0.0.1",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
require.Equal(t, CandidateTypeHost, mapper.candidateType, "should match")
require.Nil(t, mapper.ipv4Mapping.ipSole)
require.Nil(t, mapper.ipv6Mapping.ipSole)
require.Equal(t, 1, len(mapper.ipv4Mapping.ipMap), "should match")
require.Equal(t, 0, len(mapper.ipv6Mapping.ipMap), "should match")
// Cannot assign two ext IPs for one local IPv4
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4/10.0.0.1",
"1.2.3.5/10.0.0.1",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Cannot assign two ext IPs for one local IPv6
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"2200::1/fe80::1",
"2200::0002/fe80::1",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Cannot mix different IP family in a pair (1)
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"2200::1/10.0.0.1",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Cannot mix different IP family in a pair (2)
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4/fe80::1",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
// Invalid pair
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4/192.168.0.2/10.0.0.1",
})
require.Error(t, err, "should fail")
require.Nil(t, mapper, "should be nil")
})
t.Run("newExternalIPMapper with implicit and explicit local IP", func(t *testing.T) {
// Mixing implicit and explicit local IPs not allowed
_, err := newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4",
"1.2.3.5/10.0.0.1",
})
require.Error(t, err, "should fail")
// Mixing implicit and explicit local IPs not allowed
_, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.5/10.0.0.1",
"1.2.3.4",
})
require.Error(t, err, "should fail")
})
t.Run("findExternalIP without explicit local IP", func(t *testing.T) {
var mapper *externalIPMapper
var err error
var extIP net.IP
// IPv4 with explicit local IP, defaults to CandidateTypeHost
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4",
"2200::1",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
require.NotNil(t, mapper.ipv4Mapping.ipSole)
require.NotNil(t, mapper.ipv6Mapping.ipSole)
// Find external IPv4
extIP, err = mapper.findExternalIP("10.0.0.1")
require.NoError(t, err, "should succeed")
require.Equal(t, "1.2.3.4", extIP.String(), "should match")
// Find external IPv6
extIP, err = mapper.findExternalIP("fe80::0001") // Use '0001' instead of '1' on purpose
require.NoError(t, err, "should succeed")
require.Equal(t, "2200::1", extIP.String(), "should match")
// Bad local IP string
_, err = mapper.findExternalIP("really.bad")
require.Error(t, err, "should fail")
})
t.Run("findExternalIP with explicit local IP", func(t *testing.T) {
var mapper *externalIPMapper
var err error
var extIP net.IP
// IPv4 with explicit local IP, defaults to CandidateTypeHost
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4/10.0.0.1",
"1.2.3.5/10.0.0.2",
"2200::1/fe80::1",
"2200::2/fe80::2",
})
require.NoError(t, err, "should succeed")
require.NotNil(t, mapper, "should not be nil")
// Find external IPv4
extIP, err = mapper.findExternalIP("10.0.0.1")
require.NoError(t, err, "should succeed")
require.Equal(t, "1.2.3.4", extIP.String(), "should match")
extIP, err = mapper.findExternalIP("10.0.0.2")
require.NoError(t, err, "should succeed")
require.Equal(t, "1.2.3.5", extIP.String(), "should match")
_, err = mapper.findExternalIP("10.0.0.3")
require.Error(t, err, "should fail")
// Find external IPv6
extIP, err = mapper.findExternalIP("fe80::0001") // Use '0001' instead of '1' on purpose
require.NoError(t, err, "should succeed")
require.Equal(t, "2200::1", extIP.String(), "should match")
extIP, err = mapper.findExternalIP("fe80::0002") // Use '0002' instead of '2' on purpose
require.NoError(t, err, "should succeed")
require.Equal(t, "2200::2", extIP.String(), "should match")
_, err = mapper.findExternalIP("fe80::3")
require.Error(t, err, "should fail")
// Bad local IP string
_, err = mapper.findExternalIP("really.bad")
require.Error(t, err, "should fail")
})
t.Run("findExternalIP with empty map", func(t *testing.T) {
var mapper *externalIPMapper
var err error
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"1.2.3.4",
})
require.NoError(t, err, "should succeed")
// Attempt to find IPv6 that does not exist in the map
extIP, err := mapper.findExternalIP("fe80::1")
require.NoError(t, err, "should succeed")
require.Equal(t, "fe80::1", extIP.String(), "should match")
mapper, err = newExternalIPMapper(CandidateTypeUnspecified, []string{
"2200::1",
})
require.NoError(t, err, "should succeed")
// Attempt to find IPv4 that does not exist in the map
extIP, err = mapper.findExternalIP("10.0.0.1")
require.NoError(t, err, "should succeed")
require.Equal(t, "10.0.0.1", extIP.String(), "should match")
})
}