Commit | Line | Data |
---|---|---|
bbbf71a3 JL |
1 | /* |
2 | * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") | |
3 | * Copyright (C) 1998-2003 Internet Software Consortium. | |
4 | * | |
5 | * Permission to use, copy, modify, and/or 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 WITH | |
10 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |
11 | * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, | |
12 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | |
13 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | |
14 | * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
15 | * PERFORMANCE OF THIS SOFTWARE. | |
16 | */ | |
17 | ||
18 | /* $Id: name.h,v 1.126.128.2 2009/01/19 23:47:03 tbox Exp $ */ | |
19 | ||
20 | #ifndef DNS_NAME_H | |
21 | #define DNS_NAME_H 1 | |
22 | ||
23 | /***** | |
24 | ***** Module Info | |
25 | *****/ | |
26 | ||
27 | /*! \file dns/name.h | |
28 | * \brief | |
29 | * Provides facilities for manipulating DNS names and labels, including | |
30 | * conversions to and from wire format and text format. | |
31 | * | |
32 | * Given the large number of names possible in a nameserver, and because | |
33 | * names occur in rdata, it was important to come up with a very efficient | |
34 | * way of storing name data, but at the same time allow names to be | |
35 | * manipulated. The decision was to store names in uncompressed wire format, | |
36 | * and not to make them fully abstracted objects; i.e. certain parts of the | |
37 | * server know names are stored that way. This saves a lot of memory, and | |
38 | * makes adding names to messages easy. Having much of the server know | |
39 | * the representation would be perilous, and we certainly don't want each | |
40 | * user of names to be manipulating such a low-level structure. This is | |
41 | * where the Names and Labels module comes in. The module allows name or | |
42 | * label handles to be created and attached to uncompressed wire format | |
43 | * regions. All name operations and conversions are done through these | |
44 | * handles. | |
45 | * | |
46 | * MP: | |
47 | *\li Clients of this module must impose any required synchronization. | |
48 | * | |
49 | * Reliability: | |
50 | *\li This module deals with low-level byte streams. Errors in any of | |
51 | * the functions are likely to crash the server or corrupt memory. | |
52 | * | |
53 | * Resources: | |
54 | *\li None. | |
55 | * | |
56 | * Security: | |
57 | * | |
58 | *\li *** WARNING *** | |
59 | * | |
60 | *\li dns_name_fromwire() deals with raw network data. An error in | |
61 | * this routine could result in the failure or hijacking of the server. | |
62 | * | |
63 | * Standards: | |
64 | *\li RFC1035 | |
65 | *\li Draft EDNS0 (0) | |
66 | *\li Draft Binary Labels (2) | |
67 | * | |
68 | */ | |
69 | ||
70 | /*** | |
71 | *** Imports | |
72 | ***/ | |
73 | ||
74 | #include <stdio.h> | |
75 | ||
76 | #include <isc/boolean.h> | |
77 | #include <isc/lang.h> | |
78 | #include <isc/magic.h> | |
79 | #include <isc/region.h> /* Required for storage size of dns_label_t. */ | |
80 | ||
81 | #include <dns/types.h> | |
82 | ||
83 | ISC_LANG_BEGINDECLS | |
84 | ||
85 | /***** | |
86 | ***** Labels | |
87 | ***** | |
88 | ***** A 'label' is basically a region. It contains one DNS wire format | |
89 | ***** label of type 00 (ordinary). | |
90 | *****/ | |
91 | ||
92 | /***** | |
93 | ***** Names | |
94 | ***** | |
95 | ***** A 'name' is a handle to a binary region. It contains a sequence of one | |
96 | ***** or more DNS wire format labels of type 00 (ordinary). | |
97 | ***** Note that all names are not required to end with the root label, | |
98 | ***** as they are in the actual DNS wire protocol. | |
99 | *****/ | |
100 | ||
101 | /*** | |
102 | *** Compression pointer chaining limit | |
103 | ***/ | |
104 | ||
105 | #define DNS_POINTER_MAXHOPS 16 | |
106 | ||
107 | /*** | |
108 | *** Types | |
109 | ***/ | |
110 | ||
111 | /*% | |
112 | * Clients are strongly discouraged from using this type directly, with | |
113 | * the exception of the 'link' and 'list' fields which may be used directly | |
114 | * for whatever purpose the client desires. | |
115 | */ | |
116 | struct dns_name { | |
117 | unsigned int magic; | |
118 | unsigned char * ndata; | |
119 | unsigned int length; | |
120 | unsigned int labels; | |
121 | unsigned int attributes; | |
122 | unsigned char * offsets; | |
123 | isc_buffer_t * buffer; | |
124 | ISC_LINK(dns_name_t) link; | |
125 | ISC_LIST(dns_rdataset_t) list; | |
126 | }; | |
127 | ||
128 | #define DNS_NAME_MAGIC ISC_MAGIC('D','N','S','n') | |
129 | ||
130 | #define DNS_NAMEATTR_ABSOLUTE 0x0001 | |
131 | #define DNS_NAMEATTR_READONLY 0x0002 | |
132 | #define DNS_NAMEATTR_DYNAMIC 0x0004 | |
133 | #define DNS_NAMEATTR_DYNOFFSETS 0x0008 | |
134 | #define DNS_NAMEATTR_NOCOMPRESS 0x0010 | |
135 | /* | |
136 | * Attributes below 0x0100 reserved for name.c usage. | |
137 | */ | |
138 | #define DNS_NAMEATTR_CACHE 0x0100 /*%< Used by resolver. */ | |
139 | #define DNS_NAMEATTR_ANSWER 0x0200 /*%< Used by resolver. */ | |
140 | #define DNS_NAMEATTR_NCACHE 0x0400 /*%< Used by resolver. */ | |
141 | #define DNS_NAMEATTR_CHAINING 0x0800 /*%< Used by resolver. */ | |
142 | #define DNS_NAMEATTR_CHASE 0x1000 /*%< Used by resolver. */ | |
143 | #define DNS_NAMEATTR_WILDCARD 0x2000 /*%< Used by server. */ | |
144 | ||
145 | #define DNS_NAME_DOWNCASE 0x0001 | |
146 | #define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */ | |
147 | #define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */ | |
148 | #define DNS_NAME_CHECKREVERSE 0x0008 /*%< Used by rdata. */ | |
149 | #define DNS_NAME_CHECKMX 0x0010 /*%< Used by rdata. */ | |
150 | #define DNS_NAME_CHECKMXFAIL 0x0020 /*%< Used by rdata. */ | |
151 | ||
152 | LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_rootname; | |
153 | LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname; | |
154 | ||
155 | /*% | |
156 | * Standard size of a wire format name | |
157 | */ | |
158 | #define DNS_NAME_MAXWIRE 255 | |
159 | ||
160 | /* | |
161 | * Text output filter procedure. | |
162 | * 'target' is the buffer to be converted. The region to be converted | |
163 | * is from 'buffer'->base + 'used_org' to the end of the used region. | |
164 | */ | |
165 | typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target, | |
166 | unsigned int used_org, | |
167 | isc_boolean_t absolute); | |
168 | ||
169 | /*** | |
170 | *** Initialization | |
171 | ***/ | |
172 | ||
173 | void | |
174 | dns_name_init(dns_name_t *name, unsigned char *offsets); | |
175 | /*%< | |
176 | * Initialize 'name'. | |
177 | * | |
178 | * Notes: | |
179 | * \li 'offsets' is never required to be non-NULL, but specifying a | |
180 | * dns_offsets_t for 'offsets' will improve the performance of most | |
181 | * name operations if the name is used more than once. | |
182 | * | |
183 | * Requires: | |
184 | * \li 'name' is not NULL and points to a struct dns_name. | |
185 | * | |
186 | * \li offsets == NULL or offsets is a dns_offsets_t. | |
187 | * | |
188 | * Ensures: | |
189 | * \li 'name' is a valid name. | |
190 | * \li dns_name_countlabels(name) == 0 | |
191 | * \li dns_name_isabsolute(name) == ISC_FALSE | |
192 | */ | |
193 | ||
194 | void | |
195 | dns_name_reset(dns_name_t *name); | |
196 | /*%< | |
197 | * Reinitialize 'name'. | |
198 | * | |
199 | * Notes: | |
200 | * \li This function distinguishes itself from dns_name_init() in two | |
201 | * key ways: | |
202 | * | |
203 | * \li + If any buffer is associated with 'name' (via dns_name_setbuffer() | |
204 | * or by being part of a dns_fixedname_t) the link to the buffer | |
205 | * is retained but the buffer itself is cleared. | |
206 | * | |
207 | * \li + Of the attributes associated with 'name', all are retained except | |
208 | * DNS_NAMEATTR_ABSOLUTE. | |
209 | * | |
210 | * Requires: | |
211 | * \li 'name' is a valid name. | |
212 | * | |
213 | * Ensures: | |
214 | * \li 'name' is a valid name. | |
215 | * \li dns_name_countlabels(name) == 0 | |
216 | * \li dns_name_isabsolute(name) == ISC_FALSE | |
217 | */ | |
218 | ||
219 | void | |
220 | dns_name_invalidate(dns_name_t *name); | |
221 | /*%< | |
222 | * Make 'name' invalid. | |
223 | * | |
224 | * Requires: | |
225 | * \li 'name' is a valid name. | |
226 | * | |
227 | * Ensures: | |
228 | * \li If assertion checking is enabled, future attempts to use 'name' | |
229 | * without initializing it will cause an assertion failure. | |
230 | * | |
231 | * \li If the name had a dedicated buffer, that association is ended. | |
232 | */ | |
233 | ||
234 | ||
235 | /*** | |
236 | *** Dedicated Buffers | |
237 | ***/ | |
238 | ||
239 | void | |
240 | dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer); | |
241 | /*%< | |
242 | * Dedicate a buffer for use with 'name'. | |
243 | * | |
244 | * Notes: | |
245 | * \li Specification of a target buffer in dns_name_fromwire(), | |
246 | * dns_name_fromtext(), and dns_name_concatenate() is optional if | |
247 | * 'name' has a dedicated buffer. | |
248 | * | |
249 | * \li The caller must not write to buffer until the name has been | |
250 | * invalidated or is otherwise known not to be in use. | |
251 | * | |
252 | * \li If buffer is NULL and the name previously had a dedicated buffer, | |
253 | * than that buffer is no longer dedicated to use with this name. | |
254 | * The caller is responsible for ensuring that the storage used by | |
255 | * the name remains valid. | |
256 | * | |
257 | * Requires: | |
258 | * \li 'name' is a valid name. | |
259 | * | |
260 | * \li 'buffer' is a valid binary buffer and 'name' doesn't have a | |
261 | * dedicated buffer already, or 'buffer' is NULL. | |
262 | */ | |
263 | ||
264 | isc_boolean_t | |
265 | dns_name_hasbuffer(const dns_name_t *name); | |
266 | /*%< | |
267 | * Does 'name' have a dedicated buffer? | |
268 | * | |
269 | * Requires: | |
270 | * \li 'name' is a valid name. | |
271 | * | |
272 | * Returns: | |
273 | * \li ISC_TRUE 'name' has a dedicated buffer. | |
274 | * \li ISC_FALSE 'name' does not have a dedicated buffer. | |
275 | */ | |
276 | ||
277 | /*** | |
278 | *** Properties | |
279 | ***/ | |
280 | ||
281 | isc_boolean_t | |
282 | dns_name_isabsolute(const dns_name_t *name); | |
283 | /*%< | |
284 | * Does 'name' end in the root label? | |
285 | * | |
286 | * Requires: | |
287 | * \li 'name' is a valid name | |
288 | * | |
289 | * Returns: | |
290 | * \li TRUE The last label in 'name' is the root label. | |
291 | * \li FALSE The last label in 'name' is not the root label. | |
292 | */ | |
293 | ||
294 | isc_boolean_t | |
295 | dns_name_iswildcard(const dns_name_t *name); | |
296 | /*%< | |
297 | * Is 'name' a wildcard name? | |
298 | * | |
299 | * Requires: | |
300 | * \li 'name' is a valid name | |
301 | * | |
302 | * \li dns_name_countlabels(name) > 0 | |
303 | * | |
304 | * Returns: | |
305 | * \li TRUE The least significant label of 'name' is '*'. | |
306 | * \li FALSE The least significant label of 'name' is not '*'. | |
307 | */ | |
308 | ||
309 | unsigned int | |
310 | dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive); | |
311 | /*%< | |
312 | * Provide a hash value for 'name'. | |
313 | * | |
314 | * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in | |
315 | * case will have the same hash value. | |
316 | * | |
317 | * Requires: | |
318 | * \li 'name' is a valid name | |
319 | * | |
320 | * Returns: | |
321 | * \li A hash value | |
322 | */ | |
323 | ||
324 | unsigned int | |
325 | dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive); | |
326 | /*%< | |
327 | * Provide a hash value for 'name'. Unlike dns_name_hash(), this function | |
328 | * always takes into account of the entire name to calculate the hash value. | |
329 | * | |
330 | * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in | |
331 | * case will have the same hash value. | |
332 | * | |
333 | * Requires: | |
334 | *\li 'name' is a valid name | |
335 | * | |
336 | * Returns: | |
337 | *\li A hash value | |
338 | */ | |
339 | ||
340 | unsigned int | |
341 | dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive); | |
342 | /*%< | |
343 | * Provide a hash value for 'name', where the hash value is the sum | |
344 | * of the hash values of each label. | |
345 | * | |
346 | * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in | |
347 | * case will have the same hash value. | |
348 | * | |
349 | * Requires: | |
350 | *\li 'name' is a valid name | |
351 | * | |
352 | * Returns: | |
353 | *\li A hash value | |
354 | */ | |
355 | ||
356 | /* | |
357 | *** Comparisons | |
358 | ***/ | |
359 | ||
360 | dns_namereln_t | |
361 | dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, | |
362 | int *orderp, unsigned int *nlabelsp); | |
363 | /*%< | |
364 | * Determine the relative ordering under the DNSSEC order relation of | |
365 | * 'name1' and 'name2', and also determine the hierarchical | |
366 | * relationship of the names. | |
367 | * | |
368 | * Note: It makes no sense for one of the names to be relative and the | |
369 | * other absolute. If both names are relative, then to be meaningfully | |
370 | * compared the caller must ensure that they are both relative to the | |
371 | * same domain. | |
372 | * | |
373 | * Requires: | |
374 | *\li 'name1' is a valid name | |
375 | * | |
376 | *\li dns_name_countlabels(name1) > 0 | |
377 | * | |
378 | *\li 'name2' is a valid name | |
379 | * | |
380 | *\li dns_name_countlabels(name2) > 0 | |
381 | * | |
382 | *\li orderp and nlabelsp are valid pointers. | |
383 | * | |
384 | *\li Either name1 is absolute and name2 is absolute, or neither is. | |
385 | * | |
386 | * Ensures: | |
387 | * | |
388 | *\li *orderp is < 0 if name1 < name2, 0 if name1 = name2, > 0 if | |
389 | * name1 > name2. | |
390 | * | |
391 | *\li *nlabelsp is the number of common significant labels. | |
392 | * | |
393 | * Returns: | |
394 | *\li dns_namereln_none There's no hierarchical relationship | |
395 | * between name1 and name2. | |
396 | *\li dns_namereln_contains name1 properly contains name2; i.e. | |
397 | * name2 is a proper subdomain of name1. | |
398 | *\li dns_namereln_subdomain name1 is a proper subdomain of name2. | |
399 | *\li dns_namereln_equal name1 and name2 are equal. | |
400 | *\li dns_namereln_commonancestor name1 and name2 share a common | |
401 | * ancestor. | |
402 | */ | |
403 | ||
404 | int | |
405 | dns_name_compare(const dns_name_t *name1, const dns_name_t *name2); | |
406 | /*%< | |
407 | * Determine the relative ordering under the DNSSEC order relation of | |
408 | * 'name1' and 'name2'. | |
409 | * | |
410 | * Note: It makes no sense for one of the names to be relative and the | |
411 | * other absolute. If both names are relative, then to be meaningfully | |
412 | * compared the caller must ensure that they are both relative to the | |
413 | * same domain. | |
414 | * | |
415 | * Requires: | |
416 | * \li 'name1' is a valid name | |
417 | * | |
418 | * \li 'name2' is a valid name | |
419 | * | |
420 | * \li Either name1 is absolute and name2 is absolute, or neither is. | |
421 | * | |
422 | * Returns: | |
423 | * \li < 0 'name1' is less than 'name2' | |
424 | * \li 0 'name1' is equal to 'name2' | |
425 | * \li > 0 'name1' is greater than 'name2' | |
426 | */ | |
427 | ||
428 | isc_boolean_t | |
429 | dns_name_equal(const dns_name_t *name1, const dns_name_t *name2); | |
430 | /*%< | |
431 | * Are 'name1' and 'name2' equal? | |
432 | * | |
433 | * Notes: | |
434 | * \li Because it only needs to test for equality, dns_name_equal() can be | |
435 | * significantly faster than dns_name_fullcompare() or dns_name_compare(). | |
436 | * | |
437 | * \li Offsets tables are not used in the comparision. | |
438 | * | |
439 | * \li It makes no sense for one of the names to be relative and the | |
440 | * other absolute. If both names are relative, then to be meaningfully | |
441 | * compared the caller must ensure that they are both relative to the | |
442 | * same domain. | |
443 | * | |
444 | * Requires: | |
445 | * \li 'name1' is a valid name | |
446 | * | |
447 | * \li 'name2' is a valid name | |
448 | * | |
449 | * \li Either name1 is absolute and name2 is absolute, or neither is. | |
450 | * | |
451 | * Returns: | |
452 | * \li ISC_TRUE 'name1' and 'name2' are equal | |
453 | * \li ISC_FALSE 'name1' and 'name2' are not equal | |
454 | */ | |
455 | ||
456 | isc_boolean_t | |
457 | dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2); | |
458 | /*%< | |
459 | * Case sensitive version of dns_name_equal(). | |
460 | */ | |
461 | ||
462 | int | |
463 | dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2); | |
464 | /*%< | |
465 | * Compare two names as if they are part of rdata in DNSSEC canonical | |
466 | * form. | |
467 | * | |
468 | * Requires: | |
469 | * \li 'name1' is a valid absolute name | |
470 | * | |
471 | * \li dns_name_countlabels(name1) > 0 | |
472 | * | |
473 | * \li 'name2' is a valid absolute name | |
474 | * | |
475 | * \li dns_name_countlabels(name2) > 0 | |
476 | * | |
477 | * Returns: | |
478 | * \li < 0 'name1' is less than 'name2' | |
479 | * \li 0 'name1' is equal to 'name2' | |
480 | * \li > 0 'name1' is greater than 'name2' | |
481 | */ | |
482 | ||
483 | isc_boolean_t | |
484 | dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2); | |
485 | /*%< | |
486 | * Is 'name1' a subdomain of 'name2'? | |
487 | * | |
488 | * Notes: | |
489 | * \li name1 is a subdomain of name2 if name1 is contained in name2, or | |
490 | * name1 equals name2. | |
491 | * | |
492 | * \li It makes no sense for one of the names to be relative and the | |
493 | * other absolute. If both names are relative, then to be meaningfully | |
494 | * compared the caller must ensure that they are both relative to the | |
495 | * same domain. | |
496 | * | |
497 | * Requires: | |
498 | * \li 'name1' is a valid name | |
499 | * | |
500 | * \li 'name2' is a valid name | |
501 | * | |
502 | * \li Either name1 is absolute and name2 is absolute, or neither is. | |
503 | * | |
504 | * Returns: | |
505 | * \li TRUE 'name1' is a subdomain of 'name2' | |
506 | * \li FALSE 'name1' is not a subdomain of 'name2' | |
507 | */ | |
508 | ||
509 | isc_boolean_t | |
510 | dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname); | |
511 | /*%< | |
512 | * Does 'name' match the wildcard specified in 'wname'? | |
513 | * | |
514 | * Notes: | |
515 | * \li name matches the wildcard specified in wname if all labels | |
516 | * following the wildcard in wname are identical to the same number | |
517 | * of labels at the end of name. | |
518 | * | |
519 | * \li It makes no sense for one of the names to be relative and the | |
520 | * other absolute. If both names are relative, then to be meaningfully | |
521 | * compared the caller must ensure that they are both relative to the | |
522 | * same domain. | |
523 | * | |
524 | * Requires: | |
525 | * \li 'name' is a valid name | |
526 | * | |
527 | * \li dns_name_countlabels(name) > 0 | |
528 | * | |
529 | * \li 'wname' is a valid name | |
530 | * | |
531 | * \li dns_name_countlabels(wname) > 0 | |
532 | * | |
533 | * \li dns_name_iswildcard(wname) is true | |
534 | * | |
535 | * \li Either name is absolute and wname is absolute, or neither is. | |
536 | * | |
537 | * Returns: | |
538 | * \li TRUE 'name' matches the wildcard specified in 'wname' | |
539 | * \li FALSE 'name' does not match the wildcard specified in 'wname' | |
540 | */ | |
541 | ||
542 | /*** | |
543 | *** Labels | |
544 | ***/ | |
545 | ||
546 | unsigned int | |
547 | dns_name_countlabels(const dns_name_t *name); | |
548 | /*%< | |
549 | * How many labels does 'name' have? | |
550 | * | |
551 | * Notes: | |
552 | * \li In this case, as in other places, a 'label' is an ordinary label. | |
553 | * | |
554 | * Requires: | |
555 | * \li 'name' is a valid name | |
556 | * | |
557 | * Ensures: | |
558 | * \li The result is <= 128. | |
559 | * | |
560 | * Returns: | |
561 | * \li The number of labels in 'name'. | |
562 | */ | |
563 | ||
564 | void | |
565 | dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label); | |
566 | /*%< | |
567 | * Make 'label' refer to the 'n'th least significant label of 'name'. | |
568 | * | |
569 | * Notes: | |
570 | * \li Numbering starts at 0. | |
571 | * | |
572 | * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the | |
573 | * root label. | |
574 | * | |
575 | * \li 'label' refers to the same memory as 'name', so 'name' must not | |
576 | * be changed while 'label' is still in use. | |
577 | * | |
578 | * Requires: | |
579 | * \li n < dns_name_countlabels(name) | |
580 | */ | |
581 | ||
582 | void | |
583 | dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, | |
584 | unsigned int n, dns_name_t *target); | |
585 | /*%< | |
586 | * Make 'target' refer to the 'n' labels including and following 'first' | |
587 | * in 'source'. | |
588 | * | |
589 | * Notes: | |
590 | * \li Numbering starts at 0. | |
591 | * | |
592 | * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the | |
593 | * root label. | |
594 | * | |
595 | * \li 'target' refers to the same memory as 'source', so 'source' | |
596 | * must not be changed while 'target' is still in use. | |
597 | * | |
598 | * Requires: | |
599 | * \li 'source' and 'target' are valid names. | |
600 | * | |
601 | * \li first < dns_name_countlabels(name) | |
602 | * | |
603 | * \li first + n <= dns_name_countlabels(name) | |
604 | */ | |
605 | ||
606 | ||
607 | void | |
608 | dns_name_clone(const dns_name_t *source, dns_name_t *target); | |
609 | /*%< | |
610 | * Make 'target' refer to the same name as 'source'. | |
611 | * | |
612 | * Notes: | |
613 | * | |
614 | * \li 'target' refers to the same memory as 'source', so 'source' | |
615 | * must not be changed while 'target' is still in use. | |
616 | * | |
617 | * \li This call is functionally equivalent to: | |
618 | * | |
619 | * \code | |
620 | * dns_name_getlabelsequence(source, 0, | |
621 | * dns_name_countlabels(source), | |
622 | * target); | |
623 | * \endcode | |
624 | * | |
625 | * but is more efficient. Also, dns_name_clone() works even if 'source' | |
626 | * is empty. | |
627 | * | |
628 | * Requires: | |
629 | * | |
630 | * \li 'source' is a valid name. | |
631 | * | |
632 | * \li 'target' is a valid name that is not read-only. | |
633 | */ | |
634 | ||
635 | /*** | |
636 | *** Conversions | |
637 | ***/ | |
638 | ||
639 | void | |
640 | dns_name_fromregion(dns_name_t *name, const isc_region_t *r); | |
641 | /*%< | |
642 | * Make 'name' refer to region 'r'. | |
643 | * | |
644 | * Note: | |
645 | * \li If the conversion encounters a root label before the end of the | |
646 | * region the conversion stops and the length is set to the length | |
647 | * so far converted. A maximum of 255 bytes is converted. | |
648 | * | |
649 | * Requires: | |
650 | * \li The data in 'r' is a sequence of one or more type 00 or type 01000001 | |
651 | * labels. | |
652 | */ | |
653 | ||
654 | void | |
655 | dns_name_toregion(dns_name_t *name, isc_region_t *r); | |
656 | /*%< | |
657 | * Make 'r' refer to 'name'. | |
658 | * | |
659 | * Requires: | |
660 | * | |
661 | * \li 'name' is a valid name. | |
662 | * | |
663 | * \li 'r' is a valid region. | |
664 | */ | |
665 | ||
666 | isc_result_t | |
667 | dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, | |
668 | dns_decompress_t *dctx, unsigned int options, | |
669 | isc_buffer_t *target); | |
670 | /*%< | |
671 | * Copy the possibly-compressed name at source (active region) into target, | |
672 | * decompressing it. | |
673 | * | |
674 | * Notes: | |
675 | * \li Decompression policy is controlled by 'dctx'. | |
676 | * | |
677 | * \li If DNS_NAME_DOWNCASE is set, any uppercase letters in 'source' will be | |
678 | * downcased when they are copied into 'target'. | |
679 | * | |
680 | * Security: | |
681 | * | |
682 | * \li *** WARNING *** | |
683 | * | |
684 | * \li This routine will often be used when 'source' contains raw network | |
685 | * data. A programming error in this routine could result in a denial | |
686 | * of service, or in the hijacking of the server. | |
687 | * | |
688 | * Requires: | |
689 | * | |
690 | * \li 'name' is a valid name. | |
691 | * | |
692 | * \li 'source' is a valid buffer and the first byte of the active | |
693 | * region should be the first byte of a DNS wire format domain name. | |
694 | * | |
695 | * \li 'target' is a valid buffer or 'target' is NULL and 'name' has | |
696 | * a dedicated buffer. | |
697 | * | |
698 | * \li 'dctx' is a valid decompression context. | |
699 | * | |
700 | * Ensures: | |
701 | * | |
702 | * If result is success: | |
703 | * \li If 'target' is not NULL, 'name' is attached to it. | |
704 | * | |
705 | * \li Uppercase letters are downcased in the copy iff | |
706 | * DNS_NAME_DOWNCASE is set in options. | |
707 | * | |
708 | * \li The current location in source is advanced, and the used space | |
709 | * in target is updated. | |
710 | * | |
711 | * Result: | |
712 | * \li Success | |
713 | * \li Bad Form: Label Length | |
714 | * \li Bad Form: Unknown Label Type | |
715 | * \li Bad Form: Name Length | |
716 | * \li Bad Form: Compression type not allowed | |
717 | * \li Bad Form: Bad compression pointer | |
718 | * \li Bad Form: Input too short | |
719 | * \li Resource Limit: Too many compression pointers | |
720 | * \li Resource Limit: Not enough space in buffer | |
721 | */ | |
722 | ||
723 | isc_result_t | |
724 | dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, | |
725 | isc_buffer_t *target); | |
726 | /*%< | |
727 | * Convert 'name' into wire format, compressing it as specified by the | |
728 | * compression context 'cctx', and storing the result in 'target'. | |
729 | * | |
730 | * Notes: | |
731 | * \li If the compression context allows global compression, then the | |
732 | * global compression table may be updated. | |
733 | * | |
734 | * Requires: | |
735 | * \li 'name' is a valid name | |
736 | * | |
737 | * \li dns_name_countlabels(name) > 0 | |
738 | * | |
739 | * \li dns_name_isabsolute(name) == TRUE | |
740 | * | |
741 | * \li target is a valid buffer. | |
742 | * | |
743 | * \li Any offsets specified in a global compression table are valid | |
744 | * for buffer. | |
745 | * | |
746 | * Ensures: | |
747 | * | |
748 | * If the result is success: | |
749 | * | |
750 | * \li The used space in target is updated. | |
751 | * | |
752 | * Returns: | |
753 | * \li Success | |
754 | * \li Resource Limit: Not enough space in buffer | |
755 | */ | |
756 | ||
757 | isc_result_t | |
758 | dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, | |
759 | dns_name_t *origin, unsigned int options, | |
760 | isc_buffer_t *target); | |
761 | /*%< | |
762 | * Convert the textual representation of a DNS name at source | |
763 | * into uncompressed wire form stored in target. | |
764 | * | |
765 | * Notes: | |
766 | * \li Relative domain names will have 'origin' appended to them | |
767 | * unless 'origin' is NULL, in which case relative domain names | |
768 | * will remain relative. | |
769 | * | |
770 | * \li If DNS_NAME_DOWNCASE is set in 'options', any uppercase letters | |
771 | * in 'source' will be downcased when they are copied into 'target'. | |
772 | * | |
773 | * Requires: | |
774 | * | |
775 | * \li 'name' is a valid name. | |
776 | * | |
777 | * \li 'source' is a valid buffer. | |
778 | * | |
779 | * \li 'target' is a valid buffer or 'target' is NULL and 'name' has | |
780 | * a dedicated buffer. | |
781 | * | |
782 | * Ensures: | |
783 | * | |
784 | * If result is success: | |
785 | * \li If 'target' is not NULL, 'name' is attached to it. | |
786 | * | |
787 | * \li Uppercase letters are downcased in the copy iff | |
788 | * DNS_NAME_DOWNCASE is set in 'options'. | |
789 | * | |
790 | * \li The current location in source is advanced, and the used space | |
791 | * in target is updated. | |
792 | * | |
793 | * Result: | |
794 | *\li #ISC_R_SUCCESS | |
795 | *\li #DNS_R_EMPTYLABEL | |
796 | *\li #DNS_R_LABELTOOLONG | |
797 | *\li #DNS_R_BADESCAPE | |
798 | *\li (#DNS_R_BADBITSTRING: should not be returned) | |
799 | *\li (#DNS_R_BITSTRINGTOOLONG: should not be returned) | |
800 | *\li #DNS_R_BADDOTTEDQUAD | |
801 | *\li #ISC_R_NOSPACE | |
802 | *\li #ISC_R_UNEXPECTEDEND | |
803 | */ | |
804 | ||
805 | isc_result_t | |
806 | dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, | |
807 | isc_buffer_t *target); | |
808 | /*%< | |
809 | * Convert 'name' into text format, storing the result in 'target'. | |
810 | * | |
811 | * Notes: | |
812 | *\li If 'omit_final_dot' is true, then the final '.' in absolute | |
813 | * names other than the root name will be omitted. | |
814 | * | |
815 | *\li If dns_name_countlabels == 0, the name will be "@", representing the | |
816 | * current origin as described by RFC1035. | |
817 | * | |
818 | *\li The name is not NUL terminated. | |
819 | * | |
820 | * Requires: | |
821 | * | |
822 | *\li 'name' is a valid name | |
823 | * | |
824 | *\li 'target' is a valid buffer. | |
825 | * | |
826 | *\li if dns_name_isabsolute == FALSE, then omit_final_dot == FALSE | |
827 | * | |
828 | * Ensures: | |
829 | * | |
830 | *\li If the result is success: | |
831 | * the used space in target is updated. | |
832 | * | |
833 | * Returns: | |
834 | *\li #ISC_R_SUCCESS | |
835 | *\li #ISC_R_NOSPACE | |
836 | */ | |
837 | ||
838 | #define DNS_NAME_MAXTEXT 1023 | |
839 | /*%< | |
840 | * The maximum length of the text representation of a domain | |
841 | * name as generated by dns_name_totext(). This does not | |
842 | * include space for a terminating NULL. | |
843 | * | |
844 | * This definition is conservative - the actual maximum | |
845 | * is 1004, derived as follows: | |
846 | * | |
847 | * A backslash-decimal escaped character takes 4 bytes. | |
848 | * A wire-encoded name can be up to 255 bytes and each | |
849 | * label is one length byte + at most 63 bytes of data. | |
850 | * Maximizing the label lengths gives us a name of | |
851 | * three 63-octet labels, one 61-octet label, and the | |
852 | * root label: | |
853 | * | |
854 | * 1 + 63 + 1 + 63 + 1 + 63 + 1 + 61 + 1 = 255 | |
855 | * | |
856 | * When printed, this is (3 * 63 + 61) * 4 | |
857 | * bytes for the escaped label data + 4 bytes for the | |
858 | * dot terminating each label = 1004 bytes total. | |
859 | */ | |
860 | ||
861 | isc_result_t | |
862 | dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot, | |
863 | isc_buffer_t *target); | |
864 | /*%< | |
865 | * Convert 'name' into an alternate text format appropriate for filenames, | |
866 | * storing the result in 'target'. The name data is downcased, guaranteeing | |
867 | * that the filename does not depend on the case of the converted name. | |
868 | * | |
869 | * Notes: | |
870 | *\li If 'omit_final_dot' is true, then the final '.' in absolute | |
871 | * names other than the root name will be omitted. | |
872 | * | |
873 | *\li The name is not NUL terminated. | |
874 | * | |
875 | * Requires: | |
876 | * | |
877 | *\li 'name' is a valid absolute name | |
878 | * | |
879 | *\li 'target' is a valid buffer. | |
880 | * | |
881 | * Ensures: | |
882 | * | |
883 | *\li If the result is success: | |
884 | * the used space in target is updated. | |
885 | * | |
886 | * Returns: | |
887 | *\li #ISC_R_SUCCESS | |
888 | *\li #ISC_R_NOSPACE | |
889 | */ | |
890 | ||
891 | isc_result_t | |
892 | dns_name_downcase(dns_name_t *source, dns_name_t *name, | |
893 | isc_buffer_t *target); | |
894 | /*%< | |
895 | * Downcase 'source'. | |
896 | * | |
897 | * Requires: | |
898 | * | |
899 | *\li 'source' and 'name' are valid names. | |
900 | * | |
901 | *\li If source == name, then | |
902 | * 'source' must not be read-only | |
903 | * | |
904 | *\li Otherwise, | |
905 | * 'target' is a valid buffer or 'target' is NULL and | |
906 | * 'name' has a dedicated buffer. | |
907 | * | |
908 | * Returns: | |
909 | *\li #ISC_R_SUCCESS | |
910 | *\li #ISC_R_NOSPACE | |
911 | * | |
912 | * Note: if source == name, then the result will always be ISC_R_SUCCESS. | |
913 | */ | |
914 | ||
915 | isc_result_t | |
916 | dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, | |
917 | dns_name_t *name, isc_buffer_t *target); | |
918 | /*%< | |
919 | * Concatenate 'prefix' and 'suffix'. | |
920 | * | |
921 | * Requires: | |
922 | * | |
923 | *\li 'prefix' is a valid name or NULL. | |
924 | * | |
925 | *\li 'suffix' is a valid name or NULL. | |
926 | * | |
927 | *\li 'name' is a valid name or NULL. | |
928 | * | |
929 | *\li 'target' is a valid buffer or 'target' is NULL and 'name' has | |
930 | * a dedicated buffer. | |
931 | * | |
932 | *\li If 'prefix' is absolute, 'suffix' must be NULL or the empty name. | |
933 | * | |
934 | * Ensures: | |
935 | * | |
936 | *\li On success, | |
937 | * If 'target' is not NULL and 'name' is not NULL, then 'name' | |
938 | * is attached to it. | |
939 | * The used space in target is updated. | |
940 | * | |
941 | * Returns: | |
942 | *\li #ISC_R_SUCCESS | |
943 | *\li #ISC_R_NOSPACE | |
944 | *\li #DNS_R_NAMETOOLONG | |
945 | */ | |
946 | ||
947 | void | |
948 | dns_name_split(dns_name_t *name, unsigned int suffixlabels, | |
949 | dns_name_t *prefix, dns_name_t *suffix); | |
950 | /*%< | |
951 | * | |
952 | * Split 'name' into two pieces on a label boundary. | |
953 | * | |
954 | * Notes: | |
955 | * \li 'name' is split such that 'suffix' holds the most significant | |
956 | * 'suffixlabels' labels. All other labels are stored in 'prefix'. | |
957 | * | |
958 | *\li Copying name data is avoided as much as possible, so 'prefix' | |
959 | * and 'suffix' will end up pointing at the data for 'name'. | |
960 | * | |
961 | *\li It is legitimate to pass a 'prefix' or 'suffix' that has | |
962 | * its name data stored someplace other than the dedicated buffer. | |
963 | * This is useful to avoid name copying in the calling function. | |
964 | * | |
965 | *\li It is also legitimate to pass a 'prefix' or 'suffix' that is | |
966 | * the same dns_name_t as 'name'. | |
967 | * | |
968 | * Requires: | |
969 | *\li 'name' is a valid name. | |
970 | * | |
971 | *\li 'suffixlabels' cannot exceed the number of labels in 'name'. | |
972 | * | |
973 | * \li 'prefix' is a valid name or NULL, and cannot be read-only. | |
974 | * | |
975 | *\li 'suffix' is a valid name or NULL, and cannot be read-only. | |
976 | * | |
977 | *\li If non-NULL, 'prefix' and 'suffix' must have dedicated buffers. | |
978 | * | |
979 | *\li 'prefix' and 'suffix' cannot point to the same buffer. | |
980 | * | |
981 | * Ensures: | |
982 | * | |
983 | *\li On success: | |
984 | * If 'prefix' is not NULL it will contain the least significant | |
985 | * labels. | |
986 | * If 'suffix' is not NULL it will contain the most significant | |
987 | * labels. dns_name_countlabels(suffix) will be equal to | |
988 | * suffixlabels. | |
989 | * | |
990 | *\li On failure: | |
991 | * Either 'prefix' or 'suffix' is invalidated (depending | |
992 | * on which one the problem was encountered with). | |
993 | * | |
994 | * Returns: | |
995 | *\li #ISC_R_SUCCESS No worries. (This function should always success). | |
996 | */ | |
997 | ||
998 | isc_result_t | |
999 | dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, | |
1000 | dns_name_t *target); | |
1001 | /*%< | |
1002 | * Make 'target' a dynamically allocated copy of 'source'. | |
1003 | * | |
1004 | * Requires: | |
1005 | * | |
1006 | *\li 'source' is a valid non-empty name. | |
1007 | * | |
1008 | *\li 'target' is a valid name that is not read-only. | |
1009 | * | |
1010 | *\li 'mctx' is a valid memory context. | |
1011 | */ | |
1012 | ||
1013 | isc_result_t | |
1014 | dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, | |
1015 | dns_name_t *target); | |
1016 | /*%< | |
1017 | * Make 'target' a read-only dynamically allocated copy of 'source'. | |
1018 | * 'target' will also have a dynamically allocated offsets table. | |
1019 | * | |
1020 | * Requires: | |
1021 | * | |
1022 | *\li 'source' is a valid non-empty name. | |
1023 | * | |
1024 | *\li 'target' is a valid name that is not read-only. | |
1025 | * | |
1026 | *\li 'target' has no offsets table. | |
1027 | * | |
1028 | *\li 'mctx' is a valid memory context. | |
1029 | */ | |
1030 | ||
1031 | void | |
1032 | dns_name_free(dns_name_t *name, isc_mem_t *mctx); | |
1033 | /*%< | |
1034 | * Free 'name'. | |
1035 | * | |
1036 | * Requires: | |
1037 | * | |
1038 | *\li 'name' is a valid name created previously in 'mctx' by dns_name_dup(). | |
1039 | * | |
1040 | *\li 'mctx' is a valid memory context. | |
1041 | * | |
1042 | * Ensures: | |
1043 | * | |
1044 | *\li All dynamic resources used by 'name' are freed and the name is | |
1045 | * invalidated. | |
1046 | */ | |
1047 | ||
1048 | isc_result_t | |
1049 | dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg); | |
1050 | /*%< | |
1051 | * Send 'name' in DNSSEC canonical form to 'digest'. | |
1052 | * | |
1053 | * Requires: | |
1054 | * | |
1055 | *\li 'name' is a valid name. | |
1056 | * | |
1057 | *\li 'digest' is a valid dns_digestfunc_t. | |
1058 | * | |
1059 | * Ensures: | |
1060 | * | |
1061 | *\li If successful, the DNSSEC canonical form of 'name' will have been | |
1062 | * sent to 'digest'. | |
1063 | * | |
1064 | *\li If digest() returns something other than ISC_R_SUCCESS, that result | |
1065 | * will be returned as the result of dns_name_digest(). | |
1066 | * | |
1067 | * Returns: | |
1068 | * | |
1069 | *\li #ISC_R_SUCCESS | |
1070 | * | |
1071 | *\li Many other results are possible if not successful. | |
1072 | * | |
1073 | */ | |
1074 | ||
1075 | isc_boolean_t | |
1076 | dns_name_dynamic(dns_name_t *name); | |
1077 | /*%< | |
1078 | * Returns whether there is dynamic memory associated with this name. | |
1079 | * | |
1080 | * Requires: | |
1081 | * | |
1082 | *\li 'name' is a valid name. | |
1083 | * | |
1084 | * Returns: | |
1085 | * | |
1086 | *\li 'ISC_TRUE' if the name is dynamic otherwise 'ISC_FALSE'. | |
1087 | */ | |
1088 | ||
1089 | isc_result_t | |
1090 | dns_name_print(dns_name_t *name, FILE *stream); | |
1091 | /*%< | |
1092 | * Print 'name' on 'stream'. | |
1093 | * | |
1094 | * Requires: | |
1095 | * | |
1096 | *\li 'name' is a valid name. | |
1097 | * | |
1098 | *\li 'stream' is a valid stream. | |
1099 | * | |
1100 | * Returns: | |
1101 | * | |
1102 | *\li #ISC_R_SUCCESS | |
1103 | * | |
1104 | *\li Any error that dns_name_totext() can return. | |
1105 | */ | |
1106 | ||
1107 | void | |
1108 | dns_name_format(dns_name_t *name, char *cp, unsigned int size); | |
1109 | /*%< | |
1110 | * Format 'name' as text appropriate for use in log messages. | |
1111 | * | |
1112 | * Store the formatted name at 'cp', writing no more than | |
1113 | * 'size' bytes. The resulting string is guaranteed to be | |
1114 | * null terminated. | |
1115 | * | |
1116 | * The formatted name will have a terminating dot only if it is | |
1117 | * the root. | |
1118 | * | |
1119 | * This function cannot fail, instead any errors are indicated | |
1120 | * in the returned text. | |
1121 | * | |
1122 | * Requires: | |
1123 | * | |
1124 | *\li 'name' is a valid name. | |
1125 | * | |
1126 | *\li 'cp' points a valid character array of size 'size'. | |
1127 | * | |
1128 | *\li 'size' > 0. | |
1129 | * | |
1130 | */ | |
1131 | ||
1132 | isc_result_t | |
1133 | dns_name_settotextfilter(dns_name_totextfilter_t proc); | |
1134 | /*%< | |
1135 | * Set / clear a thread specific function 'proc' to be called at the | |
1136 | * end of dns_name_totext(). | |
1137 | * | |
1138 | * Note: Under Windows you need to call "dns_name_settotextfilter(NULL);" | |
1139 | * prior to exiting the thread otherwise memory will be leaked. | |
1140 | * For other platforms, which are pthreads based, this is still a good | |
1141 | * idea but not required. | |
1142 | * | |
1143 | * Returns | |
1144 | *\li #ISC_R_SUCCESS | |
1145 | *\li #ISC_R_UNEXPECTED | |
1146 | */ | |
1147 | ||
1148 | #define DNS_NAME_FORMATSIZE (DNS_NAME_MAXTEXT + 1) | |
1149 | /*%< | |
1150 | * Suggested size of buffer passed to dns_name_format(). | |
1151 | * Includes space for the terminating NULL. | |
1152 | */ | |
1153 | ||
1154 | isc_result_t | |
1155 | dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target); | |
1156 | /*%< | |
1157 | * Makes 'dest' refer to a copy of the name in 'source'. The data are | |
1158 | * either copied to 'target' or the dedicated buffer in 'dest'. | |
1159 | * | |
1160 | * Requires: | |
1161 | * \li 'source' is a valid name. | |
1162 | * | |
1163 | * \li 'dest' is an initialized name with a dedicated buffer. | |
1164 | * | |
1165 | * \li 'target' is NULL or an initialized buffer. | |
1166 | * | |
1167 | * \li Either dest has a dedicated buffer or target != NULL. | |
1168 | * | |
1169 | * Ensures: | |
1170 | * | |
1171 | *\li On success, the used space in target is updated. | |
1172 | * | |
1173 | * Returns: | |
1174 | *\li #ISC_R_SUCCESS | |
1175 | *\li #ISC_R_NOSPACE | |
1176 | */ | |
1177 | ||
1178 | isc_boolean_t | |
1179 | dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard); | |
1180 | /*%< | |
1181 | * Return if 'name' is a valid hostname. RFC 952 / RFC 1123. | |
1182 | * If 'wildcard' is ISC_TRUE then allow the first label of name to | |
1183 | * be a wildcard. | |
1184 | * The root is also accepted. | |
1185 | * | |
1186 | * Requires: | |
1187 | * 'name' to be valid. | |
1188 | */ | |
1189 | ||
1190 | ||
1191 | isc_boolean_t | |
1192 | dns_name_ismailbox(const dns_name_t *name); | |
1193 | /*%< | |
1194 | * Return if 'name' is a valid mailbox. RFC 821. | |
1195 | * | |
1196 | * Requires: | |
1197 | * \li 'name' to be valid. | |
1198 | */ | |
1199 | ||
1200 | isc_boolean_t | |
1201 | dns_name_internalwildcard(const dns_name_t *name); | |
1202 | /*%< | |
1203 | * Return if 'name' contains a internal wildcard name. | |
1204 | * | |
1205 | * Requires: | |
1206 | * \li 'name' to be valid. | |
1207 | */ | |
1208 | ||
1209 | void | |
1210 | dns_name_destroy(void); | |
1211 | /*%< | |
1212 | * Cleanup dns_name_settotextfilter() / dns_name_totext() state. | |
1213 | * | |
1214 | * This should be called as part of the final cleanup process. | |
1215 | * | |
1216 | * Note: dns_name_settotextfilter(NULL); should be called for all | |
1217 | * threads which have called dns_name_settotextfilter() with a | |
1218 | * non-NULL argument prior to calling dns_name_destroy(); | |
1219 | */ | |
1220 | ||
1221 | ISC_LANG_ENDDECLS | |
1222 | ||
1223 | /* | |
1224 | *** High Performance Macros | |
1225 | ***/ | |
1226 | ||
1227 | /* | |
1228 | * WARNING: Use of these macros by applications may require recompilation | |
1229 | * of the application in some situations where calling the function | |
1230 | * would not. | |
1231 | * | |
1232 | * WARNING: No assertion checking is done for these macros. | |
1233 | */ | |
1234 | ||
1235 | #define DNS_NAME_INIT(n, o) \ | |
1236 | do { \ | |
1237 | (n)->magic = DNS_NAME_MAGIC; \ | |
1238 | (n)->ndata = NULL; \ | |
1239 | (n)->length = 0; \ | |
1240 | (n)->labels = 0; \ | |
1241 | (n)->attributes = 0; \ | |
1242 | (n)->offsets = (o); \ | |
1243 | (n)->buffer = NULL; \ | |
1244 | ISC_LINK_INIT((n), link); \ | |
1245 | ISC_LIST_INIT((n)->list); \ | |
1246 | } while (0) | |
1247 | ||
1248 | #define DNS_NAME_RESET(n) \ | |
1249 | do { \ | |
1250 | (n)->ndata = NULL; \ | |
1251 | (n)->length = 0; \ | |
1252 | (n)->labels = 0; \ | |
1253 | (n)->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ | |
1254 | if ((n)->buffer != NULL) \ | |
1255 | isc_buffer_clear((n)->buffer); \ | |
1256 | } while (0) | |
1257 | ||
1258 | #define DNS_NAME_SETBUFFER(n, b) \ | |
1259 | (n)->buffer = (b) | |
1260 | ||
1261 | #define DNS_NAME_ISABSOLUTE(n) \ | |
1262 | (((n)->attributes & DNS_NAMEATTR_ABSOLUTE) != 0 ? ISC_TRUE : ISC_FALSE) | |
1263 | ||
1264 | #define DNS_NAME_COUNTLABELS(n) \ | |
1265 | ((n)->labels) | |
1266 | ||
1267 | #define DNS_NAME_TOREGION(n, r) \ | |
1268 | do { \ | |
1269 | (r)->base = (n)->ndata; \ | |
1270 | (r)->length = (n)->length; \ | |
1271 | } while (0) | |
1272 | ||
1273 | #define DNS_NAME_SPLIT(n, l, p, s) \ | |
1274 | do { \ | |
1275 | dns_name_t *_n = (n); \ | |
1276 | dns_name_t *_p = (p); \ | |
1277 | dns_name_t *_s = (s); \ | |
1278 | unsigned int _l = (l); \ | |
1279 | if (_p != NULL) \ | |
1280 | dns_name_getlabelsequence(_n, 0, _n->labels - _l, _p); \ | |
1281 | if (_s != NULL) \ | |
1282 | dns_name_getlabelsequence(_n, _n->labels - _l, _l, _s); \ | |
1283 | } while (0) | |
1284 | ||
1285 | #ifdef DNS_NAME_USEINLINE | |
1286 | ||
1287 | #define dns_name_init(n, o) DNS_NAME_INIT(n, o) | |
1288 | #define dns_name_reset(n) DNS_NAME_RESET(n) | |
1289 | #define dns_name_setbuffer(n, b) DNS_NAME_SETBUFFER(n, b) | |
1290 | #define dns_name_countlabels(n) DNS_NAME_COUNTLABELS(n) | |
1291 | #define dns_name_isabsolute(n) DNS_NAME_ISABSOLUTE(n) | |
1292 | #define dns_name_toregion(n, r) DNS_NAME_TOREGION(n, r) | |
1293 | #define dns_name_split(n, l, p, s) DNS_NAME_SPLIT(n, l, p, s) | |
1294 | ||
1295 | #endif /* DNS_NAME_USEINLINE */ | |
1296 | ||
1297 | #endif /* DNS_NAME_H */ |