GLIBC's name service switch doesn't provide a way to override getaddressinfo() which is the only function that supports IPv6 link-local addresses. IPv6 link-local addresses don't work without the interface name (when written as text) that then translates to scope id. http://tools.ietf.org/html/rfc2553 glibc-2.15-37.fc17.x86_64
Fedora bug: https://bugzilla.redhat.com/show_bug.cgi?id=843054 This is actually needed for link-local name resolution (whatever NSS plugin is used for it then).
There's another usecase for getaddrinfo() in nsswitch and that is avoiding problems caused by solutions to bug 12377 including bug 12398. See discussions in these two bug reports.
Hi, Pavel, I assume you're speaking of such addresses as ipv6%zone, as specified in RFC 4007. That RFC only specifies (hex) numeric addresses in standard ipv6 format, folowed by a % and a zone id, that may be numeric, an interface name, or somesuch. Since the address can only be numeric, without involving any lookups, and that and zone ids specified in that RFC are supported by existing getaddrinfo core implementation, what would the point be of introducing a getaddrinfo interface in the nss plugin interface?
Hi Alexandre, 1) scope_id There are name services that are capable of returning IPv6 link local addresses such as Multicast DNS. Those IPv6 link local addresses don't work as expected, though, as they miss the scope_id. 2) AI_ADDRCONFIG There are name resolution protocols that should avoid querying for IPv4/IPv6 data according to the system configuration when AI_ADDRCONFIG is set. On the other hand, for literal address translations, Multicast DNS and /etc/hosts, this is counter-productive, see the linked bug reports. 3) __nss_gethostbyname* The gethostbyname4 features are not superset of gethostbyname3 features which means the API is not satisfactory whichever of them is used.
Hello, I can confirm that this bug is still present. IPv6 link local addresses (fe80::/64) only work when coupled with sockaddr_in6.sin6_scope_id (some interface number). Since gethostent only returns the address (through hostent.h_addr_list), then all IPv6 link local addresses are returned in an incomplete way and so are broken. This is why mdns does not work in linux with link local addresses. Comparing with MacOS, getaddrinfo() seems to be implemented by the nss plugin, so executing ssh -6 host.local works. In linux, executing ssh -6 host.local does not work.
We need to redesign the NSS interface anyway, but I'd prefer if we had the NSS modules allocate the required memory, after bug 19591 is fixed.
Fixing bug 19591 is not necessary if we add a function to the NSS module which frees the allocated data structures.
Confirming that this issue still exists as of 2.31. ssh -v host.local works: OpenSSH_8.2p1, OpenSSL 1.1.1f 31 Mar 2020 debug1: Reading configuration data /home/gavin/.ssh/config debug1: Reading configuration data /etc/ssh/ssh_config debug1: Connecting to host.local [fe80::88aa:55ff:fec5:dd9%wlan0] port 22. debug1: Connection established. ssh -v -6 host.local does not work: OpenSSH_8.2p1, OpenSSL 1.1.1f 31 Mar 2020 debug1: Reading configuration data /home/gavin/.ssh/config debug1: Reading configuration data /etc/ssh/ssh_config debug1: Connecting to host.local [fe80::88aa:55ff:fec5:dd9] port 22. debug1: connect to address fe80::88aa:55ff:fec5:dd9 port 22: Invalid argument The first case calls get getaddrinfo() with hints->ai_family=AF_UNSPEC, the second case calls it with hints->ai_family=AF_INET6. As a workaround until gethostbyname5 comes along, would it make sense to modify gethostbyname3 such that it stuffs a whole sockaddr_in6 into h_addr, sets h_length to sizeof(sockaddr_in6), and glibc can take care of it accordingly depending on the value of h_length?