Skip to content

Commit 95e025c

Browse files
JimhHanJimhHan
authored andcommitted
add ruleset support for ruleset
1 parent 43eaf79 commit 95e025c

File tree

2 files changed

+39
-18
lines changed

2 files changed

+39
-18
lines changed

app/router/config.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (r *Rule) Apply(ctx routing.Context) bool {
6363
return r.Condition.Apply(ctx)
6464
}
6565

66-
func (rr *RoutingRule) BuildCondition() (*ConditionChan, error) {
66+
func (rr *RoutingRule) BuildCondition(rsm *rsManager) (*ConditionChan, error) {
6767
conds := NewConditionChan()
6868

6969
if len(rr.Domain) > 0 {
@@ -138,6 +138,14 @@ func (rr *RoutingRule) BuildCondition() (*ConditionChan, error) {
138138
conds.Add(cond)
139139
}
140140

141+
if rr.RuleSet != "" {
142+
if rsCond, err := rsm.getRuleSet(rr.RuleSet); err != nil {
143+
return nil, err
144+
} else {
145+
conds.Add(rsCond)
146+
}
147+
}
148+
141149
if conds.Len() == 0 && rr.RuleSet == "" {
142150
return nil, newError("this rule has no effective fields").AtWarning()
143151
}
@@ -153,14 +161,18 @@ func (br *BalancingRule) Build(ohm outbound.Manager) (*Balancer, error) {
153161
}, nil
154162
}
155163

156-
func (rrs *RoutingRules) BuildCondition() (Condition, error) {
164+
func (rrs *RoutingRules) BuildCondition(rsm *rsManager) (Condition, error) {
157165
conds := NewOrConditionChan()
158166

159167
for _, rr := range rrs.Rules {
160168
if rr.GetTag() != "" || rr.GetBalancingTag() != "" {
161169
newError("ignoring tag in rule set").AtWarning().WriteToLog()
162170
}
163-
cond, err := rr.BuildCondition()
171+
172+
if rr.RuleSet == rrs.Identifier {
173+
return nil, newError("import cycle found for tag: " + rrs.Identifier)
174+
}
175+
cond, err := rr.BuildCondition(rsm)
164176
if err != nil {
165177
return nil, err
166178
}

app/router/router.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,26 @@ type Route struct {
2828
outboundTag string
2929
}
3030

31+
type rsManager struct {
32+
ruleSets map[string]Condition
33+
rawRuleSets map[string]*RoutingRules
34+
}
35+
36+
func (m *rsManager) getRuleSet(tag string) (Condition, error) {
37+
if cond, found := m.ruleSets[tag]; found {
38+
return cond, nil
39+
}
40+
if rCond, found := m.rawRuleSets[tag]; found {
41+
cond, err := rCond.BuildCondition(m)
42+
if err != nil {
43+
return nil, err
44+
}
45+
m.ruleSets[tag] = cond
46+
return cond, nil
47+
}
48+
return nil, newError("ruleset not exist: " + tag)
49+
}
50+
3151
// Init initializes the Router.
3252
func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error {
3353
r.domainStrategy = config.DomainStrategy
@@ -42,30 +62,19 @@ func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error
4262
r.balancers[rule.Tag] = balancer
4363
}
4464

45-
var rulSets = make(map[string]Condition)
65+
var rsm = &rsManager{make(map[string]Condition), make(map[string]*RoutingRules)}
66+
4667
for _, rs := range config.RuleSets {
47-
cond, err := rs.BuildCondition()
48-
if err != nil {
49-
return err
50-
}
51-
rulSets[rs.Identifier] = cond
68+
rsm.rawRuleSets[rs.Identifier] = rs
5269
}
5370

5471
r.rules = make([]*Rule, 0, len(config.Rule))
5572
for _, rule := range config.Rule {
56-
cond, err := rule.BuildCondition()
73+
cond, err := rule.BuildCondition(rsm)
5774
if err != nil {
5875
return err
5976
}
6077

61-
if rule.RuleSet != "" {
62-
if ruleset, found := rulSets[rule.RuleSet]; found {
63-
cond.Add(ruleset)
64-
} else {
65-
return newError("undefined rule set: " + rule.RuleSet).AtError()
66-
}
67-
}
68-
6978
rr := &Rule{
7079
Condition: cond,
7180
Tag: rule.GetTag(),

0 commit comments

Comments
 (0)