File 3547-Revise-handling-of-IPv4-compatible-IPv6-address-look.patch of Package erlang
From f52792b570a9d27f724fa0a107519b8f449c3de2 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Fri, 2 Jul 2021 12:09:27 +0200
Subject: [PATCH 7/8] Revise handling of IPv4-compatible IPv6 address lookup
---
lib/kernel/src/inet_db.erl | 43 +++++++++++++++++--------------------
lib/kernel/src/inet_res.erl | 16 +++++++++++++-
2 files changed, 35 insertions(+), 24 deletions(-)
diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl
index 4644bea344..f95d8c0eec 100644
--- a/lib/kernel/src/inet_db.erl
+++ b/lib/kernel/src/inet_db.erl
@@ -773,11 +773,11 @@ gethostbyaddr(Domain, IP) ->
%% res_gethostbyaddr (newly resolved version)
%% match data field directly and cache RRs.
%%
-res_gethostbyaddr(Name, IP, Rec) ->
+res_gethostbyaddr(Domain, IP, Rec) ->
RRs = res_filter_rrs(?S_PTR, Rec#dns_rec.anlist),
?dbg("res_gethostbyaddr: ~p - ~p~n", [IP, RRs]),
LookupFun = res_lookup_fun(RRs),
- case resolve_cnames(Name, ?S_PTR, LookupFun) of
+ case resolve_cnames(Domain, ?S_PTR, LookupFun) of
{error, _} = Error ->
Error;
{_D, Domains, _Aliases} ->
@@ -791,31 +791,28 @@ res_gethostbyaddr(Name, IP, Rec) ->
end.
ent_gethostbyaddr([Domain], IP) ->
- {IP_1, AddrType, Length} = norm_ip(IP),
- H =
- #hostent{
- h_name = Domain,
- h_aliases = [],
- h_addr_list = [IP_1],
- h_addrtype = AddrType,
- h_length = Length },
- {ok, H};
+ HEnt =
+ if
+ tuple_size(IP) =:= 4 ->
+ #hostent{
+ h_name = Domain,
+ h_aliases = [],
+ h_addr_list = [IP],
+ h_addrtype = inet,
+ h_length = 4};
+ tuple_size(IP) =:= 8 ->
+ #hostent{
+ h_name = Domain,
+ h_aliases = [],
+ h_addr_list = [IP],
+ h_addrtype = inet6,
+ h_length = 16}
+ end,
+ {ok, HEnt};
ent_gethostbyaddr([_ | _] = _Domains, _IP) ->
?dbg("gethostbyaddr duplicate domains=~p~n", [_Domains]),
{error, nxdomain}.
-%% Normalize an IPv4-compatible IPv6 address
-%% into a plain IPv4 address
-%%
-norm_ip(IP) when tuple_size(IP) =:= 4 ->
- {IP, inet, 4};
-norm_ip({0,0,0,0,0,16#ffff,G,H}) ->
- A = G bsr 8, B = G band 16#ff, C = H bsr 8, D = H band 16#ff,
- {{A,B,C,D}, inet, 4};
-norm_ip(IP) when tuple_size(IP) =:= 8 ->
- {IP, inet6, 16}.
-
-
%%
%% Register socket Modules
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index f5ab7e6a23..fda656831e 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -363,7 +363,12 @@ gethostbyaddr_tm(Addr, Timer) when is_list(Addr) ->
_Error -> {error, formerr}
end;
gethostbyaddr_tm(IP, Timer) ->
- case dn_ip(IP) of
+ %% The call to norm_ip/1 here translates a lookup of
+ %% ::ffff:A.B.C.D (AAAA in ...ip6.arpa) into a plain
+ %% A.B.C.D (A in ...in-addr.arpa) lookup, and pretends
+ %% the result as if it was from the original IPv6 lookup
+ %%
+ case dn_ip(norm_ip(IP)) of
{error, _} = Error ->
Error;
Name ->
@@ -1203,6 +1208,15 @@ dn_hex(N, Tail) when is_integer(N) ->
[(N - 10) + $a, $. | Tail]
end.
+%% Normalize an IPv4-compatible IPv6 address
+%% into a plain IPv4 address
+%%
+norm_ip({0,0,0,0,0,16#ffff,G,H}) ->
+ A = G bsr 8, B = G band 16#ff, C = H bsr 8, D = H band 16#ff,
+ {A,B,C,D};
+norm_ip(IP) ->
+ IP.
+
dns_msg([]) -> [];
--
2.31.1