diff --git a/prober/dns.go b/prober/dns.go index 4b3aeac0..d86dae5a 100644 --- a/prober/dns.go +++ b/prober/dns.go @@ -248,11 +248,13 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry } } + queryName := internationalizeDNSDomain(logger, module.DNS.QueryName) + msg := new(dns.Msg) msg.Id = dns.Id() msg.RecursionDesired = true msg.Question = make([]dns.Question, 1) - msg.Question[0] = dns.Question{dns.Fqdn(module.DNS.QueryName), qt, qc} + msg.Question[0] = dns.Question{dns.Fqdn(queryName), qt, qc} level.Info(logger).Log("msg", "Making DNS query", "target", targetIP, "dial_protocol", dialProtocol, "query", module.DNS.QueryName, "type", qt, "class", qc) timeoutDeadline, _ := ctx.Deadline() diff --git a/prober/utils.go b/prober/utils.go index 98c9152e..d72cd6a0 100644 --- a/prober/utils.go +++ b/prober/utils.go @@ -22,6 +22,7 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "golang.org/x/net/idna" "github.com/prometheus/client_golang/prometheus" ) @@ -55,6 +56,8 @@ func chooseProtocol(ctx context.Context, IPProtocol string, fallbackIPProtocol b fallbackProtocol = "ip6" } + target = internationalizeDNSDomain(logger, target) + level.Info(logger).Log("msg", "Resolving target address", "ip_protocol", IPProtocol) resolveStart := time.Now() @@ -119,3 +122,18 @@ func ipHash(ip net.IP) float64 { h.Write(ip) return float64(h.Sum32()) } + +func internationalizeDNSDomain(logger log.Logger, domain string) string { + if net.ParseIP(domain) != nil { + // IP addresses don't need to be internationalized. + return domain + } + idnaDomain, err := idna.Lookup.ToASCII(domain) + if err != nil { + return domain + } + if idnaDomain != domain { + level.Info(logger).Log("msg", "Domain internationalized", "unicode", domain, "ascii", idnaDomain) + } + return idnaDomain +} diff --git a/prober/utils_test.go b/prober/utils_test.go index a53ee490..a8ebf314 100644 --- a/prober/utils_test.go +++ b/prober/utils_test.go @@ -251,3 +251,23 @@ func checkMetrics(expected map[string]map[string]map[string]struct{}, mfs []*dto } } } + +func TestChooseProtocolIDNA(t *testing.T) { + if testing.Short() { + t.Skip("skipping network dependent test") + } + var ( + ctx = context.Background() + registry = prometheus.NewPedanticRegistry() + w = log.NewSyncWriter(os.Stderr) + logger = log.NewLogfmtLogger(w) + ) + + ip, _, err := chooseProtocol(ctx, "ip4", true, "www.académie-française.fr", registry, logger) + if err != nil { + t.Error(err) + } + if ip == nil || ip.IP.To4() == nil { + t.Error("it should answer") + } +}