From f278c021e68f508383e8a7b67e5e491614c61def Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 18 Mar 2022 16:16:01 +0000 Subject: net.connect: Support for multiple pending connection attempts --- net/connect.lua | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'net/connect.lua') diff --git a/net/connect.lua b/net/connect.lua index 4b602be4..6bc5e6b5 100644 --- a/net/connect.lua +++ b/net/connect.lua @@ -28,10 +28,6 @@ local pending_connection_listeners = {}; local function attempt_connection(p) p:log("debug", "Checking for targets..."); - if p.conn then - pending_connections_map[p.conn] = nil; - p.conn = nil; - end p.target_resolver:next(function (conn_type, ip, port, extra) if not conn_type then -- No more targets to try @@ -49,7 +45,7 @@ local function attempt_connection(p) p.last_error = err or "unknown reason"; return attempt_connection(p); end - p.conn = conn; + p.conns[conn] = true; pending_connections_map[conn] = p; end); end @@ -62,6 +58,13 @@ function pending_connection_listeners.onconnect(conn) return; end pending_connections_map[conn] = nil; + if p.connected then + -- We already succeeded in connecting + p.conns[conn] = nil; + conn:close(); + return; + end + p.connected = true; p:log("debug", "Successfully connected"); conn:setlistener(p.listeners, p.data); return p.listeners.onconnect(conn); @@ -73,6 +76,7 @@ function pending_connection_listeners.ondisconnect(conn, reason) log("warn", "Failed connection, but unexpected!"); return; end + p.conns[conn] = nil; p.last_error = reason or "unknown reason"; p:log("debug", "Connection attempt failed: %s", p.last_error); attempt_connection(p); @@ -85,6 +89,7 @@ local function connect(target_resolver, listeners, options, data) listeners = assert(listeners); options = options or {}; data = data; + conns = {}; }, pending_connection_mt); p:log("debug", "Starting connection process"); -- cgit v1.2.3 From a188ece31ae32f89f945e1064c0a998454cdf936 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 18 Mar 2022 16:16:57 +0000 Subject: net.connect: When more targets are immediately available, try them after a delay RFC 8305 --- net/connect.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'net/connect.lua') diff --git a/net/connect.lua b/net/connect.lua index 6bc5e6b5..241cc65b 100644 --- a/net/connect.lua +++ b/net/connect.lua @@ -1,6 +1,7 @@ local server = require "net.server"; local log = require "util.logger".init("net.connect"); local new_id = require "util.id".short; +local timer = require "util.timer"; -- TODO #1246 Happy Eyeballs -- FIXME RFC 6724 @@ -28,7 +29,7 @@ local pending_connection_listeners = {}; local function attempt_connection(p) p:log("debug", "Checking for targets..."); - p.target_resolver:next(function (conn_type, ip, port, extra) + p.target_resolver:next(function (conn_type, ip, port, extra, more_targets_available) if not conn_type then -- No more targets to try p:log("debug", "No more connection targets to try", p.target_resolver.last_error); @@ -47,6 +48,14 @@ local function attempt_connection(p) end p.conns[conn] = true; pending_connections_map[conn] = p; + if more_targets_available then + timer.add_task(0.250, function () + if not p.connected then + p:log("debug", "Still not connected, making parallel connection attempt..."); + attempt_connection(p); + end + end); + end end); end -- cgit v1.2.3 From b42fe8746c442351e0330c4570b0ae7eba102fe8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 21 Mar 2022 11:01:58 +0000 Subject: net.connect: Improve handling of failure when attempts are still pending This could lead to failure being reported too early, even if some connections have not yet failed. --- net/connect.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'net/connect.lua') diff --git a/net/connect.lua b/net/connect.lua index 241cc65b..0ae9c2b2 100644 --- a/net/connect.lua +++ b/net/connect.lua @@ -33,8 +33,13 @@ local function attempt_connection(p) if not conn_type then -- No more targets to try p:log("debug", "No more connection targets to try", p.target_resolver.last_error); - if p.listeners.onfail then - p.listeners.onfail(p.data, p.last_error or p.target_resolver.last_error or "unable to resolve service"); + if next(p.conns) == nil then + p:log("debug", "No more targets, no pending connections. Connection failed."); + if p.listeners.onfail then + p.listeners.onfail(p.data, p.last_error or p.target_resolver.last_error or "unable to resolve service"); + end + else + p:log("debug", "One or more connection attempts are still pending. Waiting for now."); end return; end @@ -88,7 +93,10 @@ function pending_connection_listeners.ondisconnect(conn, reason) p.conns[conn] = nil; p.last_error = reason or "unknown reason"; p:log("debug", "Connection attempt failed: %s", p.last_error); - attempt_connection(p); + if next(p.conns) == nil and not p.connected then + p:log("debug", "No pending connection attempts, and not yet connected"); + attempt_connection(p); + end end local function connect(target_resolver, listeners, options, data) -- cgit v1.2.3 From 28e919462b81de447b08c490f9879234642d2200 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 21 Mar 2022 11:15:30 +0000 Subject: net.connect: Improve logging on connection attempt failure --- net/connect.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'net/connect.lua') diff --git a/net/connect.lua b/net/connect.lua index 0ae9c2b2..f2c932f9 100644 --- a/net/connect.lua +++ b/net/connect.lua @@ -93,9 +93,13 @@ function pending_connection_listeners.ondisconnect(conn, reason) p.conns[conn] = nil; p.last_error = reason or "unknown reason"; p:log("debug", "Connection attempt failed: %s", p.last_error); - if next(p.conns) == nil and not p.connected then + if p.connected then + p:log("debug", "Connection already established, ignoring failure"); + elseif next(p.conns) == nil then p:log("debug", "No pending connection attempts, and not yet connected"); attempt_connection(p); + else + p:log("debug", "Other attempts are still pending, ignoring failure"); end end -- cgit v1.2.3 From 9e8e910f1e7be52db27ec26aeb9f39171a6946b5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 20 Apr 2022 22:41:54 +0200 Subject: net.connect: Fix accumulation of connection attempt references Connection attempts that failed the Happy Eyeballs race were not unreferenced and would accumulate. Tested by inspecting the 'pending_connections_map' after establishing s2s with a s2s target where the IPv6 port has a -j DROP rule causing it to time out and the IPv4 attempt wins the race. Expected is that the losing connection stays around until net.server timeouts kick in where it should be removed. The map table should tend towards being empty during idle times. --- net/connect.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'net/connect.lua') diff --git a/net/connect.lua b/net/connect.lua index f2c932f9..d85afcff 100644 --- a/net/connect.lua +++ b/net/connect.lua @@ -91,6 +91,7 @@ function pending_connection_listeners.ondisconnect(conn, reason) return; end p.conns[conn] = nil; + pending_connections_map[conn] = nil; p.last_error = reason or "unknown reason"; p:log("debug", "Connection attempt failed: %s", p.last_error); if p.connected then -- cgit v1.2.3 From b79cb49bfba1d64dda54cf7243154624c53b5fb9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 19 Aug 2022 14:24:31 +0200 Subject: net.connect: Clear TODO for Happy Eyeballs / RFC 8305, close #1246 Gotta have the DOAP references! --- net/connect.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'net/connect.lua') diff --git a/net/connect.lua b/net/connect.lua index d85afcff..3cb407a1 100644 --- a/net/connect.lua +++ b/net/connect.lua @@ -3,7 +3,6 @@ local log = require "util.logger".init("net.connect"); local new_id = require "util.id".short; local timer = require "util.timer"; --- TODO #1246 Happy Eyeballs -- FIXME RFC 6724 -- FIXME Error propagation from resolvers doesn't work -- FIXME #1428 Reuse DNS resolver object between service and basic resolver -- cgit v1.2.3