Stabilize dns.resolve.all payload shape

This commit is contained in:
Virgil 2026-04-04 02:45:54 +00:00
parent ff0ab358df
commit 0be2f529a0
2 changed files with 28 additions and 18 deletions

View file

@ -45,15 +45,18 @@ type NameRecords struct {
// // AAAA: []string{},
// // TXT: []string{"v=lthn1 type=gateway"},
// // NS: []string{"ns.charon.lthn"},
// // DS: []string{},
// // DNSKEY: []string{},
// // RRSIG: []string{},
// // }
type ResolveAllResult struct {
A []string `json:"a"`
AAAA []string `json:"aaaa"`
TXT []string `json:"txt"`
NS []string `json:"ns"`
DS []string `json:"ds,omitempty"`
DNSKEY []string `json:"dnskey,omitempty"`
RRSIG []string `json:"rrsig,omitempty"`
DS []string `json:"ds"`
DNSKEY []string `json:"dnskey"`
RRSIG []string `json:"rrsig"`
}
// ResolveAddressResult returns the merged address list for `dns.resolve`.
@ -1116,26 +1119,21 @@ func normalizeReverseLookupInput(value string) (string, bool) {
// // ok = true
//
// Missing names still return empty arrays so the action payload stays stable.
//
// result, ok := service.ResolveAll("missing.charon.lthn")
// // result = dns.ResolveAllResult{A: []string{}, AAAA: []string{}, TXT: []string{}, NS: []string{}, DS: []string{}, DNSKEY: []string{}, RRSIG: []string{}}
func (service *Service) ResolveAll(name string) (ResolveAllResult, bool) {
if service == nil {
return ResolveAllResult{}, false
}
record, ok := service.findRecord(name)
if !ok {
empty := emptyResolveAllResult()
if normalizeName(name) == service.ZoneApex() && service.ZoneApex() != "" {
return ResolveAllResult{
A: []string{},
AAAA: []string{},
TXT: []string{},
NS: []string{"ns." + service.ZoneApex()},
}, true
empty.NS = []string{"ns." + service.ZoneApex()}
return empty, true
}
return ResolveAllResult{
A: []string{},
AAAA: []string{},
TXT: []string{},
NS: []string{},
}, true
return empty, true
}
result := resolveResult(record)
if normalizeName(name) == service.ZoneApex() && service.ZoneApex() != "" && len(result.NS) == 0 {
@ -1278,6 +1276,18 @@ func resolveResult(record NameRecords) ResolveAllResult {
}
}
func emptyResolveAllResult() ResolveAllResult {
return ResolveAllResult{
A: []string{},
AAAA: []string{},
TXT: []string{},
NS: []string{},
DS: []string{},
DNSKEY: []string{},
RRSIG: []string{},
}
}
func buildReverseIndex(records map[string]NameRecords) *ReverseIndex {
raw := map[string]map[string]struct{}{}
for name, record := range records {

View file

@ -2596,7 +2596,7 @@ func TestServiceResolveAllReturnsStableShapeForDerivedZoneApex(t *testing.T) {
if err != nil {
t.Fatalf("expected derived apex payload to marshal: %v", err)
}
if string(raw) != `{"a":[],"aaaa":[],"txt":[],"ns":["ns.charon.lthn"]}` {
if string(raw) != `{"a":[],"aaaa":[],"txt":[],"ns":["ns.charon.lthn"],"ds":[],"dnskey":[],"rrsig":[]}` {
t.Fatalf("expected stable JSON shape for derived apex, got %s", raw)
}
}
@ -2631,7 +2631,7 @@ func TestServiceResolveAllReturnsEmptyArraysForMissingRecordValues(t *testing.T)
if err != nil {
t.Fatalf("expected result to marshal: %v", err)
}
if string(raw) != `{"a":["10.10.10.10"],"aaaa":[],"txt":[],"ns":[]}` {
if string(raw) != `{"a":["10.10.10.10"],"aaaa":[],"txt":[],"ns":[],"ds":[],"dnskey":[],"rrsig":[]}` {
t.Fatalf("expected empty arrays in JSON, got %s", raw)
}
}
@ -2651,7 +2651,7 @@ func TestServiceResolveAllReturnsEmptyArraysForMissingName(t *testing.T) {
if err != nil {
t.Fatalf("expected result to marshal: %v", err)
}
if string(raw) != `{"a":[],"aaaa":[],"txt":[],"ns":[]}` {
if string(raw) != `{"a":[],"aaaa":[],"txt":[],"ns":[],"ds":[],"dnskey":[],"rrsig":[]}` {
t.Fatalf("expected empty arrays in JSON, got %s", raw)
}
}