go-nsupdate/dns.go

79 lines
1.5 KiB
Go

package main
import (
"fmt"
"github.com/miekg/dns"
"log"
"net"
"time"
)
const TSIG_FUDGE_SECONDS = 300
type TSIGAlgorithm string
func (t *TSIGAlgorithm) UnmarshalFlag(value string) error {
switch value {
case "hmac-md5", "md5":
*t = dns.HmacMD5
case "hmac-sha1", "sha1":
*t = dns.HmacSHA1
case "hmac-sha256", "sha256":
*t = dns.HmacSHA256
case "hmac-sha512", "sha512":
*t = dns.HmacSHA512
default:
return fmt.Errorf("Invalid --tsig-algorithm=%v", value)
}
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")
}