Bug 192168

Summary: resolver cannot use link-local IPV6 servers
Product: Base System Reporter: clint
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: New ---    
Severity: Affects Some People CC: ae, clint, des, slw
Priority: ---    
Version: 10.0-STABLE   
Hardware: Any   
OS: Any   

Description clint 2014-07-27 15:45:22 UTC
Resolver works inconsistently with a link-local address in resolv.conf.

If using a link local address with an interface index, no queries for hosts work. To reproduce:
1) Use a Link-Local address with interface identifier in /etc/resolv.conf, for example:  fe80::1:1%em0

Expected Results: You should be able to resolve host names if a dns server is listening on this address. You can confirm that this address can resolve names using dig @fe80::1:1%em0 google.com. But using host

Actual Results: The host command times out and trying to ping hosts not in cache fails because names cannot be resolved. You can confirm that this address can resolve hosts by using dig @fe80::1:1%em0 google.com. However, a similar test with the host command fails doing host google.com fe80::1:1%em0.

An attempted workaround is to use a Link-Local address using the in-kernel syntax for identifying an interface. For example: fe80:3::1:1

This results in being able to resolve hosts with the host command. The dig command does not work and reports a reply from an unexpected source as the reply has a source address of fe80::1:1%em0. However, new hosts still cannot be resolved for normal system operations like ping6. Only the host command succeeds.
Comment 1 Andrey V. Elsukov freebsd_committer freebsd_triage 2015-05-26 14:20:29 UTC
The drill(1) command also doesn't support IPv6 LLA for @server.
As I see, ldns_str2rdf_aaaa() function uses inet_pton(3) function to convert IPv6 address from string into uint8_t[] representation. It should use getaddrinfo(3) function, which supports scope zone ids. 

The problem is that libdns doesn't use sockaddr_in6 structure (where sin6_scope_id field used to store zone id) and it looks isn't easy to convert ldns_str2rdf_aaaa() to use it.