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