/*
* Copyright (C) 2024 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
* more information.
*/
package dns
import (
"log/slog"
"time"
"github.com/miekg/dns"
)
func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg)
m.SetReply(r)
m.Compress = false
m.SetEdns0(4096, true)
requestWasValidTsig := false
if r.IsTsig() != nil {
slog.Debug("Request is TSIG")
if w.TsigStatus() == nil {
slog.Debug("TSIG is valid")
requestWasValidTsig = true
// NOTE: The first argument here is the keyname.
m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacSHA256, 300, time.Now().Unix())
} else {
slog.Error("TSIG error", slog.String("status", w.TsigStatus().Error()))
// Stop processing the request if there was something wrong with TSIG.
return
}
}
switch r.Opcode {
case dns.OpcodeQuery:
parseQuery(m, r)
case dns.OpcodeUpdate:
if requestWasValidTsig {
parseUpdate(m, r)
} else {
// Don't process updates if request wasn't tsig.
// NOTE: I figured FORMERR was the best for this. Do you have any objections?
m.SetRcode(r, dns.RcodeFormatError)
}
default:
slog.Info("Unsupported Opcode", slog.String("type", dns.OpcodeToString[r.Opcode]))
m.SetRcode(r, dns.RcodeNotImplemented)
}
w.WriteMsg(m)
}