openresty / lua-resty-dns

DNS resolver for the nginx lua module
324 stars 107 forks source link

dead resolver raises exception #41

Closed jimdigriz closed 5 years ago

jimdigriz commented 5 years ago

Noticed that if you have a resolver that returns connection refused, then the library raises an exception:

Jan  2 14:24:51 klic local7.err nginx: 2019/01/02 14:24:51 [error] 44#44: *5 recv() failed (111: Connection refused), client: 172.17.0.1, server: _, request: "POST /l HTTP/1.1", host: "172.17.0.2"

Trivial to replicate if you set one of your resolvers to 127.0.0.1 (or 0.0.0.0).

Expected behaviour probably should be that the library retries with any other nameservers supplied when available.

jimdigriz commented 5 years ago

Okay, so the exception is in my code (should have been checking the return value of err), but the library still needs to retry with the other provided nameservers even in the event that one returns "Connection refused".

My workaround is currently:

local nameservers = { "0.0.0.0", "1.1.1.1", "1.0.0.1" }

local resolver = require "dns.resolver"

function mx (domain, resolvers)
        if not resolvers then
                resolvers = {}
                for i, v in ipairs(nameservers) do table.insert(resolvers, v) end
        end

        if #resolvers == 0 then
                return nil, "no resolvers"
        end

        local resolv, errr = resolver:new{
                nameservers = resolvers
        }
        if not resolv then
                ngx.log(ngx.ERR, "unable to init resolvers: " .. err)
                return nil
        end

        local ans, err = resolv:query(domain, { qtype = resolver.TYPE_MX })
        -- https://github.com/openresty/lua-resty-dns/issues/41
        if not ans and err:match("connection refused") then
                table.remove(resolvers, 1)
                return mx(domain, resolvers)
        end

        return ans, err
end

I call mx("example.com") to see if the record exists.

agentzh commented 5 years ago

Consider it resolved.