mirror of
https://github.com/netbirdio/ice.git
synced 2026-05-22 17:10:58 -07:00
Add a customization to control network types
- Fix an issue with ipv6 srflx candidates gathering. - Add SetNetworkTypes config to SettingEngine to control what network types are allowed to be connected. Resolves #460
This commit is contained in:
@@ -119,6 +119,10 @@ type AgentConfig struct {
|
||||
// when this is nil, it defaults to 10 seconds.
|
||||
// A keepalive interval of 0 means we never send keepalive packets
|
||||
KeepaliveInterval *time.Duration
|
||||
|
||||
// NetworkTypes is an optional configuration for disabling or enablding
|
||||
// support for specific network types.
|
||||
NetworkTypes []NetworkType
|
||||
}
|
||||
|
||||
// NewAgent creates a new Agent
|
||||
@@ -158,8 +162,8 @@ func NewAgent(config *AgentConfig) (*Agent, error) {
|
||||
}
|
||||
|
||||
// Initialize local candidates
|
||||
a.gatherCandidatesLocal()
|
||||
a.gatherCandidatesReflective(config.Urls)
|
||||
a.gatherCandidatesLocal(config.NetworkTypes)
|
||||
a.gatherCandidatesReflective(config.Urls, config.NetworkTypes)
|
||||
|
||||
go a.taskLoop()
|
||||
return a, nil
|
||||
@@ -211,8 +215,8 @@ func (a *Agent) listenUDP(network string, laddr *net.UDPAddr) (*net.UDPConn, err
|
||||
return nil, ErrPort
|
||||
}
|
||||
|
||||
func (a *Agent) gatherCandidatesLocal() {
|
||||
localIPs := localInterfaces()
|
||||
func (a *Agent) gatherCandidatesLocal(networkTypes []NetworkType) {
|
||||
localIPs := localInterfaces(networkTypes)
|
||||
for _, ip := range localIPs {
|
||||
for _, network := range supportedNetworks {
|
||||
conn, err := a.listenUDP(network, &net.UDPAddr{IP: ip, Port: 0})
|
||||
@@ -238,8 +242,8 @@ func (a *Agent) gatherCandidatesLocal() {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Agent) gatherCandidatesReflective(urls []*URL) {
|
||||
for _, networkType := range supportedNetworkTypes {
|
||||
func (a *Agent) gatherCandidatesReflective(urls []*URL, networkTypes []NetworkType) {
|
||||
for _, networkType := range networkTypes {
|
||||
network := networkType.String()
|
||||
for _, url := range urls {
|
||||
switch url.Scheme {
|
||||
|
||||
+24
-2
@@ -30,13 +30,13 @@ const (
|
||||
// NetworkTypeUDP4 indicates UDP over IPv4.
|
||||
NetworkTypeUDP4 NetworkType = iota + 1
|
||||
|
||||
// NetworkTypeUDP6 indicates UDP over IPv4.
|
||||
// NetworkTypeUDP6 indicates UDP over IPv6.
|
||||
NetworkTypeUDP6
|
||||
|
||||
// NetworkTypeTCP4 indicates TCP over IPv4.
|
||||
NetworkTypeTCP4
|
||||
|
||||
// NetworkTypeTCP6 indicates TCP over IPv4.
|
||||
// NetworkTypeTCP6 indicates TCP over IPv6.
|
||||
NetworkTypeTCP6
|
||||
)
|
||||
|
||||
@@ -78,6 +78,28 @@ func (t NetworkType) IsReliable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsIPv4 returns whether the network type is IPv4 or not.
|
||||
func (t NetworkType) IsIPv4() bool {
|
||||
switch t {
|
||||
case NetworkTypeUDP4, NetworkTypeTCP4:
|
||||
return true
|
||||
case NetworkTypeUDP6, NetworkTypeTCP6:
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsIPv6 returns whether the network type is IPv6 or not.
|
||||
func (t NetworkType) IsIPv6() bool {
|
||||
switch t {
|
||||
case NetworkTypeUDP4, NetworkTypeTCP4:
|
||||
return false
|
||||
case NetworkTypeUDP6, NetworkTypeTCP6:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// determineNetworkType determines the type of network based on
|
||||
// the short network string and an IP address.
|
||||
func determineNetworkType(network string, ip net.IP) (NetworkType, error) {
|
||||
|
||||
+25
-9
@@ -33,7 +33,7 @@ func testTimeout(t *testing.T, c *Conn, timeout time.Duration) {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
//we should never get here.
|
||||
// we should never get here.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func TestTimeout(t *testing.T) {
|
||||
err := cb.Close()
|
||||
|
||||
if err != nil {
|
||||
//we should never get here.
|
||||
// we should never get here.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestTimeout(t *testing.T) {
|
||||
err = cb.Close()
|
||||
|
||||
if err != nil {
|
||||
//we should never get here.
|
||||
// we should never get here.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -81,13 +81,13 @@ func TestReadClosed(t *testing.T) {
|
||||
|
||||
err := ca.Close()
|
||||
if err != nil {
|
||||
//we should never get here.
|
||||
// we should never get here.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = cb.Close()
|
||||
if err != nil {
|
||||
//we should never get here.
|
||||
// we should never get here.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -191,7 +191,10 @@ func pipe() (*Conn, *Conn) {
|
||||
aNotifier, aConnected := onConnected()
|
||||
bNotifier, bConnected := onConnected()
|
||||
|
||||
aAgent, err := NewAgent(&AgentConfig{Urls: urls})
|
||||
aAgent, err := NewAgent(&AgentConfig{
|
||||
Urls: urls,
|
||||
NetworkTypes: supportedNetworkTypes,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -200,7 +203,10 @@ func pipe() (*Conn, *Conn) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bAgent, err := NewAgent(&AgentConfig{Urls: urls})
|
||||
bAgent, err := NewAgent(&AgentConfig{
|
||||
Urls: urls,
|
||||
NetworkTypes: supportedNetworkTypes,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -225,7 +231,12 @@ func pipeWithTimeout(iceTimeout time.Duration, iceKeepalive time.Duration) (*Con
|
||||
aNotifier, aConnected := onConnected()
|
||||
bNotifier, bConnected := onConnected()
|
||||
|
||||
aAgent, err := NewAgent(&AgentConfig{Urls: urls, ConnectionTimeout: &iceTimeout, KeepaliveInterval: &iceKeepalive})
|
||||
aAgent, err := NewAgent(&AgentConfig{
|
||||
Urls: urls,
|
||||
ConnectionTimeout: &iceTimeout,
|
||||
KeepaliveInterval: &iceKeepalive,
|
||||
NetworkTypes: supportedNetworkTypes,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -234,7 +245,12 @@ func pipeWithTimeout(iceTimeout time.Duration, iceKeepalive time.Duration) (*Con
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bAgent, err := NewAgent(&AgentConfig{Urls: urls, ConnectionTimeout: &iceTimeout, KeepaliveInterval: &iceKeepalive})
|
||||
bAgent, err := NewAgent(&AgentConfig{
|
||||
Urls: urls,
|
||||
ConnectionTimeout: &iceTimeout,
|
||||
KeepaliveInterval: &iceKeepalive,
|
||||
NetworkTypes: supportedNetworkTypes,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -5,12 +5,23 @@ import (
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
func localInterfaces() (ips []net.IP) {
|
||||
func localInterfaces(networkTypes []NetworkType) (ips []net.IP) {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return ips
|
||||
}
|
||||
|
||||
var IPv4Requested, IPv6Requested bool
|
||||
for _, typ := range networkTypes {
|
||||
if typ.IsIPv4() {
|
||||
IPv4Requested = true
|
||||
}
|
||||
|
||||
if typ.IsIPv6() {
|
||||
IPv6Requested = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue // interface down
|
||||
@@ -33,17 +44,18 @@ func localInterfaces() (ips []net.IP) {
|
||||
ip = addr.IP
|
||||
|
||||
}
|
||||
|
||||
if ip == nil || ip.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
|
||||
// The conditions of invalidation written below are defined in
|
||||
// https://tools.ietf.org/html/rfc8445#section-5.1.1.1
|
||||
if ipv4 := ip.To4(); ipv4 == nil {
|
||||
if !isSupportedIPv6(ip) {
|
||||
if !IPv6Requested {
|
||||
continue
|
||||
} else if !isSupportedIPv6(ip) {
|
||||
continue
|
||||
}
|
||||
} else if !IPv4Requested {
|
||||
continue
|
||||
}
|
||||
|
||||
ips = append(ips, ip)
|
||||
@@ -62,6 +74,8 @@ func (a *atomicError) Load() error {
|
||||
return err.error
|
||||
}
|
||||
|
||||
// The conditions of invalidation written below are defined in
|
||||
// https://tools.ietf.org/html/rfc8445#section-5.1.1.1
|
||||
func isSupportedIPv6(ip net.IP) bool {
|
||||
if len(ip) != net.IPv6len ||
|
||||
!isZeros(ip[0:12]) || // !(IPv4-compatible IPv6)
|
||||
|
||||
Reference in New Issue
Block a user