xref: /netbsd/external/bsd/libbind/dist/irs/gen_nw.c (revision 6550d01e)
1 /*	$NetBSD: gen_nw.c,v 1.1.1.1 2009/04/12 15:33:38 christos Exp $	*/
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(LINT) && !defined(CODECENTER)
21 static const char rcsid[] = "Id: gen_nw.c,v 1.4 2005/04/27 04:56:23 sra Exp";
22 #endif
23 
24 /* Imports */
25 
26 #include "port_before.h"
27 
28 #include <sys/types.h>
29 
30 #include <netinet/in.h>
31 #include <arpa/nameser.h>
32 
33 #include <errno.h>
34 #include <resolv.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include <isc/memcluster.h>
39 #include <irs.h>
40 
41 #include "port_after.h"
42 
43 #include "irs_p.h"
44 #include "gen_p.h"
45 
46 /* Types */
47 
48 struct pvt {
49 	struct irs_rule *	rules;
50 	struct irs_rule *	rule;
51 	struct __res_state *	res;
52 	void 			(*free_res)(void *);
53 };
54 
55 /* Forward */
56 
57 static void		nw_close(struct irs_nw*);
58 static struct nwent *	nw_next(struct irs_nw *);
59 static struct nwent *	nw_byname(struct irs_nw *, const char *, int);
60 static struct nwent *	nw_byaddr(struct irs_nw *, void *, int, int);
61 static void    		nw_rewind(struct irs_nw *);
62 static void		nw_minimize(struct irs_nw *);
63 static struct __res_state * nw_res_get(struct irs_nw *this);
64 static void		nw_res_set(struct irs_nw *this,
65 				   struct __res_state *res,
66 				   void (*free_res)(void *));
67 
68 static int		init(struct irs_nw *this);
69 
70 /* Public */
71 
72 struct irs_nw *
73 irs_gen_nw(struct irs_acc *this) {
74 	struct gen_p *accpvt = (struct gen_p *)this->private;
75 	struct irs_nw *nw;
76 	struct pvt *pvt;
77 
78 	if (!(pvt = memget(sizeof *pvt))) {
79 		errno = ENOMEM;
80 		return (NULL);
81 	}
82 	memset(pvt, 0, sizeof *pvt);
83 	if (!(nw = memget(sizeof *nw))) {
84 		memput(pvt, sizeof *pvt);
85 		errno = ENOMEM;
86 		return (NULL);
87 	}
88 	memset(nw, 0x5e, sizeof *nw);
89 	pvt->rules = accpvt->map_rules[irs_nw];
90 	pvt->rule = pvt->rules;
91 	nw->private = pvt;
92 	nw->close = nw_close;
93 	nw->next = nw_next;
94 	nw->byname = nw_byname;
95 	nw->byaddr = nw_byaddr;
96 	nw->rewind = nw_rewind;
97 	nw->minimize = nw_minimize;
98 	nw->res_get = nw_res_get;
99 	nw->res_set = nw_res_set;
100 	return (nw);
101 }
102 
103 /* Methods */
104 
105 static void
106 nw_close(struct irs_nw *this) {
107 	struct pvt *pvt = (struct pvt *)this->private;
108 
109 	nw_minimize(this);
110 
111 	if (pvt->res && pvt->free_res)
112 		(*pvt->free_res)(pvt->res);
113 
114 	memput(pvt, sizeof *pvt);
115 	memput(this, sizeof *this);
116 }
117 
118 static struct nwent *
119 nw_next(struct irs_nw *this) {
120 	struct pvt *pvt = (struct pvt *)this->private;
121 	struct nwent *rval;
122 	struct irs_nw *nw;
123 
124 	if (init(this) == -1)
125 		return(NULL);
126 
127 	while (pvt->rule) {
128 		nw = pvt->rule->inst->nw;
129 		rval = (*nw->next)(nw);
130 		if (rval)
131 			return (rval);
132 		if (!(pvt->rules->flags & IRS_CONTINUE))
133 			break;
134 		pvt->rule = pvt->rule->next;
135 		if (pvt->rule) {
136 			nw = pvt->rule->inst->nw;
137 			(*nw->rewind)(nw);
138 		}
139 	}
140 	return (NULL);
141 }
142 
143 static struct nwent *
144 nw_byname(struct irs_nw *this, const char *name, int type) {
145 	struct pvt *pvt = (struct pvt *)this->private;
146 	struct irs_rule *rule;
147 	struct nwent *rval;
148 	struct irs_nw *nw;
149 
150 	if (init(this) == -1)
151 		return(NULL);
152 
153 	for (rule = pvt->rules; rule; rule = rule->next) {
154 		nw = rule->inst->nw;
155 		RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
156 		rval = (*nw->byname)(nw, name, type);
157 		if (rval != NULL)
158 			return (rval);
159 		if (pvt->res->res_h_errno != TRY_AGAIN &&
160 		    !(rule->flags & IRS_CONTINUE))
161 			break;
162 	}
163 	return (NULL);
164 }
165 
166 static struct nwent *
167 nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
168 	struct pvt *pvt = (struct pvt *)this->private;
169 	struct irs_rule *rule;
170 	struct nwent *rval;
171 	struct irs_nw *nw;
172 
173 	if (init(this) == -1)
174 		return(NULL);
175 
176 	for (rule = pvt->rules; rule; rule = rule->next) {
177 		nw = rule->inst->nw;
178 		RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
179 		rval = (*nw->byaddr)(nw, net, length, type);
180 		if (rval != NULL)
181 			return (rval);
182 		if (pvt->res->res_h_errno != TRY_AGAIN &&
183 		    !(rule->flags & IRS_CONTINUE))
184 			break;
185 	}
186 	return (NULL);
187 }
188 
189 static void
190 nw_rewind(struct irs_nw *this) {
191 	struct pvt *pvt = (struct pvt *)this->private;
192 	struct irs_nw *nw;
193 
194 	pvt->rule = pvt->rules;
195 	if (pvt->rule) {
196 		nw = pvt->rule->inst->nw;
197 		(*nw->rewind)(nw);
198 	}
199 }
200 
201 static void
202 nw_minimize(struct irs_nw *this) {
203 	struct pvt *pvt = (struct pvt *)this->private;
204 	struct irs_rule *rule;
205 
206 	if (pvt->res)
207 		res_nclose(pvt->res);
208 	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
209 		struct irs_nw *nw = rule->inst->nw;
210 
211 		(*nw->minimize)(nw);
212 	}
213 }
214 
215 static struct __res_state *
216 nw_res_get(struct irs_nw *this) {
217 	struct pvt *pvt = (struct pvt *)this->private;
218 
219 	if (!pvt->res) {
220 		struct __res_state *res;
221 		res = (struct __res_state *)malloc(sizeof *res);
222 		if (!res) {
223 			errno = ENOMEM;
224 			return (NULL);
225 		}
226 		memset(res, 0, sizeof *res);
227 		nw_res_set(this, res, free);
228 	}
229 
230 	return (pvt->res);
231 }
232 
233 static void
234 nw_res_set(struct irs_nw *this, struct __res_state *res,
235 		void (*free_res)(void *)) {
236 	struct pvt *pvt = (struct pvt *)this->private;
237 	struct irs_rule *rule;
238 
239 	if (pvt->res && pvt->free_res) {
240 		res_nclose(pvt->res);
241 		(*pvt->free_res)(pvt->res);
242 	}
243 
244 	pvt->res = res;
245 	pvt->free_res = free_res;
246 
247 	for (rule = pvt->rules; rule != NULL; rule = rule->next) {
248 		struct irs_nw *nw = rule->inst->nw;
249 
250 		(*nw->res_set)(nw, pvt->res, NULL);
251 	}
252 }
253 
254 static int
255 init(struct irs_nw *this) {
256 	struct pvt *pvt = (struct pvt *)this->private;
257 
258 	if (!pvt->res && !nw_res_get(this))
259 		return (-1);
260 	if (((pvt->res->options & RES_INIT) == 0U) &&
261 	    res_ninit(pvt->res) == -1)
262 		return (-1);
263 	return (0);
264 }
265 
266 /*! \file */
267