On Sun, Dec 20, 2020 at 10:48:01AM +0100, Florian Obser wrote:

> On Thu, Dec 17, 2020 at 12:15:16PM +0100, Otto Moerbeek wrote:
> > Hi,
> 
> > 
> > as noted on misc dig does not like to talk to local link addresses.
> > This fixes that case. While investigating I also found another bug:
> 
> Thanks for looking into this. Looks like I got distracted while
> ripping out isc_sockaddr and did not fully clean it up. Probably
> because I found another isc_indirection to delete :/
> 
> I'd rather like to get rid of isc_sockaddr_fromin* completely, see
> diff at the end.
> 
> > selecting v6 or v4 addresses only from resolv.conf via the -4 or -6
> > command line argument does not work as expected.
> 
> Nice catch.
> 
> > 
> > This fixes both. I did not test binding to a src address with this.
> > This is likely as broken as it was before.
> 
> My diff fixes that, too.
> 
> I still need to keep isc_sockaddr_fromin* because it's used for
> +subnet i.e. ecs. Which is broken, too. I'm having a look now.
> 
> > 
> >     -Otto
> > 
> 
> > 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))) {
> > 
> 
> OK florian for this

Committed

> 
> OK for this version for the rest?

A few nits inline. With those either addressed or ignored, OK,

        -Otto
> 
> 
> diff --git dig.c dig.c
> index a0988a0567b..6b142a03239 100644
> --- dig.c
> +++ dig.c
> @@ -17,7 +17,10 @@
>  /* $Id: dig.c,v 1.18 2020/09/15 11:47:42 florian Exp $ */
>  
>  /*! \file */
> -#include <sys/cdefs.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +
> +#include <netdb.h>
>  
>  #include <errno.h>
>  #include <stdlib.h>
> @@ -1275,10 +1278,7 @@ dash_option(char *option, char *next, dig_lookup_t 
> **lookup,
>       dns_rdatatype_t rdtype;
>       dns_rdataclass_t rdclass;
>       char textname[MXNAME];
> -     struct in_addr in4;
> -     struct in6_addr in6;
> -     in_port_t srcport;
> -     char *hash, *cmd;
> +     char *cmd;
>       uint32_t num;
>       const char *errstr;
>  
> @@ -1346,28 +1346,39 @@ dash_option(char *option, char *next, dig_lookup_t 
> **lookup,
>       if (value == NULL)
>               goto invalid_option;
>       switch (opt) {
> -     case 'b':
> +     case 'b': {
> +             struct addrinfo *ai = NULL, hints;
> +             int error;
> +             char *hash;
> +
> +             memset(&hints, 0, sizeof(hints));
> +             hints.ai_flags = AI_NUMERICHOST;
> +             hints.ai_socktype = SOCK_STREAM;

It does not realy matter for the rsult, but SOCK_DGRAM feels more
natural for DNS.

> +
>               hash = strchr(value, '#');
>               if (hash != NULL) {
> -                     num = strtonum(hash + 1, 0, MAXPORT, &errstr);
> -                     if (errstr != NULL)
> -                             fatal("port number is %s: '%s'", errstr,
> -                                 hash + 1);
> -                     srcport = num;
>                       *hash = '\0';
> +                     error = getaddrinfo(value, hash + 1, &hints, &ai);
> +                     *hash = '#';
>               } else
> -                     srcport = 0;
> -             if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1)
> -                     isc_sockaddr_fromin6(&bind_address, &in6, srcport);
> -             else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1)
> -                     isc_sockaddr_fromin(&bind_address, &in4, srcport);
> -             else
> +                     error = getaddrinfo(value, NULL, &hints, &ai);
> +
> +             if (error)
> +                     fatal("invalid address %s: %s", value,
> +                         gai_strerror(error));
> +             if (ai == NULL || ai->ai_addrlen > sizeof(bind_address))
> +                     fatal("invalid address %s", value);
> +             if (!have_ipv4 && ai->ai_family == AF_INET)
> +                     fatal("invalid address %s", value);

Please be more specific, like "%s: wrong address family"

> +             if (!have_ipv6 && ai->ai_family == AF_INET6)
>                       fatal("invalid address %s", value);

Same here
>  
> -             if (hash != NULL)
> -                     *hash = '#';
> +             memset(&bind_address, 0, sizeof(bind_address));
> +             memcpy(&bind_address, ai->ai_addr, ai->ai_addrlen);
> +
>               specified_source = 1;
>               return (value_from_next);
> +     }
>       case 'c':
>               if ((*lookup)->rdclassset) {
>                       fprintf(stderr, ";; Warning, extra class option\n");
> diff --git dighost.c dighost.c
> index 52afde3d7d3..3974843600d 100644
> --- dighost.c
> +++ dighost.c
> @@ -498,6 +498,7 @@ get_addresses(const char *hostname, in_port_t dstport,
>  {
>       struct addrinfo *ai = NULL, *tmpai, hints;
>       int result, i;
> +     char dport[sizeof("65535")];
>  
>       REQUIRE(hostname != NULL);
>       REQUIRE(addrs != NULL);
> @@ -515,7 +516,8 @@ get_addresses(const char *hostname, in_port_t dstport,
>       }
>       hints.ai_socktype = SOCK_STREAM;
>  
> -     result = getaddrinfo(hostname, NULL, &hints, &ai);
> +     snprintf(dport, sizeof(dport), "%d", dstport);
> +     result = getaddrinfo(hostname, dport, &hints, &ai);
>       switch (result) {
>       case 0:
>               break;
> @@ -532,16 +534,10 @@ get_addresses(const char *hostname, in_port_t dstport,
>               if (tmpai->ai_family != AF_INET &&
>                   tmpai->ai_family != AF_INET6)
>                       continue;
> -             if (tmpai->ai_family == AF_INET) {
> -                     struct sockaddr_in *sin;
> -                     sin = (struct sockaddr_in *)tmpai->ai_addr;
> -                     isc_sockaddr_fromin(&addrs[i], &sin->sin_addr, dstport);
> -             } else {
> -                     struct sockaddr_in6 *sin6;
> -                     sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
> -                     isc_sockaddr_fromin6(&addrs[i], &sin6->sin6_addr,
> -                                          dstport);
> -             }
> +             if (tmpai->ai_addrlen > sizeof(addrs[i]))
> +                     continue;
> +             memset(&addrs[i], 0, sizeof(addrs[i]));
> +             memcpy(&addrs[i], tmpai->ai_addr, tmpai->ai_addrlen);
>               i++;
>  
>       }
> 
> 
> -- 
> I'm not entirely sure you are real.

Reply via email to