ingress-nginx-helm/rootfs/etc/nginx/lua/util/dns.lua
2019-08-13 18:34:54 -04:00

97 lines
2.4 KiB
Lua

local resolver = require("resty.dns.resolver")
local lrucache = require("resty.lrucache")
local resolv_conf = require("util.resolv_conf")
local _M = {}
local CACHE_SIZE = 10000
local MAXIMUM_TTL_VALUE = 2147483647 -- maximum value according to https://tools.ietf.org/html/rfc2181
local cache, err = lrucache.new(CACHE_SIZE)
if not cache then
return error("failed to create the cache: " .. (err or "unknown"))
end
local function a_records_and_max_ttl(answers)
local addresses = {}
local ttl = MAXIMUM_TTL_VALUE -- maximum value according to https://tools.ietf.org/html/rfc2181
for _, ans in ipairs(answers) do
if ans.address then
table.insert(addresses, ans.address)
if ttl > ans.ttl then
ttl = ans.ttl
end
end
end
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
local message = string.format(
"addresses %s for host %s was resolved from cache",
table.concat(cached_addresses, ", "), host)
ngx.log(ngx.INFO, message)
return cached_addresses
end
local r
r, err = resolver:new{
nameservers = resolv_conf.nameservers,
retrans = 5,
timeout = 2000, -- 2 sec
}
if not r then
ngx.log(ngx.ERR, "failed to instantiate the resolver: " .. tostring(err))
return { host }
end
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
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
if #dns_errors > 0 then
ngx.log(ngx.ERR, "failed to query the DNS server:\n" .. table.concat(dns_errors, "\n"))
end
return { host }
end
return _M