diff --git a/client/internal/peer/conn.go b/client/internal/peer/conn.go index 423a626d1..2a5a17f19 100644 --- a/client/internal/peer/conn.go +++ b/client/internal/peer/conn.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "net" + "os" + "strconv" "strings" "sync" "time" @@ -19,6 +21,14 @@ import ( "github.com/netbirdio/netbird/version" ) +const ( + envICEKeepAliveIntervalSec = "NB_ICE_KEEP_ALIVE_INTERVAL_SEC" + envICEDisconnectedTimeoutSec = "NB_ICE_DISCONNECTED_TIMEOUT_SEC" + + iceKeepAliveDefault = 4 * time.Second + iceDisconnectedTimeoutDefault = 6 * time.Second +) + // ConnConfig is a peer Connection configuration type ConnConfig struct { @@ -149,17 +159,22 @@ func (conn *Conn) reCreateAgent() error { if err != nil { log.Errorf("failed to create pion's stdnet: %s", err) } + + iceKeepAlive, iceDisconnectedTimeout := readICEAgentConfigProperties() + agentConfig := &ice.AgentConfig{ - MulticastDNSMode: ice.MulticastDNSModeDisabled, - NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4, ice.NetworkTypeUDP6}, - Urls: conn.config.StunTurn, - CandidateTypes: []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay}, - FailedTimeout: &failedTimeout, - InterfaceFilter: stdnet.InterfaceFilter(conn.config.InterfaceBlackList), - UDPMux: conn.config.UDPMux, - UDPMuxSrflx: conn.config.UDPMuxSrflx, - NAT1To1IPs: conn.config.NATExternalIPs, - Net: transportNet, + MulticastDNSMode: ice.MulticastDNSModeDisabled, + NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4, ice.NetworkTypeUDP6}, + Urls: conn.config.StunTurn, + CandidateTypes: []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay}, + FailedTimeout: &failedTimeout, + InterfaceFilter: stdnet.InterfaceFilter(conn.config.InterfaceBlackList), + UDPMux: conn.config.UDPMux, + UDPMuxSrflx: conn.config.UDPMuxSrflx, + NAT1To1IPs: conn.config.NATExternalIPs, + Net: transportNet, + DisconnectedTimeout: &iceDisconnectedTimeout, + KeepaliveInterval: &iceKeepAlive, } if conn.config.DisableIPv6Discovery { @@ -190,6 +205,34 @@ func (conn *Conn) reCreateAgent() error { return nil } +func readICEAgentConfigProperties() (time.Duration, time.Duration) { + iceKeepAlive := iceKeepAliveDefault + iceDisconnectedTimeout := iceDisconnectedTimeoutDefault + + keepAliveEnv := os.Getenv(envICEKeepAliveIntervalSec) + if keepAliveEnv != "" { + log.Debugf("setting ICE keep alive interval to %s seconds", keepAliveEnv) + keepAliveEnvSec, err := strconv.Atoi(keepAliveEnv) + if err == nil { + iceKeepAlive = time.Duration(keepAliveEnvSec) * time.Second + } else { + log.Warnf("invalid value %s set for %s, using default %v", keepAliveEnv, envICEKeepAliveIntervalSec, iceKeepAlive) + } + } + + disconnectedTimeoutEnv := os.Getenv(envICEDisconnectedTimeoutSec) + if disconnectedTimeoutEnv != "" { + log.Debugf("setting ICE disconnected timeout to %s seconds", disconnectedTimeoutEnv) + disconnectedTimeoutSec, err := strconv.Atoi(disconnectedTimeoutEnv) + if err == nil { + iceDisconnectedTimeout = time.Duration(disconnectedTimeoutSec) * time.Second + } else { + log.Warnf("invalid value %s set for %s, using default %v", disconnectedTimeoutEnv, envICEDisconnectedTimeoutSec, iceDisconnectedTimeout) + } + } + return iceKeepAlive, iceDisconnectedTimeout +} + // Open opens connection to the remote peer starting ICE candidate gathering process. // Blocks until connection has been closed or connection timeout. // ConnStatus will be set accordingly diff --git a/iface/tun_android.go b/iface/tun_android.go index d49de66c8..cedb016c0 100644 --- a/iface/tun_android.go +++ b/iface/tun_android.go @@ -52,7 +52,9 @@ func (t *tunDevice) Create() error { log.Debugf("attaching to interface %v", name) t.device = device.NewDevice(tunDevice, t.iceBind, device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) - t.device.DisableSomeRoamingForBrokenMobileSemantics() + // without this property mobile devices can discover remote endpoints if the configured one was wrong. + // this helps with support for the older NetBird clients that had a hardcoded direct mode + //t.device.DisableSomeRoamingForBrokenMobileSemantics() err = t.device.Up() if err != nil {