Feature: dns server could lookup hosts (#872)

This commit is contained in:
Kr328
2020-08-11 10:28:17 +08:00
committed by GitHub
parent 4ba6f248bc
commit 89cf06036d
4 changed files with 71 additions and 7 deletions

View File

@ -1,9 +1,11 @@
package dns
import (
"net"
"strings"
"github.com/Dreamacro/clash/component/fakeip"
"github.com/Dreamacro/clash/component/trie"
"github.com/Dreamacro/clash/log"
D "github.com/miekg/dns"
@ -12,6 +14,52 @@ import (
type handler func(w D.ResponseWriter, r *D.Msg)
type middleware func(next handler) handler
func withHosts(hosts *trie.DomainTrie) middleware {
return func(next handler) handler {
return func(w D.ResponseWriter, r *D.Msg) {
q := r.Question[0]
if !isIPRequest(q) {
next(w, r)
return
}
record := hosts.Search(strings.TrimRight(q.Name, "."))
if record == nil {
next(w, r)
return
}
ip := record.Data.(net.IP)
msg := r.Copy()
if v4 := ip.To4(); v4 != nil && q.Qtype == D.TypeA {
rr := &D.A{}
rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL}
rr.A = v4
msg.Answer = []D.RR{rr}
} else if v6 := ip.To16(); v6 != nil && q.Qtype == D.TypeAAAA {
rr := &D.AAAA{}
rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeAAAA, Class: D.ClassINET, Ttl: dnsDefaultTTL}
rr.AAAA = v6
msg.Answer = []D.RR{rr}
} else {
next(w, r)
return
}
msg.SetRcode(r, D.RcodeSuccess)
msg.Authoritative = true
msg.RecursionAvailable = true
w.WriteMsg(msg)
return
}
}
}
func withFakeIP(fakePool *fakeip.Pool) middleware {
return func(next handler) handler {
return func(w D.ResponseWriter, r *D.Msg) {
@ -100,6 +148,10 @@ func compose(middlewares []middleware, endpoint handler) handler {
func newHandler(resolver *Resolver) handler {
middlewares := []middleware{}
if resolver.hosts != nil {
middlewares = append(middlewares, withHosts(resolver.hosts))
}
if resolver.FakeIPEnabled() {
middlewares = append(middlewares, withFakeIP(resolver.pool))
}

View File

@ -14,6 +14,7 @@ import (
"github.com/Dreamacro/clash/common/picker"
"github.com/Dreamacro/clash/component/fakeip"
"github.com/Dreamacro/clash/component/resolver"
"github.com/Dreamacro/clash/component/trie"
D "github.com/miekg/dns"
"golang.org/x/sync/singleflight"
@ -37,6 +38,7 @@ type Resolver struct {
ipv6 bool
mapping bool
fakeip bool
hosts *trie.DomainTrie
pool *fakeip.Pool
main []dnsClient
fallback []dnsClient
@ -308,6 +310,7 @@ type Config struct {
EnhancedMode EnhancedMode
FallbackFilter FallbackFilter
Pool *fakeip.Pool
Hosts *trie.DomainTrie
}
func New(config Config) *Resolver {
@ -323,6 +326,7 @@ func New(config Config) *Resolver {
mapping: config.EnhancedMode == MAPPING,
fakeip: config.EnhancedMode == FAKEIP,
pool: config.Pool,
hosts: config.Hosts,
}
if len(config.Fallback) != 0 {