diff --git a/service.go b/service.go index 6937bc3..3067125 100644 --- a/service.go +++ b/service.go @@ -971,14 +971,14 @@ func findWildcardMatch(name string, records map[string]NameRecords) (NameRecords } func wildcardMatches(suffix, name string) bool { - parts := strings.Split(suffix, ".") - if len(parts) == 0 || len(name) <= len(suffix)+1 { + if suffix == "" || name == suffix { return false } if !strings.HasSuffix(name, "."+suffix) { return false } - return strings.Count(name[:len(name)-len(suffix)], ".") >= 1 + prefix := strings.TrimSuffix(name, "."+suffix) + return prefix != "" && !strings.Contains(prefix, ".") } func betterWildcardMatch(candidate, current string) bool { diff --git a/service_test.go b/service_test.go index 41607c8..3ddc847 100644 --- a/service_test.go +++ b/service_test.go @@ -93,6 +93,35 @@ func TestServiceResolveUsesMostSpecificWildcard(t *testing.T) { } } +func TestServiceResolveWildcardMatchesOnlyOneLabel(t *testing.T) { + service := NewService(ServiceOptions{ + Records: map[string]NameRecords{ + "*.charon.lthn": { + A: []string{"10.0.0.2"}, + }, + "*.bar.charon.lthn": { + A: []string{"10.0.0.3"}, + }, + }, + }) + + if _, ok := service.Resolve("foo.bar.charon.lthn"); !ok { + t.Fatal("expected deeper wildcard match to resolve against the matching depth") + } + + result, ok := service.Resolve("foo.charon.lthn") + if !ok { + t.Fatal("expected single-label wildcard to resolve") + } + if len(result.A) != 1 || result.A[0] != "10.0.0.2" { + t.Fatalf("unexpected wildcard result for single-label match: %#v", result.A) + } + + if _, ok := service.Resolve("foo.baz.charon.lthn"); ok { + t.Fatal("expected wildcard to require an exact one-label match") + } +} + func TestServiceResolveTXTUsesWildcard(t *testing.T) { service := NewService(ServiceOptions{ Records: map[string]NameRecords{