libc/getnameinfo: stop adding NI_NUMERICHOST where inappropriate

Checking the first nibble of the IPv6 address to be 0 and then
excluding two well known cases (v4-mapped, loopback) leaves us with
more cases where the first nibble could be 0, e.g., the RFC 6052,
2.1 Well-Known Prefix 64:ff9b::/96.
It is not practical to track them all and it is not clear what lead
to this special casing originally, so remove them.

While here also remove the IN6_IS_ADDR_LINKLOCAL() + NI_NUMERICHOST
case as link-local address resolution does exist.

We do leave the IN6_IS_ADDR_MULTICAST() case for now as I could
not find any references to any official reverse lookups for these.

Adding comments for more case (and some historic behaviour) in order
to make it easier to follow the logic.

PR:		279618
Fixes:		6cb9418289
Reviewed by:	hrs
Differential Revision: https://reviews.freebsd.org/D45547

(cherry picked from commit c179937b98)
This commit is contained in:
Bjoern A. Zeeb 2024-06-10 11:34:25 +00:00
parent edf4f6a6ec
commit ff26fd77ee

View file

@ -229,24 +229,44 @@ getnameinfo_inet(const struct afd *afd,
case AF_INET6:
{
const struct sockaddr_in6 *sin6;
sin6 = (const struct sockaddr_in6 *)sa;
switch (sin6->sin6_addr.s6_addr[0]) {
case 0x00:
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
;
else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
;
else
flags |= NI_NUMERICHOST;
break;
default:
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
flags |= NI_NUMERICHOST;
}
else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
flags |= NI_NUMERICHOST;
break;
}
/*
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/getnameinfo.html
* "[IP6] [Option Start] If the socket address structure
* contains an IPv4-mapped IPv6 address or an IPv4-compatible
* IPv6 address, the implementation shall extract the embedded
* IPv4 address and lookup the node name for that IPv4 address.
* [Option End]"
* => getipnodebyaddr() handles this case for us.
* => in case of NI_NUMERICHOST being set, inet_ntop[6] will
* handle it too.
*
* "If the address is the IPv6 unspecified address ( "::" ),
* a lookup shall not be performed and the behavior shall be
* the same as when the node's name cannot be located."
* => getipnodebyaddr() handles this case for us.
* => in case of NI_NUMERICHOST being set,
* ip6_parsenumeric() -> inet_ntop[6] will handle it too.
*/
/*
* We used to exclude link-local from lookups.
* Even though calles in the resolver chain may not (yet)
* properly deal with them, we no longer do as for link-local
* there is a path to resolve these. See:
* RFC 6303 4.5. IPv6 Link-Local Addresses
* RFC 6762 4. Reverse Address Mapping
*
* XXX For IPv6 MC the only reference found was
* https://www.ietf.org/archive/id/draft-michaelson-as112-ipv6-02.html
* but there are also no "empty zone"s for x.0.f.f.ip6.arpa
* in DNS servers. Keep catching it here for now and
* do not attempt name resolution but return the address string.
*/
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
flags |= NI_NUMERICHOST;
}
break;
#endif