tailscale/wgengine/router/callback.go
David Anderson 27a1a2976a wgengine/router: add a CallbackRouter shim.
The shim implements both network and DNS configurators,
and feeds both into a single callback that receives
both configs.

Signed-off-by: David Anderson <danderson@tailscale.com>
2021-04-02 18:43:24 -07:00

55 lines
1.5 KiB
Go

// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package router
import (
"sync"
"tailscale.com/net/dns"
)
// CallbackRouter is an implementation of both Router and dns.OSConfigurator.
// When either network or DNS settings are changed, SetBoth is called with both configs.
// Mainly used as a shim for OSes that want to set both network and
// DNS configuration simultaneously (iOS, android).
type CallbackRouter struct {
SetBoth func(rcfg *Config, dcfg *dns.OSConfig) error
DNSMode dns.RoutingMode
mu sync.Mutex // protects all the following
rcfg *Config // last applied router config
dcfg *dns.OSConfig // last applied DNS config
}
// Up implements Router.
func (r *CallbackRouter) Up() error {
return nil // TODO: check that all callers have no need for initialization
}
// Set implements Router.
func (r *CallbackRouter) Set(rcfg *Config) error {
r.mu.Lock()
defer r.mu.Unlock()
r.rcfg = rcfg
return r.SetBoth(r.rcfg, r.dcfg)
}
// SetDNS implements dns.OSConfigurator.
func (r *CallbackRouter) SetDNS(dcfg dns.OSConfig) error {
r.mu.Lock()
defer r.mu.Unlock()
r.dcfg = &dcfg
return r.SetBoth(r.rcfg, r.dcfg)
}
// RoutingMode implements dns.OSConfigurator.
func (r *CallbackRouter) RoutingMode() dns.RoutingMode {
return r.DNSMode
}
func (r *CallbackRouter) Close() error {
return r.SetBoth(nil, nil) // TODO: check if makes sense
}