mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-05-27 12:52:27 +02:00
c365051732
Implement configurable DNS policy rule matching order and refactor upstreamFor method for better maintainability. New features: - Add MatchingConfig to ListenerPolicyConfig for rule order configuration - Support custom rule evaluation order (network, mac, domain) - Add stop_on_first_match configuration option - Hidden from config files (mapstructure:"-" toml:"-") for future release Code improvements: - Create upstreamForRequest struct to reduce method parameter count - Refactor upstreamForWithConfig to use single struct parameter - Improve code readability and maintainability - Maintain full backward compatibility Technical details: - String-based configuration converted to RuleType enum internally - Default behavior preserved (network → mac → domain order) - Domain rules still override MAC/network rules regardless of order - Comprehensive test coverage for configuration integration The matching configuration is programmatically accessible but hidden from user configuration files until ready for public release.
112 lines
2.9 KiB
Go
112 lines
2.9 KiB
Go
package rulematcher
|
|
|
|
import (
|
|
"context"
|
|
)
|
|
|
|
// MatchingEngine orchestrates rule matching based on configurable order
|
|
type MatchingEngine struct {
|
|
config *MatchingConfig
|
|
matchers map[RuleType]RuleMatcher
|
|
}
|
|
|
|
// NewMatchingEngine creates a new matching engine with the given configuration
|
|
func NewMatchingEngine(config *MatchingConfig) *MatchingEngine {
|
|
if config == nil {
|
|
config = DefaultMatchingConfig()
|
|
}
|
|
|
|
engine := &MatchingEngine{
|
|
config: config,
|
|
matchers: map[RuleType]RuleMatcher{
|
|
RuleTypeNetwork: &NetworkRuleMatcher{},
|
|
RuleTypeMac: &MacRuleMatcher{},
|
|
RuleTypeDomain: &DomainRuleMatcher{},
|
|
},
|
|
}
|
|
|
|
return engine
|
|
}
|
|
|
|
// FindUpstreams determines which upstreams should handle a request based on policy rules
|
|
// It implements the original behavior where MAC and domain rules can override network rules
|
|
func (e *MatchingEngine) FindUpstreams(ctx context.Context, req *MatchRequest) *MatchingResult {
|
|
result := &MatchingResult{
|
|
Upstreams: []string{},
|
|
MatchedPolicy: "no policy",
|
|
MatchedNetwork: "no network",
|
|
MatchedRule: "no rule",
|
|
Matched: false,
|
|
SrcAddr: req.SourceIP.String(),
|
|
MatchedRuleType: "",
|
|
MatchingOrder: e.config.Order,
|
|
}
|
|
|
|
if req.Policy == nil {
|
|
return result
|
|
}
|
|
|
|
result.MatchedPolicy = req.Policy.Name
|
|
|
|
var networkMatch *MatchResult
|
|
var macMatch *MatchResult
|
|
var domainMatch *MatchResult
|
|
|
|
// Check all rule types and store matches
|
|
for _, ruleType := range e.config.Order {
|
|
matcher, exists := e.matchers[ruleType]
|
|
if !exists {
|
|
continue
|
|
}
|
|
|
|
matchResult := matcher.Match(ctx, req)
|
|
if matchResult.Matched {
|
|
switch matchResult.RuleType {
|
|
case RuleTypeNetwork:
|
|
networkMatch = matchResult
|
|
case RuleTypeMac:
|
|
macMatch = matchResult
|
|
case RuleTypeDomain:
|
|
domainMatch = matchResult
|
|
}
|
|
}
|
|
}
|
|
|
|
// Determine the final match based on original logic:
|
|
// Domain rules override everything, MAC rules override network rules
|
|
if domainMatch != nil {
|
|
result.Upstreams = domainMatch.Targets
|
|
result.Matched = true
|
|
result.MatchedRuleType = string(domainMatch.RuleType)
|
|
result.MatchedRule = domainMatch.MatchedRule
|
|
// Special case: domain rules override network rules
|
|
if networkMatch != nil {
|
|
result.MatchedNetwork = networkMatch.MatchedRule + " (unenforced)"
|
|
}
|
|
} else if macMatch != nil {
|
|
result.Upstreams = macMatch.Targets
|
|
result.Matched = true
|
|
result.MatchedRuleType = string(macMatch.RuleType)
|
|
result.MatchedNetwork = macMatch.MatchedRule
|
|
} else if networkMatch != nil {
|
|
result.Upstreams = networkMatch.Targets
|
|
result.Matched = true
|
|
result.MatchedRuleType = string(networkMatch.RuleType)
|
|
result.MatchedNetwork = networkMatch.MatchedRule
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// MatchingResult represents the result of the matching engine
|
|
type MatchingResult struct {
|
|
Upstreams []string
|
|
MatchedPolicy string
|
|
MatchedNetwork string
|
|
MatchedRule string
|
|
Matched bool
|
|
SrcAddr string
|
|
MatchedRuleType string
|
|
MatchingOrder []RuleType
|
|
}
|