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