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