1 /* $NetBSD: gen_nw.c,v 1.1.1.2 2012/09/09 16:07:55 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 *
irs_gen_nw(struct irs_acc * this)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
nw_close(struct irs_nw * this)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 *
nw_next(struct irs_nw * this)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 *
nw_byname(struct irs_nw * this,const char * name,int type)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 *
nw_byaddr(struct irs_nw * this,void * net,int length,int type)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
nw_rewind(struct irs_nw * this)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
nw_minimize(struct irs_nw * this)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 *
nw_res_get(struct irs_nw * this)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
nw_res_set(struct irs_nw * this,struct __res_state * res,void (* free_res)(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
init(struct irs_nw * this)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