On Thu, Dec 17, 2020 at 11:10:59AM +0100, Otto Moerbeek wrote:

> On Thu, Dec 17, 2020 at 12:27:00AM -0800, Jordan Geoghegan wrote:
> 
> > 
> > 
> > On 12/16/20 11:19 PM, Otto Moerbeek wrote:
> > > On Wed, Dec 16, 2020 at 02:37:19PM -0800, Jordan Geoghegan wrote:
> > > 
> > > > Hi folks,
> > > > 
> > > > I've found some surprising behaviour in the 'dig' utility. I've noticed 
> > > > that
> > > > dig doesn't seem to support link local IPv6 addresses. I've got unbound
> > > > listening on a link local IPv6 address on my router and all queries 
> > > > seem to
> > > > be working. I'm advertising this DNS info with rad, and I confirmed with
> > > > tcpdump that my devices such as iPhones, Macs, Windows, Linux desktops 
> > > > etc
> > > > are all properly querying my unbound server over IPv6.
> > > > 
> > > > dhclient doesn't seem to allow you to specify an IPv6 address in it's
> > > > 'supersede'  options, so I manually edited my OpenBSD desktops 
> > > > resolv.conf
> > > > to specify the IPv6 unbound server first. Again, I confirmed with 
> > > > tcpdump
> > > > that my desktop was properly querying the unbound server over IPv6 (ie
> > > > Firefox, ping, ssh etc all resolved domains using this server).
> > > > 
> > > > I used 'dig' to make a query, and I noticed it was ignoring my link 
> > > > local
> > > > IPv6 nameserver in my resolv.conf. I'll save you guys the long form Ted 
> > > > talk
> > > > here and just make my point:
> > > > 
> > > > $ cat resolv.conf
> > > >     nameserver fe80::f29f:c2ff:fe17:b8b2%em0
> > > >     nameserver 2606:4700:4700::1111
> > > >     lookup file bind
> > > >     family inet6 inet4
> > > > 
> > > > $ dig google.ca
> > > >     [snip]
> > > >     ;; Query time: 12 msec
> > > >     ;; SERVER: 2606:4700:4700::1111#53(2606:4700:4700::1111)
> > > >     [snip]
> > > > 
> > > > There's a bit of a delay as it waits for a time out, and then it falls 
> > > > back
> > > > to the cloudflare IPv6 server.
> > > > 
> > > > I tried specifying the server with '@' as well as specifying source
> > > > IP/interface with '-I' to no avail. It seems dig really doesn't like the
> > > > 'fe80::%em0' notation, as  '@' and '-I' worked fine when used without a
> > > > link-local address.
> > > > 
> > > > Is this a bug or a feature? Am I just doing something stupid? Any 
> > > > insight
> > > > would be appreciated.
> > > I think it is a bug and I can reproduce. Will invesigate deeper later.
> > > 
> > >   -Otto
> > > 
> > 
> > Hi Otto,
> > 
> > Thanks for looking into this! I took Bodie's advice and tested nslookup and
> > host, and they both seem to have the same behaviour as dig.
> > 
> > Regards,
> > 
> > Jordan
> > 
> 
> That is no big surprise, as they are essentially the same program
> with a different user interface, all built from the same source.
> 
>       -Otto
> 

Fix below, further discussion on tech@

        -Otto

Index: dig.c
===================================================================
RCS file: /cvs/src/usr.bin/dig/dig.c,v
retrieving revision 1.18
diff -u -p -r1.18 dig.c
--- dig.c       15 Sep 2020 11:47:42 -0000      1.18
+++ dig.c       17 Dec 2020 11:06:49 -0000
@@ -1358,7 +1358,7 @@ dash_option(char *option, char *next, di
                } else
                        srcport = 0;
                if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1)
-                       isc_sockaddr_fromin6(&bind_address, &in6, srcport);
+                       isc_sockaddr_fromin6(&bind_address, &in6, srcport, 0);
                else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1)
                        isc_sockaddr_fromin(&bind_address, &in4, srcport);
                else
Index: dighost.c
===================================================================
RCS file: /cvs/src/usr.bin/dig/dighost.c,v
retrieving revision 1.34
diff -u -p -r1.34 dighost.c
--- dighost.c   15 Sep 2020 11:47:42 -0000      1.34
+++ dighost.c   17 Dec 2020 11:06:49 -0000
@@ -540,7 +540,7 @@ get_addresses(const char *hostname, in_p
                        struct sockaddr_in6 *sin6;
                        sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
                        isc_sockaddr_fromin6(&addrs[i], &sin6->sin6_addr,
-                                            dstport);
+                                            dstport, sin6->sin6_scope_id);
                }
                i++;
 
@@ -972,7 +972,7 @@ parse_netprefix(struct sockaddr_storage 
 
        if (inet_pton(AF_INET6, buf, &in6) == 1) {
                parsed = 1;
-               isc_sockaddr_fromin6(sa, &in6, 0);
+               isc_sockaddr_fromin6(sa, &in6, 0, 0);
                if (prefix_length > 128)
                        prefix_length = 128;
        } else if (inet_pton(AF_INET, buf, &in4) == 1) {
Index: lib/isc/sockaddr.c
===================================================================
RCS file: /cvs/src/usr.bin/dig/lib/isc/sockaddr.c,v
retrieving revision 1.14
diff -u -p -r1.14 sockaddr.c
--- lib/isc/sockaddr.c  28 Nov 2020 06:33:55 -0000      1.14
+++ lib/isc/sockaddr.c  17 Dec 2020 11:06:49 -0000
@@ -223,7 +223,7 @@ isc_sockaddr_anyofpf(struct sockaddr_sto
 
 void
 isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const struct in6_addr 
*ina6,
-                    in_port_t port)
+                    in_port_t port, uint32_t scope)
 {
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sockaddr;
        memset(sockaddr, 0, sizeof(*sockaddr));
@@ -231,6 +231,7 @@ isc_sockaddr_fromin6(struct sockaddr_sto
        sin6->sin6_len = sizeof(*sin6);
        sin6->sin6_addr = *ina6;
        sin6->sin6_port = htons(port);
+       sin6->sin6_scope_id = scope;
 }
 
 int
Index: lib/isc/include/isc/sockaddr.h
===================================================================
RCS file: /cvs/src/usr.bin/dig/lib/isc/include/isc/sockaddr.h,v
retrieving revision 1.7
diff -u -p -r1.7 sockaddr.h
--- lib/isc/include/isc/sockaddr.h      15 Sep 2020 11:47:42 -0000      1.7
+++ lib/isc/include/isc/sockaddr.h      17 Dec 2020 11:06:49 -0000
@@ -91,7 +91,7 @@ isc_sockaddr_fromin(struct sockaddr_stor
 
 void
 isc_sockaddr_fromin6(struct sockaddr_storage *sockaddr, const struct in6_addr 
*ina6,
-                    in_port_t port);
+                    in_port_t port, uint32_t scope);
 /*%<
  * Construct an struct sockaddr_storage from an IPv6 address and port.
  */
Index: lib/lwres/lwconfig.c
===================================================================
RCS file: /cvs/src/usr.bin/dig/lib/lwres/lwconfig.c,v
retrieving revision 1.6
diff -u -p -r1.6 lwconfig.c
--- lib/lwres/lwconfig.c        25 Feb 2020 05:00:43 -0000      1.6
+++ lib/lwres/lwconfig.c        17 Dec 2020 11:06:49 -0000
@@ -231,7 +231,7 @@ lwres_conf_parsenameserver(lwres_conf_t 
 
        res = lwres_create_addr(word, &address, 1);
        use_ipv4 = confdata->flags & LWRES_USEIPV4;
-       use_ipv6 = confdata->flags & LWRES_USEIPV4;
+       use_ipv6 = confdata->flags & LWRES_USEIPV6;
        if (res == LWRES_R_SUCCESS &&
            ((address.family == LWRES_ADDRTYPE_V4 && use_ipv4) ||
            (address.family == LWRES_ADDRTYPE_V6 && use_ipv6))) {

Reply via email to