You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
1.3 KiB
81 lines
1.3 KiB
package internal
|
|
|
|
import (
|
|
"net"
|
|
"regexp"
|
|
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
type RuleType string
|
|
|
|
const (
|
|
A = RuleType("A")
|
|
CNAME = RuleType("CNAME")
|
|
Recurse = RuleType("recurse")
|
|
)
|
|
|
|
type RuleEvaluator interface {
|
|
Evaluate(string) (Rule, bool)
|
|
}
|
|
|
|
type RuleEngine struct {
|
|
Rules []Rule
|
|
}
|
|
|
|
func (re *RuleEngine) Evaluate(domain string) (Rule, bool) {
|
|
for _, r := range re.Rules {
|
|
regex := regexp.MustCompile(r.Value)
|
|
if regex.MatchString(domain) {
|
|
return r, true
|
|
}
|
|
}
|
|
|
|
return Rule{}, false
|
|
}
|
|
|
|
type Rule struct {
|
|
Name string `json:"name"`
|
|
Value string `json:"value"`
|
|
Answer struct {
|
|
Type RuleType `json:"type"`
|
|
Value string `json:"value"`
|
|
} `json:"answer"`
|
|
TTL int `json:"ttl"`
|
|
}
|
|
|
|
func getType(rt RuleType) uint16 {
|
|
switch rt {
|
|
case A:
|
|
return dns.TypeA
|
|
case CNAME:
|
|
return dns.TypeCNAME
|
|
case Recurse:
|
|
break
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func (r Rule) CreateAnswer(name string) *dns.Msg {
|
|
return &dns.Msg{
|
|
MsgHdr: dns.MsgHdr{},
|
|
Compress: false,
|
|
Question: []dns.Question{},
|
|
Answer: []dns.RR{
|
|
&dns.A{
|
|
Hdr: dns.RR_Header{
|
|
Name: name,
|
|
Rrtype: getType(r.Answer.Type),
|
|
Class: dns.ClassINET,
|
|
Ttl: uint32(r.TTL),
|
|
},
|
|
A: net.ParseIP(r.Answer.Value).To4(),
|
|
},
|
|
},
|
|
Ns: []dns.RR{},
|
|
Extra: []dns.RR{},
|
|
}
|
|
|
|
}
|