Skip to content

Commit

Permalink
support ipv6 for dns resolver (ginuerzh#389)
Browse files Browse the repository at this point in the history
  • Loading branch information
ginuerzh committed Dec 18, 2019
1 parent e0815d3 commit b193fc5
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ type resolver struct {
domain string
stopped chan struct{}
mux sync.RWMutex
prefer string // ipv4 or ipv6
}

// NewResolver create a new Resolver with the given name servers and resolution timeout.
Expand Down Expand Up @@ -211,18 +212,36 @@ func (r *resolver) Resolve(host string) (ips []net.IP, err error) {
return
}

func (*resolver) resolve(ex Exchanger, host string) (ips []net.IP, ttl time.Duration, err error) {
func (r *resolver) resolve(ex Exchanger, host string) (ips []net.IP, ttl time.Duration, err error) {
if ex == nil {
return
}

ctx := context.Background()
if r.prefer == "ipv6" { // prefer ipv6
query := dns.Msg{}
query.SetQuestion(dns.Fqdn(host), dns.TypeAAAA)
ips, ttl, err = r.resolveIPs(ctx, ex, &query)
if err != nil || len(ips) > 0 {
return
}
}

query := dns.Msg{}
query.SetQuestion(dns.Fqdn(host), dns.TypeA)
mr, err := ex.Exchange(context.Background(), &query)
return r.resolveIPs(ctx, ex, &query)
}

func (*resolver) resolveIPs(ctx context.Context, ex Exchanger, query *dns.Msg) (ips []net.IP, ttl time.Duration, err error) {
mr, err := ex.Exchange(ctx, query)
if err != nil {
return
}
for _, ans := range mr.Answer {
if ar, _ := ans.(*dns.AAAA); ar != nil {
ips = append(ips, ar.AAAA)
ttl = time.Duration(ar.Header().Ttl) * time.Second
}
if ar, _ := ans.(*dns.A); ar != nil {
ips = append(ips, ar.A)
ttl = time.Duration(ar.Header().Ttl) * time.Second
Expand Down Expand Up @@ -271,7 +290,7 @@ func (r *resolver) storeCache(name string, ips []net.IP, ttl time.Duration) {

func (r *resolver) Reload(rd io.Reader) error {
var ttl, timeout, period time.Duration
var domain string
var domain, prefer string
var nss []NameServer

if rd == nil || r.Stopped() {
Expand Down Expand Up @@ -304,6 +323,10 @@ func (r *resolver) Reload(rd io.Reader) error {
domain = ss[1]
}
case "search", "sortlist", "options": // we don't support these features in /etc/resolv.conf
case "prefer":
if len(ss) > 1 {
prefer = strings.ToLower(ss[1])
}
case "nameserver": // nameserver option, compatible with /etc/resolv.conf
if len(ss) <= 1 {
break
Expand Down Expand Up @@ -345,6 +368,7 @@ func (r *resolver) Reload(rd io.Reader) error {
r.TTL = ttl
r.domain = domain
r.period = period
r.prefer = prefer
r.Servers = nss
r.mux.Unlock()

Expand Down

0 comments on commit b193fc5

Please sign in to comment.