mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-10 16:50:07 +09:00
policy/v2: resolve via-route grants lazily
With a via grant in the policy, ViaRoutesForPeer still resolved every grant's sources and destinations up front. Non-via grants are only read once a via grant has matched the peer, which is rare (the peer must advertise a covered route), and destinations only for grants whose sources match the viewer. Resolve each grant on first use instead. BenchmarkViaRoutesForPeer, mean per peer (Apple M3 Pro): policy nodes before after via-mixed 100 9.5us 2.1us via-mixed 1000 69.0us 11.6us via 1000 8.1us 8.6us
This commit is contained in:
committed by
Kristoffer Dalby
parent
f8018f177a
commit
9d5ce0752f
@@ -1380,16 +1380,23 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
|||||||
grants = append(grants, aclToGrants(acl)...)
|
grants = append(grants, aclToGrants(acl)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve each grant's sources against the viewer once, and each
|
// matchViewer resolves a grant lazily and at most once: non-via
|
||||||
// grant's destinations into a flat prefix list. The three passes
|
// grants are only needed once a via grant has matched, and
|
||||||
// below reuse both results instead of re-resolving per pass.
|
// destinations only for grants that match the viewer.
|
||||||
viewerIPs := viewer.IPs()
|
viewerIPs := viewer.IPs()
|
||||||
|
resolved := make([]bool, len(grants))
|
||||||
viewerMatchesGrant := make([]bool, len(grants))
|
viewerMatchesGrant := make([]bool, len(grants))
|
||||||
resolvedDstPrefixes := make([][]netip.Prefix, len(grants))
|
resolvedDstPrefixes := make([][]netip.Prefix, len(grants))
|
||||||
grantHasAutoGroupInternet := make([]bool, len(grants))
|
grantHasAutoGroupInternet := make([]bool, len(grants))
|
||||||
|
|
||||||
for i, grant := range grants {
|
matchViewer := func(i int) bool {
|
||||||
for _, src := range grant.Sources {
|
if resolved[i] {
|
||||||
|
return viewerMatchesGrant[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved[i] = true
|
||||||
|
|
||||||
|
for _, src := range grants[i].Sources {
|
||||||
ips, err := src.Resolve(pm.pol, pm.users, pm.nodes)
|
ips, err := src.Resolve(pm.pol, pm.users, pm.nodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@@ -1402,9 +1409,13 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
|
if viewerMatchesGrant[i] {
|
||||||
pm.pol, pm.users, pm.nodes, grant.Destinations,
|
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
|
||||||
)
|
pm.pol, pm.users, pm.nodes, grants[i].Destinations,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewerMatchesGrant[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, grant := range grants {
|
for i, grant := range grants {
|
||||||
@@ -1412,7 +1423,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !viewerMatchesGrant[i] {
|
if !matchViewer(i) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1495,7 +1506,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !viewerMatchesGrant[i] {
|
if !matchViewer(i) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1545,7 +1556,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !viewerMatchesGrant[i] {
|
if !matchViewer(i) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user