diff --git a/gateway/src/resty/resolver.lua b/gateway/src/resty/resolver.lua index 38a73886c..85646fafb 100644 --- a/gateway/src/resty/resolver.lua +++ b/gateway/src/resty/resolver.lua @@ -9,6 +9,7 @@ local find = string.find local insert = table.insert local concat = table.concat local io_type = io.type +local table_new = require("table.new") require('resty.core.regex') -- to allow use of ngx.re.match in the init phase @@ -285,15 +286,35 @@ local function valid_answers(answers) return answers and not answers.errcode and #answers > 0 and (not answers.addresses or #answers.addresses > 0) end +-- construct search list from resolv options: search +-- @param search table of search domain +-- @param qname the name to query for +-- @return table with search names +local function search_list(search, qname) + -- FQDN + if sub(qname, -1) == "." then + return {qname} + end + + local names = table_new(#search +1, 0) + for i=1, #search do + names[i] = qname .. "." .. search[i] + end + return names +end + local function search_dns(self, qname, stale) local search = self.search local dns = self.dns local options = self.options local cache = self.cache + local answers, err + local names = search_list(search, qname) - local function get_answer(query) - local answers, err + -- resolve all `names` and return the first valid answers + for _, query in ipairs(names) do + ngx.log(ngx.DEBUG, 'resolver query: ', qname, ' query: ', query) answers, err = cache:get(query, stale) if valid_answers(answers) then return answers, err @@ -304,23 +325,6 @@ local function search_dns(self, qname, stale) cache:save(answers) return answers, err end - return nil, err - end - - if sub(qname, -1) == "." then - local query = sub(qname, 1 ,-2) - ngx.log(ngx.DEBUG, 'resolver query: ', qname, ' query: ', query) - return get_answer(query) - end - - local answer, err - for i=1, #search do - local query = qname .. '.' .. search[i] - ngx.log(ngx.DEBUG, 'resolver query: ', qname, ' search: ', search[i], ' query: ', query) - answer, err = get_answer(query) - if answer then - return answer, err - end end return nil, err @@ -342,6 +346,12 @@ local function resolve_upstream(qname) return peers end +-- Queries the DNS for this qname. If nothing is in the cache, a +-- synchoronous queryis performed. If the cache is stale, first query is going +-- to refresh the query while all others use stale cache data. +-- @param qname the name to look for +-- @param stale if true return stale data +-- @return dns `answers + nil`, or `nil + error function _M.lookup(self, qname, stale) local cache = self.cache diff --git a/spec/resty/resolver_spec.lua b/spec/resty/resolver_spec.lua index e0e85893f..b0d8fd4e2 100644 --- a/spec/resty/resolver_spec.lua +++ b/spec/resty/resolver_spec.lua @@ -1,5 +1,6 @@ local resty_resolver = require 'resty.resolver' local resolver_cache = require 'resty.resolver.cache' +local string_byte = string.byte describe('resty.resolver', function() @@ -131,6 +132,11 @@ describe('resty.resolver', function() before_each(function() local dns = { query = spy.new(function(_, name) + -- FQDN, drop the last '.' as the answer does not contain it + + if string_byte(name, -1) == string_byte(".") then + name = name:sub(1, -2) + end return { { name = name , address = '127.0.0.1' } }