mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 10:11:18 +01:00 
			
		
		
		
	Also pull out interface method only needed in Linux. Instead of having userspace do the call into the router, just let the router pick up the change itself. Updates #15160 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
		
			
				
	
	
		
			85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) Tailscale Inc & AUTHORS
 | 
						|
// SPDX-License-Identifier: BSD-3-Clause
 | 
						|
 | 
						|
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 (Mac, iOS, Android).
 | 
						|
type CallbackRouter struct {
 | 
						|
	SetBoth  func(rcfg *Config, dcfg *dns.OSConfig) error
 | 
						|
	SplitDNS bool
 | 
						|
 | 
						|
	// GetBaseConfigFunc optionally specifies a function to return the current DNS
 | 
						|
	// config in response to GetBaseConfig.
 | 
						|
	//
 | 
						|
	// If nil, reading the current config isn't supported and GetBaseConfig()
 | 
						|
	// will return ErrGetBaseConfigNotSupported.
 | 
						|
	GetBaseConfigFunc func() (dns.OSConfig, error)
 | 
						|
 | 
						|
	// InitialMTU is the MTU the tun should be initialized with.
 | 
						|
	// Zero means don't change the MTU from the default. This MTU
 | 
						|
	// is applied only once, shortly after the TUN is created, and
 | 
						|
	// ignored thereafter.
 | 
						|
	InitialMTU uint32
 | 
						|
 | 
						|
	mu        sync.Mutex    // protects all the following
 | 
						|
	didSetMTU bool          // if we set the MTU already
 | 
						|
	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()
 | 
						|
	if r.rcfg.Equal(rcfg) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	if r.didSetMTU == false {
 | 
						|
		r.didSetMTU = true
 | 
						|
		rcfg.NewMTU = int(r.InitialMTU)
 | 
						|
	}
 | 
						|
	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()
 | 
						|
	if r.dcfg != nil && r.dcfg.Equal(dcfg) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	r.dcfg = &dcfg
 | 
						|
	return r.SetBoth(r.rcfg, r.dcfg)
 | 
						|
}
 | 
						|
 | 
						|
// SupportsSplitDNS implements dns.OSConfigurator.
 | 
						|
func (r *CallbackRouter) SupportsSplitDNS() bool {
 | 
						|
	return r.SplitDNS
 | 
						|
}
 | 
						|
 | 
						|
func (r *CallbackRouter) GetBaseConfig() (dns.OSConfig, error) {
 | 
						|
	if r.GetBaseConfigFunc == nil {
 | 
						|
		return dns.OSConfig{}, dns.ErrGetBaseConfigNotSupported
 | 
						|
	}
 | 
						|
	return r.GetBaseConfigFunc()
 | 
						|
}
 | 
						|
 | 
						|
func (r *CallbackRouter) Close() error {
 | 
						|
	return r.SetBoth(nil, nil) // TODO: check if makes sense
 | 
						|
}
 |