diff --git a/grpc_client/lib/grpc/client/adapters/gun.ex b/grpc_client/lib/grpc/client/adapters/gun.ex index 8dde77781..907772d47 100644 --- a/grpc_client/lib/grpc/client/adapters/gun.ex +++ b/grpc_client/lib/grpc/client/adapters/gun.ex @@ -94,7 +94,7 @@ defmodule GRPC.Client.Adapters.Gun do do: :gun.open_unix(socket_path, open_opts) defp open(host, port, open_opts), - do: :gun.open(String.to_charlist(host), port, open_opts) + do: :gun.open(parse_address(host), port, open_opts) @impl true def send_request(stream, message, opts) do @@ -496,6 +496,15 @@ defmodule GRPC.Client.Adapters.Gun do end end + defp parse_address(host) do + host = String.to_charlist(host) + + case :inet.parse_address(host) do + {:ok, address} -> address + {:error, _} -> host + end + end + defp get_compressor(%{"grpc-encoding" => encoding} = _headers, accepted_compressors) do Enum.find(accepted_compressors, nil, fn c -> c.name() == encoding end) end diff --git a/grpc_client/lib/grpc/client/resolver/dns.ex b/grpc_client/lib/grpc/client/resolver/dns.ex index 7d36f219f..c1b688b42 100644 --- a/grpc_client/lib/grpc/client/resolver/dns.ex +++ b/grpc_client/lib/grpc/client/resolver/dns.ex @@ -46,7 +46,15 @@ defmodule GRPC.Client.Resolver.DNS do end defp lookup_addresses(host) do - case adapter().lookup(host, :a) do + case lookup_addresses(host, :a) do + {:ok, [_ | _] = addrs} -> {:ok, addrs} + {:ok, []} -> lookup_addresses(host, :aaaa) + other -> other + end + end + + defp lookup_addresses(host, type) do + case adapter().lookup(host, type) do {:ok, addrs} when is_list(addrs) -> {:ok, addrs} addrs when is_list(addrs) -> {:ok, addrs} other -> other diff --git a/grpc_client/test/grpc/resolver/dns_test.exs b/grpc_client/test/grpc/resolver/dns_test.exs index a97982b79..6afe534c6 100644 --- a/grpc_client/test/grpc/resolver/dns_test.exs +++ b/grpc_client/test/grpc/resolver/dns_test.exs @@ -49,4 +49,23 @@ defmodule GRPC.Client.Resolver.DNSTest do assert {"foo", "bar"} in method_names assert {"baz", nil} in method_names end + + test "resolves AAAA record as fallback when A record returns empty list" do + host = "my-service.local" + config_name = "_grpc_config." <> host + + DNS.MockAdapter + |> expect(:lookup, fn ^host, :a -> + {:ok, []} + end) + |> expect(:lookup, fn ^host, :aaaa -> + {:ok, [{0, 0, 0, 0, 0, 0, 0, 1}]} + end) + |> expect(:lookup, fn ^config_name, :txt -> + {:ok, []} + end) + + assert {:ok, %{addresses: addrs}} = DNS.resolve(host) + assert [%{address: "::1", port: 50051}] = addrs + end end