aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/net/name6.c
diff options
context:
space:
mode:
authorHajimu UMEMOTO <ume@FreeBSD.org>2005-04-02 08:18:33 +0000
committerHajimu UMEMOTO <ume@FreeBSD.org>2005-04-02 08:18:33 +0000
commit0fbf0979c809ae9ddfbc5169167f161daf49e52b (patch)
treeeef6c4f8529550d835e6fcd8a26343a986b5211d /lib/libc/net/name6.c
parentef6c77648aa5959b4eb0f7565294e87c014172c3 (diff)
downloadsrc-0fbf0979c809ae9ddfbc5169167f161daf49e52b.tar.gz
src-0fbf0979c809ae9ddfbc5169167f161daf49e52b.zip
nuke the logic for AF_UNSPEC and simplify. once, it was introduced
to improve getaddrinfo(3). but, it is not needed for a long time since getaddrinfo(3) became providing its own res_*N() functions.
Notes
Notes: svn path=/head/; revision=144527
Diffstat (limited to 'lib/libc/net/name6.c')
-rw-r--r--lib/libc/net/name6.c348
1 files changed, 47 insertions, 301 deletions
diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c
index 9d2ceb1ef22b..fb3e988ea57d 100644
--- a/lib/libc/net/name6.c
+++ b/lib/libc/net/name6.c
@@ -310,6 +310,8 @@ _ghbyname(const char *name, int af, int flags, int *errp)
if (flags & AI_ADDRCONFIG) {
int s;
+ if ((s = _socket(af, SOCK_DGRAM, 0)) < 0)
+ return NULL;
/*
* TODO:
* Note that implementation dependent test for address
@@ -317,23 +319,7 @@ _ghbyname(const char *name, int af, int flags, int *errp)
* (or apropriate interval),
* because addresses will be dynamically assigned or deleted.
*/
- 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 NULL;
- _close(s);
- }
+ _close(s);
}
rval = _nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyname", default_src,
@@ -341,19 +327,16 @@ _ghbyname(const char *name, int af, int flags, int *errp)
return (rval == NS_SUCCESS) ? hp : NULL;
}
-/* getipnodebyname() internal routine for multiple query(PF_UNSPEC) support. */
-static struct hostent *
-_getipnodebyname_multi(const char *name, int af, int flags, int *errp)
+struct hostent *
+getipnodebyname(const char *name, int af, int flags, int *errp)
{
struct hostent *hp;
union inx_addr addrbuf;
- /* XXX: PF_UNSPEC is only supposed to be passed from getaddrinfo() */
if (af != AF_INET
#ifdef INET6
&& af != AF_INET6
#endif
- && af != PF_UNSPEC
)
{
*errp = NO_RECOVERY;
@@ -405,21 +388,6 @@ _getipnodebyname_multi(const char *name, int af, int flags, int *errp)
}
struct hostent *
-getipnodebyname(const char *name, int af, int flags, int *errp)
-{
- if (af != AF_INET
-#ifdef INET6
- && af != AF_INET6
-#endif
- )
- {
- *errp = NO_RECOVERY;
- return NULL;
- }
- return(_getipnodebyname_multi(name, af ,flags, errp));
-}
-
-struct hostent *
getipnodebyaddr(const void *src, size_t len, int af, int *errp)
{
struct hostent *hp;
@@ -1320,7 +1288,6 @@ _files_ghbyname(void *rval, void *cb_data, va_list ap)
char *aliases[MAXALIASES + 1], *addrs[2];
union inx_addr addrbuf;
char buf[BUFSIZ];
- int af0;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
@@ -1332,7 +1299,6 @@ _files_ghbyname(void *rval, void *cb_data, va_list ap)
return NS_UNAVAIL;
rethp = hp = NULL;
- af0 = af;
while (fgets(buf, sizeof(buf), fp)) {
line = buf;
if ((addrstr = _hgetword(&line)) == NULL
@@ -1348,14 +1314,13 @@ _files_ghbyname(void *rval, void *cb_data, va_list ap)
}
if (!match)
continue;
- switch (af0) {
+ switch (af) {
case AF_INET:
if (inet_aton(addrstr, (struct in_addr *)&addrbuf)
!= 1) {
*errp = NO_DATA; /* name found */
continue;
}
- af = af0;
break;
#ifdef INET6
case AF_INET6:
@@ -1363,24 +1328,8 @@ _files_ghbyname(void *rval, void *cb_data, va_list ap)
*errp = NO_DATA; /* name found */
continue;
}
- af = af0;
break;
#endif
- case AF_UNSPEC:
- if (inet_aton(addrstr, (struct in_addr *)&addrbuf)
- == 1) {
- af = AF_INET;
- break;
- }
-#ifdef INET6
- if (inet_pton(AF_INET6, addrstr, &addrbuf) == 1) {
- af = AF_INET6;
- break;
- }
-#endif
- *errp = NO_DATA; /* name found */
- continue;
- /* NOTREACHED */
}
hp = &hpbuf;
hp->h_name = cname;
@@ -1472,9 +1421,7 @@ _nis_ghbyname(void *rval, void *cb_data, va_list ap)
name = va_arg(ap, const char *);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
-
- if (af == AF_UNSPEC)
- af = AF_INET;
+
if (af == AF_INET) {
THREAD_LOCK();
hp = _gethostbynisname(name, af);
@@ -1513,11 +1460,6 @@ _nis_ghbyaddr(void *rval, void *cb_data, va_list ap)
}
#endif
-struct __res_type_list {
- SLIST_ENTRY(__res_type_list) rtl_entry;
- int rtl_type;
-};
-
#define MAXPACKET (64*1024)
typedef union {
@@ -1801,259 +1743,63 @@ getanswer(answer, anslen, qname, qtype, template, errp)
#undef DNS_FATAL
}
-/* res_search() variant with multiple query support. */
-static struct hostent *
-_res_search_multi(name, rtl, errp)
- const char *name; /* domain name */
- struct __res_type_list *rtl; /* list of query types */
- int *errp;
-{
- const char *cp, * const *domain;
- struct hostent *hp0 = NULL, *hp;
- struct hostent hpbuf;
- u_int dots;
- int trailing_dot, ret, saved_herrno;
- int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
- struct __res_type_list *rtl0 = rtl;
- querybuf *buf;
-
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
- *errp = NETDB_INTERNAL;
- return (NULL);
- }
- dots = 0;
- for (cp = name; *cp; cp++)
- dots += (*cp == '.');
- trailing_dot = 0;
- if (cp > name && *--cp == '.')
- trailing_dot++;
-
- buf = malloc(sizeof(*buf));
- if (buf == NULL) {
- *errp = NETDB_INTERNAL;
- return NULL;
- }
-
- /* If there aren't any dots, it could be a user-level alias */
- if (!dots && (cp = hostalias(name)) != NULL) {
- for(rtl = rtl0; rtl != NULL;
- rtl = SLIST_NEXT(rtl, rtl_entry)) {
- ret = res_query(cp, C_IN, rtl->rtl_type, buf->buf,
- sizeof(buf->buf));
- if (ret > 0 && ret < sizeof(buf->buf)) {
- hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA)
- ? AF_INET6 : AF_INET;
- hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype);
- hp = getanswer(buf, ret, name, rtl->rtl_type,
- &hpbuf, errp);
- if (!hp)
- continue;
- hp = _hpcopy(&hpbuf, errp);
- hp0 = _hpmerge(hp0, hp, errp);
- } else
- *errp = h_errno;
- }
- free(buf);
- return (hp0);
- }
-
- /*
- * If there are dots in the name already, let's just give it a try
- * 'as is'. The threshold can be set with the "ndots" option.
- */
- saved_herrno = -1;
- if (dots >= _res.ndots) {
- for(rtl = rtl0; rtl != NULL;
- rtl = SLIST_NEXT(rtl, rtl_entry)) {
- ret = res_querydomain(name, NULL, C_IN, rtl->rtl_type,
- buf->buf, sizeof(buf->buf));
- if (ret > 0 && ret < sizeof(buf->buf)) {
- hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA)
- ? AF_INET6 : AF_INET;
- hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype);
- hp = getanswer(buf, ret, name, rtl->rtl_type,
- &hpbuf, errp);
- if (!hp)
- continue;
- hp = _hpcopy(&hpbuf, errp);
- hp0 = _hpmerge(hp0, hp, errp);
- } else
- *errp = h_errno;
- }
- if (hp0 != NULL) {
- free(buf);
- return (hp0);
- }
- saved_herrno = *errp;
- tried_as_is++;
- }
-
- /*
- * We do at least one level of search if
- * - there is no dot and RES_DEFNAME is set, or
- * - there is at least one dot, there is no trailing dot,
- * and RES_DNSRCH is set.
- */
- if ((!dots && (_res.options & RES_DEFNAMES)) ||
- (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
- int done = 0;
-
- for (domain = (const char * const *)_res.dnsrch;
- *domain && !done;
- domain++) {
-
- for(rtl = rtl0; rtl != NULL;
- rtl = SLIST_NEXT(rtl, rtl_entry)) {
- ret = res_querydomain(name, *domain, C_IN,
- rtl->rtl_type,
- buf->buf, sizeof(buf->buf));
- if (ret > 0 && ret < sizeof(buf->buf)) {
- hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA)
- ? AF_INET6 : AF_INET;
- hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype);
- hp = getanswer(buf, ret, name,
- rtl->rtl_type, &hpbuf, errp);
- if (!hp)
- continue;
- hp = _hpcopy(&hpbuf, errp);
- hp0 = _hpmerge(hp0, hp, errp);
- } else
- *errp = h_errno;
- }
- if (hp0 != NULL) {
- free(buf);
- return (hp0);
- }
-
- /*
- * If no server present, give up.
- * If name isn't found in this domain,
- * keep trying higher domains in the search list
- * (if that's enabled).
- * On a NO_DATA error, keep trying, otherwise
- * a wildcard entry of another type could keep us
- * from finding this entry higher in the domain.
- * If we get some other error (negative answer or
- * server failure), then stop searching up,
- * but try the input name below in case it's
- * fully-qualified.
- */
- if (errno == ECONNREFUSED) {
- free(buf);
- *errp = TRY_AGAIN;
- return (NULL);
- }
-
- switch (*errp) {
- case NO_DATA:
- got_nodata++;
- /* FALLTHROUGH */
- case HOST_NOT_FOUND:
- /* keep trying */
- break;
- case TRY_AGAIN:
- if (buf->hdr.rcode == SERVFAIL) {
- /* try next search element, if any */
- got_servfail++;
- break;
- }
- /* FALLTHROUGH */
- default:
- /* anything else implies that we're done */
- done++;
- }
-
- /* if we got here for some reason other than DNSRCH,
- * we only wanted one iteration of the loop, so stop.
- */
- if (!(_res.options & RES_DNSRCH))
- done++;
- }
- }
-
- /*
- * If we have not already tried the name "as is", do that now.
- * note that we do this regardless of how many dots were in the
- * name or whether it ends with a dot unless NOTLDQUERY is set.
- */
- if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
- for(rtl = rtl0; rtl != NULL;
- rtl = SLIST_NEXT(rtl, rtl_entry)) {
- ret = res_querydomain(name, NULL, C_IN, rtl->rtl_type,
- buf->buf, sizeof(buf->buf));
- if (ret > 0 && ret < sizeof(buf->buf)) {
- hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA)
- ? AF_INET6 : AF_INET;
- hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype);
- hp = getanswer(buf, ret, name, rtl->rtl_type,
- &hpbuf, errp);
- if (!hp)
- continue;
- hp = _hpcopy(&hpbuf, errp);
- hp0 = _hpmerge(hp0, hp, errp);
- } else
- *errp = h_errno;
- }
- if (hp0 != NULL) {
- free(buf);
- return (hp0);
- }
- }
-
- free(buf);
-
- /* if we got here, we didn't satisfy the search.
- * if we did an initial full query, return that query's h_errno
- * (note that we wouldn't be here if that query had succeeded).
- * else if we ever got a nodata, send that back as the reason.
- * else send back meaningless h_errno, that being the one from
- * the last DNSRCH we did.
- */
- if (saved_herrno != -1)
- *errp = saved_herrno;
- else if (got_nodata)
- *errp = NO_DATA;
- else if (got_servfail)
- *errp = TRY_AGAIN;
- return (NULL);
-}
-
static int
_dns_ghbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
int *errp;
- struct __res_type_list *rtl, rtl4;
-#ifdef INET6
- struct __res_type_list rtl6;
-#endif
+ int n;
+ struct hostent *hp;
+ int qtype;
+ struct hostent hbuf;
+ querybuf *buf;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
-#ifdef INET6
+ if ((_res.options & RES_INIT) == 0) {
+ if (res_init() < 0) {
+ *errp = h_errno;
+ return NS_UNAVAIL;
+ }
+ }
+ memset(&hbuf, 0, sizeof(hbuf));
+ hbuf.h_addrtype = af;
+ hbuf.h_length = ADDRLEN(af);
+
switch (af) {
- case AF_UNSPEC:
- SLIST_NEXT(&rtl4, rtl_entry) = NULL; rtl4.rtl_type = T_A;
- SLIST_NEXT(&rtl6, rtl_entry) = &rtl4; rtl6.rtl_type = T_AAAA;
- rtl = &rtl6;
- break;
+#ifdef INET6
case AF_INET6:
- SLIST_NEXT(&rtl6, rtl_entry) = NULL; rtl6.rtl_type = T_AAAA;
- rtl = &rtl6;
+ qtype = T_AAAA;
break;
+#endif
case AF_INET:
- SLIST_NEXT(&rtl4, rtl_entry) = NULL; rtl4.rtl_type = T_A;
- rtl = &rtl4;
+ qtype = T_A;
break;
+ default:
+ *errp = NO_RECOVERY;
+ return NS_NOTFOUND;
}
-#else
- SLIST_NEXT(&rtl4, rtl_entry) = NULL; rtl4.rtl_type = T_A;
- rtl = &rtl4;
-#endif
- *(struct hostent **)rval = _res_search_multi(name, rtl, errp);
+ buf = malloc(sizeof(*buf));
+ if (buf == NULL) {
+ *errp = NETDB_INTERNAL;
+ return NS_UNAVAIL;
+ }
+ n = res_search(name, C_IN, qtype, buf->buf, sizeof(buf->buf));
+ if (n < 0) {
+ free(buf);
+ *errp = h_errno;
+ return NS_UNAVAIL;
+ }
+ hp = getanswer(buf, n, name, qtype, &hbuf, errp);
+ free(buf);
+ if (!hp) {
+ *errp = NO_RECOVERY;
+ return NS_NOTFOUND;
+ }
+ *(struct hostent **)rval = _hpcopy(&hbuf, errp);
if (*(struct hostent **)rval != NULL)
return NS_SUCCESS;
else if (*errp == TRY_AGAIN)