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