1248590Smm/* $NetBSD$ */ 2248590Smm 3248590Smm/* 4248590Smm * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5248590Smm * Copyright (c) 1996,1999 by Internet Software Consortium. 6248590Smm * 7248590Smm * Permission to use, copy, modify, and distribute this software for any 8248590Smm * purpose with or without fee is hereby granted, provided that the above 9248590Smm * copyright notice and this permission notice appear in all copies. 10248590Smm * 11248590Smm * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12248590Smm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13248590Smm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14248590Smm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15248590Smm * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16248590Smm * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17248590Smm * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18248590Smm */ 19248590Smm 20248590Smm#if !defined(LINT) && !defined(CODECENTER) 21248590Smmstatic const char rcsid[] = "Id: gen_nw.c,v 1.4 2005/04/27 04:56:23 sra Exp "; 22248590Smm#endif 23248590Smm 24248590Smm/* Imports */ 25248590Smm 26248590Smm#include "port_before.h" 27248590Smm 28248590Smm#include <sys/types.h> 29248590Smm 30248590Smm#include <netinet/in.h> 31248590Smm#include <arpa/nameser.h> 32248590Smm 33248590Smm#include <errno.h> 34248590Smm#include <resolv.h> 35248590Smm#include <stdlib.h> 36248590Smm#include <string.h> 37248590Smm 38248590Smm#include <isc/memcluster.h> 39248590Smm#include <irs.h> 40248590Smm 41248590Smm#include "port_after.h" 42248590Smm 43248590Smm#include "irs_p.h" 44248590Smm#include "gen_p.h" 45248590Smm 46248590Smm/* Types */ 47248590Smm 48248590Smmstruct 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 57static void nw_close(struct irs_nw*); 58static struct nwent * nw_next(struct irs_nw *); 59static struct nwent * nw_byname(struct irs_nw *, const char *, int); 60static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int); 61static void nw_rewind(struct irs_nw *); 62static void nw_minimize(struct irs_nw *); 63static struct __res_state * nw_res_get(struct irs_nw *this); 64static void nw_res_set(struct irs_nw *this, 65 struct __res_state *res, 66 void (*free_res)(void *)); 67 68static int init(struct irs_nw *this); 69 70/* Public */ 71 72struct irs_nw * 73irs_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 105static void 106nw_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 118static struct nwent * 119nw_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 143static struct nwent * 144nw_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 166static struct nwent * 167nw_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 189static void 190nw_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 201static void 202nw_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 215static struct __res_state * 216nw_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 233static void 234nw_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 254static int 255init(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