checker: join Hdr.Name to apex in preferRRName

happyDomain encodes service-embedded record owners relative to the
zone apex, so returning the trimmed Hdr.Name as the FQDN owner left
relative names like "_465._tcp" leaking into pointer dedup keys and
discovery entries. Join with apex unless the name is already
suffix-anchored.
This commit is contained in:
nemunaire 2026-04-29 17:35:56 +07:00
commit a624a7bfd1

View file

@ -159,7 +159,7 @@ func extractPointers(sub, apex string, svc rawService) ([]Pointer, error) {
if target == "" { if target == "" {
return nil, nil return nil, nil
} }
ptOwner := preferRRName(b.Record.Hdr.Name, owner) ptOwner := preferRRName(b.Record.Hdr.Name, owner, apex)
return []Pointer{{ return []Pointer{{
Owner: ptOwner, Owner: ptOwner,
Subdomain: sub, Subdomain: sub,
@ -180,7 +180,7 @@ func extractPointers(sub, apex string, svc rawService) ([]Pointer, error) {
continue continue
} }
out = append(out, Pointer{ out = append(out, Pointer{
Owner: preferRRName(r.Hdr.Name, owner), Owner: preferRRName(r.Hdr.Name, owner, apex),
Subdomain: sub, Subdomain: sub,
Rrtype: "MX", Rrtype: "MX",
Target: target, Target: target,
@ -201,7 +201,7 @@ func extractPointers(sub, apex string, svc rawService) ([]Pointer, error) {
continue continue
} }
out = append(out, Pointer{ out = append(out, Pointer{
Owner: preferRRName(r.Hdr.Name, owner), Owner: preferRRName(r.Hdr.Name, owner, apex),
Subdomain: sub, Subdomain: sub,
Rrtype: "SRV", Rrtype: "SRV",
Target: target, Target: target,
@ -215,7 +215,7 @@ func extractPointers(sub, apex string, svc rawService) ([]Pointer, error) {
if err := json.Unmarshal(svc.Service, &b); err != nil { if err := json.Unmarshal(svc.Service, &b); err != nil {
return nil, fmt.Errorf("decode orphan body: %w", err) return nil, fmt.Errorf("decode orphan body: %w", err)
} }
ptOwner := preferRRName(b.Record.Hdr.Name, owner) ptOwner := preferRRName(b.Record.Hdr.Name, owner, apex)
switch b.Record.Hdr.Rrtype { switch b.Record.Hdr.Rrtype {
case dns.TypeNS: case dns.TypeNS:
target := normaliseTarget(b.Record.Ns, ptOwner, apex) target := normaliseTarget(b.Record.Ns, ptOwner, apex)
@ -330,13 +330,20 @@ func ownerFQDN(svcDomain, sub, apex string) string {
return sub + "." + apex return sub + "." + apex
} }
// preferRRName returns the RR header Name when present, as it is authoritative over the service-derived owner. // preferRRName returns the RR header Name as an FQDN when present.
func preferRRName(rrName, fallback string) string { // happyDomain encodes service-embedded record owners relative to the zone
// apex, so the rrName must be joined with apex unless it already contains
// the apex suffix (services published with absolute owners).
func preferRRName(rrName, fallback, apex string) string {
rrName = strings.TrimSuffix(rrName, ".") rrName = strings.TrimSuffix(rrName, ".")
if rrName != "" { if rrName == "" {
return fallback
}
apex = strings.TrimSuffix(apex, ".")
if apex == "" || rrName == apex || strings.HasSuffix(rrName, "."+apex) {
return rrName return rrName
} }
return fallback return rrName + "." + apex
} }
// normaliseTarget converts a target to FQDN form; happyDomain stores in-zone targets relative, external ones absolute. // normaliseTarget converts a target to FQDN form; happyDomain stores in-zone targets relative, external ones absolute.