From 0622e0af7210c40c479892de2a44053b36b6d95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Fri, 31 Jan 2025 15:58:46 +0100 Subject: [PATCH] Fix connecting from runtime to remote Livebook nodes (#2923) --- lib/livebook/runtime/epmd.ex | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/livebook/runtime/epmd.ex b/lib/livebook/runtime/epmd.ex index f5f43b78a..99d5f3384 100644 --- a/lib/livebook/runtime/epmd.ex +++ b/lib/livebook/runtime/epmd.ex @@ -47,9 +47,34 @@ defmodule Livebook.Runtime.EPMD do def port_please(name, host), do: port_please(name, host, :infinity) def port_please(name, host, timeout) do - case livebook_port(name) do - 0 -> :erl_epmd.port_please(name, host, timeout) - port -> {:port, port, @epmd_dist_version} + # If the target node is on the same host, check if it's a Livebook + # server or runtime to bypass EPMD. If it is a different node, we + # always fall back to :erl_epmd, even if it's a Livebook node. + if host_to_ip(host()) == host_to_ip(host) do + case livebook_port(name) do + 0 -> :erl_epmd.port_please(name, host, timeout) + port -> {:port, port, @epmd_dist_version} + end + else + :erl_epmd.port_please(name, host, timeout) + end + end + + defp host() do + [_, host] = node() |> Atom.to_charlist() |> :string.split(~c"@") + host + end + + import Record + defrecordp :hostent, Record.extract(:hostent, from_lib: "kernel/include/inet.hrl") + + defp host_to_ip(host) when is_tuple(host), do: {:ok, host} + defp host_to_ip(host) when is_atom(host), do: host_to_ip(Atom.to_charlist(host)) + + defp host_to_ip(host) when is_list(host) do + case :inet.gethostbyname(host) do + {:ok, hostent(h_addrtype: :inet, h_addr_list: [ip | _])} -> {:ok, ip} + _other -> :error end end