From 577ac5c91a9a95969c0dc8eb6ca68943f3557504 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 21 Mar 2018 09:05:30 +0100 Subject: [PATCH] When using a fallback resolver, favor IPv6 for DoH servers if use_ipv6 is set Fixes #153 --- dnscrypt-proxy/config.go | 2 ++ dnscrypt-proxy/xtransport.go | 52 +++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/dnscrypt-proxy/config.go b/dnscrypt-proxy/config.go index c9048810..6fc057de 100644 --- a/dnscrypt-proxy/config.go +++ b/dnscrypt-proxy/config.go @@ -182,6 +182,8 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error { if len(config.FallbackResolver) > 0 { proxy.xTransport.ignoreSystemDNS = config.IgnoreSystemDNS } + proxy.xTransport.useIPv4 = config.SourceIPv4 + proxy.xTransport.useIPv6 = config.SourceIPv6 proxy.timeout = time.Duration(config.Timeout) * time.Millisecond proxy.maxClients = config.MaxClients proxy.mainProto = "udp" diff --git a/dnscrypt-proxy/xtransport.go b/dnscrypt-proxy/xtransport.go index 232edeba..24876df9 100644 --- a/dnscrypt-proxy/xtransport.go +++ b/dnscrypt-proxy/xtransport.go @@ -135,30 +135,50 @@ func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string, dlog.Debugf("IP for [%s] was cached to [%s], but connection failed: [%s]", host, cachedIP, err) return nil, 0, err } - if !xTransport.useIPv4 { - return nil, 0, fmt.Errorf("IPv4 connectivity would be required to use [%s]", host) - } - dnsClient := new(dns.Client) - msg := new(dns.Msg) - msg.SetQuestion(dns.Fqdn(host), dns.TypeA) - msg.SetEdns0(4096, true) if !xTransport.ignoreSystemDNS { dlog.Noticef("System DNS configuration not usable yet, exceptionally resolving [%s] using fallback resolver [%s]", host, xTransport.fallbackResolver) } else { dlog.Debugf("Resolving [%s] using fallback resolver [%s]", host, xTransport.fallbackResolver) } - in, _, err := dnsClient.Exchange(msg, xTransport.fallbackResolver) + dnsClient := new(dns.Client) + + var foundIP *string + err = nil + if xTransport.useIPv4 { + msg := new(dns.Msg) + msg.SetQuestion(dns.Fqdn(host), dns.TypeA) + msg.SetEdns0(4096, true) + var in *dns.Msg + in, _, err = dnsClient.Exchange(msg, xTransport.fallbackResolver) + if err == nil { + for _, answer := range in.Answer { + if answer.Header().Rrtype == dns.TypeA { + foundIPx := answer.(*dns.A).A.String() + foundIP = &foundIPx + break + } + } + } + } + if xTransport.useIPv6 && foundIP == nil { + msg := new(dns.Msg) + msg.SetQuestion(dns.Fqdn(host), dns.TypeAAAA) + msg.SetEdns0(4096, true) + var in *dns.Msg + in, _, err = dnsClient.Exchange(msg, xTransport.fallbackResolver) + if err == nil { + for _, answer := range in.Answer { + if answer.Header().Rrtype == dns.TypeAAAA { + foundIPx := "[" + answer.(*dns.AAAA).AAAA.String() + "]" + foundIP = &foundIPx + break + } + } + } + } if err != nil { return nil, 0, err } - var foundIP *string - for _, answer := range in.Answer { - if answer.Header().Rrtype == dns.TypeA { - foundIPx := answer.(*dns.A).A.String() - foundIP = &foundIPx - break - } - } if foundIP == nil { return nil, 0, fmt.Errorf("No IP found for [%s]", host) }