Software /
code /
prosody
Annotate
net/resolvers/service.lua @ 10917:1eb83bc6f706
util.human.io: Fix right-alignment
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 06 Jun 2020 16:43:28 +0200 |
parent | 10650:324a0c7d1c6a |
child | 10970:4603697aee50 |
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 |
10484
b13a31cea7d9
net.connect: Add some TODOs and FIXMEs
Kim Alvefur <zash@zash.se>
parents:
10440
diff
changeset
|
7 -- FIXME #1428 Reuse DNS resolver object (pass to basic resorver) |
b13a31cea7d9
net.connect: Add some TODOs and FIXMEs
Kim Alvefur <zash@zash.se>
parents:
10440
diff
changeset
|
8 -- FIXME #1429 Close DNS resolver object when done |
b13a31cea7d9
net.connect: Add some TODOs and FIXMEs
Kim Alvefur <zash@zash.se>
parents:
10440
diff
changeset
|
9 |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 local methods = {}; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 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
|
12 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 -- 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
|
14 -- pass it to cb() |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 function methods:next(cb) |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 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
|
17 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
|
18 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
|
19 cb(nil); |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
20 return; |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
21 end |
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
22 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
|
23 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
|
24 end |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
25 self.resolver:next(function (...) |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
26 if ... == nil then |
10650
324a0c7d1c6a
net.resolvers.service: Fix resolving of targets with multiple IPs
Kim Alvefur <zash@zash.se>
parents:
10484
diff
changeset
|
27 self.resolver = nil; |
9388
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
28 self:next(cb); |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
29 else |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
30 cb(...); |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
31 end |
a5d11627ce5d
net.resolvers.service: net.connect resolver that uses SRV records
Kim Alvefur <zash@zash.se>
parents:
8775
diff
changeset
|
32 end); |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 return; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 |
10385
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
36 if not self.hostname then |
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
37 -- FIXME report IDNA error |
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
38 cb(nil); |
10400
4c2d789a106b
net.resolvers: Fix traceback from hostname failing IDNA
Kim Alvefur <zash@zash.se>
parents:
10385
diff
changeset
|
39 return; |
10385
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
40 end |
62a7042e0771
net.resolvers: Abort on hostnames not passing IDNA validation
Kim Alvefur <zash@zash.se>
parents:
10384
diff
changeset
|
41 |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 local targets = {}; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 local function ready() |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 self.targets = targets; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 self:next(cb); |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 -- 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
|
49 local dns_resolver = adns.resolver(); |
10121
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
50 dns_resolver:lookup(function (answer, err) |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
51 if not answer and not err then |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
52 -- 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
|
53 answer = {}; |
33f287519bf6
net.resolvers.service: Fix DNS fallback
Kim Alvefur <zash@zash.se>
parents:
9691
diff
changeset
|
54 end |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 if answer then |
9393
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
56 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
|
57 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
|
58 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
|
59 end |
9393
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
60 ready(); |
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
61 return; |
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
62 end |
e2733f504d9e
net.resolvers.service: Early return on empty result set
Kim Alvefur <zash@zash.se>
parents:
9392
diff
changeset
|
63 |
9392
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
64 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
|
65 ready(); |
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
66 return; |
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
67 end |
f2d71e4284b7
net.resolvers.service: Understand when service is explicitly unavailable
Kim Alvefur <zash@zash.se>
parents:
9388
diff
changeset
|
68 |
9397
e09ddd061ec4
net.resolvers.service: Sort SRV records in correct direction
Kim Alvefur <zash@zash.se>
parents:
9396
diff
changeset
|
69 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
|
70 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
|
71 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
|
72 end |
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 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
|
75 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
|
76 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 |
9395
794eda565c69
net.resolvers.service: Rename internal variable since net.connect uses it for __tostring
Kim Alvefur <zash@zash.se>
parents:
9394
diff
changeset
|
78 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
|
79 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
|
80 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
|
81 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
|
82 end |
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
83 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
|
84 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
|
85 end |
1ee87b4979c2
net.resolvers.service: Pass IP literals directly to basic resolver
Kim Alvefur <zash@zash.se>
parents:
10401
diff
changeset
|
86 |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 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
|
88 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
|
89 service = service; |
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 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
|
91 extra = extra; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 }, resolver_mt); |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 end |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 return { |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 new = new; |
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
97 }; |