@@ -12,6 +12,7 @@ local io_type = io.type
12
12
local re_match = ngx .re .match
13
13
local semaphore = require " ngx.semaphore"
14
14
local resolver_cache = require ' resty.resolver.cache'
15
+ local dns_client = require ' resty.resolver.dns_client'
15
16
local re = require (' ngx.re' )
16
17
17
18
local init = semaphore .new (1 )
@@ -30,16 +31,12 @@ local default_resolver_port = 53
30
31
local _M = {
31
32
_VERSION = ' 0.1' ,
32
33
_nameservers = {},
33
- search = {}
34
+ search = { ' ' }
34
35
}
35
36
36
37
local mt = { __index = _M }
37
38
38
- function _M .parse_nameservers (path )
39
- local search = {}
40
- local nameservers = { search = search }
41
- local resolver = getenv (' RESOLVER' )
42
-
39
+ local function read_resolv_conf (path )
43
40
path = path or ' /etc/resolv.conf'
44
41
45
42
local handle , err
@@ -56,13 +53,25 @@ function _M.parse_nameservers(path)
56
53
handle :seek (" set" )
57
54
output = handle :read (" *a" )
58
55
handle :close ()
59
- else
60
- ngx .log (ngx .ERR , ' resolver could not get nameservers: ' , err )
61
- return nil , err
62
56
end
63
- ngx .log (ngx .DEBUG , ' /etc/resolv.conf:\n ' , output )
64
57
65
- local domains = match (output , ' search%s+([^\n ]+)' )
58
+ return output or " " , err
59
+ end
60
+
61
+ function _M .parse_nameservers (path )
62
+ local resolv_conf , err = read_resolv_conf (path )
63
+
64
+ if err then
65
+ ngx .log (ngx .WARN , ' resolver could not get nameservers: ' , err )
66
+ end
67
+
68
+ ngx .log (ngx .DEBUG , ' /etc/resolv.conf:\n ' , resolv_conf )
69
+
70
+ local search = { ' ' }
71
+ local nameservers = { search = search }
72
+ local resolver = getenv (' RESOLVER' )
73
+ local domains = match (resolv_conf , ' search%s+([^\n ]+)' )
74
+
66
75
ngx .log (ngx .DEBUG , ' search ' , domains )
67
76
for domain in gmatch (domains or ' ' , ' ([^%s]+)' ) do
68
77
ngx .log (ngx .DEBUG , ' search domain: ' , domain )
@@ -75,7 +84,7 @@ function _M.parse_nameservers(path)
75
84
return nameservers
76
85
end
77
86
78
- for nameserver in gmatch (output , ' nameserver%s+([^%s]+)' ) do
87
+ for nameserver in gmatch (resolv_conf , ' nameserver%s+([^%s]+)' ) do
79
88
-- TODO: implement port matching based on https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=549190
80
89
if nameserver ~= resolver then
81
90
insert (nameservers , { nameserver , default_resolver_port } )
@@ -133,6 +142,18 @@ function _M.new(dns, opts)
133
142
}, mt )
134
143
end
135
144
145
+ function _M :instance ()
146
+ local ctx = ngx .ctx
147
+ local resolver = ctx .resolver
148
+
149
+ if not resolver then
150
+ local dns = dns_client :instance (self .nameservers ())
151
+ resolver = self .new (dns )
152
+ ctx .resolver = resolver
153
+ end
154
+
155
+ return resolver
156
+ end
136
157
137
158
local function new_server (answer , port )
138
159
if not answer then return nil , ' missing answer' end
@@ -164,14 +185,6 @@ local function is_ip(address)
164
185
end
165
186
end
166
187
167
- local function has_tld (qname )
168
- return match (qname , ' %.' )
169
- end
170
-
171
- local function have_addresses (answers )
172
- return answers and next (answers .addresses or {}) and # answers > 0 and not answers .errcode
173
- end
174
-
175
188
local function convert_answers (answers , port )
176
189
local servers = {}
177
190
@@ -184,6 +197,8 @@ local function convert_answers(answers, port)
184
197
return servers
185
198
end
186
199
200
+ local empty = {}
201
+
187
202
local function lookup (dns , qname , search , options )
188
203
ngx .log (ngx .DEBUG , ' resolver query: ' , qname )
189
204
@@ -193,22 +208,18 @@ local function lookup(dns, qname, search, options)
193
208
ngx .log (ngx .DEBUG , ' host is ip address: ' , qname )
194
209
answers = { new_answer (qname ) }
195
210
else
196
- answers , err = dns : query ( qname , options )
197
-
198
- if not has_tld ( qname ) and not have_addresses ( answers ) then
199
- for i = 1 , # search do
211
+ for i = 1 , # search do
212
+ local query = qname .. ' . ' .. search [ i ]
213
+ ngx . log ( ngx . DEBUG , ' resolver query: ' , qname , ' search: ' , search [ i ], ' query: ' , query )
214
+ answers , err = dns : query ( query , options )
200
215
201
- local query = qname .. ' .' .. search [i ]
202
- ngx .log (ngx .DEBUG , ' resolver query: ' , qname , ' search: ' , search [i ], ' query: ' , query )
203
- answers , err = dns :query (query , options )
204
-
205
- if answers and not answers .errcode and # answers > 0 then
206
- break
207
- end
216
+ if answers and not answers .errcode and # answers > 0 then
217
+ break
208
218
end
209
219
end
210
220
end
211
221
222
+ ngx .log (ngx .DEBUG , ' resolver query: ' , qname , ' finished with ' , # (answers or empty ), ' answers' )
212
223
return answers , err
213
224
end
214
225
@@ -225,8 +236,7 @@ function _M.get_servers(self, qname, opts)
225
236
end
226
237
227
238
local cache = self .cache
228
- local search = self .search or {}
229
-
239
+ local search = self .search or _M .search
230
240
231
241
-- TODO: pass proper options to dns resolver (like SRV query type)
232
242
@@ -245,13 +255,17 @@ function _M.get_servers(self, qname, opts)
245
255
end
246
256
247
257
if err then
258
+ ngx .log (ngx .DEBUG , ' query for ' , qname , ' finished with error: ' , err )
248
259
return {}, err
249
260
end
250
261
251
262
if not answers then
263
+ ngx .log (ngx .DEBUG , ' query for ' , qname , ' finished with no answers' )
252
264
return {}, ' no answers'
253
265
end
254
266
267
+ ngx .log (ngx .DEBUG , ' query for ' , qname , ' finished with ' , # answers , ' answers' )
268
+
255
269
local servers = convert_answers (answers , opts .port )
256
270
257
271
servers .query = qname
0 commit comments