diff --git a/agent.go b/agent.go index 54728a2..eb66de8 100644 --- a/agent.go +++ b/agent.go @@ -129,6 +129,7 @@ type Agent struct { udpMuxSrflx UniversalUDPMux interfaceFilter func(string) bool + ipFilter func(net.IP) bool insecureSkipVerify bool @@ -313,6 +314,8 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit interfaceFilter: config.InterfaceFilter, + ipFilter: config.IPFilter, + insecureSkipVerify: config.InsecureSkipVerify, } diff --git a/agent_config.go b/agent_config.go index 08aa158..7e5cedd 100644 --- a/agent_config.go +++ b/agent_config.go @@ -1,6 +1,7 @@ package ice import ( + "net" "time" "github.com/pion/logging" @@ -132,10 +133,14 @@ type AgentConfig struct { // (see github.com/pion/transport/vnet) Net *vnet.Net - // InterfaceFilter is a function that you can use in order to whitelist or blacklist + // InterfaceFilter is a function that you can use in order to whitelist or blacklist // the interfaces which are used to gather ICE candidates. InterfaceFilter func(string) bool + // IPFilter is a function that you can use in order to whitelist or blacklist + // the ips which are used to gather ICE candidates. + IPFilter func(net.IP) bool + // InsecureSkipVerify controls if self-signed certificates are accepted when connecting // to TURN servers via TLS or DTLS InsecureSkipVerify bool diff --git a/gather.go b/gather.go index b83237d..a370f42 100644 --- a/gather.go +++ b/gather.go @@ -149,7 +149,7 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ delete(networks, udp) } - localIPs, err := localInterfaces(a.net, a.interfaceFilter, networkTypes) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, networkTypes) if err != nil { a.log.Warnf("failed to iterate local interfaces, host candidates will not be gathered %s", err) return @@ -273,7 +273,7 @@ func (a *Agent) gatherCandidatesLocalUDPMux(ctx context.Context) error { //nolin return errUDPMuxDisabled } - localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.networkTypes) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, a.networkTypes) switch { case err != nil: return err diff --git a/gather_test.go b/gather_test.go index 6ce344c..901c290 100644 --- a/gather_test.go +++ b/gather_test.go @@ -31,7 +31,7 @@ func TestListenUDP(t *testing.T) { a, err := NewAgent(&AgentConfig{}) assert.NoError(t, err) - localIPs, err := localInterfaces(a.net, a.interfaceFilter, []NetworkType{NetworkTypeUDP4}) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) assert.NotEqual(t, len(localIPs), 0, "localInterfaces found no interfaces, unable to test") assert.NoError(t, err) diff --git a/gather_vnet_test.go b/gather_vnet_test.go index fff589e..f03771a 100644 --- a/gather_vnet_test.go +++ b/gather_vnet_test.go @@ -29,7 +29,7 @@ func TestVNetGather(t *testing.T) { }) assert.NoError(t, err) - localIPs, err := localInterfaces(a.net, a.interfaceFilter, []NetworkType{NetworkTypeUDP4}) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) if len(localIPs) > 0 { t.Fatal("should return no local IP") } else if err != nil { @@ -69,7 +69,7 @@ func TestVNetGather(t *testing.T) { }) assert.NoError(t, err) - localIPs, err := localInterfaces(a.net, a.interfaceFilter, []NetworkType{NetworkTypeUDP4}) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) if len(localIPs) == 0 { t.Fatal("should have one local IP") } else if err != nil { @@ -112,7 +112,7 @@ func TestVNetGather(t *testing.T) { t.Fatalf("Failed to create agent: %s", err) } - localIPs, err := localInterfaces(a.net, a.interfaceFilter, []NetworkType{NetworkTypeUDP4}) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) if len(localIPs) == 0 { t.Fatal("localInterfaces found no interfaces, unable to test") } else if err != nil { @@ -385,7 +385,7 @@ func TestVNetGatherWithInterfaceFilter(t *testing.T) { }) assert.NoError(t, err) - localIPs, err := localInterfaces(a.net, a.interfaceFilter, []NetworkType{NetworkTypeUDP4}) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) if err != nil { t.Fatal(err) } else if len(localIPs) != 0 { @@ -395,6 +395,26 @@ func TestVNetGatherWithInterfaceFilter(t *testing.T) { assert.NoError(t, a.Close()) }) + t.Run("IPFilter should exclude the IP", func(t *testing.T) { + a, err := NewAgent(&AgentConfig{ + Net: nw, + IPFilter: func(ip net.IP) bool { + assert.Equal(t, net.IP{1, 2, 3, 1}, ip) + return false + }, + }) + assert.NoError(t, err) + + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) + if err != nil { + t.Fatal(err) + } else if len(localIPs) != 0 { + t.Fatal("IPFilter should have excluded everything") + } + + assert.NoError(t, a.Close()) + }) + t.Run("InterfaceFilter should not exclude the interface", func(t *testing.T) { a, err := NewAgent(&AgentConfig{ Net: nw, @@ -405,7 +425,7 @@ func TestVNetGatherWithInterfaceFilter(t *testing.T) { }) assert.NoError(t, err) - localIPs, err := localInterfaces(a.net, a.interfaceFilter, []NetworkType{NetworkTypeUDP4}) + localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{NetworkTypeUDP4}) if err != nil { t.Fatal(err) } else if len(localIPs) == 0 { diff --git a/util.go b/util.go index af4c30c..011fd8c 100644 --- a/util.go +++ b/util.go @@ -132,7 +132,7 @@ func stunRequest(read func([]byte) (int, error), write func([]byte) (int, error) return res, nil } -func localInterfaces(vnet *vnet.Net, interfaceFilter func(string) bool, networkTypes []NetworkType) ([]net.IP, error) { //nolint:gocognit +func localInterfaces(vnet *vnet.Net, interfaceFilter func(string) bool, ipFilter func(net.IP) bool, networkTypes []NetworkType) ([]net.IP, error) { //nolint:gocognit ips := []net.IP{} ifaces, err := vnet.Interfaces() if err != nil { @@ -189,6 +189,10 @@ func localInterfaces(vnet *vnet.Net, interfaceFilter func(string) bool, networkT continue } + if ipFilter != nil && !ipFilter(ip) { + continue + } + ips = append(ips, ip) } }