net/resolvers/service.lua
author Kim Alvefur <zash@zash.se>
Sat, 23 Mar 2024 20:48:19 +0100
changeset 13465 c673ff1075bd
parent 12978 ba409c67353b
permissions -rw-r--r--
mod_posix: Move everything to util.startup This allows greater control over the order of events. Notably, the internal ordering between daemonization, initialization of libunbound and setup of signal handling is sensitive. libunbound starts a separate thread for processing DNS requests. If this thread is started before signal handling has been set up, it will not inherit the signal handlers and instead behave as it would have before signal handlers were set up, i.e. cause the whole process to immediately exit. libunbound is usually initialized on the first DNS request, usually triggered by an outgoing s2s connection attempt. If daemonization happens before signals have been set up, signals may not be processed at all.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12978
ba409c67353b net: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12818
diff changeset
     1
local adns = require "prosody.net.adns";
ba409c67353b net: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12818
diff changeset
     2
local basic = require "prosody.net.resolvers.basic";
ba409c67353b net: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12818
diff changeset
     3
local inet_pton = require "prosody.util.net".pton;
ba409c67353b net: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12818
diff changeset
     4
local idna_to_ascii = require "prosody.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
     5
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local methods = {};
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
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
     8
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
     9
local function new_target_selector(rrset)
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    10
	local rr_count = rrset and #rrset;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    11
	if not rr_count or rr_count == 0 then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    12
		rrset = nil;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    13
	else
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    14
		table.sort(rrset, function (a, b) return a.srv.priority < b.srv.priority end);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    15
	end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    16
	local rrset_pos = 1;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    17
	local priority_bucket, bucket_total_weight, bucket_len, bucket_used;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    18
	return function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    19
		if not rrset then return; end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    20
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    21
		if not priority_bucket or bucket_used >= bucket_len then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    22
			if rrset_pos > rr_count then return; end -- Used up all records
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    23
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    24
			-- Going to start on a new priority now. Gather up all the next
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    25
			-- records with the same priority and add them to priority_bucket
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    26
			priority_bucket, bucket_total_weight, bucket_len, bucket_used = {}, 0, 0, 0;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    27
			local current_priority;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    28
			repeat
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    29
				local curr_record = rrset[rrset_pos].srv;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    30
				if not current_priority then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    31
					current_priority = curr_record.priority;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    32
				elseif current_priority ~= curr_record.priority then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    33
					break;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    34
				end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    35
				table.insert(priority_bucket, curr_record);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    36
				bucket_total_weight = bucket_total_weight + curr_record.weight;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    37
				bucket_len = bucket_len + 1;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    38
				rrset_pos = rrset_pos + 1;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    39
			until rrset_pos > rr_count;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    40
		end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    41
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    42
		bucket_used = bucket_used + 1;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    43
		local n, running_total = math.random(0, bucket_total_weight), 0;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    44
		local target_record;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    45
		for i = 1, bucket_len do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    46
			local candidate = priority_bucket[i];
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    47
			if candidate then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    48
				running_total = running_total + candidate.weight;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    49
				if running_total >= n then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    50
					target_record = candidate;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    51
					bucket_total_weight = bucket_total_weight - candidate.weight;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    52
					priority_bucket[i] = nil;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    53
					break;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    54
				end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    55
			end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    56
		end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    57
		return target_record;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    58
	end;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    59
end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    60
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
-- 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
    62
-- pass it to cb()
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
function methods:next(cb)
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    64
	if self.resolver or self._get_next_target then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    65
		if not self.resolver then -- Do we have a basic resolver currently?
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    66
			-- We don't, so fetch a new SRV target, create a new basic resolver for it
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    67
			local next_srv_target = self._get_next_target and self._get_next_target();
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    68
			if not next_srv_target then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    69
				-- No more SRV targets left
10654
324a0c7d1c6a net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents: 10488
diff changeset
    70
				cb(nil);
324a0c7d1c6a net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents: 10488
diff changeset
    71
				return;
324a0c7d1c6a net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents: 10488
diff changeset
    72
			end
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    73
			-- Create a new basic resolver for this SRV target
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    74
			self.resolver = basic.new(next_srv_target.target, next_srv_target.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
    75
		end
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    76
		-- Look up the next (basic) target from the current target's resolver
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    77
		self.resolver:next(function (...)
11905
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
    78
			if self.resolver then
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
    79
				self.last_error = self.resolver.last_error;
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
    80
			end
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    81
			if ... == nil then
10654
324a0c7d1c6a net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents: 10488
diff changeset
    82
				self.resolver = nil;
9391
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    83
				self:next(cb);
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    84
			else
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    85
				cb(...);
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    86
			end
a5d11627ce5d net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents: 8778
diff changeset
    87
		end);
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
		return;
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    89
	elseif self.in_progress then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    90
		cb(nil);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
    91
		return;
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
	end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
10389
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    94
	if not self.hostname then
12029
6ed7fd28f5e3 net.resolvers: Report when hostname fails IDNA
Kim Alvefur <zash@zash.se>
parents: 11905
diff changeset
    95
		self.last_error = "hostname failed IDNA";
10389
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    96
		cb(nil);
10404
4c2d789a106b net.resolvers: Fix traceback from hostname failing IDNA
Kim Alvefur <zash@zash.se>
parents: 10389
diff changeset
    97
		return;
10389
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    98
	end
62a7042e0771 net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents: 10388
diff changeset
    99
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
   100
	self.in_progress = true;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
   101
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
	local function ready()
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   103
		self:next(cb);
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
	end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
	-- 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
   107
	local dns_resolver = adns.resolver();
10125
33f287519bf6 net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents: 9695
diff changeset
   108
	dns_resolver:lookup(function (answer, err)
33f287519bf6 net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents: 9695
diff changeset
   109
		if not answer and not err then
33f287519bf6 net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents: 9695
diff changeset
   110
			-- net.adns returns nil if there are zero records or nxdomain
33f287519bf6 net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents: 9695
diff changeset
   111
			answer = {};
33f287519bf6 net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents: 9695
diff changeset
   112
		end
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
		if answer then
12817
4be161c25e14 net.resolvers.service: Fix reporting of Bogus DNSSEC results
Kim Alvefur <zash@zash.se>
parents: 12816
diff changeset
   114
			if answer.bogus then
12133
7a68d5828f3b net.resolvers: Report DNSSEC validation errors instead of NoError
Kim Alvefur <zash@zash.se>
parents: 12029
diff changeset
   115
				self.last_error = "Validation error in SRV lookup";
7a68d5828f3b net.resolvers: Report DNSSEC validation errors instead of NoError
Kim Alvefur <zash@zash.se>
parents: 12029
diff changeset
   116
				ready();
7a68d5828f3b net.resolvers: Report DNSSEC validation errors instead of NoError
Kim Alvefur <zash@zash.se>
parents: 12029
diff changeset
   117
				return;
12817
4be161c25e14 net.resolvers.service: Fix reporting of Bogus DNSSEC results
Kim Alvefur <zash@zash.se>
parents: 12816
diff changeset
   118
			elseif not answer.secure then
4be161c25e14 net.resolvers.service: Fix reporting of Bogus DNSSEC results
Kim Alvefur <zash@zash.se>
parents: 12816
diff changeset
   119
				if self.extra then
4be161c25e14 net.resolvers.service: Fix reporting of Bogus DNSSEC results
Kim Alvefur <zash@zash.se>
parents: 12816
diff changeset
   120
					-- Insecure results, so no DANE
4be161c25e14 net.resolvers.service: Fix reporting of Bogus DNSSEC results
Kim Alvefur <zash@zash.se>
parents: 12816
diff changeset
   121
					self.extra.use_dane = false;
4be161c25e14 net.resolvers.service: Fix reporting of Bogus DNSSEC results
Kim Alvefur <zash@zash.se>
parents: 12816
diff changeset
   122
				end
11714
26a8cc9d9eb7 net.resolvers.service: Only do DANE with secure SRV records
Kim Alvefur <zash@zash.se>
parents: 10974
diff changeset
   123
			end
12818
3bfb2f9e13af net.resolvers.service: Record DNSSEC security status of SRV records
Kim Alvefur <zash@zash.se>
parents: 12817
diff changeset
   124
			if self.extra then
3bfb2f9e13af net.resolvers.service: Record DNSSEC security status of SRV records
Kim Alvefur <zash@zash.se>
parents: 12817
diff changeset
   125
				self.extra.srv_secure = answer.secure;
3bfb2f9e13af net.resolvers.service: Record DNSSEC security status of SRV records
Kim Alvefur <zash@zash.se>
parents: 12817
diff changeset
   126
			end
11714
26a8cc9d9eb7 net.resolvers.service: Only do DANE with secure SRV records
Kim Alvefur <zash@zash.se>
parents: 10974
diff changeset
   127
9396
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
   128
			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
   129
				if self.extra and self.extra.default_port then
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
   130
					self.resolver = basic.new(self.hostname, self.extra.default_port, self.conn_type, self.extra);
11905
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
   131
				else
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
   132
					self.last_error = "zero SRV records found";
9397
bcd94cc355d3 net.resolvers.service: Add support for fallback to bare domain and default port
Kim Alvefur <zash@zash.se>
parents: 9396
diff changeset
   133
				end
9396
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
   134
				ready();
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
   135
				return;
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
   136
			end
e2733f504d9e net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents: 9395
diff changeset
   137
9395
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
   138
			if #answer == 1 and answer[1].srv.target == "." then -- No service here
11905
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
   139
				self.last_error = "service explicitly unavailable";
9395
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
   140
				ready();
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
   141
				return;
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
   142
			end
f2d71e4284b7 net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents: 9391
diff changeset
   143
12405
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents: 12133
diff changeset
   144
			self._get_next_target = new_target_selector(answer);
11905
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
   145
		else
26406ce35e20 net.connect: Propagate last error message from resolvers
Kim Alvefur <zash@zash.se>
parents: 11714
diff changeset
   146
			self.last_error = err;
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
		end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   148
		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
   149
	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
   150
end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
9398
794eda565c69 net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents: 9397
diff changeset
   152
local function new(hostname, service, conn_type, extra)
10444
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   153
	local is_ip = inet_pton(hostname);
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   154
	if not is_ip and hostname:sub(1,1) == '[' then
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   155
		is_ip = inet_pton(hostname:sub(2,-2));
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   156
	end
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   157
	if is_ip and extra and extra.default_port then
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   158
		return basic.new(hostname, extra.default_port, conn_type, extra);
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   159
	end
1ee87b4979c2 net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents: 10405
diff changeset
   160
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
	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
   162
		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
   163
		service = service;
8534
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
		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
   165
		extra = extra;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
	}, resolver_mt);
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
end
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
return {
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   170
	new = new;
601681acea73 net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
};