aboutsummaryrefslogtreecommitdiffstats
path: root/net/dns.lua
diff options
context:
space:
mode:
Diffstat (limited to 'net/dns.lua')
-rw-r--r--net/dns.lua61
1 files changed, 55 insertions, 6 deletions
diff --git a/net/dns.lua b/net/dns.lua
index 592471bb..ff07d26e 100644
--- a/net/dns.lua
+++ b/net/dns.lua
@@ -488,7 +488,7 @@ function resolver:decode (packet, force) -- - - - - - - - - - - - - - decode
-- socket layer -------------------------------------------------- socket layer
-resolver.delays = { 1, 3, 11, 45 }
+resolver.delays = { 1, 3 }
function resolver:addnameserver (address) -- - - - - - - - - - addnameserver
@@ -529,16 +529,25 @@ function resolver:getsocket (servernum) -- - - - - - - - - - - - - getsocket
if sock then return sock end
sock = socket.udp ()
- if self.socket_wrapper then sock = self.socket_wrapper (sock) end
+ if self.socket_wrapper then sock = self.socket_wrapper (sock, self) end
sock:settimeout (0)
-- todo: attempt to use a random port, fallback to 0
sock:setsockname ('*', 0)
sock:setpeername (self.server[servernum], 53)
self.socket[servernum] = sock
- self.socketset[sock] = sock
+ self.socketset[sock] = servernum
return sock
end
+function resolver:voidsocket (sock)
+ if self.socket[sock] then
+ self.socketset[self.socket[sock]] = nil
+ self.socket[sock] = nil
+ elseif self.socketset[sock] then
+ self.socket[self.socketset[sock]] = nil
+ self.socketset[sock] = nil
+ end
+end
function resolver:socket_wrapper_set (func) -- - - - - - - socket_wrapper_set
self.socket_wrapper = func
@@ -612,10 +621,9 @@ function resolver:query (qname, qtype, qclass) -- - - - - - - - - - -- query
local header, id = encodeHeader ()
--print ('query id', id, qclass, qtype, qname)
local o = { packet = header..question,
- server = 1,
+ server = self.best_server,
delay = 1,
retry = socket.gettime () + self.delays[1] }
- self:getsocket (o.server):send (o.packet)
-- remember the query
self.active[id] = self.active[id] or {}
@@ -627,9 +635,49 @@ function resolver:query (qname, qtype, qclass) -- - - - - - - - - - -- query
set (self.wanted, qclass, qtype, qname, co, true)
--set (self.yielded, co, qclass, qtype, qname, true)
end
+
+ self:getsocket (o.server):send (o.packet)
+
end
+function resolver:servfail(sock)
+ -- Resend all queries for this server
+
+ local num = self.socketset[sock]
+
+ -- Socket is dead now
+ self:voidsocket(sock);
+
+ -- Find all requests to the down server, and retry on the next server
+ self.time = socket.gettime ()
+ for id,queries in pairs (self.active) do
+ for question,o in pairs (queries) do
+ if o.server == num then -- This request was to the broken server
+ o.server = o.server + 1 -- Use next server
+ if o.server > #self.server then
+ o.server = 1
+ end
+ o.retries = (o.retries or 0) + 1;
+ if o.retries >= #self.server then
+ --print ('timeout')
+ queries[question] = nil
+ else
+ local _a = self:getsocket(o.server);
+ if _a then _a:send (o.packet) end
+ end
+ end
+ end
+ end
+
+ if num == self.best_server then
+ self.best_server = self.best_server + 1
+ if self.best_server > #self.server then
+ -- Exhausted all servers, try first again
+ self.best_server = 1
+ end
+ end
+end
function resolver:receive (rset) -- - - - - - - - - - - - - - - - - receive
@@ -832,7 +880,8 @@ function dns.resolver () -- - - - - - - - - - - - - - - - - - - - - resolver
-- this function seems to be redundant with resolver.new ()
- local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {} }
+ local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {},
+ best_server = 1 }
setmetatable (r, resolver)
setmetatable (r.cache, cache_metatable)
setmetatable (r.unsorted, { __mode = 'kv' })