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) 19static const char rcsid[] = "$Id: gen_sv.c,v 1.3 2005/04/27 04:56:24 sra Exp $"; 20#endif 21 22/* Imports */ 23 24#include "port_before.h" 25 26#include <sys/types.h> 27#include <netinet/in.h> 28#include <arpa/nameser.h> 29#include <resolv.h> 30 31#include <errno.h> 32#include <stdlib.h> 33#include <string.h> 34 35#include <isc/memcluster.h> 36#include <irs.h> 37 38#include "port_after.h" 39 40#include "irs_p.h" 41#include "gen_p.h" 42 43/* Types */ 44 45struct pvt { 46 struct irs_rule * rules; 47 struct irs_rule * rule; 48 struct __res_state * res; 49 void (*free_res)(void *); 50}; 51 52/* Forward */ 53 54static void sv_close(struct irs_sv*); 55static struct servent * sv_next(struct irs_sv *); 56static struct servent * sv_byname(struct irs_sv *, const char *, 57 const char *); 58static struct servent * sv_byport(struct irs_sv *, int, const char *); 59static void sv_rewind(struct irs_sv *); 60static void sv_minimize(struct irs_sv *); 61static struct __res_state * sv_res_get(struct irs_sv *); 62static void sv_res_set(struct irs_sv *, 63 struct __res_state *, 64 void (*)(void *)); 65 66/* Public */ 67 68struct irs_sv * 69irs_gen_sv(struct irs_acc *this) { 70 struct gen_p *accpvt = (struct gen_p *)this->private; 71 struct irs_sv *sv; 72 struct pvt *pvt; 73 74 if (!(sv = memget(sizeof *sv))) { 75 errno = ENOMEM; 76 return (NULL); 77 } 78 memset(sv, 0x5e, sizeof *sv); 79 if (!(pvt = memget(sizeof *pvt))) { 80 memput(sv, sizeof *sv); 81 errno = ENOMEM; 82 return (NULL); 83 } 84 memset(pvt, 0, sizeof *pvt); 85 pvt->rules = accpvt->map_rules[irs_sv]; 86 pvt->rule = pvt->rules; 87 sv->private = pvt; 88 sv->close = sv_close; 89 sv->next = sv_next; 90 sv->byname = sv_byname; 91 sv->byport = sv_byport; 92 sv->rewind = sv_rewind; 93 sv->minimize = sv_minimize; 94 sv->res_get = sv_res_get; 95 sv->res_set = sv_res_set; 96 return (sv); 97} 98 99/* Methods */ 100 101static void 102sv_close(struct irs_sv *this) { 103 struct pvt *pvt = (struct pvt *)this->private; 104 105 memput(pvt, sizeof *pvt); 106 memput(this, sizeof *this); 107} 108 109static struct servent * 110sv_next(struct irs_sv *this) { 111 struct pvt *pvt = (struct pvt *)this->private; 112 struct servent *rval; 113 struct irs_sv *sv; 114 115 while (pvt->rule) { 116 sv = pvt->rule->inst->sv; 117 rval = (*sv->next)(sv); 118 if (rval) 119 return (rval); 120 if (!(pvt->rule->flags & IRS_CONTINUE)) 121 break; 122 pvt->rule = pvt->rule->next; 123 if (pvt->rule) { 124 sv = pvt->rule->inst->sv; 125 (*sv->rewind)(sv); 126 } 127 } 128 return (NULL); 129} 130 131static struct servent * 132sv_byname(struct irs_sv *this, const char *name, const char *proto) { 133 struct pvt *pvt = (struct pvt *)this->private; 134 struct irs_rule *rule; 135 struct servent *rval; 136 struct irs_sv *sv; 137 138 rval = NULL; 139 for (rule = pvt->rules; rule; rule = rule->next) { 140 sv = rule->inst->sv; 141 rval = (*sv->byname)(sv, name, proto); 142 if (rval || !(rule->flags & IRS_CONTINUE)) 143 break; 144 } 145 return (rval); 146} 147 148static struct servent * 149sv_byport(struct irs_sv *this, int port, const char *proto) { 150 struct pvt *pvt = (struct pvt *)this->private; 151 struct irs_rule *rule; 152 struct servent *rval; 153 struct irs_sv *sv; 154 155 rval = NULL; 156 for (rule = pvt->rules; rule; rule = rule->next) { 157 sv = rule->inst->sv; 158 rval = (*sv->byport)(sv, port, proto); 159 if (rval || !(rule->flags & IRS_CONTINUE)) 160 break; 161 } 162 return (rval); 163} 164 165static void 166sv_rewind(struct irs_sv *this) { 167 struct pvt *pvt = (struct pvt *)this->private; 168 struct irs_sv *sv; 169 170 pvt->rule = pvt->rules; 171 if (pvt->rule) { 172 sv = pvt->rule->inst->sv; 173 (*sv->rewind)(sv); 174 } 175} 176 177static void 178sv_minimize(struct irs_sv *this) { 179 struct pvt *pvt = (struct pvt *)this->private; 180 struct irs_rule *rule; 181 182 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 183 struct irs_sv *sv = rule->inst->sv; 184 185 (*sv->minimize)(sv); 186 } 187} 188 189static struct __res_state * 190sv_res_get(struct irs_sv *this) { 191 struct pvt *pvt = (struct pvt *)this->private; 192 193 if (!pvt->res) { 194 struct __res_state *res; 195 res = (struct __res_state *)malloc(sizeof *res); 196 if (!res) { 197 errno = ENOMEM; 198 return (NULL); 199 } 200 memset(res, 0, sizeof *res); 201 sv_res_set(this, res, free); 202 } 203 204 return (pvt->res); 205} 206 207static void 208sv_res_set(struct irs_sv *this, struct __res_state *res, 209 void (*free_res)(void *)) { 210 struct pvt *pvt = (struct pvt *)this->private; 211 struct irs_rule *rule; 212 213 if (pvt->res && pvt->free_res) { 214 res_nclose(pvt->res); 215 (*pvt->free_res)(pvt->res); 216 } 217 218 pvt->res = res; 219 pvt->free_res = free_res; 220 221 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 222 struct irs_sv *sv = rule->inst->sv; 223 224 if (sv->res_set) 225 (*sv->res_set)(sv, pvt->res, NULL); 226 } 227} 228 229/*! \file */ 230