dyndns/service/dns.go
Torben Nehmer 45d4e45bb1 Reworked update code, split v4/v6 updates
- collect dns updatees individually, so that we clear A and AAAA separately if and only if needed.
- made nft AddIP call more resilient against partial updates
- updated nft processing code to no longer add nil to a v4/v6 set which would end in an invalid call to AddIP when updating nft. call it individually now.
- updated samples with real world traces from an AVM Box
2021-09-25 11:56:50 +02:00

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
}