diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2013-05-27 17:31:02 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2013-05-27 17:31:02 +0000 |
commit | 595fac8a14905c9e48e876b0dfb69492af15bf6b (patch) | |
tree | 89313f5e551ef8cb78a4c587c63453f5fda9c8ed /lib/libc/asr | |
parent | 3db28768772e2df85e857d3071948ff3eea00f09 (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.c | 8 | ||||
-rw-r--r-- | lib/libc/asr/asr_debug.c | 19 | ||||
-rw-r--r-- | lib/libc/asr/asr_private.h | 12 | ||||
-rw-r--r-- | lib/libc/asr/getaddrinfo.c | 4 | ||||
-rw-r--r-- | lib/libc/asr/gethostnamadr.c | 16 | ||||
-rw-r--r-- | lib/libc/asr/getnameinfo.c | 4 | ||||
-rw-r--r-- | lib/libc/asr/getnetnamadr.c | 6 | ||||
-rw-r--r-- | lib/libc/asr/getrrsetbyname.c | 4 | ||||
-rw-r--r-- | lib/libc/asr/res_init.c | 55 | ||||
-rw-r--r-- | lib/libc/asr/res_query.c | 6 | ||||
-rw-r--r-- | lib/libc/asr/res_send.c | 4 |
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); |