author | Kim Alvefur <zash@zash.se> |
Tue, 22 Nov 2022 23:56:01 +0100 | |
branch | 0.11 |
changeset 12801 | be09ac8300a7 |
parent 9390 | 33e52f727f0f |
child 10116 | b327f2870382 |
permissions | -rw-r--r-- |
8534
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) |
8550
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8549
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:
8549
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:
8549
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:
8549
diff
changeset
|
33 |
if p.listeners.onfail then |
8552
69e942c2990f
net.connect: Improve error message
Matthew Wild <mwild1@gmail.com>
parents:
8551
diff
changeset
|
34 |
p.listeners.onfail(p.data, p.last_error or "unable to resolve service"); |
8550
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8549
diff
changeset
|
35 |
end |
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8549
diff
changeset
|
36 |
return; |
5e9c87376891
net.connect: Handle case when resolver runs out of targets
Matthew Wild <mwild1@gmail.com>
parents:
8549
diff
changeset
|
37 |
end |
8534
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); |
8551
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8550
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:
8550
diff
changeset
|
40 |
if not conn then |
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8550
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:
8550
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:
8550
diff
changeset
|
43 |
return attempt_connection(p); |
162f75ac2693
net.connect: Handle immediate failures of server.addclient
Matthew Wild <mwild1@gmail.com>
parents:
8550
diff
changeset
|
44 |
end |
8534
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"); |
9390
33e52f727f0f
net.connect: Fix passing request table to new listener
Kim Alvefur <zash@zash.se>
parents:
9389
diff
changeset
|
59 |
conn:setlistener(p.listeners, p.data); |
8534
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 |
8549
d66916dc318a
net.connect: Track last connection error
Matthew Wild <mwild1@gmail.com>
parents:
8539
diff
changeset
|
69 |
p.last_error = reason or "unknown reason"; |
d66916dc318a
net.connect: Track last connection error
Matthew Wild <mwild1@gmail.com>
parents:
8539
diff
changeset
|
70 |
p:log("debug", "Connection attempt failed: %s", p.last_error); |
8534
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 {}; |
8553
f841d359da65
net.connect: Fix to store correct parameter
Matthew Wild <mwild1@gmail.com>
parents:
8552
diff
changeset
|
80 |
data = data; |
8534
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 |
}; |