net.server_select: Set select() timeout to 3600 by default.
[prosody.git] / net / dns.lua
index 1b8a88fa2ab2f34c9cbff68a9ad5cd04a15f95eb..c5f219a8f0a5b07c7e9831ae07a0018331afd0e7 100644 (file)
@@ -29,7 +29,7 @@ local ipairs, next, pairs, print, setmetatable, tostring, assert, error, unpack
 
 local get, set = ztact.get, ztact.set;
 
-local dns_timeout = 15;
+local default_timeout = 15;
 
 -------------------------------------------------- module dns
 module('dns')
@@ -118,6 +118,7 @@ end
 local resolver = {};
 resolver.__index = resolver;
 
+resolver.timeout = default_timeout;
 
 local SRV_tostring;
 
@@ -437,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;
@@ -527,7 +531,7 @@ end
 
 function resolver:adddefaultnameservers()    -- - - - -  adddefaultnameservers
        if is_windows then
-               if windows then
+               if windows and windows.get_nameservers then
                        for _, server in ipairs(windows.get_nameservers()) do
                                self:addnameserver(server);
                        end
@@ -670,11 +674,11 @@ function resolver:query(qname, qtype, qclass)    -- - - - - - - - - - -- query
                retry  = socket.gettime() + self.delays[1]
        };
 
-  -- remember the query
+       -- remember the query
        self.active[id] = self.active[id] or {};
        self.active[id][question] = o;
 
-  -- remember which coroutine wants the answer
+       -- remember which coroutine wants the answer
        local co = coroutine.running();
        if co then
                set(self.wanted, qclass, qtype, qname, co, true);
@@ -684,10 +688,10 @@ function resolver:query(qname, qtype, qclass)    -- - - - - - - - - - -- query
        local conn = self:getsocket(o.server)
        conn:send (o.packet)
        
-       if timer then
+       if timer and self.timeout then
                local num_servers = #self.server;
                local i = 1;
-               timer.add_task(dns_timeout, function ()
+               timer.add_task(self.timeout, function ()
                        if get(self.wanted, qclass, qtype, qname, co) then
                                if i < num_servers then
                                        i = i + 1;
@@ -695,10 +699,10 @@ function resolver:query(qname, qtype, qclass)    -- - - - - - - - - - -- query
                                        o.server = self.best_server;
                                        conn = self:getsocket(o.server);
                                        conn:send(o.packet);
-                                       return dns_timeout;
+                                       return self.timeout;
                                else
                                        -- Tried everything, failed
-                                       resolver:cancel({qclass, qtype, qname, co}, true);
+                                       self:cancel(qclass, qtype, qname, co, true);
                                end
                        end
                end)
@@ -734,7 +738,7 @@ function resolver:servfail(sock)
                        end
                end
        end
-   
+
        if num == self.best_server then
                self.best_server = self.best_server + 1;
                if self.best_server > #self.server then
@@ -744,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();
@@ -793,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');
@@ -830,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
 
@@ -876,12 +887,12 @@ end
 function resolver:lookup(qname, qtype, qclass)    -- - - - - - - - - -  lookup
        self:query (qname, qtype, qclass)
        while self:pulse() do
-           local recvt = {}
-           for i, s in ipairs(self.socket) do
-              recvt[i] = s
-           end
-           socket.select(recvt, nil, 4)
-        end
+               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
@@ -985,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