00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <stddef.h>
00025 #include <string.h>
00026
00027 #include <isc/util.h>
00028
00029 #include <dns/name.h>
00030 #include <dns/nsec3.h>
00031 #include <dns/rdata.h>
00032 #include <dns/rdatalist.h>
00033 #include <dns/rdataset.h>
00034
00035 #include "rdatalist_p.h"
00036
00037 static dns_rdatasetmethods_t methods = {
00038 isc__rdatalist_disassociate,
00039 isc__rdatalist_first,
00040 isc__rdatalist_next,
00041 isc__rdatalist_current,
00042 isc__rdatalist_clone,
00043 isc__rdatalist_count,
00044 isc__rdatalist_addnoqname,
00045 isc__rdatalist_getnoqname,
00046 isc__rdatalist_addclosest,
00047 isc__rdatalist_getclosest,
00048 NULL,
00049 NULL,
00050 NULL,
00051 NULL,
00052 NULL,
00053 NULL,
00054 isc__rdatalist_setownercase,
00055 isc__rdatalist_getownercase
00056 };
00057
00058 void
00059 dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
00060
00061 REQUIRE(rdatalist != NULL);
00062
00063
00064
00065
00066
00067 rdatalist->rdclass = 0;
00068 rdatalist->type = 0;
00069 rdatalist->covers = 0;
00070 rdatalist->ttl = 0;
00071 ISC_LIST_INIT(rdatalist->rdata);
00072 ISC_LINK_INIT(rdatalist, link);
00073 memset(rdatalist->upper, 0xeb, sizeof(rdatalist->upper));
00074
00075
00076
00077 rdatalist->upper[0] &= ~0x01;
00078 }
00079
00080 isc_result_t
00081 dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
00082 dns_rdataset_t *rdataset)
00083 {
00084
00085
00086
00087
00088 REQUIRE(rdatalist != NULL);
00089 REQUIRE(DNS_RDATASET_VALID(rdataset));
00090 REQUIRE(! dns_rdataset_isassociated(rdataset));
00091
00092
00093 REQUIRE(rdatalist->upper[0] == 0xea);
00094
00095 rdataset->methods = &methods;
00096 rdataset->rdclass = rdatalist->rdclass;
00097 rdataset->type = rdatalist->type;
00098 rdataset->covers = rdatalist->covers;
00099 rdataset->ttl = rdatalist->ttl;
00100 rdataset->trust = 0;
00101 rdataset->private1 = rdatalist;
00102 rdataset->private2 = NULL;
00103 rdataset->private3 = NULL;
00104 rdataset->privateuint4 = 0;
00105 rdataset->private5 = NULL;
00106
00107 return (ISC_R_SUCCESS);
00108 }
00109
00110 isc_result_t
00111 dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
00112 dns_rdatalist_t **rdatalist)
00113 {
00114 REQUIRE(rdatalist != NULL && rdataset != NULL);
00115 *rdatalist = rdataset->private1;
00116
00117 return (ISC_R_SUCCESS);
00118 }
00119
00120 void
00121 isc__rdatalist_disassociate(dns_rdataset_t *rdataset) {
00122 UNUSED(rdataset);
00123 }
00124
00125 isc_result_t
00126 isc__rdatalist_first(dns_rdataset_t *rdataset) {
00127 dns_rdatalist_t *rdatalist;
00128
00129 rdatalist = rdataset->private1;
00130 rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata);
00131
00132 if (rdataset->private2 == NULL)
00133 return (ISC_R_NOMORE);
00134
00135 return (ISC_R_SUCCESS);
00136 }
00137
00138 isc_result_t
00139 isc__rdatalist_next(dns_rdataset_t *rdataset) {
00140 dns_rdata_t *rdata;
00141
00142 REQUIRE(rdataset != NULL);
00143
00144 rdata = rdataset->private2;
00145 if (rdata == NULL)
00146 return (ISC_R_NOMORE);
00147
00148 rdataset->private2 = ISC_LIST_NEXT(rdata, link);
00149
00150 if (rdataset->private2 == NULL)
00151 return (ISC_R_NOMORE);
00152
00153 return (ISC_R_SUCCESS);
00154 }
00155
00156 void
00157 isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
00158 dns_rdata_t *list_rdata;
00159
00160 REQUIRE(rdataset != NULL);
00161
00162 list_rdata = rdataset->private2;
00163 INSIST(list_rdata != NULL);
00164
00165 dns_rdata_clone(list_rdata, rdata);
00166 }
00167
00168 void
00169 isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
00170
00171 REQUIRE(source != NULL);
00172 REQUIRE(target != NULL);
00173
00174 *target = *source;
00175
00176
00177
00178
00179 target->private2 = NULL;
00180 }
00181
00182 unsigned int
00183 isc__rdatalist_count(dns_rdataset_t *rdataset) {
00184 dns_rdatalist_t *rdatalist;
00185 dns_rdata_t *rdata;
00186 unsigned int count;
00187
00188 REQUIRE(rdataset != NULL);
00189
00190 rdatalist = rdataset->private1;
00191
00192 count = 0;
00193 for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
00194 rdata != NULL;
00195 rdata = ISC_LIST_NEXT(rdata, link))
00196 count++;
00197
00198 return (count);
00199 }
00200
00201 isc_result_t
00202 isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
00203 dns_rdataset_t *neg = NULL;
00204 dns_rdataset_t *negsig = NULL;
00205 dns_rdataset_t *rdset;
00206 dns_ttl_t ttl;
00207
00208 REQUIRE(rdataset != NULL);
00209
00210 for (rdset = ISC_LIST_HEAD(name->list);
00211 rdset != NULL;
00212 rdset = ISC_LIST_NEXT(rdset, link))
00213 {
00214 if (rdset->rdclass != rdataset->rdclass)
00215 continue;
00216 if (rdset->type == dns_rdatatype_nsec ||
00217 rdset->type == dns_rdatatype_nsec3)
00218 neg = rdset;
00219 }
00220 if (neg == NULL)
00221 return (ISC_R_NOTFOUND);
00222
00223 for (rdset = ISC_LIST_HEAD(name->list);
00224 rdset != NULL;
00225 rdset = ISC_LIST_NEXT(rdset, link))
00226 {
00227 if (rdset->type == dns_rdatatype_rrsig &&
00228 rdset->covers == neg->type)
00229 negsig = rdset;
00230 }
00231
00232 if (negsig == NULL)
00233 return (ISC_R_NOTFOUND);
00234
00235
00236
00237 ttl = rdataset->ttl;
00238 if (neg->ttl < ttl)
00239 ttl = neg->ttl;
00240 if (negsig->ttl < ttl)
00241 ttl = negsig->ttl;
00242 rdataset->ttl = neg->ttl = negsig->ttl = ttl;
00243 rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
00244 rdataset->private6 = name;
00245 return (ISC_R_SUCCESS);
00246 }
00247
00248 isc_result_t
00249 isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
00250 dns_rdataset_t *neg, dns_rdataset_t *negsig)
00251 {
00252 dns_rdataclass_t rdclass = rdataset->rdclass;
00253 dns_rdataset_t *tneg = NULL;
00254 dns_rdataset_t *tnegsig = NULL;
00255 dns_name_t *noqname = rdataset->private6;
00256
00257 REQUIRE(rdataset != NULL);
00258 REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
00259
00260 (void)dns_name_dynamic(noqname);
00261
00262 for (rdataset = ISC_LIST_HEAD(noqname->list);
00263 rdataset != NULL;
00264 rdataset = ISC_LIST_NEXT(rdataset, link))
00265 {
00266 if (rdataset->rdclass != rdclass)
00267 continue;
00268 if (rdataset->type == dns_rdatatype_nsec ||
00269 rdataset->type == dns_rdatatype_nsec3)
00270 tneg = rdataset;
00271 }
00272 if (tneg == NULL)
00273 return (ISC_R_NOTFOUND);
00274
00275 for (rdataset = ISC_LIST_HEAD(noqname->list);
00276 rdataset != NULL;
00277 rdataset = ISC_LIST_NEXT(rdataset, link))
00278 {
00279 if (rdataset->type == dns_rdatatype_rrsig &&
00280 rdataset->covers == tneg->type)
00281 tnegsig = rdataset;
00282 }
00283 if (tnegsig == NULL)
00284 return (ISC_R_NOTFOUND);
00285
00286 dns_name_clone(noqname, name);
00287 dns_rdataset_clone(tneg, neg);
00288 dns_rdataset_clone(tnegsig, negsig);
00289 return (ISC_R_SUCCESS);
00290 }
00291
00292 isc_result_t
00293 isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
00294 dns_rdataset_t *neg = NULL;
00295 dns_rdataset_t *negsig = NULL;
00296 dns_rdataset_t *rdset;
00297 dns_ttl_t ttl;
00298
00299 REQUIRE(rdataset != NULL);
00300
00301 for (rdset = ISC_LIST_HEAD(name->list);
00302 rdset != NULL;
00303 rdset = ISC_LIST_NEXT(rdset, link))
00304 {
00305 if (rdset->rdclass != rdataset->rdclass)
00306 continue;
00307 if (rdset->type == dns_rdatatype_nsec ||
00308 rdset->type == dns_rdatatype_nsec3)
00309 neg = rdset;
00310 }
00311 if (neg == NULL)
00312 return (ISC_R_NOTFOUND);
00313
00314 for (rdset = ISC_LIST_HEAD(name->list);
00315 rdset != NULL;
00316 rdset = ISC_LIST_NEXT(rdset, link))
00317 {
00318 if (rdset->type == dns_rdatatype_rrsig &&
00319 rdset->covers == neg->type)
00320 negsig = rdset;
00321 }
00322
00323 if (negsig == NULL)
00324 return (ISC_R_NOTFOUND);
00325
00326
00327
00328 ttl = rdataset->ttl;
00329 if (neg->ttl < ttl)
00330 ttl = neg->ttl;
00331 if (negsig->ttl < ttl)
00332 ttl = negsig->ttl;
00333 rdataset->ttl = neg->ttl = negsig->ttl = ttl;
00334 rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
00335 rdataset->private7 = name;
00336 return (ISC_R_SUCCESS);
00337 }
00338
00339 isc_result_t
00340 isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
00341 dns_rdataset_t *neg, dns_rdataset_t *negsig)
00342 {
00343 dns_rdataclass_t rdclass = rdataset->rdclass;
00344 dns_rdataset_t *tneg = NULL;
00345 dns_rdataset_t *tnegsig = NULL;
00346 dns_name_t *closest = rdataset->private7;
00347
00348 REQUIRE(rdataset != NULL);
00349 REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0);
00350
00351 (void)dns_name_dynamic(closest);
00352
00353 for (rdataset = ISC_LIST_HEAD(closest->list);
00354 rdataset != NULL;
00355 rdataset = ISC_LIST_NEXT(rdataset, link))
00356 {
00357 if (rdataset->rdclass != rdclass)
00358 continue;
00359 if (rdataset->type == dns_rdatatype_nsec ||
00360 rdataset->type == dns_rdatatype_nsec3)
00361 tneg = rdataset;
00362 }
00363 if (tneg == NULL)
00364 return (ISC_R_NOTFOUND);
00365
00366 for (rdataset = ISC_LIST_HEAD(closest->list);
00367 rdataset != NULL;
00368 rdataset = ISC_LIST_NEXT(rdataset, link))
00369 {
00370 if (rdataset->type == dns_rdatatype_rrsig &&
00371 rdataset->covers == tneg->type)
00372 tnegsig = rdataset;
00373 }
00374 if (tnegsig == NULL)
00375 return (ISC_R_NOTFOUND);
00376
00377 dns_name_clone(closest, name);
00378 dns_rdataset_clone(tneg, neg);
00379 dns_rdataset_clone(tnegsig, negsig);
00380 return (ISC_R_SUCCESS);
00381 }
00382
00383 void
00384 isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
00385 dns_rdatalist_t *rdatalist;
00386 unsigned int i;
00387
00388
00389
00390
00391
00392 rdatalist = rdataset->private1;
00393 memset(rdatalist->upper, 0, sizeof(rdatalist->upper));
00394 for (i = 1; i < name->length; i++)
00395 if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
00396 rdatalist->upper[i/8] |= 1 << (i%8);
00397
00398
00399
00400 rdatalist->upper[0] |= 0x01;
00401 }
00402
00403 void
00404 isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
00405 dns_rdatalist_t *rdatalist;
00406 unsigned int i;
00407
00408 rdatalist = rdataset->private1;
00409 if ((rdatalist->upper[0] & 0x01) == 0)
00410 return;
00411 for (i = 0; i < name->length; i++) {
00412
00413
00414
00415 if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
00416 (rdatalist->upper[i/8] & (1 << (i%8))) != 0)
00417 name->ndata[i] &= ~0x20;
00418 else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
00419 (rdatalist->upper[i/8] & (1 << (i%8))) == 0)
00420 name->ndata[i] |= 0x20;
00421 }
00422 }