4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996,1999 by Internet Software Consortium.
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.
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.
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";
26 #include "port_before.h"
28 #include <sys/types.h>
30 #include <netinet/in.h>
31 #include <arpa/nameser.h>
38 #include <isc/memcluster.h>
41 #include "port_after.h"
49 struct irs_rule
* rules
;
50 struct irs_rule
* rule
;
51 struct __res_state
* res
;
52 void (*free_res
)(void *);
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 *));
68 static int init(struct irs_nw
*this);
73 irs_gen_nw(struct irs_acc
*this) {
74 struct gen_p
*accpvt
= (struct gen_p
*)this->private;
78 if (!(pvt
= memget(sizeof *pvt
))) {
82 memset(pvt
, 0, sizeof *pvt
);
83 if (!(nw
= memget(sizeof *nw
))) {
84 memput(pvt
, sizeof *pvt
);
88 memset(nw
, 0x5e, sizeof *nw
);
89 pvt
->rules
= accpvt
->map_rules
[irs_nw
];
90 pvt
->rule
= pvt
->rules
;
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
;
106 nw_close(struct irs_nw
*this) {
107 struct pvt
*pvt
= (struct pvt
*)this->private;
111 if (pvt
->res
&& pvt
->free_res
)
112 (*pvt
->free_res
)(pvt
->res
);
114 memput(pvt
, sizeof *pvt
);
115 memput(this, sizeof *this);
118 static struct nwent
*
119 nw_next(struct irs_nw
*this) {
120 struct pvt
*pvt
= (struct pvt
*)this->private;
124 if (init(this) == -1)
128 nw
= pvt
->rule
->inst
->nw
;
129 rval
= (*nw
->next
)(nw
);
132 if (!(pvt
->rules
->flags
& IRS_CONTINUE
))
134 pvt
->rule
= pvt
->rule
->next
;
136 nw
= pvt
->rule
->inst
->nw
;
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
;
150 if (init(this) == -1)
153 for (rule
= pvt
->rules
; rule
; rule
= rule
->next
) {
155 RES_SET_H_ERRNO(pvt
->res
, NETDB_INTERNAL
);
156 rval
= (*nw
->byname
)(nw
, name
, type
);
159 if (pvt
->res
->res_h_errno
!= TRY_AGAIN
&&
160 !(rule
->flags
& IRS_CONTINUE
))
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
;
173 if (init(this) == -1)
176 for (rule
= pvt
->rules
; rule
; rule
= rule
->next
) {
178 RES_SET_H_ERRNO(pvt
->res
, NETDB_INTERNAL
);
179 rval
= (*nw
->byaddr
)(nw
, net
, length
, type
);
182 if (pvt
->res
->res_h_errno
!= TRY_AGAIN
&&
183 !(rule
->flags
& IRS_CONTINUE
))
190 nw_rewind(struct irs_nw
*this) {
191 struct pvt
*pvt
= (struct pvt
*)this->private;
194 pvt
->rule
= pvt
->rules
;
196 nw
= pvt
->rule
->inst
->nw
;
202 nw_minimize(struct irs_nw
*this) {
203 struct pvt
*pvt
= (struct pvt
*)this->private;
204 struct irs_rule
*rule
;
207 res_nclose(pvt
->res
);
208 for (rule
= pvt
->rules
; rule
!= NULL
; rule
= rule
->next
) {
209 struct irs_nw
*nw
= rule
->inst
->nw
;
215 static struct __res_state
*
216 nw_res_get(struct irs_nw
*this) {
217 struct pvt
*pvt
= (struct pvt
*)this->private;
220 struct __res_state
*res
;
221 res
= (struct __res_state
*)malloc(sizeof *res
);
226 memset(res
, 0, sizeof *res
);
227 nw_res_set(this, res
, free
);
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
;
239 if (pvt
->res
&& pvt
->free_res
) {
240 res_nclose(pvt
->res
);
241 (*pvt
->free_res
)(pvt
->res
);
245 pvt
->free_res
= free_res
;
247 for (rule
= pvt
->rules
; rule
!= NULL
; rule
= rule
->next
) {
248 struct irs_nw
*nw
= rule
->inst
->nw
;
250 (*nw
->res_set
)(nw
, pvt
->res
, NULL
);
255 init(struct irs_nw
*this) {
256 struct pvt
*pvt
= (struct pvt
*)this->private;
258 if (!pvt
->res
&& !nw_res_get(this))
260 if (((pvt
->res
->options
& RES_INIT
) == 0U) &&
261 res_ninit(pvt
->res
) == -1)