tailcfg: make SelfNodeV4MasqAddrForThisPeer a pointer

This makes `omitempty` actually work, and saves bytes in each map response.

Updates tailscale/corp#8020

Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
Maisem Ali 2023-04-13 10:12:31 -07:00 committed by Maisem Ali
parent a5fd51ebdc
commit 64bbf1738e
11 changed files with 38 additions and 22 deletions

View File

@ -580,12 +580,12 @@ func natConfigFromWGConfig(wcfg *wgcfg.Config) *natV4Config {
) )
for i := range wcfg.Peers { for i := range wcfg.Peers {
p := &wcfg.Peers[i] p := &wcfg.Peers[i]
if !p.V4MasqAddr.IsValid() { if p.V4MasqAddr == nil || !p.V4MasqAddr.IsValid() {
continue continue
} }
rt.InsertOrReplace(p.PublicKey, p.AllowedIPs...) rt.InsertOrReplace(p.PublicKey, p.AllowedIPs...)
mak.Set(&dstMasqAddrs, p.PublicKey, p.V4MasqAddr) mak.Set(&dstMasqAddrs, p.PublicKey, *p.V4MasqAddr)
mak.Set(&listenAddrs, p.V4MasqAddr, struct{}{}) mak.Set(&listenAddrs, *p.V4MasqAddr, struct{}{})
} }
if len(listenAddrs) == 0 || len(dstMasqAddrs) == 0 { if len(listenAddrs) == 0 || len(dstMasqAddrs) == 0 {
return nil return nil

View File

@ -31,6 +31,7 @@
"tailscale.com/types/key" "tailscale.com/types/key"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/types/netlogtype" "tailscale.com/types/netlogtype"
"tailscale.com/types/ptr"
"tailscale.com/util/must" "tailscale.com/util/must"
"tailscale.com/wgengine/filter" "tailscale.com/wgengine/filter"
"tailscale.com/wgengine/wgcfg" "tailscale.com/wgengine/wgcfg"
@ -602,7 +603,7 @@ func TestNATCfg(t *testing.T) {
AllowedIPs: []netip.Prefix{ AllowedIPs: []netip.Prefix{
netip.PrefixFrom(ip, ip.BitLen()), netip.PrefixFrom(ip, ip.BitLen()),
}, },
V4MasqAddr: eip, V4MasqAddr: ptr.To(eip),
} }
p.AllowedIPs = append(p.AllowedIPs, otherAllowedIPs...) p.AllowedIPs = append(p.AllowedIPs, otherAllowedIPs...)
return p return p

View File

@ -289,7 +289,7 @@ type Node struct {
// This only applies to traffic originating from the current node to the // This only applies to traffic originating from the current node to the
// peer or any of its subnets. Traffic originating from subnet routes will // peer or any of its subnets. Traffic originating from subnet routes will
// not be masqueraded (e.g. in case of --snat-subnet-routes). // not be masqueraded (e.g. in case of --snat-subnet-routes).
SelfNodeV4MasqAddrForThisPeer netip.Addr `json:",omitempty"` SelfNodeV4MasqAddrForThisPeer *netip.Addr `json:",omitempty"`
// IsWireGuardOnly indicates that this is a non-Tailscale WireGuard peer, it // IsWireGuardOnly indicates that this is a non-Tailscale WireGuard peer, it
// is not expected to speak Disco or DERP, and it must have Endpoints in // is not expected to speak Disco or DERP, and it must have Endpoints in
@ -1705,7 +1705,7 @@ func (n *Node) Equal(n2 *Node) bool {
bytes.Equal(n.KeySignature, n2.KeySignature) && bytes.Equal(n.KeySignature, n2.KeySignature) &&
n.Machine == n2.Machine && n.Machine == n2.Machine &&
n.DiscoKey == n2.DiscoKey && n.DiscoKey == n2.DiscoKey &&
eqBoolPtr(n.Online, n2.Online) && eqPtr(n.Online, n2.Online) &&
eqCIDRs(n.Addresses, n2.Addresses) && eqCIDRs(n.Addresses, n2.Addresses) &&
eqCIDRs(n.AllowedIPs, n2.AllowedIPs) && eqCIDRs(n.AllowedIPs, n2.AllowedIPs) &&
eqCIDRs(n.PrimaryRoutes, n2.PrimaryRoutes) && eqCIDRs(n.PrimaryRoutes, n2.PrimaryRoutes) &&
@ -1722,11 +1722,11 @@ func (n *Node) Equal(n2 *Node) bool {
n.ComputedNameWithHost == n2.ComputedNameWithHost && n.ComputedNameWithHost == n2.ComputedNameWithHost &&
eqStrings(n.Tags, n2.Tags) && eqStrings(n.Tags, n2.Tags) &&
n.Expired == n2.Expired && n.Expired == n2.Expired &&
n.SelfNodeV4MasqAddrForThisPeer == n2.SelfNodeV4MasqAddrForThisPeer && eqPtr(n.SelfNodeV4MasqAddrForThisPeer, n2.SelfNodeV4MasqAddrForThisPeer) &&
n.IsWireGuardOnly == n2.IsWireGuardOnly n.IsWireGuardOnly == n2.IsWireGuardOnly
} }
func eqBoolPtr(a, b *bool) bool { func eqPtr[T comparable](a, b *T) bool {
if a == b { // covers nil if a == b { // covers nil
return true return true
} }
@ -1734,7 +1734,6 @@ func eqBoolPtr(a, b *bool) bool {
return false return false
} }
return *a == *b return *a == *b
} }
func eqStrings(a, b []string) bool { func eqStrings(a, b []string) bool {

View File

@ -63,6 +63,10 @@ func (src *Node) Clone() *Node {
*dst.Online = *src.Online *dst.Online = *src.Online
} }
dst.Capabilities = append(src.Capabilities[:0:0], src.Capabilities...) dst.Capabilities = append(src.Capabilities[:0:0], src.Capabilities...)
if dst.SelfNodeV4MasqAddrForThisPeer != nil {
dst.SelfNodeV4MasqAddrForThisPeer = new(netip.Addr)
*dst.SelfNodeV4MasqAddrForThisPeer = *src.SelfNodeV4MasqAddrForThisPeer
}
return dst return dst
} }
@ -98,7 +102,7 @@ func (src *Node) Clone() *Node {
ComputedNameWithHost string ComputedNameWithHost string
DataPlaneAuditLogID string DataPlaneAuditLogID string
Expired bool Expired bool
SelfNodeV4MasqAddrForThisPeer netip.Addr SelfNodeV4MasqAddrForThisPeer *netip.Addr
IsWireGuardOnly bool IsWireGuardOnly bool
}{}) }{})

View File

@ -18,6 +18,7 @@
. "tailscale.com/tailcfg" . "tailscale.com/tailcfg"
"tailscale.com/tstest" "tailscale.com/tstest"
"tailscale.com/types/key" "tailscale.com/types/key"
"tailscale.com/types/ptr"
"tailscale.com/util/must" "tailscale.com/util/must"
"tailscale.com/version" "tailscale.com/version"
) )
@ -537,12 +538,12 @@ func TestNodeEqual(t *testing.T) {
}, },
{ {
&Node{}, &Node{},
&Node{SelfNodeV4MasqAddrForThisPeer: netip.MustParseAddr("100.64.0.1")}, &Node{SelfNodeV4MasqAddrForThisPeer: ptr.To(netip.MustParseAddr("100.64.0.1"))},
false, false,
}, },
{ {
&Node{SelfNodeV4MasqAddrForThisPeer: netip.MustParseAddr("100.64.0.1")}, &Node{SelfNodeV4MasqAddrForThisPeer: ptr.To(netip.MustParseAddr("100.64.0.1"))},
&Node{SelfNodeV4MasqAddrForThisPeer: netip.MustParseAddr("100.64.0.1")}, &Node{SelfNodeV4MasqAddrForThisPeer: ptr.To(netip.MustParseAddr("100.64.0.1"))},
true, true,
}, },
} }

View File

@ -176,9 +176,14 @@ func (v NodeView) ComputedName() string { return v.ж.ComputedName
func (v NodeView) ComputedNameWithHost() string { return v.ж.ComputedNameWithHost } func (v NodeView) ComputedNameWithHost() string { return v.ж.ComputedNameWithHost }
func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID } func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID }
func (v NodeView) Expired() bool { return v.ж.Expired } func (v NodeView) Expired() bool { return v.ж.Expired }
func (v NodeView) SelfNodeV4MasqAddrForThisPeer() netip.Addr { func (v NodeView) SelfNodeV4MasqAddrForThisPeer() *netip.Addr {
return v.ж.SelfNodeV4MasqAddrForThisPeer if v.ж.SelfNodeV4MasqAddrForThisPeer == nil {
return nil
}
x := *v.ж.SelfNodeV4MasqAddrForThisPeer
return &x
} }
func (v NodeView) IsWireGuardOnly() bool { return v.ж.IsWireGuardOnly } func (v NodeView) IsWireGuardOnly() bool { return v.ж.IsWireGuardOnly }
func (v NodeView) Equal(v2 NodeView) bool { return v.ж.Equal(v2.ж) } func (v NodeView) Equal(v2 NodeView) bool { return v.ж.Equal(v2.ж) }
@ -214,7 +219,7 @@ func (v NodeView) Equal(v2 NodeView) bool { return v.ж.Equal(v2.ж) }
ComputedNameWithHost string ComputedNameWithHost string
DataPlaneAuditLogID string DataPlaneAuditLogID string
Expired bool Expired bool
SelfNodeV4MasqAddrForThisPeer netip.Addr SelfNodeV4MasqAddrForThisPeer *netip.Addr
IsWireGuardOnly bool IsWireGuardOnly bool
}{}) }{})

View File

@ -33,6 +33,7 @@
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
"tailscale.com/types/key" "tailscale.com/types/key"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/types/ptr"
) )
const msgLimit = 1 << 20 // encrypted message length limit const msgLimit = 1 << 20 // encrypted message length limit
@ -843,7 +844,7 @@ func (s *Server) MapResponse(req *tailcfg.MapRequest) (res *tailcfg.MapResponse,
continue continue
} }
if masqIP := nodeMasqs[p.Key]; masqIP.IsValid() { if masqIP := nodeMasqs[p.Key]; masqIP.IsValid() {
p.SelfNodeV4MasqAddrForThisPeer = masqIP p.SelfNodeV4MasqAddrForThisPeer = ptr.To(masqIP)
} }
s.mu.Lock() s.mu.Lock()

View File

@ -575,8 +575,8 @@ func TestGetTypeHasher(t *testing.T) {
{ {
name: "tailcfg.Node", name: "tailcfg.Node",
val: &tailcfg.Node{}, val: &tailcfg.Node{},
out: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", out: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
out32: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", out32: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
}, },
} }
for _, tt := range tests { for _, tt := range tests {

View File

@ -50,6 +50,7 @@
"tailscale.com/types/netlogtype" "tailscale.com/types/netlogtype"
"tailscale.com/types/netmap" "tailscale.com/types/netmap"
"tailscale.com/types/nettype" "tailscale.com/types/nettype"
"tailscale.com/types/ptr"
"tailscale.com/util/cibuild" "tailscale.com/util/cibuild"
"tailscale.com/util/racebuild" "tailscale.com/util/racebuild"
"tailscale.com/wgengine/filter" "tailscale.com/wgengine/filter"
@ -2240,7 +2241,7 @@ func TestIsWireGuardOnlyPeerWithMasquerade(t *testing.T) {
IsWireGuardOnly: true, IsWireGuardOnly: true,
Addresses: []netip.Prefix{wgaip}, Addresses: []netip.Prefix{wgaip},
AllowedIPs: []netip.Prefix{wgaip}, AllowedIPs: []netip.Prefix{wgaip},
SelfNodeV4MasqAddrForThisPeer: masqip.Addr(), SelfNodeV4MasqAddrForThisPeer: ptr.To(masqip.Addr()),
}, },
}, },
} }

View File

@ -37,7 +37,7 @@ type Peer struct {
PublicKey key.NodePublic PublicKey key.NodePublic
DiscoKey key.DiscoPublic // present only so we can handle restarts within wgengine, not passed to WireGuard DiscoKey key.DiscoPublic // present only so we can handle restarts within wgengine, not passed to WireGuard
AllowedIPs []netip.Prefix AllowedIPs []netip.Prefix
V4MasqAddr netip.Addr // if non-zero, masquerade IPv4 traffic to this peer using this address V4MasqAddr *netip.Addr // if non-nil, masquerade IPv4 traffic to this peer using this address
PersistentKeepalive uint16 PersistentKeepalive uint16
// wireguard-go's endpoint for this peer. It should always equal Peer.PublicKey. // wireguard-go's endpoint for this peer. It should always equal Peer.PublicKey.
// We represent it explicitly so that we can detect if they diverge and recover. // We represent it explicitly so that we can detect if they diverge and recover.

View File

@ -54,6 +54,10 @@ func (src *Peer) Clone() *Peer {
dst := new(Peer) dst := new(Peer)
*dst = *src *dst = *src
dst.AllowedIPs = append(src.AllowedIPs[:0:0], src.AllowedIPs...) dst.AllowedIPs = append(src.AllowedIPs[:0:0], src.AllowedIPs...)
if dst.V4MasqAddr != nil {
dst.V4MasqAddr = new(netip.Addr)
*dst.V4MasqAddr = *src.V4MasqAddr
}
return dst return dst
} }
@ -62,7 +66,7 @@ func (src *Peer) Clone() *Peer {
PublicKey key.NodePublic PublicKey key.NodePublic
DiscoKey key.DiscoPublic DiscoKey key.DiscoPublic
AllowedIPs []netip.Prefix AllowedIPs []netip.Prefix
V4MasqAddr netip.Addr V4MasqAddr *netip.Addr
PersistentKeepalive uint16 PersistentKeepalive uint16
WGEndpoint key.NodePublic WGEndpoint key.NodePublic
}{}) }{})