* dnsfilter: change DNS answer for host rules
When matched by a host rule, return only the IP address specified in rule. Respond with an empty IP list to another request type. :: host -- return nothing to A, return :: to AAAA request 0.0.0.0 host -- return 0.0.0.0 to A, return nothing to AAAA request
This commit is contained in:
parent
94d86eee10
commit
8d2a9ce923
|
@ -1,7 +1,6 @@
|
||||||
package dnsfilter
|
package dnsfilter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
@ -538,24 +537,15 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16) (Result, error) {
|
||||||
|
|
||||||
} else if hostRule, ok := rule.(*rules.HostRule); ok {
|
} else if hostRule, ok := rule.(*rules.HostRule); ok {
|
||||||
|
|
||||||
|
res.IP = net.IP{}
|
||||||
if qtype == dns.TypeA && hostRule.IP.To4() != nil {
|
if qtype == dns.TypeA && hostRule.IP.To4() != nil {
|
||||||
// either IPv4 or IPv4-mapped IPv6 address
|
// either IPv4 or IPv4-mapped IPv6 address
|
||||||
res.IP = hostRule.IP.To4()
|
res.IP = hostRule.IP.To4()
|
||||||
return res, nil
|
|
||||||
|
|
||||||
} else if qtype == dns.TypeAAAA {
|
} else if qtype == dns.TypeAAAA && hostRule.IP.To4() == nil {
|
||||||
ip4 := hostRule.IP.To4()
|
|
||||||
if ip4 == nil {
|
|
||||||
res.IP = hostRule.IP
|
res.IP = hostRule.IP
|
||||||
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
|
||||||
if bytes.Equal(ip4, []byte{0, 0, 0, 0}) {
|
|
||||||
// send IP="::" response for a rule "0.0.0.0 blockdomain"
|
|
||||||
res.IP = net.IPv6zero
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.Tracef("Rule type is unsupported: '%s' list_id: %d",
|
log.Tracef("Rule type is unsupported: '%s' list_id: %d",
|
||||||
|
|
|
@ -98,7 +98,7 @@ func (d *Dnsfilter) checkMatchEmpty(t *testing.T, hostname string) {
|
||||||
func TestEtcHostsMatching(t *testing.T) {
|
func TestEtcHostsMatching(t *testing.T) {
|
||||||
addr := "216.239.38.120"
|
addr := "216.239.38.120"
|
||||||
addr6 := "::1"
|
addr6 := "::1"
|
||||||
text := fmt.Sprintf(" %s google.com www.google.com # enforce google's safesearch \n%s google.com\n0.0.0.0 block.com\n",
|
text := fmt.Sprintf(" %s google.com www.google.com # enforce google's safesearch \n%s ipv6.com\n0.0.0.0 block.com\n",
|
||||||
addr, addr6)
|
addr, addr6)
|
||||||
filters := make(map[int]string)
|
filters := make(map[int]string)
|
||||||
filters[0] = text
|
filters[0] = text
|
||||||
|
@ -110,12 +110,19 @@ func TestEtcHostsMatching(t *testing.T) {
|
||||||
d.checkMatchEmpty(t, "subdomain.google.com")
|
d.checkMatchEmpty(t, "subdomain.google.com")
|
||||||
d.checkMatchEmpty(t, "example.org")
|
d.checkMatchEmpty(t, "example.org")
|
||||||
|
|
||||||
// IPv6 address
|
// IPv4
|
||||||
d.checkMatchIP(t, "google.com", addr6, dns.TypeAAAA)
|
|
||||||
|
|
||||||
// block both IPv4 and IPv6
|
|
||||||
d.checkMatchIP(t, "block.com", "0.0.0.0", dns.TypeA)
|
d.checkMatchIP(t, "block.com", "0.0.0.0", dns.TypeA)
|
||||||
d.checkMatchIP(t, "block.com", "::", dns.TypeAAAA)
|
|
||||||
|
// ...but empty IPv6
|
||||||
|
ret, err := d.CheckHost("block.com", dns.TypeAAAA, &setts)
|
||||||
|
assert.True(t, err == nil && ret.IsFiltered && ret.IP != nil && len(ret.IP) == 0)
|
||||||
|
|
||||||
|
// IPv6
|
||||||
|
d.checkMatchIP(t, "ipv6.com", addr6, dns.TypeAAAA)
|
||||||
|
|
||||||
|
// ...but empty IPv4
|
||||||
|
ret, err = d.CheckHost("ipv6.com", dns.TypeA, &setts)
|
||||||
|
assert.True(t, err == nil && ret.IsFiltered && ret.IP != nil && len(ret.IP) == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFE BROWSING
|
// SAFE BROWSING
|
||||||
|
|
|
@ -788,7 +788,8 @@ func (s *Server) genAAAAAnswer(req *dns.Msg, ip net.IP) *dns.AAAA {
|
||||||
func (s *Server) genResponseWithIP(req *dns.Msg, ip net.IP) *dns.Msg {
|
func (s *Server) genResponseWithIP(req *dns.Msg, ip net.IP) *dns.Msg {
|
||||||
if req.Question[0].Qtype == dns.TypeA && ip.To4() != nil {
|
if req.Question[0].Qtype == dns.TypeA && ip.To4() != nil {
|
||||||
return s.genARecord(req, ip.To4())
|
return s.genARecord(req, ip.To4())
|
||||||
} else if req.Question[0].Qtype == dns.TypeAAAA && ip.To4() == nil {
|
} else if req.Question[0].Qtype == dns.TypeAAAA &&
|
||||||
|
len(ip) == net.IPv6len && ip.To4() == nil {
|
||||||
return s.genAAAARecord(req, ip)
|
return s.genAAAARecord(req, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue