net.dns: Clean up query list when a server is marked down
[prosody.git] / net / dns.lua
index 61fb62e8e2f6855f5f2117bcb74f977b46dfe21e..1950ba73e35180f1645c91f8beec7668f75e5ef2 100644 (file)
@@ -158,8 +158,6 @@ resolver.__index = resolver;
 
 resolver.timeout = default_timeout;
 
-local SRV_tostring;
-
 local function default_rr_tostring(rr)
        local rr_val = rr.type and rr[rr.type:lower()];
        if type(rr_val) ~= "string" then
@@ -170,8 +168,13 @@ end
 
 local special_tostrings = {
        LOC = resolver.LOC_tostring;
-       MX = function (rr) return string.format('%2i %s', rr.pref, rr.mx); end;
-       SRV = SRV_tostring;
+       MX  = function (rr)
+               return string.format('%2i %s', rr.pref, rr.mx);
+       end;
+       SRV = function (rr)
+               local s = rr.srv;
+               return string.format('%5d %5d %5d %s', s.priority, s.weight, s.port, s.target);
+       end;
 };
 
 local rr_metatable = {};   -- - - - - - - - - - - - - - - - - - -  rr_metatable
@@ -355,6 +358,7 @@ function resolver:name()    -- - - - - - - - - - - - - - - - - - - - - -  name
        local remember, pointers = nil, 0;
        local len = self:byte();
        local n = {};
+       if len == 0 then return "." end -- Root label
        while len > 0 do
                if len >= 0xc0 then    -- name is "compressed"
                        pointers = pointers + 1;
@@ -386,6 +390,25 @@ function resolver:A(rr)    -- - - - - - - - - - - - - - - - - - - - - - - -  A
        rr.a = string.format('%i.%i.%i.%i', b1, b2, b3, b4);
 end
 
+function resolver:AAAA(rr)
+       local addr = {};
+       for i = 1, rr.rdlength, 2 do
+               local b1, b2 = self:byte(2);
+               table.insert(addr, ("%02x%02x"):format(b1, b2));
+       end
+       addr = table.concat(addr, ":"):gsub("%f[%x]0+(%x)","%1");
+       local zeros = {};
+       for item in addr:gmatch(":[0:]+:") do
+               table.insert(zeros, item)
+       end
+       if #zeros == 0 then
+               rr.aaaa = addr;
+               return
+       elseif #zeros > 1 then
+               table.sort(zeros, function(a, b) return #a > #b end);
+       end
+       rr.aaaa = addr:gsub(zeros[1], "::", 1):gsub("^0::", "::"):gsub("::0$", "::");
+end
 
 function resolver:CNAME(rr)    -- - - - - - - - - - - - - - - - - - - -  CNAME
        rr.cname = self:name();
@@ -475,14 +498,8 @@ function resolver:PTR(rr)
        rr.ptr = self:name();
 end
 
-function SRV_tostring(rr)    -- - - - - - - - - - - - - - - - - - SRV_tostring
-       local s = rr.srv;
-       return string.format( '%5d %5d %5d %s', s.priority, s.weight, s.port, s.target );
-end
-
-
 function resolver:TXT(rr)    -- - - - - - - - - - - - - - - - - - - - - -  TXT
-       rr.txt = self:sub (rr.rdlength);
+       rr.txt = self:sub (self:byte());
 end
 
 
@@ -532,6 +549,7 @@ function resolver:decode(packet, force)    -- - - - - - - - - - - - - - decode
 
        if not force then
                if not self.active[response.header.id] or not self.active[response.header.id][response.question.raw] then
+                       self.active[response.header.id] = nil;
                        return nil;
                end
        end
@@ -689,7 +707,7 @@ function resolver:purge(soft)    -- - - - - - - - - - - - - - - - - - -  purge
                                end
                        end
                end
-       else self.cache = {}; end
+       else self.cache = setmetatable({}, cache_metatable); end
 end
 
 
@@ -779,6 +797,9 @@ function resolver:servfail(sock)
                                end
                        end
                end
+               if next(queries) == nil then
+                       self.active[id] = nil;
+               end
        end
 
        if num == self.best_server then
@@ -835,6 +856,7 @@ function resolver:receive(rset)    -- - - - - - - - - - - - - - - - -  receive
                                                set(self.wanted, q.class, q.type, q.name, nil);
                                        end
                                end
+                               
                        end
                end
        end