From 27a1a2976a8f6b2bcd07df6c5187a633553aa4c2 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 2 Apr 2021 18:43:24 -0700 Subject: [PATCH] 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 --- wgengine/router/callback.go | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 wgengine/router/callback.go diff --git a/wgengine/router/callback.go b/wgengine/router/callback.go new file mode 100644 index 000000000..b36e399a3 --- /dev/null +++ b/wgengine/router/callback.go @@ -0,0 +1,54 @@ +// 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 +}