mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
wgengine/router: provide explicit hook to signal Android when VPN needs to be reconfigured
This allows clients to avoid establishing their VPN multiple times when both routes and DNS are changing in rapid succession. Updates tailscale/corp#18928 Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit is contained in:
parent
1a38d2a3b4
commit
853e3e29a0
@ -126,6 +126,7 @@ type userspaceEngine struct {
|
||||
sentActivityAt map[netip.Addr]*mono.Time // value is accessed atomically
|
||||
destIPActivityFuncs map[netip.Addr]func()
|
||||
lastStatusPollTime mono.Time // last time we polled the engine status
|
||||
reconfigureVPN func() error // or nil
|
||||
|
||||
mu sync.Mutex // guards following; see lock order comment below
|
||||
netMap *netmap.NetworkMap // or nil
|
||||
@ -175,6 +176,13 @@ type Config struct {
|
||||
// If nil, a fake OSConfigurator that does nothing is used.
|
||||
DNS dns.OSConfigurator
|
||||
|
||||
// ReconfigureVPN provides an optional hook for platforms like Android to
|
||||
// know when it's time to reconfigure their VPN implementation. Such
|
||||
// platforms can only set their entire VPN configuration (routes, DNS, etc)
|
||||
// at all once and can't make piecemeal incremental changes, so this
|
||||
// provides a hook to "flush" a batch of Router and/or DNS changes.
|
||||
ReconfigureVPN func() error
|
||||
|
||||
// NetMon optionally provides an existing network monitor to re-use.
|
||||
// If nil, a new network monitor is created.
|
||||
NetMon *netmon.Monitor
|
||||
@ -283,6 +291,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
||||
confListenPort: conf.ListenPort,
|
||||
birdClient: conf.BIRDClient,
|
||||
controlKnobs: conf.ControlKnobs,
|
||||
reconfigureVPN: conf.ReconfigureVPN,
|
||||
}
|
||||
|
||||
if e.birdClient != nil {
|
||||
@ -956,6 +965,9 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.reconfigureVPNIfNecessary(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown the network logger.
|
||||
@ -1161,10 +1173,12 @@ func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) {
|
||||
}
|
||||
}
|
||||
|
||||
// Hacky workaround for Linux DNS issue 2458: on
|
||||
// Hacky workaround for Unix DNS issue 2458: on
|
||||
// suspend/resume or whenever NetworkManager is started, it
|
||||
// nukes all systemd-resolved configs. So reapply our DNS
|
||||
// config on major link change.
|
||||
// TODO: explain why this is ncessary not just on Linux but also android
|
||||
// and Apple platforms.
|
||||
if changed {
|
||||
switch runtime.GOOS {
|
||||
case "linux", "android", "ios", "darwin":
|
||||
@ -1174,6 +1188,8 @@ func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) {
|
||||
if dnsCfg != nil {
|
||||
if err := e.dns.Set(*dnsCfg); err != nil {
|
||||
e.logf("wgengine: error setting DNS config after major link change: %v", err)
|
||||
} else if err := e.reconfigureVPNIfNecessary(); err != nil {
|
||||
e.logf("wgengine: error reconfiguring VPN after major link change: %v", err)
|
||||
} else {
|
||||
e.logf("wgengine: set DNS config again after major link change")
|
||||
}
|
||||
@ -1528,3 +1544,10 @@ func (e *userspaceEngine) InstallCaptureHook(cb capture.Callback) {
|
||||
e.tundev.InstallCaptureHook(cb)
|
||||
e.magicConn.InstallCaptureHook(cb)
|
||||
}
|
||||
|
||||
func (e *userspaceEngine) reconfigureVPNIfNecessary() error {
|
||||
if e.reconfigureVPN == nil {
|
||||
return nil
|
||||
}
|
||||
return e.reconfigureVPN()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user