package service import ( "fmt" "log" "net" "github.com/miekg/dns" ) var dnsClient dns.Client func init() { dnsClient = dns.Client{ Net: "tcp", } } func UpdateDNSEntry(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) msg.RemoveName([]dns.RR{ &dns.RR_Header{Name: fqdn}, }) var rrs []dns.RR if ip4 != nil { ip4bin := ip4.To4() if ip4bin == nil { return fmt.Errorf("ip4 (%v) is not a valid IPv4 address", ip4) } rrs = append(rrs, &dns.A{ Hdr: dns.RR_Header{ Name: fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: C.DefaultTTL, }, A: ip4bin, }) } if ip6 != nil { ip6bin := ip6.To16() if ip6bin == nil { return fmt.Errorf("ip6 (%v) is not a valid IPv6 address", ip4) } rrs = append(rrs, &dns.AAAA{ Hdr: dns.RR_Header{ Name: fqdn, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: C.DefaultTTL, }, AAAA: ip6bin, }) } msg.Insert(rrs) log.Printf("Sending DNS Update: %v", msg) reply, _, err := dnsClient.Exchange(msg, C.DNSServer) if err != nil { return fmt.Errorf("failed to execute DNS Udpate: %v", err) } log.Printf("Received DNS Update Reply: %v", reply) return nil }