From b2f9c977719626bebd9c9f9f7e52e50f2514ace7 Mon Sep 17 00:00:00 2001 From: Tero Marttila Date: Sun, 19 Jun 2016 20:05:55 +0300 Subject: autodiscover server from zone SOA --- dns.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'dns.go') diff --git a/dns.go b/dns.go index 4822012..ff3a109 100644 --- a/dns.go +++ b/dns.go @@ -3,6 +3,9 @@ package main import ( "github.com/miekg/dns" "fmt" + "time" + "log" + "net" ) const TSIG_FUDGE_SECONDS = 300 @@ -24,3 +27,51 @@ func (t *TSIGAlgorithm) UnmarshalFlag(value string) error { return nil } + +func query(query *dns.Msg) (*dns.Msg, error) { + clientConfig, err := dns.ClientConfigFromFile("/etc/resolv.conf") + if err != nil { + return nil, err + } + + timeout := time.Duration(clientConfig.Timeout * int(time.Second)) + + var client = new(dns.Client) + + client.DialTimeout = timeout + client.ReadTimeout = timeout + client.WriteTimeout = timeout + + for _, server := range clientConfig.Servers { + addr := net.JoinHostPort(server, "53") + + if answer, _, err := client.Exchange(query, addr); err != nil { + log.Printf("query %v: %v", server, err) + continue + } else { + return answer, nil + } + } + + return nil, fmt.Errorf("DNS query failed") +} + +// Discover likely master NS for zone +func discoverZoneServer(zone string) (string, error) { + var q = new(dns.Msg) + + q.SetQuestion(zone, dns.TypeSOA) + + r, err := query(q) + if err != nil { + return "", err + } + + for _, rr := range r.Answer { + if soa, ok := rr.(*dns.SOA); ok { + return soa.Ns, nil + } + } + + return "", fmt.Errorf("No SOA response") +} -- cgit v1.2.3