aboutsummaryrefslogtreecommitdiffstats
path: root/net/resolvers/service.lua
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2018-09-27 12:25:46 +0200
committerKim Alvefur <zash@zash.se>2018-09-27 12:25:46 +0200
commit0a784969c0b07f461be2fdfe42a76573b9060e68 (patch)
treec2e8e62c924dcac981607919a2ec9ed4d06c8bdc /net/resolvers/service.lua
parent7a86af343f4755531e9c04adefa808c36462ae43 (diff)
downloadprosody-0a784969c0b07f461be2fdfe42a76573b9060e68.tar.gz
prosody-0a784969c0b07f461be2fdfe42a76573b9060e68.zip
net.resolvers.service: net.connect resolver that uses SRV records
Diffstat (limited to 'net/resolvers/service.lua')
-rw-r--r--net/resolvers/service.lua57
1 files changed, 57 insertions, 0 deletions
diff --git a/net/resolvers/service.lua b/net/resolvers/service.lua
new file mode 100644
index 00000000..736a838b
--- /dev/null
+++ b/net/resolvers/service.lua
@@ -0,0 +1,57 @@
+local adns = require "net.adns";
+local basic = require "net.resolvers.basic";
+
+local methods = {};
+local resolver_mt = { __index = methods };
+
+-- Find the next target to connect to, and
+-- pass it to cb()
+function methods:next(cb)
+ if self.targets 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));
+ self.resolver:next(function (...)
+ if ... == nil then
+ self:next(cb);
+ else
+ cb(...);
+ end
+ end);
+ return;
+ end
+
+ local targets = {};
+ local function ready()
+ self.targets = targets;
+ self:next(cb);
+ end
+
+ -- Resolve DNS to target list
+ local dns_resolver = adns.resolver();
+ dns_resolver:lookup(function (answer)
+ if answer then
+ table.sort(answer, function (a, b) return a.priority > b.priority end);
+ for _, record in ipairs(answer) do
+ table.insert(targets, { record.srv.target, record.srv.port, self.conn_type, self.extra });
+ end
+ end
+ ready();
+ end, "_" .. self.service .. "._" .. self.conn_type .. "." .. self.domain, "SRV", "IN");
+end
+
+local function new(domain, service, conn_type, extra)
+ return setmetatable({
+ domain = domain;
+ service = service;
+ conn_type = conn_type or "tcp";
+ extra = extra;
+ }, resolver_mt);
+end
+
+return {
+ new = new;
+};