mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-07-16 13:17:19 +02:00
refactor: extract rule matching logic into internal/rulematcher package
Extract DNS policy rule matching logic from dns_proxy.go into a dedicated internal/rulematcher package to improve code organization and maintainability. The new package provides: - RuleMatcher interface for extensible rule matching - NetworkRuleMatcher for IP-based network rules - MacRuleMatcher for MAC address-based rules - DomainRuleMatcher for domain/wildcard rules - Comprehensive unit tests for all matchers This refactoring improves: - Separation of concerns between DNS proxy and rule matching - Testability with isolated rule matcher components - Reusability of rule matching logic across the codebase - Maintainability with focused, single-responsibility modules
This commit is contained in:
committed by
Cuong Manh Le
parent
ef7432df55
commit
3afdaef6e6
@@ -0,0 +1,67 @@
|
||||
package rulematcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MacRuleMatcher handles matching of MAC address-based rules
|
||||
type MacRuleMatcher struct{}
|
||||
|
||||
// Type returns the rule type for MAC matcher
|
||||
func (m *MacRuleMatcher) Type() RuleType {
|
||||
return RuleTypeMac
|
||||
}
|
||||
|
||||
// Match evaluates MAC address rules against the source MAC address
|
||||
func (m *MacRuleMatcher) Match(ctx context.Context, req *MatchRequest) *MatchResult {
|
||||
if req.Policy == nil || len(req.Policy.Macs) == 0 {
|
||||
return &MatchResult{Matched: false, RuleType: RuleTypeMac}
|
||||
}
|
||||
|
||||
for _, rule := range req.Policy.Macs {
|
||||
for source, targets := range rule {
|
||||
if source != "" && (strings.EqualFold(source, req.SourceMac) || wildcardMatches(strings.ToLower(source), strings.ToLower(req.SourceMac))) {
|
||||
return &MatchResult{
|
||||
Matched: true,
|
||||
Targets: targets,
|
||||
MatchedRule: source, // Return the original source from the rule
|
||||
RuleType: RuleTypeMac,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &MatchResult{Matched: false, RuleType: RuleTypeMac}
|
||||
}
|
||||
|
||||
// wildcardMatches checks if a wildcard pattern matches a string
|
||||
// This is copied from the original implementation to maintain compatibility
|
||||
func wildcardMatches(wildcard, str string) bool {
|
||||
if wildcard == "" {
|
||||
return false
|
||||
}
|
||||
if wildcard == "*" {
|
||||
return true
|
||||
}
|
||||
if !strings.Contains(wildcard, "*") {
|
||||
return wildcard == str
|
||||
}
|
||||
|
||||
parts := strings.Split(wildcard, "*")
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
prefix := parts[0]
|
||||
suffix := parts[1]
|
||||
|
||||
if prefix != "" && !strings.HasPrefix(str, prefix) {
|
||||
return false
|
||||
}
|
||||
if suffix != "" && !strings.HasSuffix(str, suffix) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user