diff --git a/rootfs/etc/nginx/lua/test/util/dns_test.lua b/rootfs/etc/nginx/lua/test/util/dns_test.lua index 12757c52cd..48e7c6ca31 100644 --- a/rootfs/etc/nginx/lua/test/util/dns_test.lua +++ b/rootfs/etc/nginx/lua/test/util/dns_test.lua @@ -18,20 +18,20 @@ describe("resolve", function() assert.spy(s_ngx_log).was_called_with(ngx.ERR, "failed to instantiate the resolver: an error") dns_helper.mock_dns_query(nil, "oops!") - assert.are.same({ "example.com" }, dns.resolve("example.com")) - assert.spy(s_ngx_log).was_called_with(ngx.ERR, "failed to query the DNS server: oops!") + assert.are.same({ "example.com" }, dns.resolve("example.com")) + assert.spy(s_ngx_log).was_called_with(ngx.ERR, "failed to query the DNS server:\noops!\noops!") dns_helper.mock_dns_query({ errcode = 1, errstr = "format error" }) assert.are.same({ "example.com" }, dns.resolve("example.com")) - assert.spy(s_ngx_log).was_called_with(ngx.ERR, "server returned error code: 1: format error") + assert.spy(s_ngx_log).was_called_with(ngx.ERR, "failed to query the DNS server:\nserver returned error code: 1: format error\nserver returned error code: 1: format error") dns_helper.mock_dns_query({}) assert.are.same({ "example.com" }, dns.resolve("example.com")) - assert.spy(s_ngx_log).was_called_with(ngx.ERR, "no A record resolved") + assert.spy(s_ngx_log).was_called_with(ngx.ERR, "failed to query the DNS server:\nno record resolved\nno record resolved") dns_helper.mock_dns_query({ { name = "example.com", cname = "sub.example.com", ttl = 60 } }) assert.are.same({ "example.com" }, dns.resolve("example.com")) - assert.spy(s_ngx_log).was_called_with(ngx.ERR, "no A record resolved") + assert.spy(s_ngx_log).was_called_with(ngx.ERR, "failed to query the DNS server:\nno record resolved\nno record resolved") end) it("resolves all A records of given host, caches them with minimal ttl and returns from cache next time", function() diff --git a/rootfs/etc/nginx/lua/util/dns.lua b/rootfs/etc/nginx/lua/util/dns.lua index 88cff2ce7b..fcebeae0bf 100644 --- a/rootfs/etc/nginx/lua/util/dns.lua +++ b/rootfs/etc/nginx/lua/util/dns.lua @@ -28,6 +28,25 @@ local function a_records_and_max_ttl(answers) return addresses, ttl end +local function resolve_host(host, r, qtype) + local answers + answers, err = r:query(host, { qtype = qtype }, {}) + if not answers then + return nil, -1, tostring(err) + end + + if answers.errcode then + return nil, -1, string.format("server returned error code: %s: %s", answers.errcode, answers.errstr) + end + + local addresses, ttl = a_records_and_max_ttl(answers) + if #addresses == 0 then + return nil, -1, "no record resolved" + end + + return addresses, ttl, nil +end + function _M.resolve(host) local cached_addresses = cache:get(host) if cached_addresses then @@ -50,26 +69,30 @@ function _M.resolve(host) return { host } end - local answers - answers, err = r:query(host, { qtype = r.TYPE_A }, {}) - if not answers then - ngx.log(ngx.ERR, "failed to query the DNS server: " .. tostring(err)) - return { host } + local dns_errors = {} + + local addresses, ttl + addresses, ttl, err = resolve_host(host, r, r.TYPE_A) + if not addresses then + table.insert(dns_errors, tostring(err)) + elseif #addresses > 0 then + cache:set(host, addresses, ttl) + return addresses end - if answers.errcode then - ngx.log(ngx.ERR, string.format("server returned error code: %s: %s", answers.errcode, answers.errstr)) - return { host } + addresses, ttl, err = resolve_host(host, r, r.TYPE_AAAA) + if not addresses then + table.insert(dns_errors, tostring(err)) + elseif #addresses > 0 then + cache:set(host, addresses, ttl) + return addresses end - local addresses, ttl = a_records_and_max_ttl(answers) - if #addresses == 0 then - ngx.log(ngx.ERR, "no A record resolved") - return { host } + if #dns_errors > 0 then + ngx.log(ngx.ERR, "failed to query the DNS server:\n" .. table.concat(dns_errors, "\n")) end - cache:set(host, addresses, ttl) - return addresses + return { host } end return _M