NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: standards/44777: NetBSD lacks AI_ADDRCONFIG



The following reply was made to PR standards/44777; it has been noted by GNATS.

From: Pierre Pronchery <khorben%defora.org@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: standards/44777: NetBSD lacks AI_ADDRCONFIG
Date: Tue, 03 Apr 2012 20:18:49 +0200

 This is a multi-part message in MIME format.
 --------------090007060304070409040308
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 
                        Hi everyone,
 
 I've been stumbling on this issue as well, as building bitcoin (at least
 from git) requires AI_ADDRCONFIG to be set. It feels a bit sensitive to
 me, as there seems to be some gray area about how this value should be
 interpreted.
 
 From lib/libc/net/getaddrinfo.c:
 > 50  * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
 > 51  *   (1) what should we do against numeric hostname (2) what should we do
 > 52  *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not 
 > ready?
 > 53  *   non-loopback address configured?  global address configured?
 
 I have had a look at how FreeBSD solved this and adapted their patch.
 They have implemented AI_ADDRCONFIG (and added the other missing
 definitions) but left this comment in this same file as well.
 
 Please find the relevant patch attached here. However, I am not offering
 a fix to the underlying issue, or not even implementing RFC 2553, so
 this bug should be left opened regardless. Plus, I admit to have not
 checked for the correctness of this implementation.
 
 In any case, I could build bitcoin with this patch, and it would be
 great to get it pulled-up into the netbsd-6 branch if at all accepted.
 
 Cheers,
 -- 
 khorben
 
 --------------090007060304070409040308
 Content-Type: text/plain;
  name="patch-ai_addrinfo.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="patch-ai_addrinfo.diff"
 
 Index: include/netdb.h
 ===================================================================
 RCS file: /cvsroot/src/include/netdb.h,v
 retrieving revision 1.64
 diff -p -u -r1.64 netdb.h
 --- include/netdb.h    5 May 2010 17:12:29 -0000       1.64
 +++ include/netdb.h    3 Apr 2012 17:56:18 -0000
 @@ -272,6 +272,13 @@ struct addrinfo {
      (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV)
  #endif
  
 +#define       AI_ALL          0x00000100 /* IPv6 and IPv4-mapped (with 
AI_V4MAPPED) */
 +#define       AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel 
supports */
 +#define       AI_ADDRCONFIG   0x00000400 /* only if any address is assigned */
 +#define       AI_V4MAPPED     0x00000800 /* accept IPv4-mapped IPv6 address */
 +/* special recommended flags for getipnodebyname */
 +#define       AI_DEFAULT      (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
 +
  #if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \
      defined(_NETBSD_SOURCE)
  /*%
 Index: lib/libc/net/getaddrinfo.c
 ===================================================================
 RCS file: /cvsroot/src/lib/libc/net/getaddrinfo.c,v
 retrieving revision 1.96
 diff -p -u -r1.96 getaddrinfo.c
 --- lib/libc/net/getaddrinfo.c 15 Oct 2011 23:00:02 -0000      1.96
 +++ lib/libc/net/getaddrinfo.c 3 Apr 2012 17:56:24 -0000
 @@ -208,6 +208,7 @@ static int get_portmatch(const struct ad
  static int get_port(const struct addrinfo *, const char *, int,
      struct servent_data *);
  static const struct afd *find_afd(int);
 +static int addrconfig(struct addrinfo *);
  #ifdef INET6
  static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
  #endif
 @@ -367,7 +368,7 @@ getaddrinfo(const char *hostname, const 
        pai->ai_canonname = NULL;
        pai->ai_addr = NULL;
        pai->ai_next = NULL;
 -      
 +
        if (hostname == NULL && servname == NULL)
                return EAI_NONAME;
        if (hints) {
 @@ -486,6 +487,9 @@ getaddrinfo(const char *hostname, const 
        if (pai->ai_flags & AI_NUMERICHOST)
                ERR(EAI_NONAME);
  
 +      if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0))
 +              ERR(EAI_FAIL);
 +
        /*
         * hostname as alphabetical name.
         * we would like to prefer AF_INET6 than AF_INET, so we'll make a
 @@ -1006,6 +1010,48 @@ find_afd(int af)
        return NULL;
  }
  
 +/*
 + * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
 + * will take care of it.
 + * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
 + * if the code is right or not.
 + *
 + * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with
 + * _dns_getaddrinfo.
 + */
 +static int
 +addrconfig(struct addrinfo *pai)
 +{
 +      int s, af;
 +
 +      /*
 +       * TODO:
 +       * Note that implementation dependent test for address
 +       * configuration should be done everytime called
 +       * (or apropriate interval),
 +       * because addresses will be dynamically assigned or deleted.
 +       */
 +      af = pai->ai_family;
 +      if (af == AF_UNSPEC) {
 +              if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
 +                      af = AF_INET;
 +              else {
 +                      close(s);
 +                      if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 +                              af = AF_INET6;
 +                      else
 +                              close(s);
 +              }
 +      }
 +      if (af != AF_UNSPEC) {
 +              if ((s = socket(af, SOCK_DGRAM, 0)) < 0)
 +                      return 0;
 +              close(s);
 +      }
 +      pai->ai_family = af;
 +      return 1;
 +}
 +
  #ifdef INET6
  /* convert a string to a scope identifier. XXX: IPv6 specific */
  static int
 
 --------------090007060304070409040308--
 


Home | Main Index | Thread Index | Old Index