1 /* 2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (c) 1996,1999 by Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #if !defined(LINT) && !defined(CODECENTER) 19 static const char rcsid[] = "$Id: gen_nw.c,v 1.4 2005/04/27 04:56:23 sra Exp $"; 20 #endif 21 22 /* Imports */ 23 24 #include "port_before.h" 25 26 #include <sys/types.h> 27 28 #include <netinet/in.h> 29 #include <arpa/nameser.h> 30 31 #include <errno.h> 32 #include <resolv.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include <isc/memcluster.h> 37 #include <irs.h> 38 39 #include "port_after.h" 40 41 #include "irs_p.h" 42 #include "gen_p.h" 43 44 /* Types */ 45 46 struct pvt { 47 struct irs_rule * rules; 48 struct irs_rule * rule; 49 struct __res_state * res; 50 void (*free_res)(void *); 51 }; 52 53 /* Forward */ 54 55 static void nw_close(struct irs_nw*); 56 static struct nwent * nw_next(struct irs_nw *); 57 static struct nwent * nw_byname(struct irs_nw *, const char *, int); 58 static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int); 59 static void nw_rewind(struct irs_nw *); 60 static void nw_minimize(struct irs_nw *); 61 static struct __res_state * nw_res_get(struct irs_nw *this); 62 static void nw_res_set(struct irs_nw *this, 63 struct __res_state *res, 64 void (*free_res)(void *)); 65 66 static int init(struct irs_nw *this); 67 68 /* Public */ 69 70 struct irs_nw * 71 irs_gen_nw(struct irs_acc *this) { 72 struct gen_p *accpvt = (struct gen_p *)this->private; 73 struct irs_nw *nw; 74 struct pvt *pvt; 75 76 if (!(pvt = memget(sizeof *pvt))) { 77 errno = ENOMEM; 78 return (NULL); 79 } 80 memset(pvt, 0, sizeof *pvt); 81 if (!(nw = memget(sizeof *nw))) { 82 memput(pvt, sizeof *pvt); 83 errno = ENOMEM; 84 return (NULL); 85 } 86 memset(nw, 0x5e, sizeof *nw); 87 pvt->rules = accpvt->map_rules[irs_nw]; 88 pvt->rule = pvt->rules; 89 nw->private = pvt; 90 nw->close = nw_close; 91 nw->next = nw_next; 92 nw->byname = nw_byname; 93 nw->byaddr = nw_byaddr; 94 nw->rewind = nw_rewind; 95 nw->minimize = nw_minimize; 96 nw->res_get = nw_res_get; 97 nw->res_set = nw_res_set; 98 return (nw); 99 } 100 101 /* Methods */ 102 103 static void 104 nw_close(struct irs_nw *this) { 105 struct pvt *pvt = (struct pvt *)this->private; 106 107 nw_minimize(this); 108 109 if (pvt->res && pvt->free_res) 110 (*pvt->free_res)(pvt->res); 111 112 memput(pvt, sizeof *pvt); 113 memput(this, sizeof *this); 114 } 115 116 static struct nwent * 117 nw_next(struct irs_nw *this) { 118 struct pvt *pvt = (struct pvt *)this->private; 119 struct nwent *rval; 120 struct irs_nw *nw; 121 122 if (init(this) == -1) 123 return(NULL); 124 125 while (pvt->rule) { 126 nw = pvt->rule->inst->nw; 127 rval = (*nw->next)(nw); 128 if (rval) 129 return (rval); 130 if (!(pvt->rules->flags & IRS_CONTINUE)) 131 break; 132 pvt->rule = pvt->rule->next; 133 if (pvt->rule) { 134 nw = pvt->rule->inst->nw; 135 (*nw->rewind)(nw); 136 } 137 } 138 return (NULL); 139 } 140 141 static struct nwent * 142 nw_byname(struct irs_nw *this, const char *name, int type) { 143 struct pvt *pvt = (struct pvt *)this->private; 144 struct irs_rule *rule; 145 struct nwent *rval; 146 struct irs_nw *nw; 147 148 if (init(this) == -1) 149 return(NULL); 150 151 for (rule = pvt->rules; rule; rule = rule->next) { 152 nw = rule->inst->nw; 153 RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); 154 rval = (*nw->byname)(nw, name, type); 155 if (rval != NULL) 156 return (rval); 157 if (pvt->res->res_h_errno != TRY_AGAIN && 158 !(rule->flags & IRS_CONTINUE)) 159 break; 160 } 161 return (NULL); 162 } 163 164 static struct nwent * 165 nw_byaddr(struct irs_nw *this, void *net, int length, int type) { 166 struct pvt *pvt = (struct pvt *)this->private; 167 struct irs_rule *rule; 168 struct nwent *rval; 169 struct irs_nw *nw; 170 171 if (init(this) == -1) 172 return(NULL); 173 174 for (rule = pvt->rules; rule; rule = rule->next) { 175 nw = rule->inst->nw; 176 RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); 177 rval = (*nw->byaddr)(nw, net, length, type); 178 if (rval != NULL) 179 return (rval); 180 if (pvt->res->res_h_errno != TRY_AGAIN && 181 !(rule->flags & IRS_CONTINUE)) 182 break; 183 } 184 return (NULL); 185 } 186 187 static void 188 nw_rewind(struct irs_nw *this) { 189 struct pvt *pvt = (struct pvt *)this->private; 190 struct irs_nw *nw; 191 192 pvt->rule = pvt->rules; 193 if (pvt->rule) { 194 nw = pvt->rule->inst->nw; 195 (*nw->rewind)(nw); 196 } 197 } 198 199 static void 200 nw_minimize(struct irs_nw *this) { 201 struct pvt *pvt = (struct pvt *)this->private; 202 struct irs_rule *rule; 203 204 if (pvt->res) 205 res_nclose(pvt->res); 206 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 207 struct irs_nw *nw = rule->inst->nw; 208 209 (*nw->minimize)(nw); 210 } 211 } 212 213 static struct __res_state * 214 nw_res_get(struct irs_nw *this) { 215 struct pvt *pvt = (struct pvt *)this->private; 216 217 if (!pvt->res) { 218 struct __res_state *res; 219 res = (struct __res_state *)malloc(sizeof *res); 220 if (!res) { 221 errno = ENOMEM; 222 return (NULL); 223 } 224 memset(res, 0, sizeof *res); 225 nw_res_set(this, res, free); 226 } 227 228 return (pvt->res); 229 } 230 231 static void 232 nw_res_set(struct irs_nw *this, struct __res_state *res, 233 void (*free_res)(void *)) { 234 struct pvt *pvt = (struct pvt *)this->private; 235 struct irs_rule *rule; 236 237 if (pvt->res && pvt->free_res) { 238 res_nclose(pvt->res); 239 (*pvt->free_res)(pvt->res); 240 } 241 242 pvt->res = res; 243 pvt->free_res = free_res; 244 245 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 246 struct irs_nw *nw = rule->inst->nw; 247 248 (*nw->res_set)(nw, pvt->res, NULL); 249 } 250 } 251 252 static int 253 init(struct irs_nw *this) { 254 struct pvt *pvt = (struct pvt *)this->private; 255 256 if (!pvt->res && !nw_res_get(this)) 257 return (-1); 258 if (((pvt->res->options & RES_INIT) == 0U) && 259 res_ninit(pvt->res) == -1) 260 return (-1); 261 return (0); 262 } 263 264 /*! \file */ 265