Skip to content

Commit 57a96ca

Browse files
v1rtllidel
andauthored
refactor: remove miekg/dns dep (#72)
* fix: remove dns dependency that is used only for one util * test: add unit tests for isFqdn and fqdn functions improve function documentation to explain escaped dot handling --------- Co-authored-by: Marcin Rataj <lidel@lidel.org>
1 parent 9ccb786 commit 57a96ca

File tree

4 files changed

+72
-20
lines changed

4 files changed

+72
-20
lines changed

go.mod

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
module github.com/multiformats/go-multiaddr-dns
22

3-
require (
4-
github.com/miekg/dns v1.1.41
5-
github.com/multiformats/go-multiaddr v0.13.0
6-
)
3+
require github.com/multiformats/go-multiaddr v0.13.0
74

85
require (
96
github.com/ipfs/go-cid v0.0.7 // indirect
@@ -18,7 +15,6 @@ require (
1815
github.com/spaolacci/murmur3 v1.1.0 // indirect
1916
golang.org/x/crypto v0.18.0 // indirect
2017
golang.org/x/exp v0.0.0-20230725012225-302865e7556b // indirect
21-
golang.org/x/net v0.10.0 // indirect
2218
golang.org/x/sys v0.16.0 // indirect
2319
lukechampine.com/blake3 v1.2.1 // indirect
2420
)

go.sum

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY=
44
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
55
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
66
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
7-
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
8-
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
97
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
108
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
119
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
@@ -44,22 +42,12 @@ golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1m
4442
golang.org/x/exp v0.0.0-20230725012225-302865e7556b h1:tK7yjGqVRzYdXsBcfD2MLhFAhHfDgGLm2rY1ub7FA9k=
4543
golang.org/x/exp v0.0.0-20230725012225-302865e7556b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
4644
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
47-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
48-
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
49-
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
50-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
51-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5245
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5346
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
54-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
55-
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5647
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5748
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
5849
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
59-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
6050
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
61-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
62-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
6351
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
6452
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6553
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=

resolve.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,38 @@ import (
55
"net"
66
"strings"
77

8-
"github.com/miekg/dns"
98
ma "github.com/multiformats/go-multiaddr"
109
)
1110

11+
// isFqdn checks if s is a fully qualified domain name.
12+
// A domain is fully qualified if it ends with an unescaped dot.
13+
// Escaped dots (preceded by an odd number of backslashes) do not count
14+
// as terminators.
15+
func isFqdn(s string) bool {
16+
if s == "" || s[len(s)-1] != '.' {
17+
return false
18+
}
19+
s = s[:len(s)-1]
20+
if s == "" || s[len(s)-1] != '\\' {
21+
return true
22+
}
23+
// Check if the dot is escaped by counting backslashes
24+
i := strings.LastIndexFunc(s, func(r rune) bool {
25+
return r != '\\'
26+
})
27+
return (len(s)-i)%2 != 0
28+
}
29+
30+
// fqdn returns the fully qualified domain name of s by appending a trailing
31+
// dot if one is not already present. If s is already fully qualified, it is
32+
// returned unchanged.
33+
func fqdn(s string) string {
34+
if isFqdn(s) {
35+
return s
36+
}
37+
return s + "."
38+
}
39+
1240
var (
1341
dnsaddrProtocol = ma.ProtocolWithCode(ma.P_DNSADDR)
1442
dns4Protocol = ma.ProtocolWithCode(ma.P_DNS4)
@@ -75,14 +103,14 @@ func WithDomainResolver(domain string, rslv BasicResolver) Option {
75103
if r.custom == nil {
76104
r.custom = make(map[string]BasicResolver)
77105
}
78-
fqdn := dns.Fqdn(domain)
106+
fqdn := fqdn(domain)
79107
r.custom[fqdn] = rslv
80108
return nil
81109
}
82110
}
83111

84112
func (r *Resolver) getResolver(domain string) BasicResolver {
85-
fqdn := dns.Fqdn(domain)
113+
fqdn := fqdn(domain)
86114

87115
// we match left-to-right, with more specific resolvers superseding generic ones.
88116
// So for a domain a.b.c, we will try a.b,c, b.c, c, and fallback to the default if

resolve_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,43 @@ func TestLimitResolver(t *testing.T) {
387387
t.Fatalf("expected %d, got %d", maxResolvedAddrs, len(addrs))
388388
}
389389
}
390+
391+
func TestIsFqdn(t *testing.T) {
392+
tests := []struct {
393+
input string
394+
expected bool
395+
}{
396+
{"", false},
397+
{".", true},
398+
{"example.com", false},
399+
{"example.com.", true},
400+
{"example\\.com.", true}, // escaped dot in middle, real dot at end
401+
{"example.com\\.", false}, // trailing dot is escaped
402+
{"example.com\\\\.", true}, // escaped backslash before real dot
403+
{"example.com\\\\\\.", false}, // escaped backslash + escaped dot
404+
}
405+
for _, tc := range tests {
406+
if got := isFqdn(tc.input); got != tc.expected {
407+
t.Errorf("isFqdn(%q) = %v, want %v", tc.input, got, tc.expected)
408+
}
409+
}
410+
}
411+
412+
func TestFqdn(t *testing.T) {
413+
tests := []struct {
414+
input string
415+
expected string
416+
}{
417+
{"", "."},
418+
{".", "."},
419+
{"example.com", "example.com."},
420+
{"example.com.", "example.com."},
421+
{"example.com\\.", "example.com\\.."}, // escaped dot, needs real dot added
422+
{"example.com\\\\.", "example.com\\\\."}, // already fqdn
423+
}
424+
for _, tc := range tests {
425+
if got := fqdn(tc.input); got != tc.expected {
426+
t.Errorf("fqdn(%q) = %q, want %q", tc.input, got, tc.expected)
427+
}
428+
}
429+
}

0 commit comments

Comments
 (0)