Software / code / prosody
Annotate
net/connect.lua @ 11172:712b2e6a09d9 0.11
Back out 6dde2c9fa272: Doesn't work on Lua 5.1
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 15 Oct 2020 17:12:33 +0200 |
| parent | 9387:33e52f727f0f |
| child | 10112:b327f2870382 |
| 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 server = require "net.server"; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local log = require "util.logger".init("net.connect"); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local new_id = require "util.id".short; |
|
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 pending_connection_methods = {}; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 local pending_connection_mt = { |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 __name = "pending_connection"; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 __index = pending_connection_methods; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 __tostring = function (p) |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 return "<pending connection "..p.id.." to "..tostring(p.target_resolver.hostname)..">"; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 end; |
|
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 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 function pending_connection_methods:log(level, message, ...) |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 log(level, "[pending connection %s] "..message, self.id, ...); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 end |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 -- pending_connections_map[conn] = pending_connection |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 local pending_connections_map = {}; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 local pending_connection_listeners = {}; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 local function attempt_connection(p) |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 p:log("debug", "Checking for targets..."); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 if p.conn then |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 pending_connections_map[p.conn] = nil; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 p.conn = nil; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 end |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 p.target_resolver:next(function (conn_type, ip, port, extra) |
|
8547
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
30 if not conn_type then |
|
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
31 -- No more targets to try |
|
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
32 p:log("debug", "No more connection targets to try"); |
|
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
33 if p.listeners.onfail then |
|
8549
69e942c2990f
net.connect: Improve error message
Matthew Wild <mwild1@gmail.com>
parents:
8548
diff
changeset
|
34 p.listeners.onfail(p.data, p.last_error or "unable to resolve service"); |
|
8547
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
35 end |
|
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
36 return; |
|
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8546
diff
changeset
|
37 end |
|
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 p:log("debug", "Next target to try is %s:%d", ip, port); |
|
8548
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8547
diff
changeset
|
39 local conn, err = server.addclient(ip, port, pending_connection_listeners, p.options.pattern or "*a", p.options.sslctx, conn_type, extra); |
|
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8547
diff
changeset
|
40 if not conn then |
|
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8547
diff
changeset
|
41 log("debug", "Connection attempt failed immediately: %s", tostring(err)); |
|
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8547
diff
changeset
|
42 p.last_error = err or "unknown reason"; |
|
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8547
diff
changeset
|
43 return attempt_connection(p); |
|
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8547
diff
changeset
|
44 end |
|
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 p.conn = conn; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 pending_connections_map[conn] = p; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 end); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 end |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 function pending_connection_listeners.onconnect(conn) |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 local p = pending_connections_map[conn]; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 if not p then |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 log("warn", "Successful connection, but unexpected! Closing."); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 conn:close(); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 return; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 end |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 pending_connections_map[conn] = nil; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 p:log("debug", "Successfully connected"); |
|
9387
33e52f727f0f
net.connect: Fix passing request table to new listener
Kim Alvefur <zash@zash.se>
parents:
9386
diff
changeset
|
59 conn:setlistener(p.listeners, p.data); |
|
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 return p.listeners.onconnect(conn); |
|
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 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 function pending_connection_listeners.ondisconnect(conn, reason) |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 local p = pending_connections_map[conn]; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 if not p then |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 log("warn", "Failed connection, but unexpected!"); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 return; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 end |
|
8546
d66916dc318a
net.connect: Track last connection error
Matthew Wild <mwild1@gmail.com>
parents:
8536
diff
changeset
|
69 p.last_error = reason or "unknown reason"; |
|
d66916dc318a
net.connect: Track last connection error
Matthew Wild <mwild1@gmail.com>
parents:
8536
diff
changeset
|
70 p:log("debug", "Connection attempt failed: %s", p.last_error); |
|
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 attempt_connection(p); |
|
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 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 local function connect(target_resolver, listeners, options, data) |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 local p = setmetatable({ |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 id = new_id(); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 target_resolver = target_resolver; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 listeners = assert(listeners); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 options = options or {}; |
|
8550
f841d359da65
net.connect: Fix to store correct parameter
Matthew Wild <mwild1@gmail.com>
parents:
8549
diff
changeset
|
80 data = data; |
|
8531
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 }, pending_connection_mt); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 p:log("debug", "Starting connection process"); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 attempt_connection(p); |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 end |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 return { |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 connect = connect; |
|
601681acea73
net.connect: New API for outgoing connections, based on 'service resolvers'
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 }; |