net/resolvers/service.lua
author Kim Alvefur <zash@zash.se>
Thu, 04 Nov 2021 01:00:06 +0100
branch0.11
changeset 12093 76b4e3f12b53
parent 10404 4c2d789a106b
child 10405 1ef1f6c43c5b
permissions -rw-r--r--
mod_pep: Wipe pubsub service on user deletion Data is already wiped from storage, but this ensures everything is properly unsubscribed, possibly with notifications etc. Clears recipient cache as well, since it is no longer relevant.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
local adns = require "net.adns";
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
     2
local basic = require "net.resolvers.basic";
10388
94c9c574cd8a net.resolvers: Apply IDNA conversion to ascii for DNS lookups (fixes #1426)
Kim Alvefur <zash@zash.se>
parents: 9400
diff changeset
     3
local idna_to_ascii = require "util.encodings".idna.to_ascii;
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
local methods = {};
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local resolver_mt = { __index = methods };
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
-- Find the next target to connect to, and
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
-- pass it to cb()
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
function methods:next(cb)
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
	if self.targets then
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
		if #self.targets == 0 then
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
			cb(nil);
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
			return;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
		end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
		local next_target = table.remove(self.targets, 1);
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    17
		self.resolver = basic.new(unpack(next_target, 1, 4));
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    18
		self.resolver:next(function (...)
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    19
			if ... == nil then
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    20
				self:next(cb);
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    21
			else
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    22
				cb(...);
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    23
			end
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    24
		end);
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
		return;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
10389
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    28
	if not self.hostname then
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    29
		-- FIXME report IDNA error
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    30
		cb(nil);
10404
4c2d789a106b net.resolvers: Fix traceback from hostname failing IDNA
Kim Alvefur <zash@zash.se>
parents: 10389
diff changeset
    31
		return;
10389
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    32
	end
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    33
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	local targets = {};
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	local function ready()
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
		self.targets = targets;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
		self:next(cb);
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	-- Resolve DNS to target list
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
	local dns_resolver = adns.resolver();
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	dns_resolver:lookup(function (answer)
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
		if answer then
9396
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
    44
			if #answer == 0 then
9397
bcd94cc355d3 net.resolvers.service: Add support for fallback to bare domain and default port
Kim Alvefur <zash@zash.se>
parents: 9396
diff changeset
    45
				if self.extra and self.extra.default_port then
9398
794eda565c69 net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents: 9397
diff changeset
    46
					table.insert(targets, { self.hostname, self.extra.default_port, self.conn_type, self.extra });
9397
bcd94cc355d3 net.resolvers.service: Add support for fallback to bare domain and default port
Kim Alvefur <zash@zash.se>
parents: 9396
diff changeset
    47
				end
9396
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
    48
				ready();
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
    49
				return;
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
    50
			end
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
    51
9395
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
    52
			if #answer == 1 and answer[1].srv.target == "." then -- No service here
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
    53
				ready();
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
    54
				return;
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
    55
			end
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
    56
9400
e09ddd061ec4 net.resolvers.service: Sort SRV records in correct direction
Kim Alvefur <zash@zash.se>
parents: 9399
diff changeset
    57
			table.sort(answer, function (a, b) return a.srv.priority < b.srv.priority end);
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
			for _, record in ipairs(answer) do
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    59
				table.insert(targets, { record.srv.target, record.srv.port, self.conn_type, self.extra });
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
			end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
		end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
		ready();
9398
794eda565c69 net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents: 9397
diff changeset
    63
	end, "_" .. self.service .. "._" .. self.conn_type .. "." .. self.hostname, "SRV", "IN");
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
9398
794eda565c69 net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents: 9397
diff changeset
    66
local function new(hostname, service, conn_type, extra)
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
	return setmetatable({
10388
94c9c574cd8a net.resolvers: Apply IDNA conversion to ascii for DNS lookups (fixes #1426)
Kim Alvefur <zash@zash.se>
parents: 9400
diff changeset
    68
		hostname = idna_to_ascii(hostname);
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    69
		service = service;
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
		conn_type = conn_type or "tcp";
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
		extra = extra;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
	}, resolver_mt);
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
return {
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
	new = new;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
};