feat(dns): add RFC dns.resolve address result

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-03 19:49:59 +00:00
parent 9c6b2f4bc1
commit b784bb7927
2 changed files with 44 additions and 0 deletions

View file

@ -22,6 +22,10 @@ type ResolveAllResult struct {
NS []string `json:"ns"`
}
type ResolveAddressResult struct {
Addresses []string `json:"addresses"`
}
type Service struct {
mu sync.RWMutex
records map[string]NameRecords
@ -73,6 +77,16 @@ func (service *Service) ResolveTXT(name string) ([]string, bool) {
return append([]string(nil), record.TXT...), true
}
func (service *Service) ResolveAddress(name string) (ResolveAddressResult, bool) {
record, ok := service.findRecord(name)
if !ok {
return ResolveAddressResult{}, false
}
return ResolveAddressResult{
Addresses: MergeRecords(record.A, record.AAAA),
}, true
}
func (service *Service) ResolveReverse(ip string) ([]string, bool) {
service.mu.RLock()
defer service.mu.RUnlock()

View file

@ -62,6 +62,36 @@ func TestServiceResolveTXTUsesWildcard(t *testing.T) {
}
}
func TestServiceResolveAddressReturnsMergedRecords(t *testing.T) {
service := NewService(ServiceOptions{
Records: map[string]NameRecords{
"gateway.charon.lthn": {
A: []string{"10.10.10.10", "10.10.10.10"},
AAAA: []string{"2600:1f1c:7f0:4f01:0000:0000:0000:0001"},
},
},
})
result, ok := service.ResolveAddress("gateway.charon.lthn")
if !ok {
t.Fatal("expected address record to resolve")
}
if len(result.Addresses) != 2 {
t.Fatalf("expected merged unique addresses, got %#v", result.Addresses)
}
if result.Addresses[0] != "10.10.10.10" || result.Addresses[1] != "2600:1f1c:7f0:4f01:0000:0000:0000:0001" {
t.Fatalf("unexpected address order or value: %#v", result.Addresses)
}
}
func TestServiceResolveAddressFallsBackToFalseWhenMissing(t *testing.T) {
service := NewService(ServiceOptions{})
if _, ok := service.ResolveAddress("missing.charon.lthn"); ok {
t.Fatal("expected missing record to return false")
}
}
func TestServiceResolveReverseUsesARecords(t *testing.T) {
service := NewService(ServiceOptions{
Records: map[string]NameRecords{