1
0
mirror of https://github.com/juanfont/headscale.git synced 2025-05-18 01:16:48 +02:00
juanfont.headscale/hscontrol/policy/matcher/matcher.go
aergus-tng 4651d06fa8
Make matchers part of the Policy interface (#2514)
* Make matchers part of the Policy interface

* Prevent race condition between rules and matchers

* Test also matchers in tests for Policy.Filter

* Compute `filterChanged` in v2 policy correctly

* Fix nil vs. empty list issue in v2 policy test

* policy/v2: always clear ssh map

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

---------

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Co-authored-by: Aras Ergus <aras.ergus@tngtech.com>
Co-authored-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-05-01 07:06:30 +02:00

99 lines
1.7 KiB
Go

package matcher
import (
"net/netip"
"github.com/juanfont/headscale/hscontrol/util"
"go4.org/netipx"
"tailscale.com/tailcfg"
)
type Match struct {
srcs *netipx.IPSet
dests *netipx.IPSet
}
func MatchesFromFilterRules(rules []tailcfg.FilterRule) []Match {
matches := make([]Match, 0, len(rules))
for _, rule := range rules {
matches = append(matches, MatchFromFilterRule(rule))
}
return matches
}
func MatchFromFilterRule(rule tailcfg.FilterRule) Match {
dests := []string{}
for _, dest := range rule.DstPorts {
dests = append(dests, dest.IP)
}
return MatchFromStrings(rule.SrcIPs, dests)
}
func MatchFromStrings(sources, destinations []string) Match {
srcs := new(netipx.IPSetBuilder)
dests := new(netipx.IPSetBuilder)
for _, srcIP := range sources {
set, _ := util.ParseIPSet(srcIP, nil)
srcs.AddSet(set)
}
for _, dest := range destinations {
set, _ := util.ParseIPSet(dest, nil)
dests.AddSet(set)
}
srcsSet, _ := srcs.IPSet()
destsSet, _ := dests.IPSet()
match := Match{
srcs: srcsSet,
dests: destsSet,
}
return match
}
func (m *Match) SrcsContainsIPs(ips ...netip.Addr) bool {
for _, ip := range ips {
if m.srcs.Contains(ip) {
return true
}
}
return false
}
func (m *Match) DestsContainsIP(ips ...netip.Addr) bool {
for _, ip := range ips {
if m.dests.Contains(ip) {
return true
}
}
return false
}
func (m *Match) SrcsOverlapsPrefixes(prefixes ...netip.Prefix) bool {
for _, prefix := range prefixes {
if m.srcs.ContainsPrefix(prefix) {
return true
}
}
return false
}
func (m *Match) DestsOverlapsPrefixes(prefixes ...netip.Prefix) bool {
for _, prefix := range prefixes {
if m.dests.ContainsPrefix(prefix) {
return true
}
}
return false
}