Skip to content

Commit c20e1ca

Browse files
authored
feat: support for CNAME record fallback (#187)
This adds support for falling back to a matching CNAME record when there's no available A/AAAA record matching a query. Fixes #186
1 parent 0f0b4b3 commit c20e1ca

File tree

1 file changed

+34
-26
lines changed

1 file changed

+34
-26
lines changed

internal/dns/dns.go

+34-26
Original file line numberDiff line numberDiff line change
@@ -85,37 +85,45 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
8585
metricQueryTotal.Inc()
8686

8787
// Check for known record from local storage
88-
records, err := state.GetState().LookupRecords(
89-
[]string{dns.Type(r.Question[0].Qtype).String()},
90-
strings.TrimSuffix(r.Question[0].Name, "."),
91-
)
92-
if err != nil {
93-
slog.Error(
94-
fmt.Sprintf("failed to lookup records in state: %s", err),
88+
lookupRecordTypes := []uint16{r.Question[0].Qtype}
89+
switch r.Question[0].Qtype {
90+
case dns.TypeA, dns.TypeAAAA:
91+
// If the query is for A/AAAA, also try looking up matching CNAME records
92+
lookupRecordTypes = append(lookupRecordTypes, dns.TypeCNAME)
93+
}
94+
for _, lookupRecordType := range lookupRecordTypes {
95+
records, err := state.GetState().LookupRecords(
96+
[]string{dns.Type(lookupRecordType).String()},
97+
strings.TrimSuffix(r.Question[0].Name, "."),
9598
)
96-
return
97-
}
98-
if records != nil {
99-
// Assemble response
100-
m.SetReply(r)
101-
for _, tmpRecord := range records {
102-
tmpRR, err := stateRecordToDnsRR(tmpRecord)
103-
if err != nil {
99+
if err != nil {
100+
slog.Error(
101+
fmt.Sprintf("failed to lookup records in state: %s", err),
102+
)
103+
return
104+
}
105+
if records != nil {
106+
// Assemble response
107+
m.SetReply(r)
108+
for _, tmpRecord := range records {
109+
tmpRR, err := stateRecordToDnsRR(tmpRecord)
110+
if err != nil {
111+
slog.Error(
112+
fmt.Sprintf("failed to convert state record to dns.RR: %s", err),
113+
)
114+
return
115+
}
116+
m.Answer = append(m.Answer, tmpRR)
117+
}
118+
// Send response
119+
if err := w.WriteMsg(m); err != nil {
104120
slog.Error(
105-
fmt.Sprintf("failed to convert state record to dns.RR: %s", err),
121+
fmt.Sprintf("failed to write response: %s", err),
106122
)
107-
return
108123
}
109-
m.Answer = append(m.Answer, tmpRR)
110-
}
111-
// Send response
112-
if err := w.WriteMsg(m); err != nil {
113-
slog.Error(
114-
fmt.Sprintf("failed to write response: %s", err),
115-
)
124+
// We found our answer, to return from handler
125+
return
116126
}
117-
// We found our answer, to return from handler
118-
return
119127
}
120128

121129
// Check for any NS records for parent domains from local storage

0 commit comments

Comments
 (0)