ipn: add methods on Prefs to get/set exit node being advertised

This code was copied in a few places (Windows, Android), so unify it
and add tests.

Change-Id: Id0510c0f5974761365a2045279d1fb498feca11e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/3677/head
Brad Fitzpatrick 2 years ago committed by Maisem Ali
parent addda5b96f
commit 2cfc96aa90

@ -426,6 +426,47 @@ func (p *Prefs) AdminPageURL() string {
return url + "/admin/machines"
}
// AdvertisesExitNode reports whether p is advertising both the v4 and
// v6 /0 exit node routes.
func (p *Prefs) AdvertisesExitNode() bool {
if p == nil {
return false
}
var v4, v6 bool
for _, r := range p.AdvertiseRoutes {
if r.Bits() != 0 {
continue
}
if r.IP().Is4() {
v4 = true
} else if r.IP().Is6() {
v6 = true
}
}
return v4 && v6
}
// SetRunExitNode mutates p (if non-nil) to add or remove the two
// /0 exit node routes.
func (p *Prefs) SetRunExitNode(runExit bool) {
if p == nil {
return
}
all := p.AdvertiseRoutes
p.AdvertiseRoutes = p.AdvertiseRoutes[:0]
for _, r := range all {
if r.Bits() != 0 {
p.AdvertiseRoutes = append(p.AdvertiseRoutes, r)
}
}
if !runExit {
return
}
p.AdvertiseRoutes = append(p.AdvertiseRoutes,
netaddr.IPPrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0),
netaddr.IPPrefixFrom(netaddr.IPv6Unspecified(), 0))
}
// PrefsFromBytes deserializes Prefs from a JSON blob. If
// enforceDefaults is true, Prefs.RouteAll and Prefs.AllowSingleHosts
// are forced on.

@ -646,3 +646,35 @@ func TestMaskedPrefsPretty(t *testing.T) {
}
}
}
func TestPrefsExitNode(t *testing.T) {
var p *Prefs
if p.AdvertisesExitNode() {
t.Errorf("nil shouldn't advertise exit node")
}
p = NewPrefs()
if p.AdvertisesExitNode() {
t.Errorf("default shouldn't advertise exit node")
}
p.AdvertiseRoutes = []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("10.0.0.0/16"),
}
p.SetRunExitNode(true)
if got, want := len(p.AdvertiseRoutes), 3; got != want {
t.Errorf("routes = %d; want %d", got, want)
}
p.SetRunExitNode(true)
if got, want := len(p.AdvertiseRoutes), 3; got != want {
t.Errorf("routes = %d; want %d", got, want)
}
if !p.AdvertisesExitNode() {
t.Errorf("not advertising after enable")
}
p.SetRunExitNode(false)
if p.AdvertisesExitNode() {
t.Errorf("advertising after disable")
}
if got, want := len(p.AdvertiseRoutes), 1; got != want {
t.Errorf("routes = %d; want %d", got, want)
}
}

Loading…
Cancel
Save