1/*	$NetBSD$	*/
2
3/*
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996-1999 by Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21static const char rcsid[] = "Id: dns.c,v 1.5 2006/03/09 23:57:56 marka Exp ";
22#endif
23
24/*! \file
25 * \brief
26 * dns.c --- this is the top-level accessor function for the dns
27 */
28
29#include "port_before.h"
30
31#include <stdlib.h>
32#include <string.h>
33#include <errno.h>
34
35#include <sys/types.h>
36#include <netinet/in.h>
37#include <arpa/nameser.h>
38#include <resolv.h>
39
40#include <resolv.h>
41
42#include <isc/memcluster.h>
43#include <irs.h>
44
45#include "port_after.h"
46
47#include "irs_p.h"
48#include "hesiod.h"
49#include "dns_p.h"
50
51/* forward */
52
53static void		dns_close(struct irs_acc *);
54static struct __res_state *	dns_res_get(struct irs_acc *);
55static void		dns_res_set(struct irs_acc *, struct __res_state *,
56				void (*)(void *));
57
58/* public */
59
60struct irs_acc *
61irs_dns_acc(const char *options) {
62	struct irs_acc *acc;
63	struct dns_p *dns;
64
65	UNUSED(options);
66
67	if (!(acc = memget(sizeof *acc))) {
68		errno = ENOMEM;
69		return (NULL);
70	}
71	memset(acc, 0x5e, sizeof *acc);
72	if (!(dns = memget(sizeof *dns))) {
73		errno = ENOMEM;
74		memput(acc, sizeof *acc);
75		return (NULL);
76	}
77	memset(dns, 0x5e, sizeof *dns);
78	dns->res = NULL;
79	dns->free_res = NULL;
80	if (hesiod_init(&dns->hes_ctx) < 0) {
81		/*
82		 * We allow the dns accessor class to initialize
83		 * despite hesiod failing to initialize correctly,
84		 * since dns host queries don't depend on hesiod.
85		 */
86		dns->hes_ctx = NULL;
87	}
88	acc->private = dns;
89#ifdef WANT_IRS_GR
90	acc->gr_map = irs_dns_gr;
91#else
92	acc->gr_map = NULL;
93#endif
94#ifdef WANT_IRS_PW
95	acc->pw_map = irs_dns_pw;
96#else
97	acc->pw_map = NULL;
98#endif
99	acc->sv_map = irs_dns_sv;
100	acc->pr_map = irs_dns_pr;
101	acc->ho_map = irs_dns_ho;
102	acc->nw_map = irs_dns_nw;
103	acc->ng_map = irs_nul_ng;
104	acc->res_get = dns_res_get;
105	acc->res_set = dns_res_set;
106	acc->close = dns_close;
107	return (acc);
108}
109
110/* methods */
111static struct __res_state *
112dns_res_get(struct irs_acc *this) {
113	struct dns_p *dns = (struct dns_p *)this->private;
114
115	if (dns->res == NULL) {
116		struct __res_state *res;
117		res = (struct __res_state *)malloc(sizeof *res);
118		if (res == NULL)
119			return (NULL);
120		memset(res, 0, sizeof *res);
121		dns_res_set(this, res, free);
122	}
123
124	if ((dns->res->options & RES_INIT) == 0U &&
125	    res_ninit(dns->res) < 0)
126		return (NULL);
127
128	return (dns->res);
129}
130
131static void
132dns_res_set(struct irs_acc *this, struct __res_state *res,
133	    void (*free_res)(void *)) {
134	struct dns_p *dns = (struct dns_p *)this->private;
135
136	if (dns->res && dns->free_res) {
137		res_nclose(dns->res);
138		(*dns->free_res)(dns->res);
139	}
140	dns->res = res;
141	dns->free_res = free_res;
142}
143
144static void
145dns_close(struct irs_acc *this) {
146	struct dns_p *dns;
147
148	dns = (struct dns_p *)this->private;
149	if (dns->res && dns->free_res)
150		(*dns->free_res)(dns->res);
151	if (dns->hes_ctx)
152		hesiod_end(dns->hes_ctx);
153	memput(dns, sizeof *dns);
154	memput(this, sizeof *this);
155}
156
157