mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-10 08:40: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)...)
|
||||
}
|
||||
|
||||
// Resolve each grant's sources against the viewer once, and each
|
||||
// grant's destinations into a flat prefix list. The three passes
|
||||
// below reuse both results instead of re-resolving per pass.
|
||||
// matchViewer resolves a grant lazily and at most once: non-via
|
||||
// grants are only needed once a via grant has matched, and
|
||||
// destinations only for grants that match the viewer.
|
||||
viewerIPs := viewer.IPs()
|
||||
resolved := make([]bool, len(grants))
|
||||
viewerMatchesGrant := make([]bool, len(grants))
|
||||
resolvedDstPrefixes := make([][]netip.Prefix, len(grants))
|
||||
grantHasAutoGroupInternet := make([]bool, len(grants))
|
||||
|
||||
for i, grant := range grants {
|
||||
for _, src := range grant.Sources {
|
||||
matchViewer := func(i int) bool {
|
||||
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)
|
||||
if err != nil {
|
||||
continue
|
||||
@@ -1402,9 +1409,13 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
||||
}
|
||||
}
|
||||
|
||||
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
|
||||
pm.pol, pm.users, pm.nodes, grant.Destinations,
|
||||
)
|
||||
if viewerMatchesGrant[i] {
|
||||
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
|
||||
pm.pol, pm.users, pm.nodes, grants[i].Destinations,
|
||||
)
|
||||
}
|
||||
|
||||
return viewerMatchesGrant[i]
|
||||
}
|
||||
|
||||
for i, grant := range grants {
|
||||
@@ -1412,7 +1423,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
||||
continue
|
||||
}
|
||||
|
||||
if !viewerMatchesGrant[i] {
|
||||
if !matchViewer(i) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1495,7 +1506,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
||||
continue
|
||||
}
|
||||
|
||||
if !viewerMatchesGrant[i] {
|
||||
if !matchViewer(i) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1545,7 +1556,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
|
||||
continue
|
||||
}
|
||||
|
||||
if !viewerMatchesGrant[i] {
|
||||
if !matchViewer(i) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user