diff --git a/plugin/transfer/transfer.go b/plugin/transfer/transfer.go index 5adf1c1e2..bbd91b5eb 100644 --- a/plugin/transfer/transfer.go +++ b/plugin/transfer/transfer.go @@ -209,7 +209,7 @@ func longestMatch(xfrs []*xfr, name string) *xfr { zone := "" // longest zone match wins for _, xfr := range xfrs { 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 x = xfr } diff --git a/plugin/transfer/transfer_test.go b/plugin/transfer/transfer_test.go index 04ea6f8b5..2bf75ce07 100644 --- a/plugin/transfer/transfer_test.go +++ b/plugin/transfer/transfer_test.go @@ -369,3 +369,22 @@ func TestAXFRZoneMatchCaseInsensitive(t *testing.T) { 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) + } +}