Skip to content

Commit a446408

Browse files
authored
Merge pull request #5281 from arthlr/fix/zone-finder
fix(zonefinder): handle underscores in dns records
2 parents 2603519 + 64f7989 commit a446408

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

provider/zonefinder.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,34 @@ func (z ZoneIDName) Add(zoneID, zoneName string) {
2929
z[zoneID] = zoneName
3030
}
3131

32+
// FindZone identifies the most suitable DNS zone for a given hostname.
33+
// It returns the zone ID and name that best match the hostname.
34+
//
35+
// The function processes the hostname by splitting it into labels and
36+
// converting each label to its Unicode form using IDNA (Internationalized
37+
// Domain Names for Applications) standards.
38+
//
39+
// Labels containing underscores ('_') are skipped during Unicode conversion.
40+
// This is because underscores are often used in special DNS records (e.g.,
41+
// SRV records as per RFC 2782, or TXT record for services) that are not
42+
// IDNA-aware and cannot represent non-ASCII labels. Skipping these labels
43+
// ensures compatibility with such use cases.
3244
func (z ZoneIDName) FindZone(hostname string) (suitableZoneID, suitableZoneName string) {
33-
name, err := idna.Lookup.ToUnicode(hostname)
34-
if err != nil {
35-
log.Warnf("Failed to convert hostname '%s' to its Unicode form: %v", hostname, err)
36-
name = hostname
45+
var name string
46+
domain_labels := strings.Split(hostname, ".")
47+
for i, label := range domain_labels {
48+
if strings.Contains(label, "_") {
49+
continue
50+
}
51+
convertedLabel, err := idna.Lookup.ToUnicode(label)
52+
if err != nil {
53+
log.Warnf("Failed to convert label '%s' of hostname '%s' to its Unicode form: %v", label, hostname, err)
54+
convertedLabel = label
55+
}
56+
domain_labels[i] = convertedLabel
3757
}
58+
name = strings.Join(domain_labels, ".")
59+
3860
for zoneID, zoneName := range z {
3961
if name == zoneName || strings.HasSuffix(name, "."+zoneName) {
4062
if suitableZoneName == "" || len(zoneName) > len(suitableZoneName) {

provider/zonefinder_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@ func TestZoneIDName(t *testing.T) {
3030
z.Add("123456", "qux.baz")
3131
z.Add("654321", "foo.qux.baz")
3232
z.Add("987654", "エイミー.みんな")
33+
z.Add("123123", "_metadata.example.com")
34+
z.Add("456456", "_metadata.エイミー.みんな")
3335

3436
assert.Equal(t, ZoneIDName{
3537
"123456": "qux.baz",
3638
"654321": "foo.qux.baz",
3739
"987654": "エイミー.みんな",
40+
"123123": "_metadata.example.com",
41+
"456456": "_metadata.エイミー.みんな",
3842
}, z)
3943

4044
// simple entry in a domain
@@ -73,6 +77,6 @@ func TestZoneIDName(t *testing.T) {
7377
assert.Equal(t, "987654", zoneID)
7478

7579
b := testutils.LogsToBuffer(log.WarnLevel, t)
76-
zoneID, zoneName = z.FindZone("???")
77-
assert.Contains(t, b.String(), "level=warning msg=\"Failed to convert hostname '???' to its Unicode form: idna: disallowed rune U+003F\"")
80+
_, _ = z.FindZone("???")
81+
assert.Contains(t, b.String(), "level=warning msg=\"Failed to convert label '???' of hostname '???' to its Unicode form: idna: disallowed rune U+003F\"")
7882
}

0 commit comments

Comments
 (0)