plugin/transfter: Fix longestMatch to select the most specific zone correctly. (#7949)

* plugin/transfter: Fix longestMatch to select the most specific zone correctly.

This PR Fix longestMatch to select the most specific zone correctly.The previous implementation used lexicographic string comparison, which could choose the wrong zone; this change selects the longest matching zone instead.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

* Tie breaker

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

* Fix

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

---------

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang
2026-03-24 11:35:20 -07:00
committed by GitHub
parent 980b0fe16b
commit a025712827
2 changed files with 20 additions and 1 deletions

View File

@@ -209,7 +209,7 @@ func longestMatch(xfrs []*xfr, name string) *xfr {
zone := "" // longest zone match wins zone := "" // longest zone match wins
for _, xfr := range xfrs { for _, xfr := range xfrs {
if z := plugin.Zones(xfr.Zones).Matches(name); z != "" { if z := plugin.Zones(xfr.Zones).Matches(name); z != "" {
if z > zone { if len(z) > len(zone) || (len(z) == len(zone) && z > zone) {
zone = z zone = z
x = xfr x = xfr
} }

View File

@@ -369,3 +369,22 @@ func TestAXFRZoneMatchCaseInsensitive(t *testing.T) {
validateAXFRResponse(t, w) validateAXFRResponse(t, w)
} }
func TestLongestMatchMostSpecificZone(t *testing.T) {
x1 := &xfr{Zones: []string{"example.org."}}
x2 := &xfr{Zones: []string{"a.example.org."}}
got := longestMatch([]*xfr{x1, x2}, "host.a.example.org.")
if got != x2 {
t.Fatalf("expected most specific zone (a.example.org.) to match, got %+v", got)
}
}
func TestLongestMatchNilWhenNoMatch(t *testing.T) {
x1 := &xfr{Zones: []string{"example.org."}}
got := longestMatch([]*xfr{x1}, "other.net.")
if got != nil {
t.Fatalf("expected nil when no zones match, got %+v", got)
}
}