Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc Rest of fix for PR#31184: getaddrinfo() now honors ...
details: https://anonhg.NetBSD.org/src/rev/18ad9f7c21be
branches: trunk
changeset: 584414:18ad9f7c21be
user: tsarna <tsarna%NetBSD.org@localhost>
date: Thu Sep 15 23:33:41 2005 +0000
description:
Rest of fix for PR#31184: getaddrinfo() now honors resolv.conf sortlist
directive for dns answers.
Also, unifdef the RESLVSORT (non-)option sillyness.
Reviewed by christos.
diffstat:
lib/libc/net/getaddrinfo.c | 83 +++++++++++++++++++++++++++++++++------------
lib/libc/net/gethnamaddr.c | 11 +----
lib/libc/resolv/res_init.c | 17 +--------
3 files changed, 64 insertions(+), 47 deletions(-)
diffs (truncated from 372 to 300 lines):
diff -r 70ab3ba883f0 -r 18ad9f7c21be lib/libc/net/getaddrinfo.c
--- a/lib/libc/net/getaddrinfo.c Thu Sep 15 22:49:33 2005 +0000
+++ b/lib/libc/net/getaddrinfo.c Thu Sep 15 23:33:41 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: getaddrinfo.c,v 1.72 2004/05/27 18:40:07 christos Exp $ */
+/* $NetBSD: getaddrinfo.c,v 1.73 2005/09/15 23:33:41 tsarna Exp $ */
/* $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */
/*
@@ -79,7 +79,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: getaddrinfo.c,v 1.72 2004/05/27 18:40:07 christos Exp $");
+__RCSID("$NetBSD: getaddrinfo.c,v 1.73 2005/09/15 23:33:41 tsarna Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@@ -234,6 +234,7 @@
static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
const struct addrinfo *);
+static void aisort(struct addrinfo *s, res_state res);
static int _dns_getaddrinfo(void *, void *, va_list);
static void _sethtent(FILE **);
static void _endhtent(FILE **);
@@ -246,7 +247,7 @@
#endif
static int res_queryN(const char *, struct res_target *, res_state);
-static int res_searchN(const char *, struct res_target *);
+static int res_searchN(const char *, struct res_target *, res_state);
static int res_querydomainN(const char *, const char *,
struct res_target *, res_state);
@@ -1241,6 +1242,37 @@
return NULL;
}
+#define SORTEDADDR(p) (((struct sockaddr_in *)(void *)(p->ai_next->ai_addr))->sin_addr.s_addr)
+#define SORTMATCH(p, s) ((SORTEDADDR(p) & (s).mask) == (s).addr.s_addr)
+
+static void
+aisort(struct addrinfo *s, res_state res)
+{
+ struct addrinfo head, *t, *p;
+ int i;
+
+ head.ai_next = NULL;
+ t = &head;
+
+ for (i = 0; i < res->nsort; i++) {
+ p = s;
+ while (p->ai_next) {
+ if ((p->ai_next->ai_family != AF_INET)
+ || SORTMATCH(p, res->sort_list[i])) {
+ t->ai_next = p->ai_next;
+ t = t->ai_next;
+ p->ai_next = p->ai_next->ai_next;
+ } else {
+ p = p->ai_next;
+ }
+ }
+ }
+
+ /* add rest of list and reset s to the new list*/
+ t->ai_next = s->ai_next;
+ s->ai_next = head.ai_next;
+}
+
/*ARGSUSED*/
static int
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
@@ -1251,6 +1283,7 @@
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
struct res_target q, q2;
+ res_state res;
name = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
@@ -1306,7 +1339,16 @@
free(buf2);
return NS_UNAVAIL;
}
- if (res_searchN(name, &q) < 0) {
+
+ res = __res_get_state();
+ if (res == NULL) {
+ free(buf);
+ free(buf2);
+ return NS_NOTFOUND;
+ }
+
+ if (res_searchN(name, &q, res) < 0) {
+ __res_put_state(res);
free(buf);
free(buf2);
return NS_NOTFOUND;
@@ -1324,7 +1366,8 @@
}
free(buf);
free(buf2);
- if (sentinel.ai_next == NULL)
+ if (sentinel.ai_next == NULL) {
+ __res_put_state(res);
switch (h_errno) {
case HOST_NOT_FOUND:
return NS_NOTFOUND;
@@ -1333,6 +1376,13 @@
default:
return NS_UNAVAIL;
}
+ }
+
+ if (res->nsort)
+ aisort(&sentinel, res);
+
+ __res_put_state(res);
+
*((struct addrinfo **)rv) = sentinel.ai_next;
return NS_SUCCESS;
}
@@ -1712,17 +1762,13 @@
* is detected. Error code, if any, is left in h_errno.
*/
static int
-res_searchN(const char *name, /* domain name */ struct res_target *target)
+res_searchN(const char *name, struct res_target *target, res_state res)
{
const char *cp, * const *domain;
HEADER *hp;
u_int dots;
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
- res_state res = __res_get_state();
-
- if (res == NULL)
- return -1;
_DIAGASSERT(name != NULL);
_DIAGASSERT(target != NULL);
@@ -1743,7 +1789,6 @@
*/
if (!dots && (cp = __hostalias(name)) != NULL) {
ret = res_queryN(cp, target, res);
- __res_put_state(res);
return ret;
}
@@ -1754,10 +1799,8 @@
saved_herrno = -1;
if (dots >= res->ndots) {
ret = res_querydomainN(name, NULL, target, res);
- if (ret > 0) {
- __res_put_state(res);
+ if (ret > 0)
return (ret);
- }
saved_herrno = h_errno;
tried_as_is++;
}
@@ -1777,10 +1820,8 @@
domain++) {
ret = res_querydomainN(name, *domain, target, res);
- if (ret > 0) {
- __res_put_state(res);
+ if (ret > 0)
return ret;
- }
/*
* If no server present, give up.
@@ -1797,7 +1838,6 @@
*/
if (errno == ECONNREFUSED) {
h_errno = TRY_AGAIN;
- __res_put_state(res);
return -1;
}
@@ -1835,13 +1875,10 @@
*/
if (!tried_as_is) {
ret = res_querydomainN(name, NULL, target, res);
- if (ret > 0) {
- __res_put_state(res);
+ if (ret > 0)
return ret;
- }
}
- __res_put_state(res);
/*
* if we got here, we didn't satisfy the search.
* if we did an initial full query, return that query's h_errno
@@ -1864,7 +1901,7 @@
* removing a trailing dot from name if domain is NULL.
*/
static int
-res_querydomainN(const char *name, const char *domain,
+res_querydomainN(const char *name, const char *domain,
struct res_target *target, res_state res)
{
char nbuf[MAXDNAME];
diff -r 70ab3ba883f0 -r 18ad9f7c21be lib/libc/net/gethnamaddr.c
--- a/lib/libc/net/gethnamaddr.c Thu Sep 15 22:49:33 2005 +0000
+++ b/lib/libc/net/gethnamaddr.c Thu Sep 15 23:33:41 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gethnamaddr.c,v 1.66 2005/09/15 15:25:40 tsarna Exp $ */
+/* $NetBSD: gethnamaddr.c,v 1.67 2005/09/15 23:33:41 tsarna Exp $ */
/*
* ++Copyright++ 1985, 1988, 1993
@@ -57,7 +57,7 @@
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp ";
#else
-__RCSID("$NetBSD: gethnamaddr.c,v 1.66 2005/09/15 15:25:40 tsarna Exp $");
+__RCSID("$NetBSD: gethnamaddr.c,v 1.67 2005/09/15 23:33:41 tsarna Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -84,7 +84,6 @@
#endif
#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
-#define RESOLVSORT
#include <nsswitch.h>
#include <stdlib.h>
@@ -141,9 +140,7 @@
res_state);
static void map_v4v6_address(const char *, char *);
static void map_v4v6_hostent(struct hostent *, char **, char *);
-#ifdef RESOLVSORT
static void addrsort(char **, int, res_state);
-#endif
void _sethtent(int);
void _endhtent(void);
@@ -481,7 +478,6 @@
if (haveanswer) {
*ap = NULL;
*hap = NULL;
-# if defined(RESOLVSORT)
/*
* Note: we sort even if host can take only one address
* in its return structures - should give it the "best"
@@ -489,7 +485,6 @@
*/
if (res->nsort && haveanswer > 1 && qtype == T_A)
addrsort(h_addr_ptrs, haveanswer, res);
-# endif /*RESOLVSORT*/
if (!host.h_name) {
n = strlen(qname) + 1; /* for the \0 */
if (n > ep - bp || n >= MAXHOSTNAMELEN)
@@ -1020,7 +1015,6 @@
}
}
-#ifdef RESOLVSORT
static void
addrsort(char **ap, int num, res_state res)
{
@@ -1063,7 +1057,6 @@
needsort++;
}
}
-#endif
struct hostent *
gethostent(void)
diff -r 70ab3ba883f0 -r 18ad9f7c21be lib/libc/resolv/res_init.c
--- a/lib/libc/resolv/res_init.c Thu Sep 15 22:49:33 2005 +0000
+++ b/lib/libc/resolv/res_init.c Thu Sep 15 23:33:41 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: res_init.c,v 1.5 2004/05/21 16:03:05 christos Exp $ */
+/* $NetBSD: res_init.c,v 1.6 2005/09/15 23:33:41 tsarna Exp $ */
/*
* Copyright (c) 1985, 1989, 1993
@@ -76,7 +76,7 @@
static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
static const char rcsid[] = "Id: res_init.c,v 1.9.2.5.4.2 2004/03/16 12:34:18 marka Exp";
#else
-__RCSID("$NetBSD: res_init.c,v 1.5 2004/05/21 16:03:05 christos Exp $");
+__RCSID("$NetBSD: res_init.c,v 1.6 2005/09/15 23:33:41 tsarna Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -121,16 +121,13 @@
#include "res_private.h"
/* Options. Should all be left alone. */
-#define RESOLVSORT
#define DEBUG
static void res_setoptions __P((res_state, const char *, const char *));
Home |
Main Index |
Thread Index |
Old Index