nameserver.go: use custom resolver to avoid update delays caused by dns caching
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
Thomas Preisner 2021-09-12 02:08:53 +02:00
parent 8e86f5992e
commit 204d5eacf6
2 changed files with 25 additions and 5 deletions

View file

@ -1,17 +1,37 @@
package main
import (
"context"
"fmt"
"log"
"net"
"os/exec"
"strings"
"time"
)
func requiresRRUpdate(entry *RRConfig, addr net.IP) bool {
// TODO: use custom resolver to query authoritive nameserver instead of
// local resolver
addrs, err := net.LookupIP(entry.Recordname)
const (
resolverTimeout = time.Millisecond * time.Duration(8000)
)
func getResolver(nameserver string) *net.Resolver {
return &net.Resolver{
// use go's built-in dns resolver
PreferGo: true,
// specify alternate dialer for go's dns resolver
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: resolverTimeout,
}
return d.DialContext(ctx, network, nameserver)
},
}
}
func requiresRRUpdate(record string, addr net.IP, resolver *net.Resolver) bool {
// TODO: the context could be replaced in order to allow cancelling the dns
// query if the user disconnects prematurely
addrs, err := resolver.LookupIP(context.Background(), "ip", record)
if err != nil {
log.Printf("dns lookup failed: %s", err)
// enforce update, it's better than not trying at all

2
web.go
View file

@ -124,7 +124,7 @@ func RequestHandler(cfg *Config) func(w http.ResponseWriter, r *http.Request) {
return
}
if !requiresRRUpdate(entry, ipaddr) {
if !requiresRRUpdate(entry.Recordname, ipaddr, getResolver(entry.Nameserver)) {
fmt.Fprintf(w, "nochg %s\n", ipaddr.String())
return
}