summaryrefslogtreecommitdiff
path: root/dns.go
diff options
context:
space:
mode:
Diffstat (limited to 'dns.go')
-rw-r--r--dns.go51
1 files changed, 51 insertions, 0 deletions
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")
+}