summaryrefslogtreecommitdiff
path: root/lib/libc/asr
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2013-05-27 17:31:02 +0000
committerEric Faurot <eric@cvs.openbsd.org>2013-05-27 17:31:02 +0000
commit595fac8a14905c9e48e876b0dfb69492af15bf6b (patch)
tree89313f5e551ef8cb78a4c587c63453f5fda9c8ed /lib/libc/asr
parent3db28768772e2df85e857d3071948ff3eea00f09 (diff)
Add minimal support for _res setup and update.
Change res_init() to initialize the _res structure on first call, and udpate the global async context if changes were made by the user. All resolver functions now call res_init() internally. fixes issue spotted by otto@
Diffstat (limited to 'lib/libc/asr')
-rw-r--r--lib/libc/asr/asr.c8
-rw-r--r--lib/libc/asr/asr_debug.c19
-rw-r--r--lib/libc/asr/asr_private.h12
-rw-r--r--lib/libc/asr/getaddrinfo.c4
-rw-r--r--lib/libc/asr/gethostnamadr.c16
-rw-r--r--lib/libc/asr/getnameinfo.c4
-rw-r--r--lib/libc/asr/getnetnamadr.c6
-rw-r--r--lib/libc/asr/getrrsetbyname.c4
-rw-r--r--lib/libc/asr/res_init.c55
-rw-r--r--lib/libc/asr/res_query.c6
-rw-r--r--lib/libc/asr/res_send.c4
11 files changed, 93 insertions, 45 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c
index 1aea2bd4e7c..a2025ec4af0 100644
--- a/lib/libc/asr/asr.c
+++ b/lib/libc/asr/asr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.c,v 1.25 2013/04/30 12:02:39 eric Exp $ */
+/* $OpenBSD: asr.c,v 1.26 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org>
*
@@ -394,9 +394,9 @@ asr_ctx_free(struct asr_ctx *ac)
if (ac->ac_domain)
free(ac->ac_domain);
- for (i = 0; i < ac->ac_nscount; i++)
+ for (i = 0; i < ASR_MAXNS; i++)
free(ac->ac_ns[i]);
- for (i = 0; i < ac->ac_domcount; i++)
+ for (i = 0; i < ASR_MAXDOM; i++)
free(ac->ac_dom[i]);
free(ac);
@@ -632,7 +632,7 @@ pass0(char **tok, int n, struct asr_ctx *ac)
}
} else if (!strcmp(tok[0], "search")) {
/* resolv.conf says the last line wins */
- for (i = 0; i < ac->ac_domcount; i++)
+ for (i = 0; i < ASR_MAXDOM; i++)
free(ac->ac_dom[i]);
ac->ac_domcount = 0;
for (i = 1; i < n; i++)
diff --git a/lib/libc/asr/asr_debug.c b/lib/libc/asr/asr_debug.c
index 468c197134e..8cc54e2062f 100644
--- a/lib/libc/asr/asr_debug.c
+++ b/lib/libc/asr/asr_debug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_debug.c,v 1.12 2013/04/09 06:42:17 otto Exp $ */
+/* $OpenBSD: asr_debug.c,v 1.13 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -302,22 +302,7 @@ asr_dump_config(FILE *f, struct asr *a)
fprintf(f, " %s\n", print_sockaddr(ac->ac_ns[i], buf,
sizeof buf));
fprintf(f, "HOSTFILE %s\n", ac->ac_hostfile);
- fprintf(f, "LOOKUP");
- for (i = 0; i < ac->ac_dbcount; i++) {
- switch (ac->ac_db[i]) {
- case ASR_DB_FILE:
- fprintf(f, " file");
- break;
- case ASR_DB_DNS:
- fprintf(f, " dns");
- break;
- case ASR_DB_YP:
- fprintf(f, " yp");
- break;
- default:
- fprintf(f, " ?%i", ac->ac_db[i]);
- }
- }
+ fprintf(f, "LOOKUP %s", ac->ac_db);
fprintf(f, "\n------------------------------------\n");
}
diff --git a/lib/libc/asr/asr_private.h b/lib/libc/asr/asr_private.h
index 275d18eb576..3564e302c6a 100644
--- a/lib/libc/asr/asr_private.h
+++ b/lib/libc/asr/asr_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_private.h,v 1.17 2013/04/30 12:02:39 eric Exp $ */
+/* $OpenBSD: asr_private.h,v 1.18 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -121,11 +121,9 @@ enum async_type {
ASR_GETNAMEINFO,
};
-enum asr_db_type {
- ASR_DB_FILE,
- ASR_DB_DNS,
- ASR_DB_YP,
-};
+#define ASR_DB_FILE 'f'
+#define ASR_DB_DNS 'b'
+#define ASR_DB_YP 'y'
struct asr_ctx {
int ac_refcount;
@@ -135,7 +133,7 @@ struct asr_ctx {
int ac_domcount;
char *ac_dom[ASR_MAXDOM];
int ac_dbcount;
- int ac_db[ASR_MAXDB];
+ char ac_db[ASR_MAXDB + 1];
int ac_family[3];
char *ac_hostfile;
diff --git a/lib/libc/asr/getaddrinfo.c b/lib/libc/asr/getaddrinfo.c
index 84b11ce5b80..9e8ba91c5b2 100644
--- a/lib/libc/asr/getaddrinfo.c
+++ b/lib/libc/asr/getaddrinfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getaddrinfo.c,v 1.1 2012/09/08 11:08:21 eric Exp $ */
+/* $OpenBSD: getaddrinfo.c,v 1.2 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -31,6 +31,8 @@ getaddrinfo(const char *hostname, const char *servname,
struct async_res ar;
int saved_errno = errno;
+ res_init();
+
as = getaddrinfo_async(hostname, servname, hints, NULL);
if (as == NULL) {
if (errno == ENOMEM) {
diff --git a/lib/libc/asr/gethostnamadr.c b/lib/libc/asr/gethostnamadr.c
index 6833166dbf7..363d0a2e527 100644
--- a/lib/libc/asr/gethostnamadr.c
+++ b/lib/libc/asr/gethostnamadr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gethostnamadr.c,v 1.6 2013/04/14 22:23:08 deraadt Exp $ */
+/* $OpenBSD: gethostnamadr.c,v 1.7 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -127,12 +127,22 @@ _gethostbyname(const char *name, int af)
struct hostent *
gethostbyname(const char *name)
{
- return _gethostbyname(name, -1);
+ struct hostent *h;
+
+ res_init();
+
+ if (_res.options & RES_USE_INET6 &&
+ (h = _gethostbyname(name, AF_INET6)))
+ return (h);
+
+ return _gethostbyname(name, AF_INET);
}
struct hostent *
gethostbyname2(const char *name, int af)
{
+ res_init();
+
return _gethostbyname(name, af);
}
@@ -142,6 +152,8 @@ gethostbyaddr(const void *addr, socklen_t len, int af)
struct async *as;
struct async_res ar;
+ res_init();
+
as = gethostbyaddr_async(addr, len, af, NULL);
if (as == NULL) {
h_errno = NETDB_INTERNAL;
diff --git a/lib/libc/asr/getnameinfo.c b/lib/libc/asr/getnameinfo.c
index 0349732ab10..7e2b5d43db4 100644
--- a/lib/libc/asr/getnameinfo.c
+++ b/lib/libc/asr/getnameinfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnameinfo.c,v 1.1 2012/09/08 11:08:21 eric Exp $ */
+/* $OpenBSD: getnameinfo.c,v 1.2 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -31,6 +31,8 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
struct async_res ar;
int saved_errno = errno;
+ res_init();
+
as = getnameinfo_async(sa, salen, host, hostlen, serv, servlen, flags,
NULL);
if (as == NULL) {
diff --git a/lib/libc/asr/getnetnamadr.c b/lib/libc/asr/getnetnamadr.c
index 63cc0754f68..5c8781cb2ef 100644
--- a/lib/libc/asr/getnetnamadr.c
+++ b/lib/libc/asr/getnetnamadr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnetnamadr.c,v 1.4 2013/04/04 17:50:19 eric Exp $ */
+/* $OpenBSD: getnetnamadr.c,v 1.5 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -83,6 +83,8 @@ getnetbyname(const char *name)
struct async *as;
struct async_res ar;
+ res_init();
+
as = getnetbyname_async(name, NULL);
if (as == NULL) {
h_errno = NETDB_INTERNAL;
@@ -108,6 +110,8 @@ getnetbyaddr(in_addr_t net, int type)
struct async *as;
struct async_res ar;
+ res_init();
+
as = getnetbyaddr_async(net, type, NULL);
if (as == NULL) {
h_errno = NETDB_INTERNAL;
diff --git a/lib/libc/asr/getrrsetbyname.c b/lib/libc/asr/getrrsetbyname.c
index 12bb56b06f8..9cafae80877 100644
--- a/lib/libc/asr/getrrsetbyname.c
+++ b/lib/libc/asr/getrrsetbyname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getrrsetbyname.c,v 1.1 2012/09/08 11:08:21 eric Exp $ */
+/* $OpenBSD: getrrsetbyname.c,v 1.2 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -32,6 +32,8 @@ getrrsetbyname(const char *name, unsigned int class, unsigned int type,
struct async_res ar;
int r, saved_errno = errno;
+ res_init();
+
as = getrrsetbyname_async(name, class, type, flags, NULL);
if (as == NULL) {
r = (errno == ENOMEM) ? ERRSET_NOMEMORY : ERRSET_FAIL;
diff --git a/lib/libc/asr/res_init.c b/lib/libc/asr/res_init.c
index 1ba38cd0c24..c8958793b46 100644
--- a/lib/libc/asr/res_init.c
+++ b/lib/libc/asr/res_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_init.c,v 1.1 2012/09/08 11:08:21 eric Exp $ */
+/* $OpenBSD: res_init.c,v 1.2 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -16,18 +16,16 @@
*/
#include <sys/types.h>
+#include <arpa/nameser.h>
#include <netinet/in.h>
#include <resolv.h>
+#include <string.h>
#include "asr.h"
+#include "asr_private.h"
+#include "thread_private.h"
-/*
- * XXX these function is actually internal to asr, but we use it here to force
- * the creation a default resolver context in res_init().
- */
-struct asr_ctx *asr_use_resolver(struct asr *);
-void asr_ctx_unref(struct asr_ctx *);
struct __res_state _res;
struct __res_state_ext _res_ext;
@@ -37,8 +35,47 @@ int h_errno;
int
res_init(void)
{
- async_resolver_done(NULL);
- asr_ctx_unref(asr_use_resolver(NULL));
+ _THREAD_PRIVATE_MUTEX(init);
+ struct asr_ctx *ac;
+
+ ac = asr_use_resolver(NULL);
+
+ /*
+ * The first thread to call res_init() will setup the global _res
+ * structure from the async context, not overriding fields set early
+ * by the user.
+ */
+ _THREAD_PRIVATE_MUTEX_LOCK(init);
+ if (!(_res.options & RES_INIT)) {
+ if (_res.retry == 0)
+ _res.retry = ac->ac_nsretries;
+ if (_res.options == 0)
+ _res.options = ac->ac_options;
+ if (_res.lookups[0] == '\0')
+ strlcpy(_res.lookups, ac->ac_db, sizeof(_res.lookups));
+
+ _res.nscount = ac->ac_nscount;
+ _res.options |= RES_INIT;
+ }
+ _THREAD_PRIVATE_MUTEX_UNLOCK(init);
+
+ /*
+ * If the program is not threaded, we want to reflect (some) changes
+ * made by the user to the global _res structure.
+ * This is a bit of a hack: if there is already an async query on
+ * this context, it might change things in its back. It is ok
+ * as long as the user only uses the blocking resolver API.
+ * If needed we could consider cloning the context if there is
+ * a running query.
+ */
+ if (!__isthreaded) {
+ ac->ac_nsretries = _res.retry;
+ ac->ac_options = _res.options;
+ strlcpy(ac->ac_db, _res.lookups, sizeof(ac->ac_db));
+ ac->ac_dbcount = strlen(ac->ac_db);
+ }
+
+ asr_ctx_unref(ac);
return (0);
}
diff --git a/lib/libc/asr/res_query.c b/lib/libc/asr/res_query.c
index 7a6a1db0ca4..c30188fae54 100644
--- a/lib/libc/asr/res_query.c
+++ b/lib/libc/asr/res_query.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_query.c,v 1.3 2013/04/30 12:02:39 eric Exp $ */
+/* $OpenBSD: res_query.c,v 1.4 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -31,6 +31,8 @@ res_query(const char *name, int class, int type, u_char *ans, int anslen)
struct async_res ar;
size_t len;
+ res_init();
+
if (ans == NULL || anslen <= 0) {
h_errno = NO_RECOVERY;
errno = EINVAL;
@@ -71,6 +73,8 @@ res_search(const char *name, int class, int type, u_char *ans, int anslen)
struct async_res ar;
size_t len;
+ res_init();
+
if (ans == NULL || anslen <= 0) {
h_errno = NO_RECOVERY;
errno = EINVAL;
diff --git a/lib/libc/asr/res_send.c b/lib/libc/asr/res_send.c
index 5135a8d15da..2353796a080 100644
--- a/lib/libc/asr/res_send.c
+++ b/lib/libc/asr/res_send.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_send.c,v 1.3 2013/04/30 12:02:39 eric Exp $ */
+/* $OpenBSD: res_send.c,v 1.4 2013/05/27 17:31:01 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -31,6 +31,8 @@ res_send(const u_char *buf, int buflen, u_char *ans, int anslen)
struct async_res ar;
size_t len;
+ res_init();
+
if (ans == NULL || anslen <= 0) {
errno = EINVAL;
return (-1);