@@ -24,6 +24,10 @@ type UpstreamConfig struct {
24
24
// corresponding upstreams.
25
25
SpecifiedDomainUpstreams map [string ][]upstream.Upstream
26
26
27
+ // LocalOnlyDomains is a list of domains which should never be looked up on
28
+ // any upstream server.
29
+ LocalOnlyDomains map [string ]bool
30
+
27
31
// SubdomainExclusions is set of domains with subdomains exclusions.
28
32
SubdomainExclusions * stringutil.Set
29
33
@@ -58,16 +62,23 @@ var _ io.Closer = (*UpstreamConfig)(nil)
58
62
//
59
63
// [/domain1/../domainN/]#
60
64
//
65
+ // To ensure domains will never be looked up on any upstream servers, and will
66
+ // respond with NXDOMAIN if not resolved locally, use the following syntax:
67
+ //
68
+ // [/domain1/../domainN/]-
69
+ //
61
70
// So the following config:
62
71
//
63
72
// [/host.com/]1.2.3.4
64
73
// [/www.host.com/]2.3.4.5"
74
+ // [/domain.local/]-
65
75
// [/maps.host.com/news.host.com/]#
66
76
// 3.4.5.6
67
77
//
68
78
// will send queries for *.host.com to 1.2.3.4. Except for *.www.host.com,
69
- // which will go to 2.3.4.5. And *.maps.host.com or *.news.host.com, which
70
- // will go to default server 3.4.5.6 with all other domains.
79
+ // which will go to 2.3.4.5. Any requests to *.domain.local or domain.local
80
+ // will only be resolved locally. And *.maps.host.com or *.news.host.com,
81
+ // which will go to default server 3.4.5.6 with all other domains.
71
82
//
72
83
// To exclude top level domain from reserved upstreams querying you could use
73
84
// the following:
@@ -95,6 +106,7 @@ func ParseUpstreamsConfig(upstreamConfig []string, options *upstream.Options) (*
95
106
domainReservedUpstreams : map [string ][]upstream.Upstream {},
96
107
specifiedDomainUpstreams : map [string ][]upstream.Upstream {},
97
108
subdomainsOnlyUpstreams : map [string ][]upstream.Upstream {},
109
+ localOnlyDomains : map [string ]bool {},
98
110
subdomainsOnlyExclusions : stringutil .NewSet (),
99
111
}
100
112
@@ -121,6 +133,10 @@ type configParser struct {
121
133
// corresponding upstreams.
122
134
subdomainsOnlyUpstreams map [string ][]upstream.Upstream
123
135
136
+ // localOnlyDomains is a list of domains which should never be looked up on
137
+ // any upstream server.
138
+ localOnlyDomains map [string ]bool
139
+
124
140
// subdomainsOnlyExclusions is set of domains with subdomains exclusions.
125
141
subdomainsOnlyExclusions * stringutil.Set
126
142
@@ -147,6 +163,7 @@ func (p *configParser) parse(conf []string) (c *UpstreamConfig, err error) {
147
163
DomainReservedUpstreams : p .domainReservedUpstreams ,
148
164
SpecifiedDomainUpstreams : p .specifiedDomainUpstreams ,
149
165
SubdomainExclusions : p .subdomainsOnlyExclusions ,
166
+ LocalOnlyDomains : p .localOnlyDomains ,
150
167
}, nil
151
168
}
152
169
@@ -158,6 +175,12 @@ func (p *configParser) parseLine(idx int, confLine string) (err error) {
158
175
return err
159
176
}
160
177
178
+ if upstreams [0 ] == "-" && len (domains ) > 0 {
179
+ p .specifyLocalOnly (domains )
180
+
181
+ return nil
182
+ }
183
+
161
184
if upstreams [0 ] == "#" && len (domains ) > 0 {
162
185
p .excludeFromReserved (domains )
163
186
@@ -208,6 +231,12 @@ func splitConfigLine(idx int, confLine string) (upstreams, domains []string, err
208
231
return strings .Fields (upstreamsLine ), domains , nil
209
232
}
210
233
234
+ func (p * configParser ) specifyLocalOnly (domains []string ) {
235
+ for _ , domain := range domains {
236
+ p .localOnlyDomains [domain ] = true
237
+ }
238
+ }
239
+
211
240
// specifyUpstream specifies the upstream for domains.
212
241
func (p * configParser ) specifyUpstream (
213
242
domains []string ,
@@ -296,6 +325,17 @@ func (uc *UpstreamConfig) validate() (err error) {
296
325
}
297
326
}
298
327
328
+ func (uc * UpstreamConfig ) checkLocalOnly (host string ) bool {
329
+ for host != "" {
330
+ var ok bool
331
+ if _ , ok = uc .LocalOnlyDomains [host ]; ok {
332
+ return true
333
+ }
334
+ _ , host , _ = strings .Cut (host , "." )
335
+ }
336
+ return false
337
+ }
338
+
299
339
// getUpstreamsForDomain looks for a domain in the reserved domains map and
300
340
// returns a list of corresponding upstreams. It returns default upstreams list
301
341
// if the domain was not found in the map. More specific domains take priority
0 commit comments