X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=net%2Fdns.lua;h=29d9cf36d227a52df80b9e4ae75a730e094b4e2c;hb=2fcf677c4dce862df770bb51eec44a6a9e5ab476;hp=8855cc61546954b3e0b4ba9b6526c85dd9f422d3;hpb=09ac9eefa27a5e0ed5e859cc5d9f366740cc47b0;p=prosody.git diff --git a/net/dns.lua b/net/dns.lua index 8855cc61..29d9cf36 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -16,6 +16,8 @@ local socket = require "socket"; local ztact = require "util.ztact"; +local timer = require "util.timer"; + local _, windows = pcall(require, "util.windows"); local is_windows = (_ and windows) or os.getenv("WINDIR"); @@ -27,6 +29,7 @@ local ipairs, next, pairs, print, setmetatable, tostring, assert, error, unpack local get, set = ztact.get, ztact.set; +local default_timeout = 15; -------------------------------------------------- module dns module('dns') @@ -115,6 +118,7 @@ end local resolver = {}; resolver.__index = resolver; +resolver.timeout = default_timeout; local SRV_tostring; @@ -434,6 +438,9 @@ function resolver:SRV(rr) -- - - - - - - - - - - - - - - - - - - - - - SRV rr.srv.target = self:name(); end +function resolver:PTR(rr) + rr.ptr = self:name(); +end function SRV_tostring(rr) -- - - - - - - - - - - - - - - - - - SRV_tostring local s = rr.srv; @@ -678,7 +685,28 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query --set(self.yielded, co, qclass, qtype, qname, true); end - self:getsocket (o.server):send (o.packet) + local conn = self:getsocket(o.server) + conn:send (o.packet) + + if timer and self.timeout then + local num_servers = #self.server; + local i = 1; + timer.add_task(self.timeout, function () + if get(self.wanted, qclass, qtype, qname, co) then + if i < num_servers then + i = i + 1; + self:servfail(conn); + o.server = self.best_server; + conn = self:getsocket(o.server); + conn:send(o.packet); + return self.timeout; + else + -- Tried everything, failed + self:cancel(qclass, qtype, qname, co, true); + end + end + end) + end end function resolver:servfail(sock) @@ -720,6 +748,10 @@ function resolver:servfail(sock) end end +function resolver:settimeout(seconds) + self.timeout = seconds; +end + function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive --print('receive'); print(self.socket); self.time = socket.gettime(); @@ -769,11 +801,11 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive end -function resolver:feed(sock, packet) +function resolver:feed(sock, packet, force) --print('receive'); print(self.socket); self.time = socket.gettime(); - local response = self:decode(packet); + local response = self:decode(packet, force); if response and self.active[response.header.id] and self.active[response.header.id][response.question.raw] then --print('received response'); @@ -806,10 +838,13 @@ function resolver:feed(sock, packet) return response; end -function resolver:cancel(data) - local cos = get(self.wanted, unpack(data, 1, 3)); +function resolver:cancel(qclass, qtype, qname, co, call_handler) + local cos = get(self.wanted, qclass, qtype, qname); if cos then - cos[data[4]] = nil; + if call_handler then + coroutine.resume(co); + end + cos[co] = nil; end end @@ -851,7 +886,13 @@ end function resolver:lookup(qname, qtype, qclass) -- - - - - - - - - - lookup self:query (qname, qtype, qclass) - while self:pulse() do socket.select(self.socket, nil, 4); end + while self:pulse() do + local recvt = {} + for i, s in ipairs(self.socket) do + recvt[i] = s + end + socket.select(recvt, nil, 4) + end --print(self.cache); return self:peek(qname, qtype, qclass); end @@ -955,6 +996,10 @@ function dns.cancel(...) -- - - - - - - - - - - - - - - - - - - - - - cancel return _resolver:cancel(...); end +function dns.settimeout(...) + return _resolver:settimeout(...); +end + function dns.socket_wrapper_set(...) -- - - - - - - - - socket_wrapper_set return _resolver:socket_wrapper_set(...); end