-
Notifications
You must be signed in to change notification settings - Fork 35
/
zone.go
216 lines (181 loc) · 5.64 KB
/
zone.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package zonedb
import (
"strings"
)
//go:generate go run cmd/zonedb/main.go -generate-go
// And performs a bitwise AND between tags and q,
// comparing the result to zero. Returns true if any
// tags match q.
func (tags Tags) And(q Tags) bool {
return (tags & q) != 0
}
// String returns a space-delimited list of values for tags.
func (tags Tags) String() string {
var a [numTags]string
s := a[0:0]
for i := uint64(0); i < numTags; i++ {
t := Tags(1 << i)
if (tags & t) != 0 {
s = append(s, TagStrings[t])
}
}
return strings.Join(s, " ")
}
// Zone represents a single DNS zone (a public suffix), where subdomains may be registered or created.
type Zone struct {
// Normalized (ASCII, punycode) fully-qualified domain name
Domain string
// Parent Zone (nil if Zone is a TLD)
Parent *Zone
// Slice of subdomain (child) Zones (nil if empty)
Subdomains []Zone
// Tags stored as an integer bit field
Tags Tags
// Registry operator for this Zone
RegistryOperator string
// Informational URL for this Zone
InfoURL string
// DNS name servers for this Zone
NameServers []string
// Wildcard addresses for unregistered subdomains
Wildcards []string
// Locations associated with this Zone
Locations []string
// BCP 47 language tags associated with this Zone
// https://tools.ietf.org/html/bcp47
languages []string
// Whois server responding on port 43
whoisServer string
// URL to look up whois info for a subdomain of this Zone
whoisURL string
// URLs for RDAP endpoints for a subdomain of this Zone
rdapURLs []string
// Transitional: does the zone operator allow registration of non-ASCII subdomains?
allowsIDN bool
}
// Languages returns a slice of BCP 47 language specifiers.
func (z *Zone) Languages() []string {
return z.languages
}
// WhoisServer returns the whois server that responds on port 43
// for the zone. It first searches the specific zone, then the parent,
// returning an empty string if none found.
func (z *Zone) WhoisServer() string {
if z.whoisServer != "" {
return z.whoisServer
}
if z.Parent != nil {
return z.Parent.WhoisServer()
}
return ""
}
// WhoisURL returns a URL to retrieve whois data for a subdomain
// of the zone. It first searches the specific zone, then the parent,
// returning an empty string if none found.
func (z *Zone) WhoisURL() string {
if z.whoisURL != "" {
return z.whoisURL
}
if z.Parent != nil {
return z.Parent.WhoisURL()
}
return ""
}
// RDAPURLs returns the set of RDAP URL endpoints for a zone.
func (z *Zone) RDAPURLs() []string {
if len(z.rdapURLs) != 0 {
return z.rdapURLs
}
if z.Parent != nil {
return z.Parent.RDAPURLs()
}
return nil
}
// IsTLD returns true if the Zone is a top-level domain.
func (z *Zone) IsTLD() bool {
return z.Parent == nil
}
// IsDelegated returns true if the Zone has name servers.
func (z *Zone) IsDelegated() bool {
return len(z.NameServers) != 0
}
// IsInRootZone returns true if the Zone is a top-level domain.
// present in the root DNS zone.
func (z *Zone) IsInRootZone() bool {
return z.IsTLD() && z.IsDelegated()
}
// IsValidDomain and IDNTable have been removed. We searched for public code
// on GitHub that imported the zonedb package and found no open-source clients
// using these methods.
//
// Rationale: the generation and validation of (IDN) labels requires state
// beyond what can be represented in simple list if code points.
//
// This branch attempts to reconcile the objective of documenting and normalizing
// zone metadata, including policies that define allowed labels such as
// IDN tables, Label Generation Rulesets (LGRs), and implicit or undocumented
// policies such as applied by ccTLDs.
// AllowsIDN returns true if the zone operator (registry)
// permits registration of non-ASCII labels under this Zone.
func (z *Zone) AllowsIDN() bool {
return z.allowsIDN
}
// AllowsRegistration returns true if the Zone’s authority (registry)
// permits registration of subdomains of this Zone. Examples include
// zones that are closed, withdrawn, or retired zones.
// A closed zone is where the registry operator does not permit registration,
// typically at the second level, like .ck.
// A withdrawn zone is a gTLD that was withdrawn and removed from the root
// zone file by the RO.
// A retired zone was active, but has since been undelegated.
func (z *Zone) AllowsRegistration() bool {
return !z.Tags.And(TagClosed | TagWithdrawn | TagReserved | TagRetired | TagSpecial | TagTest)
}
// IsZone returns true if the input domain is a Zone.
func IsZone(domain string) bool {
_, ok := ZoneMap[domain]
return ok
}
// IsTLD returns true if the input domain is a top-level domain.
func IsTLD(domain string) bool {
z, ok := ZoneMap[domain]
if !ok {
return false
}
return z.IsTLD()
}
// PublicZone returns the public zone for a given domain name
// or nil if none found.
// Input must be normalized by the client (lowercase, ASCII-encoded).
func PublicZone(domain string) *Zone {
sfx := domain
for {
if z, ok := ZoneMap[sfx]; ok {
return z
}
if i := strings.Index(sfx, "."); i >= 0 {
sfx = sfx[i+1:]
} else {
break
}
}
return nil
}
// List implements the cookiejar.PublicSuffixList interface.
var List list
type list struct{}
// PublicSuffix returns the public suffix (zone) for a given domain name
// by calling PublicZone. Input must be normalized by the client
// (lowercase, ASCII, punycode). Malformed input, IP addresses, or other non-domain
// name strings will be returned unmodified.
func (l list) PublicSuffix(domain string) string {
z := PublicZone(domain)
if z == nil {
return domain
}
return z.Domain
}
// String returns a description of source of this public suffix list.
func (l list) String() string {
return "ZoneDB"
}