Skip to content

Commit

Permalink
feat: support for CNAME record fallback (#187)
Browse files Browse the repository at this point in the history
This adds support for falling back to a matching CNAME record when
there's no available A/AAAA record matching a query.

Fixes #186
  • Loading branch information
agaffney authored Aug 10, 2024
1 parent 0f0b4b3 commit c20e1ca
Showing 1 changed file with 34 additions and 26 deletions.
60 changes: 34 additions & 26 deletions internal/dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,37 +85,45 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
metricQueryTotal.Inc()

// Check for known record from local storage
records, err := state.GetState().LookupRecords(
[]string{dns.Type(r.Question[0].Qtype).String()},
strings.TrimSuffix(r.Question[0].Name, "."),
)
if err != nil {
slog.Error(
fmt.Sprintf("failed to lookup records in state: %s", err),
lookupRecordTypes := []uint16{r.Question[0].Qtype}
switch r.Question[0].Qtype {
case dns.TypeA, dns.TypeAAAA:
// If the query is for A/AAAA, also try looking up matching CNAME records
lookupRecordTypes = append(lookupRecordTypes, dns.TypeCNAME)
}
for _, lookupRecordType := range lookupRecordTypes {
records, err := state.GetState().LookupRecords(
[]string{dns.Type(lookupRecordType).String()},
strings.TrimSuffix(r.Question[0].Name, "."),
)
return
}
if records != nil {
// Assemble response
m.SetReply(r)
for _, tmpRecord := range records {
tmpRR, err := stateRecordToDnsRR(tmpRecord)
if err != nil {
if err != nil {
slog.Error(
fmt.Sprintf("failed to lookup records in state: %s", err),
)
return
}
if records != nil {
// Assemble response
m.SetReply(r)
for _, tmpRecord := range records {
tmpRR, err := stateRecordToDnsRR(tmpRecord)
if err != nil {
slog.Error(
fmt.Sprintf("failed to convert state record to dns.RR: %s", err),
)
return
}
m.Answer = append(m.Answer, tmpRR)
}
// Send response
if err := w.WriteMsg(m); err != nil {
slog.Error(
fmt.Sprintf("failed to convert state record to dns.RR: %s", err),
fmt.Sprintf("failed to write response: %s", err),
)
return
}
m.Answer = append(m.Answer, tmpRR)
}
// Send response
if err := w.WriteMsg(m); err != nil {
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
// We found our answer, to return from handler
return
}
// We found our answer, to return from handler
return
}

// Check for any NS records for parent domains from local storage
Expand Down

0 comments on commit c20e1ca

Please sign in to comment.