From eb5855c419abe614bc526c0290de83073a4eea4e Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Sat, 25 Jan 2025 09:13:43 +0100 Subject: [PATCH] Resolve short names using .local suffix with `inet:getaddr/2` This allows to connect to localhost if shortnames are used and host cannot be resolved. BEAM succeeds even if gethostbyname(2) fails, typically on macOS 15. Signed-off-by: Paul Guyot --- libs/estdlib/src/inet.erl | 23 +++++++++++++++++++++++ libs/estdlib/src/socket_dist.erl | 22 +++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/libs/estdlib/src/inet.erl b/libs/estdlib/src/inet.erl index 8eb3b2b61..345cee5ee 100644 --- a/libs/estdlib/src/inet.erl +++ b/libs/estdlib/src/inet.erl @@ -108,6 +108,29 @@ getaddr(Name, Family) -> [] -> {error, nxdomain}; [IPAddr | _] -> {ok, IPAddr} end; + {error, eainoname} -> + case string:split(Name, ".") of + [Name] -> + % BEAM succeeds to resolve short names even if gethostbyname(2) fails. + % Work around for distribution by trying to add .local suffix. + case net:getaddrinfo(Name ++ ".local") of + {ok, ResultsLocal} -> + FilteredLocal = [ + Addr + || #{family := F, addr := #{addr := Addr}} <- ResultsLocal, + F =:= Family, + Addr =:= {127, 0, 0, 1} orelse Addr =:= {0, 0, 0, 0, 0, 0, 0, 1} + ], + case FilteredLocal of + [] -> {error, nxdomain}; + [LocalIPAddr | _] -> {ok, LocalIPAddr} + end; + _ -> + {error, nxdomain} + end; + _ -> + {error, nxdomain} + end; {error, _} = Err -> Err catch diff --git a/libs/estdlib/src/socket_dist.erl b/libs/estdlib/src/socket_dist.erl index 437700de2..bfcee1b5d 100644 --- a/libs/estdlib/src/socket_dist.erl +++ b/libs/estdlib/src/socket_dist.erl @@ -128,11 +128,11 @@ setup(Node, Type, MyNode, LongOrShortNames, SetupTime) -> dist_util:net_ticker_spawn_options() ). -do_setup(Kernel, Node, Type, MyNode, _LongOrShortNames, SetupTime) -> +do_setup(Kernel, Node, Type, MyNode, _LongNames, SetupTime) -> case string:split(atom_to_list(Node), "@") of - [Name, Address] -> + [Name, Host] -> Timer = dist_util:start_timer(SetupTime), - case inet:getaddr(Address, inet) of + case inet:getaddr(Host, inet) of {ok, Ip} -> dist_util:reset_timer(Timer), ErlEpmd = net_kernel:epmd_module(), @@ -159,17 +159,17 @@ do_setup(Kernel, Node, Type, MyNode, _LongOrShortNames, SetupTime) -> Timer ), dist_util:handshake_we_started(HSData); - _ -> - ?shutdown(Node) + Other1 -> + ?shutdown2(Node, {unexpected, Other1}) end; - _ -> - ?shutdown(Node) + Other2 -> + ?shutdown2(Node, {unexpected, Other2}) end; - _ -> - ?shutdown(Node) + Other3 -> + ?shutdown2(Node, {unexpected, Other3}) end; - _ -> - ?shutdown(Node) + Other4 -> + ?shutdown2(Node, {unexpected, Other4}) end. close(Listen) ->