plugin/rewrite: fix flow control logic for all rule types (#1308)

Resolves: #1307
This commit is contained in:
Paul Greenberg
2017-12-14 13:25:36 -05:00
committed by John Belamaric
parent 671d170619
commit 3125381f2d
4 changed files with 34 additions and 20 deletions

View File

@@ -8,19 +8,22 @@ import (
) )
type classRule struct { type classRule struct {
fromClass, toClass uint16 fromClass uint16
toClass uint16
NextAction string
} }
func newClassRule(fromS, toS string) (Rule, error) { // newClassRule creates a class matching rule
func newClassRule(nextAction string, args ...string) (Rule, error) {
var from, to uint16 var from, to uint16
var ok bool var ok bool
if from, ok = dns.StringToClass[strings.ToUpper(fromS)]; !ok { if from, ok = dns.StringToClass[strings.ToUpper(args[0])]; !ok {
return nil, fmt.Errorf("invalid class %q", strings.ToUpper(fromS)) return nil, fmt.Errorf("invalid class %q", strings.ToUpper(args[0]))
} }
if to, ok = dns.StringToClass[strings.ToUpper(toS)]; !ok { if to, ok = dns.StringToClass[strings.ToUpper(args[1])]; !ok {
return nil, fmt.Errorf("invalid class %q", strings.ToUpper(toS)) return nil, fmt.Errorf("invalid class %q", strings.ToUpper(args[1]))
} }
return &classRule{fromClass: from, toClass: to}, nil return &classRule{from, to, nextAction}, nil
} }
// Rewrite rewrites the the current request. // Rewrite rewrites the the current request.
@@ -36,5 +39,5 @@ func (rule *classRule) Rewrite(w dns.ResponseWriter, r *dns.Msg) Result {
// Mode returns the processing mode // Mode returns the processing mode
func (rule *classRule) Mode() string { func (rule *classRule) Mode() string {
return Stop return rule.NextAction
} }

View File

@@ -107,9 +107,9 @@ func newRule(args ...string) (Rule, error) {
case "name": case "name":
return newNameRule(mode, args[startArg:]...) return newNameRule(mode, args[startArg:]...)
case "class": case "class":
return newClassRule(args[startArg], args[startArg+1]) return newClassRule(mode, args[startArg:]...)
case "type": case "type":
return newTypeRule(args[startArg], args[startArg+1]) return newTypeRule(mode, args[startArg:]...)
case "edns0": case "edns0":
return newEdns0Rule(mode, args[startArg:]...) return newEdns0Rule(mode, args[startArg:]...)
default: default:

View File

@@ -162,9 +162,15 @@ func TestRewrite(t *testing.T) {
rules = append(rules, r) rules = append(rules, r)
r, _ = newNameRule("stop", "regex", "(f.*m)\\.regex\\.(nl)", "to.{2}") r, _ = newNameRule("stop", "regex", "(f.*m)\\.regex\\.(nl)", "to.{2}")
rules = append(rules, r) rules = append(rules, r)
r, _ = newClassRule("CH", "IN") r, _ = newNameRule("continue", "regex", "consul\\.(rocks)", "core.dns.{1}")
rules = append(rules, r) rules = append(rules, r)
r, _ = newTypeRule("ANY", "HINFO") r, _ = newNameRule("stop", "core.dns.rocks", "to.nl.")
rules = append(rules, r)
r, _ = newClassRule("continue", "HS", "CH")
rules = append(rules, r)
r, _ = newClassRule("stop", "CH", "IN")
rules = append(rules, r)
r, _ = newTypeRule("stop", "ANY", "HINFO")
rules = append(rules, r) rules = append(rules, r)
rw := Rewrite{ rw := Rewrite{
@@ -192,8 +198,11 @@ func TestRewrite(t *testing.T) {
{"to.suffix.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET}, {"to.suffix.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET},
{"from.substring.nl.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET}, {"from.substring.nl.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET},
{"from.regex.nl.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET}, {"from.regex.nl.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET},
{"consul.rocks.", dns.TypeA, dns.ClassINET, "to.nl.", dns.TypeA, dns.ClassINET},
// name is not, type is, but class is, because class is the 2nd rule. // name is not, type is, but class is, because class is the 2nd rule.
{"a.nl.", dns.TypeANY, dns.ClassCHAOS, "a.nl.", dns.TypeANY, dns.ClassINET}, {"a.nl.", dns.TypeANY, dns.ClassCHAOS, "a.nl.", dns.TypeANY, dns.ClassINET},
// class gets rewritten twice because of continue/stop logic: HS to CH, CH to IN
{"a.nl.", dns.TypeANY, 4, "a.nl.", dns.TypeANY, dns.ClassINET},
} }
ctx := context.TODO() ctx := context.TODO()

View File

@@ -10,19 +10,21 @@ import (
// typeRule is a type rewrite rule. // typeRule is a type rewrite rule.
type typeRule struct { type typeRule struct {
fromType, toType uint16 fromType uint16
toType uint16
nextAction string
} }
func newTypeRule(fromS, toS string) (Rule, error) { func newTypeRule(nextAction string, args ...string) (Rule, error) {
var from, to uint16 var from, to uint16
var ok bool var ok bool
if from, ok = dns.StringToType[strings.ToUpper(fromS)]; !ok { if from, ok = dns.StringToType[strings.ToUpper(args[0])]; !ok {
return nil, fmt.Errorf("invalid type %q", strings.ToUpper(fromS)) return nil, fmt.Errorf("invalid type %q", strings.ToUpper(args[0]))
} }
if to, ok = dns.StringToType[strings.ToUpper(toS)]; !ok { if to, ok = dns.StringToType[strings.ToUpper(args[1])]; !ok {
return nil, fmt.Errorf("invalid type %q", strings.ToUpper(toS)) return nil, fmt.Errorf("invalid type %q", strings.ToUpper(args[1]))
} }
return &typeRule{fromType: from, toType: to}, nil return &typeRule{from, to, nextAction}, nil
} }
// Rewrite rewrites the the current request. // Rewrite rewrites the the current request.
@@ -38,5 +40,5 @@ func (rule *typeRule) Rewrite(w dns.ResponseWriter, r *dns.Msg) Result {
// Mode returns the processing mode // Mode returns the processing mode
func (rule *typeRule) Mode() string { func (rule *typeRule) Mode() string {
return Stop return rule.nextAction
} }