Annotation of src/external/mpl/bind/dist/lib/dns/rdatalist.c, Revision 1.1.1.1
1.1 christos 1: /* $NetBSD$ */
2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
6: * This Source Code Form is subject to the terms of the Mozilla Public
7: * License, v. 2.0. If a copy of the MPL was not distributed with this
8: * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9: *
10: * See the COPYRIGHT file distributed with this work for additional
11: * information regarding copyright ownership.
12: */
13:
14:
15: /*! \file */
16:
17: #include <config.h>
18:
19: #include <stddef.h>
20: #include <string.h>
21:
22: #include <isc/util.h>
23:
24: #include <dns/name.h>
25: #include <dns/nsec3.h>
26: #include <dns/rdata.h>
27: #include <dns/rdatalist.h>
28: #include <dns/rdataset.h>
29:
30: #include "rdatalist_p.h"
31:
32: static dns_rdatasetmethods_t methods = {
33: isc__rdatalist_disassociate,
34: isc__rdatalist_first,
35: isc__rdatalist_next,
36: isc__rdatalist_current,
37: isc__rdatalist_clone,
38: isc__rdatalist_count,
39: isc__rdatalist_addnoqname,
40: isc__rdatalist_getnoqname,
41: isc__rdatalist_addclosest,
42: isc__rdatalist_getclosest,
43: NULL, /* settrust */
44: NULL, /* expire */
45: NULL, /* clearprefetch */
46: isc__rdatalist_setownercase,
47: isc__rdatalist_getownercase,
48: NULL /* addglue */
49: };
50:
51: void
52: dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
53:
54: REQUIRE(rdatalist != NULL);
55:
56: /*
57: * Initialize rdatalist.
58: */
59:
60: rdatalist->rdclass = 0;
61: rdatalist->type = 0;
62: rdatalist->covers = 0;
63: rdatalist->ttl = 0;
64: ISC_LIST_INIT(rdatalist->rdata);
65: ISC_LINK_INIT(rdatalist, link);
66: memset(rdatalist->upper, 0xeb, sizeof(rdatalist->upper));
67: /*
68: * Clear upper set bit.
69: */
70: rdatalist->upper[0] &= ~0x01;
71: }
72:
73: isc_result_t
74: dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
75: dns_rdataset_t *rdataset)
76: {
77: /*
78: * Make 'rdataset' refer to the rdata in 'rdatalist'.
79: */
80:
81: REQUIRE(rdatalist != NULL);
82: REQUIRE(DNS_RDATASET_VALID(rdataset));
83: REQUIRE(! dns_rdataset_isassociated(rdataset));
84:
85: /* Check if dns_rdatalist_init has was called. */
86: REQUIRE(rdatalist->upper[0] == 0xea);
87:
88: rdataset->methods = &methods;
89: rdataset->rdclass = rdatalist->rdclass;
90: rdataset->type = rdatalist->type;
91: rdataset->covers = rdatalist->covers;
92: rdataset->ttl = rdatalist->ttl;
93: rdataset->trust = 0;
94: rdataset->private1 = rdatalist;
95: rdataset->private2 = NULL;
96: rdataset->private3 = NULL;
97: rdataset->privateuint4 = 0;
98: rdataset->private5 = NULL;
99:
100: return (ISC_R_SUCCESS);
101: }
102:
103: isc_result_t
104: dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
105: dns_rdatalist_t **rdatalist)
106: {
107: REQUIRE(rdatalist != NULL && rdataset != NULL);
108: *rdatalist = rdataset->private1;
109:
110: return (ISC_R_SUCCESS);
111: }
112:
113: void
114: isc__rdatalist_disassociate(dns_rdataset_t *rdataset) {
115: UNUSED(rdataset);
116: }
117:
118: isc_result_t
119: isc__rdatalist_first(dns_rdataset_t *rdataset) {
120: dns_rdatalist_t *rdatalist;
121:
122: rdatalist = rdataset->private1;
123: rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata);
124:
125: if (rdataset->private2 == NULL)
126: return (ISC_R_NOMORE);
127:
128: return (ISC_R_SUCCESS);
129: }
130:
131: isc_result_t
132: isc__rdatalist_next(dns_rdataset_t *rdataset) {
133: dns_rdata_t *rdata;
134:
135: REQUIRE(rdataset != NULL);
136:
137: rdata = rdataset->private2;
138: if (rdata == NULL)
139: return (ISC_R_NOMORE);
140:
141: rdataset->private2 = ISC_LIST_NEXT(rdata, link);
142:
143: if (rdataset->private2 == NULL)
144: return (ISC_R_NOMORE);
145:
146: return (ISC_R_SUCCESS);
147: }
148:
149: void
150: isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
151: dns_rdata_t *list_rdata;
152:
153: REQUIRE(rdataset != NULL);
154:
155: list_rdata = rdataset->private2;
156: INSIST(list_rdata != NULL);
157:
158: dns_rdata_clone(list_rdata, rdata);
159: }
160:
161: void
162: isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
163:
164: REQUIRE(source != NULL);
165: REQUIRE(target != NULL);
166:
167: *target = *source;
168:
169: /*
170: * Reset iterator state.
171: */
172: target->private2 = NULL;
173: }
174:
175: unsigned int
176: isc__rdatalist_count(dns_rdataset_t *rdataset) {
177: dns_rdatalist_t *rdatalist;
178: dns_rdata_t *rdata;
179: unsigned int count;
180:
181: REQUIRE(rdataset != NULL);
182:
183: rdatalist = rdataset->private1;
184:
185: count = 0;
186: for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
187: rdata != NULL;
188: rdata = ISC_LIST_NEXT(rdata, link))
189: count++;
190:
191: return (count);
192: }
193:
194: isc_result_t
195: isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const dns_name_t *name) {
196: dns_rdataset_t *neg = NULL;
197: dns_rdataset_t *negsig = NULL;
198: dns_rdataset_t *rdset;
199: dns_ttl_t ttl;
200:
201: REQUIRE(rdataset != NULL);
202:
203: for (rdset = ISC_LIST_HEAD(name->list);
204: rdset != NULL;
205: rdset = ISC_LIST_NEXT(rdset, link))
206: {
207: if (rdset->rdclass != rdataset->rdclass)
208: continue;
209: if (rdset->type == dns_rdatatype_nsec ||
210: rdset->type == dns_rdatatype_nsec3)
211: neg = rdset;
212: }
213: if (neg == NULL)
214: return (ISC_R_NOTFOUND);
215:
216: for (rdset = ISC_LIST_HEAD(name->list);
217: rdset != NULL;
218: rdset = ISC_LIST_NEXT(rdset, link))
219: {
220: if (rdset->type == dns_rdatatype_rrsig &&
221: rdset->covers == neg->type)
222: negsig = rdset;
223: }
224:
225: if (negsig == NULL)
226: return (ISC_R_NOTFOUND);
227: /*
228: * Minimise ttl.
229: */
230: ttl = rdataset->ttl;
231: if (neg->ttl < ttl)
232: ttl = neg->ttl;
233: if (negsig->ttl < ttl)
234: ttl = negsig->ttl;
235: rdataset->ttl = neg->ttl = negsig->ttl = ttl;
236: rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
237: rdataset->private6 = name;
238: return (ISC_R_SUCCESS);
239: }
240:
241: isc_result_t
242: isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
243: dns_rdataset_t *neg, dns_rdataset_t *negsig)
244: {
245: dns_rdataclass_t rdclass = rdataset->rdclass;
246: dns_rdataset_t *tneg = NULL;
247: dns_rdataset_t *tnegsig = NULL;
248: const dns_name_t *noqname = rdataset->private6;
249:
250: REQUIRE(rdataset != NULL);
251: REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
252:
253: (void)dns_name_dynamic(noqname); /* Sanity Check. */
254:
255: for (rdataset = ISC_LIST_HEAD(noqname->list);
256: rdataset != NULL;
257: rdataset = ISC_LIST_NEXT(rdataset, link))
258: {
259: if (rdataset->rdclass != rdclass)
260: continue;
261: if (rdataset->type == dns_rdatatype_nsec ||
262: rdataset->type == dns_rdatatype_nsec3)
263: tneg = rdataset;
264: }
265: if (tneg == NULL)
266: return (ISC_R_NOTFOUND);
267:
268: for (rdataset = ISC_LIST_HEAD(noqname->list);
269: rdataset != NULL;
270: rdataset = ISC_LIST_NEXT(rdataset, link))
271: {
272: if (rdataset->type == dns_rdatatype_rrsig &&
273: rdataset->covers == tneg->type)
274: tnegsig = rdataset;
275: }
276: if (tnegsig == NULL)
277: return (ISC_R_NOTFOUND);
278:
279: dns_name_clone(noqname, name);
280: dns_rdataset_clone(tneg, neg);
281: dns_rdataset_clone(tnegsig, negsig);
282: return (ISC_R_SUCCESS);
283: }
284:
285: isc_result_t
286: isc__rdatalist_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name) {
287: dns_rdataset_t *neg = NULL;
288: dns_rdataset_t *negsig = NULL;
289: dns_rdataset_t *rdset;
290: dns_ttl_t ttl;
291:
292: REQUIRE(rdataset != NULL);
293:
294: for (rdset = ISC_LIST_HEAD(name->list);
295: rdset != NULL;
296: rdset = ISC_LIST_NEXT(rdset, link))
297: {
298: if (rdset->rdclass != rdataset->rdclass)
299: continue;
300: if (rdset->type == dns_rdatatype_nsec ||
301: rdset->type == dns_rdatatype_nsec3)
302: neg = rdset;
303: }
304: if (neg == NULL)
305: return (ISC_R_NOTFOUND);
306:
307: for (rdset = ISC_LIST_HEAD(name->list);
308: rdset != NULL;
309: rdset = ISC_LIST_NEXT(rdset, link))
310: {
311: if (rdset->type == dns_rdatatype_rrsig &&
312: rdset->covers == neg->type)
313: negsig = rdset;
314: }
315:
316: if (negsig == NULL)
317: return (ISC_R_NOTFOUND);
318: /*
319: * Minimise ttl.
320: */
321: ttl = rdataset->ttl;
322: if (neg->ttl < ttl)
323: ttl = neg->ttl;
324: if (negsig->ttl < ttl)
325: ttl = negsig->ttl;
326: rdataset->ttl = neg->ttl = negsig->ttl = ttl;
327: rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
328: rdataset->private7 = name;
329: return (ISC_R_SUCCESS);
330: }
331:
332: isc_result_t
333: isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
334: dns_rdataset_t *neg, dns_rdataset_t *negsig)
335: {
336: dns_rdataclass_t rdclass = rdataset->rdclass;
337: dns_rdataset_t *tneg = NULL;
338: dns_rdataset_t *tnegsig = NULL;
339: const dns_name_t *closest = rdataset->private7;
340:
341: REQUIRE(rdataset != NULL);
342: REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0);
343:
344: (void)dns_name_dynamic(closest); /* Sanity Check. */
345:
346: for (rdataset = ISC_LIST_HEAD(closest->list);
347: rdataset != NULL;
348: rdataset = ISC_LIST_NEXT(rdataset, link))
349: {
350: if (rdataset->rdclass != rdclass)
351: continue;
352: if (rdataset->type == dns_rdatatype_nsec ||
353: rdataset->type == dns_rdatatype_nsec3)
354: tneg = rdataset;
355: }
356: if (tneg == NULL)
357: return (ISC_R_NOTFOUND);
358:
359: for (rdataset = ISC_LIST_HEAD(closest->list);
360: rdataset != NULL;
361: rdataset = ISC_LIST_NEXT(rdataset, link))
362: {
363: if (rdataset->type == dns_rdatatype_rrsig &&
364: rdataset->covers == tneg->type)
365: tnegsig = rdataset;
366: }
367: if (tnegsig == NULL)
368: return (ISC_R_NOTFOUND);
369:
370: dns_name_clone(closest, name);
371: dns_rdataset_clone(tneg, neg);
372: dns_rdataset_clone(tnegsig, negsig);
373: return (ISC_R_SUCCESS);
374: }
375:
376: void
377: isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
378: dns_rdatalist_t *rdatalist;
379: unsigned int i;
380:
381: /*
382: * We do not need to worry about label lengths as they are all
383: * less than or equal to 63.
384: */
385: rdatalist = rdataset->private1;
386: memset(rdatalist->upper, 0, sizeof(rdatalist->upper));
387: for (i = 1; i < name->length; i++)
388: if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
389: rdatalist->upper[i/8] |= 1 << (i%8);
390: /*
391: * Record that upper has been set.
392: */
393: rdatalist->upper[0] |= 0x01;
394: }
395:
396: void
397: isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
398: dns_rdatalist_t *rdatalist;
399: unsigned int i;
400:
401: rdatalist = rdataset->private1;
402: if ((rdatalist->upper[0] & 0x01) == 0)
403: return;
404: for (i = 0; i < name->length; i++) {
405: /*
406: * Set the case bit if it does not match the recorded bit.
407: */
408: if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
409: (rdatalist->upper[i/8] & (1 << (i%8))) != 0)
410: name->ndata[i] &= ~0x20; /* clear the lower case bit */
411: else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
412: (rdatalist->upper[i/8] & (1 << (i%8))) == 0)
413: name->ndata[i] |= 0x20; /* set the lower case bit */
414: }
415: }
CVSweb <webmaster@jp.NetBSD.org>