dyndns/service/dns.go

80 lines
1.5 KiB
Go

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)
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.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)
}
rrs = append(rrs, &dns.AAAA{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeAAAA,
Class: dns.ClassINET,
Ttl: C.DNS.DefaultTTL,
},
AAAA: ip6bin,
})
}
msg.Insert(rrs)
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
}