Software /
code /
prosody
Annotate
net/resolvers/service.lua @ 11710:26a8cc9d9eb7
net.resolvers.service: Only do DANE with secure SRV records
If this seems backwards, that' because it is but the API isn't really
designed to easily pass along details from each resolution step onto the
next.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 18 Jul 2021 23:25:45 +0200 |
parent | 10970:4603697aee50 |
child | 11901:26406ce35e20 |
rev | line source |
---|---|
8531
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"; |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
2 local basic = require "net.resolvers.basic"; |
10440
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
3 local inet_pton = require "util.net".pton; |
10384
94c9c574cd8a
net.resolvers: Apply IDNA conversion to ascii for DNS lookups (fixes #1426)
Kim Alvefur <zash@zash.se>
parents:
9397
diff
changeset
|
4 local idna_to_ascii = require "util.encodings".idna.to_ascii; |
9691
e11e076f0eb8
various: Don't rely on _G.unpack existing
Kim Alvefur <zash@zash.se>
parents:
9397
diff
changeset
|
5 local unpack = table.unpack or unpack; -- luacheck: ignore 113 |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 local methods = {}; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 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
|
9 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 -- 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
|
11 -- pass it to cb() |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 function methods:next(cb) |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 if self.targets then |
10650
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
14 if not self.resolver then |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
15 if #self.targets == 0 then |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
16 cb(nil); |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
17 return; |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
18 end |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
19 local next_target = table.remove(self.targets, 1); |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
20 self.resolver = basic.new(unpack(next_target, 1, 4)); |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 end |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
22 self.resolver:next(function (...) |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
23 if ... == nil then |
10650
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
24 self.resolver = nil; |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
25 self:next(cb); |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
26 else |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
27 cb(...); |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
28 end |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
29 end); |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 return; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 |
10385
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
33 if not self.hostname then |
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
34 -- FIXME report IDNA error |
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
35 cb(nil); |
10400
4c2d789a106b
net.resolvers: Fix traceback from hostname failing IDNA
Kim Alvefur <zash@zash.se>
parents:
10385
diff
changeset
|
36 return; |
10385
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
37 end |
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
38 |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 local targets = {}; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 local function ready() |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 self.targets = targets; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 self:next(cb); |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 -- 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
|
46 local dns_resolver = adns.resolver(); |
10121
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
47 dns_resolver:lookup(function (answer, err) |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
48 if not answer and not err then |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
49 -- net.adns returns nil if there are zero records or nxdomain |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
50 answer = {}; |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
51 end |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 if answer then |
11710
26a8cc9d9eb7
net.resolvers.service: Only do DANE with secure SRV records
Kim Alvefur <zash@zash.se>
parents:
10970
diff
changeset
|
53 if self.extra and not answer.secure then |
26a8cc9d9eb7
net.resolvers.service: Only do DANE with secure SRV records
Kim Alvefur <zash@zash.se>
parents:
10970
diff
changeset
|
54 self.extra.use_dane = false; |
26a8cc9d9eb7
net.resolvers.service: Only do DANE with secure SRV records
Kim Alvefur <zash@zash.se>
parents:
10970
diff
changeset
|
55 end |
26a8cc9d9eb7
net.resolvers.service: Only do DANE with secure SRV records
Kim Alvefur <zash@zash.se>
parents:
10970
diff
changeset
|
56 |
9393
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
57 if #answer == 0 then |
9394
bcd94cc355d3
net.resolvers.service: Add support for fallback to bare domain and default port
Kim Alvefur <zash@zash.se>
parents:
9393
diff
changeset
|
58 if self.extra and self.extra.default_port then |
9395
794eda565c69
net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents:
9394
diff
changeset
|
59 table.insert(targets, { self.hostname, self.extra.default_port, self.conn_type, self.extra }); |
9394
bcd94cc355d3
net.resolvers.service: Add support for fallback to bare domain and default port
Kim Alvefur <zash@zash.se>
parents:
9393
diff
changeset
|
60 end |
9393
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
61 ready(); |
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
62 return; |
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
63 end |
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
64 |
9392
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
65 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:
9388
diff
changeset
|
66 ready(); |
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
67 return; |
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
68 end |
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
69 |
9397
e09ddd061ec4
net.resolvers.service: Sort SRV records in correct direction
Kim Alvefur <zash@zash.se>
parents:
9396
diff
changeset
|
70 table.sort(answer, function (a, b) return a.srv.priority < b.srv.priority end); |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 for _, record in ipairs(answer) do |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
72 table.insert(targets, { record.srv.target, record.srv.port, self.conn_type, self.extra }); |
8531
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 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 ready(); |
9395
794eda565c69
net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents:
9394
diff
changeset
|
76 end, "_" .. self.service .. "._" .. self.conn_type .. "." .. self.hostname, "SRV", "IN"); |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
9395
794eda565c69
net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents:
9394
diff
changeset
|
79 local function new(hostname, service, conn_type, extra) |
10440
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
80 local is_ip = inet_pton(hostname); |
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
81 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:
10401
diff
changeset
|
82 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:
10401
diff
changeset
|
83 end |
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
84 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:
10401
diff
changeset
|
85 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:
10401
diff
changeset
|
86 end |
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
87 |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 return setmetatable({ |
10384
94c9c574cd8a
net.resolvers: Apply IDNA conversion to ascii for DNS lookups (fixes #1426)
Kim Alvefur <zash@zash.se>
parents:
9397
diff
changeset
|
89 hostname = idna_to_ascii(hostname); |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
90 service = service; |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 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
|
92 extra = extra; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 }, resolver_mt); |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 return { |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
97 new = new; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
98 }; |