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