package service import ( "fmt" "log" "net" "github.com/miekg/dns" ) var dnsClient dns.Client func init() { dnsClient = dns.Client{ Net: "tcp", } } func DNSUpdateEntry(domain string, hostname string, ip4 net.IP, ip6 net.IP) error { if ip4 == nil && ip6 == nil { return fmt.Errorf("at least one of --ipv4 and --ipv6 have to be set") } msg := new(dns.Msg) fqdn := fmt.Sprintf("%s.%s.", hostname, domain) zone := fmt.Sprintf("%s.", domain) msg.SetUpdate(zone) if ip4 != nil { ip4bin := ip4.To4() if ip4bin == nil { return fmt.Errorf("ip4 (%v) is not a valid IPv4 address", ip4) } msg.RemoveRRset([]dns.RR{ &dns.RR_Header{Name: fqdn, Rrtype: dns.TypeA}, }) msg.Insert([]dns.RR{&dns.A{ Hdr: dns.RR_Header{ Name: fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: C.DNS.DefaultTTL, }, A: ip4bin, }}) } if ip6 != nil { ip6bin := ip6.To16() if ip6bin == nil { return fmt.Errorf("ip6 (%v) is not a valid IPv6 address", ip4) } msg.RemoveRRset([]dns.RR{ &dns.RR_Header{Name: fqdn, Rrtype: dns.TypeAAAA}, }) msg.Insert([]dns.RR{&dns.AAAA{ Hdr: dns.RR_Header{ Name: fqdn, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: C.DNS.DefaultTTL, }, AAAA: ip6bin, }}) } log.Printf("Sending DNS Update for %s.%s:\n%v", hostname, domain, msg) reply, _, err := dnsClient.Exchange(msg, C.DNS.Server) if err != nil { return fmt.Errorf("failed to execute DNS Udpate: %v", err) } log.Printf("Received DNS Update Reply for %s.%s:\n%v", hostname, domain, reply) return nil }