Skip to content

Commit f9a66bc

Browse files
authored
net: consider /dns/localhost as private address (#221)
* manet: consider /dns/localhost as private address * fix naming
1 parent a124954 commit f9a66bc

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

net/private.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,14 @@ var privateUseDomains = []string{
6969
// MDNS
7070
".local",
7171

72-
// RFC 6761: Users may assume that IPv4 and IPv6 address queries for localhost names will
73-
// always resolve to the respective IP loopback address
74-
".localhost",
7572
// RFC 6761: No central authority for .test names
7673
".test",
7774
}
7875

76+
// RFC 6761: Users may assume that IPv4 and IPv6 address queries for localhost names will
77+
// always resolve to the respective IP loopback address
78+
const localHostDomain = ".localhost"
79+
7980
func init() {
8081
Private4 = parseCIDR(privateCIDR4)
8182
Private6 = parseCIDR(privateCIDR6)
@@ -112,14 +113,18 @@ func IsPublicAddr(a ma.Multiaddr) bool {
112113
case ma.P_DNS, ma.P_DNS4, ma.P_DNS6, ma.P_DNSADDR:
113114
dnsAddr := c.Value()
114115
isPublic = true
116+
if isSubdomain(dnsAddr, localHostDomain) {
117+
isPublic = false
118+
return false
119+
}
115120
for _, ud := range unResolvableDomains {
116-
if strings.HasSuffix(dnsAddr, ud) {
121+
if isSubdomain(dnsAddr, ud) {
117122
isPublic = false
118123
return false
119124
}
120125
}
121126
for _, pd := range privateUseDomains {
122-
if strings.HasSuffix(dnsAddr, pd) {
127+
if isSubdomain(dnsAddr, pd) {
123128
isPublic = false
124129
break
125130
}
@@ -130,6 +135,13 @@ func IsPublicAddr(a ma.Multiaddr) bool {
130135
return isPublic
131136
}
132137

138+
// isSubdomain checks if child is sub domain of parent. It also returns true if child and parent are
139+
// the same domain.
140+
// Parent must have a "." prefix.
141+
func isSubdomain(child, parent string) bool {
142+
return strings.HasSuffix(child, parent) || child == parent[1:]
143+
}
144+
133145
// IsPrivateAddr returns true if the IP part of the mutiaddr is in a private network
134146
func IsPrivateAddr(a ma.Multiaddr) bool {
135147
isPrivate := false
@@ -141,6 +153,13 @@ func IsPrivateAddr(a ma.Multiaddr) bool {
141153
isPrivate = inAddrRange(net.IP(c.RawValue()), Private4)
142154
case ma.P_IP6:
143155
isPrivate = inAddrRange(net.IP(c.RawValue()), Private6)
156+
case ma.P_DNS, ma.P_DNS4, ma.P_DNS6, ma.P_DNSADDR:
157+
dnsAddr := c.Value()
158+
if isSubdomain(dnsAddr, localHostDomain) {
159+
isPrivate = true
160+
}
161+
// We don't check for privateUseDomains because private use domains can
162+
// resolve to public IP addresses
144163
}
145164
return false
146165
})

net/private_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ func TestIsPublicAddr(t *testing.T) {
4343
isPublic: false,
4444
isPrivate: false, // You can configure .local domains in local networks to return public addrs
4545
},
46+
{
47+
addr: ma.StringCast("/dns/localhost/udp/1/quic-v1"),
48+
isPublic: false,
49+
isPrivate: true,
50+
},
51+
{
52+
addr: ma.StringCast("/dns/a.localhost/tcp/1"),
53+
isPublic: false,
54+
isPrivate: true,
55+
},
4656
}
4757
for i, tt := range tests {
4858
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {

0 commit comments

Comments
 (0)