diff options
Diffstat (limited to 'net/resolvers')
-rw-r--r-- | net/resolvers/basic.lua | 65 | ||||
-rw-r--r-- | net/resolvers/manual.lua | 1 | ||||
-rw-r--r-- | net/resolvers/service.lua | 33 |
3 files changed, 80 insertions, 19 deletions
diff --git a/net/resolvers/basic.lua b/net/resolvers/basic.lua index 867ccf60..34f1e1c7 100644 --- a/net/resolvers/basic.lua +++ b/net/resolvers/basic.lua @@ -2,10 +2,13 @@ local adns = require "net.adns"; local inet_pton = require "util.net".pton; local inet_ntop = require "util.net".ntop; local idna_to_ascii = require "util.encodings".idna.to_ascii; +local unpack = table.unpack or unpack; -- luacheck: ignore 113 local methods = {}; local resolver_mt = { __index = methods }; +-- FIXME RFC 6724 + -- Find the next target to connect to, and -- pass it to cb() function methods:next(cb) @@ -25,34 +28,70 @@ function methods:next(cb) return; end + local secure = true; + local tlsa = {}; local targets = {}; - local n = 2; + local n = 3; local function ready() n = n - 1; if n > 0 then return; end self.targets = targets; + if self.extra and self.extra.use_dane then + if secure and tlsa[1] then + self.extra.tlsa = tlsa; + self.extra.dane_hostname = self.hostname; + else + self.extra.tlsa = nil; + self.extra.dane_hostname = nil; + end + end self:next(cb); end -- Resolve DNS to target list local dns_resolver = adns.resolver(); - dns_resolver:lookup(function (answer) - if answer then - for _, record in ipairs(answer) do - table.insert(targets, { self.conn_type.."4", record.a, self.port, self.extra }); + + if not self.extra or self.extra.use_ipv4 ~= false then + dns_resolver:lookup(function (answer) + if answer then + secure = secure and answer.secure; + for _, record in ipairs(answer) do + table.insert(targets, { self.conn_type.."4", record.a, self.port, self.extra }); + end end - end + ready(); + end, self.hostname, "A", "IN"); + else + ready(); + end + + if not self.extra or self.extra.use_ipv6 ~= false then + dns_resolver:lookup(function (answer) + if answer then + secure = secure and answer.secure; + for _, record in ipairs(answer) do + table.insert(targets, { self.conn_type.."6", record.aaaa, self.port, self.extra }); + end + end + ready(); + end, self.hostname, "AAAA", "IN"); + else ready(); - end, self.hostname, "A", "IN"); + end - dns_resolver:lookup(function (answer) - if answer then - for _, record in ipairs(answer) do - table.insert(targets, { self.conn_type.."6", record.aaaa, self.port, self.extra }); + if self.extra and self.extra.use_dane == true then + dns_resolver:lookup(function (answer) + if answer then + secure = secure and answer.secure; + for _, record in ipairs(answer) do + table.insert(tlsa, record.tlsa); + end end - end + ready(); + end, ("_%d._tcp.%s"):format(self.port, self.hostname), "TLSA", "IN"); + else ready(); - end, self.hostname, "AAAA", "IN"); + end end local function new(hostname, port, conn_type, extra) diff --git a/net/resolvers/manual.lua b/net/resolvers/manual.lua index c0d4e5d5..dbc40256 100644 --- a/net/resolvers/manual.lua +++ b/net/resolvers/manual.lua @@ -1,5 +1,6 @@ local methods = {}; local resolver_mt = { __index = methods }; +local unpack = table.unpack or unpack; -- luacheck: ignore 113 -- Find the next target to connect to, and -- pass it to cb() diff --git a/net/resolvers/service.lua b/net/resolvers/service.lua index 34f14cba..204c8a7f 100644 --- a/net/resolvers/service.lua +++ b/net/resolvers/service.lua @@ -1,6 +1,8 @@ local adns = require "net.adns"; local basic = require "net.resolvers.basic"; +local inet_pton = require "util.net".pton; local idna_to_ascii = require "util.encodings".idna.to_ascii; +local unpack = table.unpack or unpack; -- luacheck: ignore 113 local methods = {}; local resolver_mt = { __index = methods }; @@ -9,14 +11,17 @@ local resolver_mt = { __index = methods }; -- pass it to cb() function methods:next(cb) if self.targets then - if #self.targets == 0 then - cb(nil); - return; + if not self.resolver then + if #self.targets == 0 then + cb(nil); + return; + end + local next_target = table.remove(self.targets, 1); + self.resolver = basic.new(unpack(next_target, 1, 4)); end - local next_target = table.remove(self.targets, 1); - self.resolver = basic.new(unpack(next_target, 1, 4)); self.resolver:next(function (...) if ... == nil then + self.resolver = nil; self:next(cb); else cb(...); @@ -39,8 +44,16 @@ function methods:next(cb) -- Resolve DNS to target list local dns_resolver = adns.resolver(); - dns_resolver:lookup(function (answer) + dns_resolver:lookup(function (answer, err) + if not answer and not err then + -- net.adns returns nil if there are zero records or nxdomain + answer = {}; + end if answer then + if self.extra and not answer.secure then + self.extra.use_dane = false; + end + if #answer == 0 then if self.extra and self.extra.default_port then table.insert(targets, { self.hostname, self.extra.default_port, self.conn_type, self.extra }); @@ -64,6 +77,14 @@ function methods:next(cb) end local function new(hostname, service, conn_type, extra) + local is_ip = inet_pton(hostname); + if not is_ip and hostname:sub(1,1) == '[' then + is_ip = inet_pton(hostname:sub(2,-2)); + end + if is_ip and extra and extra.default_port then + return basic.new(hostname, extra.default_port, conn_type, extra); + end + return setmetatable({ hostname = idna_to_ascii(hostname); service = service; |