summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/net/getaddrinfo.c41
-rw-r--r--lib/libc/net/res_init.c30
2 files changed, 63 insertions, 8 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index 0f3b6319f46..87125c89ccf 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getaddrinfo.c,v 1.67 2007/05/20 03:54:52 ray Exp $ */
+/* $OpenBSD: getaddrinfo.c,v 1.68 2009/06/04 18:06:35 pyr Exp $ */
/* $KAME: getaddrinfo.c,v 1.31 2000/08/31 17:36:43 itojun Exp $ */
/*
@@ -233,7 +233,8 @@ static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
static int res_queryN(const char *, struct res_target *);
static int res_searchN(const char *, struct res_target *);
static int res_querydomainN(const char *, const char *, struct res_target *);
-static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *);
+static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *,
+ const struct __res_state *);
/* XXX macros that make external reference is BAD. */
@@ -517,7 +518,7 @@ explore_fqdn(const struct addrinfo *pai, const char *hostname,
break;
#endif
case 'b':
- result = _dns_getaddrinfo(hostname, pai);
+ result = _dns_getaddrinfo(hostname, pai, _resp);
break;
case 'f':
result = _files_getaddrinfo(hostname, pai);
@@ -1142,7 +1143,8 @@ getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
/*ARGSUSED*/
static struct addrinfo *
-_dns_getaddrinfo(const char *name, const struct addrinfo *pai)
+_dns_getaddrinfo(const char *name, const struct addrinfo *pai,
+ const struct __res_state *_resp)
{
struct addrinfo *ai;
querybuf *buf, *buf2;
@@ -1168,14 +1170,39 @@ _dns_getaddrinfo(const char *name, const struct addrinfo *pai)
switch (pai->ai_family) {
case AF_UNSPEC:
- /* prefer IPv6 */
+ if (_resp->family[0] == -1) {
+ /* prefer IPv4 by default*/
+ q.qclass = C_IN;
+ q.qtype = T_A;
+ q.answer = buf->buf;
+ q.anslen = sizeof(buf->buf);
+ q.next = &q2;
+ q2.qclass = C_IN;
+ q2.qtype = T_AAAA;
+ q2.answer = buf2->buf;
+ q2.anslen = sizeof(buf2->buf);
+ break;
+ }
+
+ /* respect user supplied order */
q.qclass = C_IN;
- q.qtype = T_AAAA;
+ if (_resp->family[0] == AF_INET6)
+ q.qtype = T_AAAA;
+ else
+ q.qtype = T_A;
q.answer = buf->buf;
q.anslen = sizeof(buf->buf);
+ if (_resp->family[1] == -1) {
+ q.next = NULL;
+ break;
+ }
q.next = &q2;
+
q2.qclass = C_IN;
- q2.qtype = T_A;
+ if (_resp->family[1] == AF_INET6)
+ q2.qtype = T_AAAA;
+ else
+ q2.qtype = T_A;
q2.answer = buf2->buf;
q2.anslen = sizeof(buf2->buf);
break;
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index 42d3b3ca1e3..5cb597dad80 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_init.c,v 1.37 2008/08/15 14:57:20 djm Exp $ */
+/* $OpenBSD: res_init.c,v 1.38 2009/06/04 18:06:35 pyr Exp $ */
/*
* ++Copyright++ 1985, 1989, 1993
@@ -165,6 +165,7 @@ _res_init(int usercall)
FILE *fp;
char *cp, **pp;
int n;
+ int findex;
char buf[BUFSIZ];
int nserv = 0; /* number of nameserver records read from file */
int haveenv = 0;
@@ -296,6 +297,33 @@ _res_init(int usercall)
*cp = '\0';
if (buf[0] == '\0')
continue;
+ /* set family lookup order */
+ if (MATCH(buf, "family")) {
+ cp = buf + sizeof("family") - 1;
+ cp += strspn(cp, " \t");
+ cp[strcspn(cp, "\n")] = '\0';
+ findex = 0;
+ _resp->family[0] = _resp->family[1] = -1;
+ while (*cp != '\0' && findex < 2) {
+ if (!strncmp(cp, "inet6", strlen("inet6"))) {
+ _resp->family[findex] = AF_INET6;
+ cp += strlen("inet6");
+ } else if (!strncmp(cp, "inet4",
+ strlen("inet4"))) {
+ _resp->family[findex] = AF_INET;
+ cp += strlen("inet4");
+ }
+ if (*cp != ' ' && *cp != '\t' && *cp != '\0') {
+ _resp->family[findex] = -1;
+ break;
+ }
+ findex++;
+ cp += strspn(cp, " \t");
+ }
+
+ if (_resp->family[0] == _resp->family[1])
+ _resp->family[1] = -1;
+ }
/* read default domain name */
if (MATCH(buf, "domain")) {
if (haveenv) /* skip if have from environ */