1
It seems that glibc's resolver does not support IPv6 link-local
2
addresses with an explicit scope (like fe80::[...]%eth0), in the
3
nameserver options in /etc/resolv.conf. Currently, nameservers with a
4
scope fail to be parsed. Nameservers with a link-local address (without
5
scope) are parsed and used, but obviously do not work (connect() fails
6
with EINVAL because a sin6_scope_id of 0 is used with the link-local
9
With the apparition of the new RDNSS option (RFC5006), which allows
10
for DNS configuration through stateless autoconf, we expect that IPv6
11
link-local resolvers may be used, and set into /etc/resolv.conf.
12
Kernel-side support is included in Linux 2.6.24, and the corresponding
13
userland RDNSS daemon is currently under development and will be shipped
14
in the next release of the ndisc6 package. We would need glibc to
15
support this feature to integrate our work.
17
Please review this patch, and consider it for application and submission
20
--- resolv/res_init.c 2007-12-09 17:30:57.000000000 +0100
21
+++ resolv/res_init.c 2007-12-09 18:19:40.000000000 +0100
22
@@ -74,11 +74,14 @@ static const char rcsid[] = "$BINDId: re
23
#include <sys/socket.h>
27
#include <netinet/in.h>
28
#include <arpa/inet.h>
29
#include <arpa/nameser.h>
36
#include <stdio_ext.h>
37
@@ -327,6 +330,8 @@ __res_vinit(res_state statp, int preinit
39
if ((el = strchr(cp, '\n')) != NULL)
41
+ if ((el = strchr(cp, SCOPE_DELIMITER)) != NULL)
44
(inet_pton(AF_INET6, cp, &a6) > 0)) {
45
struct sockaddr_in6 *sa6;
46
@@ -336,6 +341,27 @@ __res_vinit(res_state statp, int preinit
48
sa6->sin6_family = AF_INET6;
49
sa6->sin6_port = htons(NAMESERVER_PORT);
52
+ int try_numericscope = 0;
53
+ if (IN6_IS_ADDR_LINKLOCAL(&a6)
54
+ || IN6_IS_ADDR_MC_LINKLOCAL(&a6)) {
55
+ sa6->sin6_scope_id = if_nametoindex(el + 1);
56
+ if (sa6->sin6_scope_id == 0)
57
+ try_numericscope = 1;
59
+ try_numericscope = 1;
61
+ if (try_numericscope != 0) {
63
+ assert(sizeof(uint32_t) <= sizeof(unsigned long));
64
+ sa6->sin6_scope_id = (uint32_t) strtoul(el + 1, &end, 10);
66
+ sa6->sin6_scope_id = 0;
69
+ sa6->sin6_scope_id = 0;
71
statp->_u._ext.nsaddrs[nservall] = sa6;
72
statp->_u._ext.nssocks[nservall] = -1;
73
statp->_u._ext.nsmap[nservall] = MAXNS + 1;