dyndns/service/dns.go

79 lines
1.6 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)
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
}