Kea 2.5.6
name.cc
Go to the documentation of this file.
1// Copyright (C) 2009-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <cctype>
10#include <iterator>
11#include <functional>
12#include <vector>
13#include <iostream>
14#include <algorithm>
15
17#include <util/buffer.h>
18#include <dns/exceptions.h>
19#include <dns/name.h>
20#include <dns/name_internal.h>
21#include <dns/messagerenderer.h>
22#include <dns/labelsequence.h>
23
24using namespace std;
25using namespace isc::util;
27using namespace isc::dns::name::internal;
28
29namespace isc {
30namespace dns {
31
32namespace {
51const signed char digitvalue[256] = {
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16
53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32
54 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 48
55 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 64
56 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
57 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96
58 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112
59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128
60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
63 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
64 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
65 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
66 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
67 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 256
68};
69}
70
71namespace name {
72namespace internal {
73const uint8_t maptolower[] = {
74 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
75 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
76 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
77 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
78 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
79 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
80 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
81 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
82 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // ..., 'A' - 'G'
83 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, // 'H' - 'O'
84 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // 'P' - 'W'
85 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, // 'X' - 'Z', ...
86 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
87 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
88 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
89 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
90 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
91 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
92 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
93 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
94 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
95 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
96 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
97 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
98 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
99 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
100 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
101 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
102 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
103 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
104 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
105 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
106};
107} // end of internal
108} // end of name
109
110namespace {
114typedef enum {
115 ft_init = 0, // begin of the name
116 ft_start, // begin of a label
117 ft_ordinary, // parsing an ordinary label
118 ft_initialescape, // just found '\'
119 ft_escape, // begin of handling a '\'-escaped sequence
120 ft_escdecimal // parsing a '\DDD' octet.
121} ft_state;
122
123// The parser of name from a string. It is a template, because
124// some parameters are used with two different types, while others
125// are private type aliases.
126template<class Iterator, class Offsets, class Data>
127void
128stringParse(Iterator s, Iterator send, bool downcase, Offsets& offsets,
129 Data& ndata)
130{
131 const Iterator orig_s(s);
132 //
133 // Initialize things to make the compiler happy; they're not required.
134 //
135 unsigned int digits = 0;
136 unsigned int value = 0;
137 unsigned int count = 0;
138
139 //
140 // Set up the state machine.
141 //
142 bool done = false;
143 bool is_root = false;
144 const bool empty = s == send;
145 ft_state state = ft_init;
146
147 // Prepare the output buffers.
148 offsets.reserve(Name::MAX_LABELS);
149 offsets.push_back(0);
150 ndata.reserve(Name::MAX_WIRE);
151
152 // should we refactor this code using, e.g, the state pattern? Probably
153 // not at this point, as this is based on proved code (derived from BIND9)
154 // and it's less likely that we'll have more variations in the domain name
155 // syntax. If this ever happens next time, we should consider refactor
156 // the code, rather than adding more states and cases below.
157 while (ndata.size() < Name::MAX_WIRE && s != send && !done) {
158 unsigned char c = *s++;
159
160 switch (state) {
161 case ft_init:
162 //
163 // Is this the root name?
164 //
165 if (c == '.') {
166 if (s != send) {
168 "non terminating empty label in " <<
169 string(orig_s, send));
170 }
171 is_root = true;
172 } else if (c == '@' && s == send) {
173 // handle a single '@' as the root name.
174 is_root = true;
175 }
176
177 if (is_root) {
178 ndata.push_back(0);
179 done = true;
180 break;
181 }
182
183 // FALLTHROUGH
184 case ft_start:
185 ndata.push_back(0); // placeholder for the label length field
186 count = 0;
187 if (c == '\\') {
188 state = ft_initialescape;
189 break;
190 }
191 state = ft_ordinary;
192 isc_throw_assert(ndata.size() < Name::MAX_WIRE);
193 // FALLTHROUGH
194 case ft_ordinary:
195 if (c == '.') {
196 if (count == 0) {
198 "duplicate period in " << string(orig_s, send));
199 }
200 ndata.at(offsets.back()) = count;
201 offsets.push_back(ndata.size());
202 if (s == send) {
203 ndata.push_back(0);
204 done = true;
205 }
206 state = ft_start;
207 } else if (c == '\\') {
208 state = ft_escape;
209 } else {
210 if (++count > Name::MAX_LABELLEN) {
212 "label is too long in " << string(orig_s, send));
213 }
214 ndata.push_back(downcase ? maptolower[c] : c);
215 }
216 break;
217 case ft_initialescape:
218 if (c == '[') {
219 // This looks like a bitstring label, which was deprecated.
220 // Intentionally drop it.
222 "invalid label type in " << string(orig_s, send));
223 }
224 // FALLTHROUGH
225 case ft_escape:
226 if (!isdigit(c & 0xff)) {
227 if (++count > Name::MAX_LABELLEN) {
229 "label is too long in " << string(orig_s, send));
230 }
231 ndata.push_back(downcase ? maptolower[c] : c);
232 state = ft_ordinary;
233 break;
234 }
235 digits = 0;
236 value = 0;
237 state = ft_escdecimal;
238 // FALLTHROUGH
239 case ft_escdecimal:
240 if (!isdigit(c & 0xff)) {
242 "mixture of escaped digit and non-digit in "
243 << string(orig_s, send));
244 }
245 value *= 10;
246 value += digitvalue[c];
247 digits++;
248 if (digits == 3) {
249 if (value > 255) {
251 "escaped decimal is too large in "
252 << string(orig_s, send));
253 }
254 if (++count > Name::MAX_LABELLEN) {
256 "label is too long in " << string(orig_s, send));
257 }
258 ndata.push_back(downcase ? maptolower[value] : value);
259 state = ft_ordinary;
260 }
261 break;
262 default:
263 // impossible case
264 isc_throw_assert(false);
265 }
266 }
267
268 if (!done) { // no trailing '.' was found.
269 if (ndata.size() == Name::MAX_WIRE) {
271 "name is too long for termination in " <<
272 string(orig_s, send));
273 }
274 isc_throw_assert(s == send);
275 if (state != ft_ordinary) {
277 "incomplete textual name in " <<
278 (empty ? "<empty>" : string(orig_s, send)));
279 }
280 if (state == ft_ordinary) {
281 isc_throw_assert(count != 0);
282 ndata.at(offsets.back()) = count;
283
284 offsets.push_back(ndata.size());
285 // add a trailing \0
286 ndata.push_back('\0');
287 }
288 }
289}
290
291}
292
293Name::Name(const std::string &namestring, bool downcase) {
294 // Prepare inputs for the parser
295 const std::string::const_iterator s = namestring.begin();
296 const std::string::const_iterator send = namestring.end();
297
298 // Prepare outputs
299 NameOffsets offsets;
300 NameString ndata;
301
302 // To the parsing
303 stringParse(s, send, downcase, offsets, ndata);
304
305 // And get the output
306 labelcount_ = offsets.size();
307 isc_throw_assert(labelcount_ > 0 && labelcount_ <= Name::MAX_LABELS);
308 ndata_.assign(ndata.data(), ndata.size());
309 length_ = ndata_.size();
310 offsets_.assign(offsets.begin(), offsets.end());
311}
312
313Name::Name(const char* namedata, size_t data_len, const Name* origin,
314 bool downcase)
315{
316 // Check validity of data
317 if (namedata == NULL || data_len == 0) {
319 "No data provided to Name constructor");
320 }
321 // If the last character is not a dot, it is a relative to origin.
322 // It is safe to check now, we know there's at least one character.
323 const bool absolute = (namedata[data_len - 1] == '.');
324 // If we are not absolute, we need the origin to complete the name.
325 if (!absolute && origin == NULL) {
327 "No origin available and name is relative");
328 }
329 // Prepare inputs for the parser
330 const char* end = namedata + data_len;
331
332 // Prepare outputs
333 NameOffsets offsets;
334 NameString ndata;
335
336 // Do the actual parsing
337 stringParse(namedata, end, downcase, offsets, ndata);
338
339 // Get the output
340 labelcount_ = offsets.size();
341 isc_throw_assert(labelcount_ > 0 && labelcount_ <= Name::MAX_LABELS);
342 ndata_.assign(ndata.data(), ndata.size());
343 length_ = ndata_.size();
344 offsets_.assign(offsets.begin(), offsets.end());
345
346 if (!absolute) {
347 // Now, extend the data with the ones from origin. But eat the
348 // last label (the empty one).
349
350 // Drop the last character of the data (the \0) and append a copy of
351 // the origin's data
352 ndata_.erase(ndata_.end() - 1);
353 ndata_.append(origin->ndata_);
354
355 // Do a similar thing with offsets. However, we need to move them
356 // so they point after the prefix we parsed before.
357 size_t offset = offsets_.back();
358 offsets_.pop_back();
359 size_t offset_count = offsets_.size();
360 offsets_.insert(offsets_.end(), origin->offsets_.begin(),
361 origin->offsets_.end());
362 for (auto it(offsets_.begin() + offset_count); it != offsets_.end(); ++it) {
363 *it += offset;
364 }
365
366 // Adjust sizes.
367 length_ = ndata_.size();
368 labelcount_ = offsets_.size();
369
370 // And check the sizes are OK.
371 if (labelcount_ > Name::MAX_LABELS || length_ > Name::MAX_WIRE) {
372 isc_throw(TooLongName, "Combined name is too long");
373 }
374 }
375}
376
377namespace {
381typedef enum {
382 fw_start = 0, // beginning of a label
383 fw_ordinary, // inside an ordinary (non compressed) label
384 fw_newcurrent // beginning of a compression pointer
385} fw_state;
386}
387
388Name::Name(InputBuffer& buffer, bool downcase) {
389 NameOffsets offsets;
390 offsets.reserve(Name::MAX_LABELS);
391
392 /*
393 * Initialize things to make the compiler happy; they're not required.
394 */
395 unsigned int n = 0;
396
397 //
398 // Set up.
399 //
400 bool done = false;
401 unsigned int nused = 0;
402 bool seen_pointer = false;
403 fw_state state = fw_start;
404
405 unsigned int cused = 0; // Bytes of compressed name data used
406 unsigned int current = buffer.getPosition();
407 unsigned int pos_begin = current;
408 unsigned int biggest_pointer = current;
409
410 // Make the compiler happy; this is not required.
411 // XXX: bad style in that we initialize it with a dummy value and define
412 // it far from where it's used. But alternatives seemed even worse.
413 unsigned int new_current = 0;
414
415 //
416 // Note: The following code is not optimized for speed, but
417 // rather for correctness. Speed will be addressed in the future.
418 //
419 while (current < buffer.getLength() && !done) {
420 unsigned int c = buffer.readUint8();
421 current++;
422 if (!seen_pointer) {
423 cused++;
424 }
425
426 switch (state) {
427 case fw_start:
428 if (c <= MAX_LABELLEN) {
429 offsets.push_back(nused);
430 if (nused + c + 1 > Name::MAX_WIRE) {
431 isc_throw(DNSMessageFORMERR, "wire name is too long: "
432 << nused + c + 1 << " bytes");
433 }
434 nused += c + 1;
435 ndata_.push_back(c);
436 if (c == 0) {
437 done = true;
438 }
439 n = c;
440 state = fw_ordinary;
442 //
443 // Ordinary 14-bit pointer.
444 //
445 new_current = c & ~COMPRESS_POINTER_MARK8;
446 n = 1;
447 state = fw_newcurrent;
448 } else {
449 // this case includes local compression pointer, which hasn't
450 // been standardized.
451 isc_throw(DNSMessageFORMERR, "unknown label character: " << c);
452 }
453 break;
454 case fw_ordinary:
455 if (downcase) {
456 c = maptolower[c];
457 }
458 ndata_.push_back(c);
459 if (--n == 0) {
460 state = fw_start;
461 }
462 break;
463 case fw_newcurrent:
464 new_current *= 256;
465 new_current += c;
466 if (--n != 0) {
467 break;
468 }
469 if (new_current >= biggest_pointer) {
471 "bad compression pointer (out of range): " <<
472 new_current);
473 }
474 biggest_pointer = new_current;
475 current = new_current;
476 buffer.setPosition(current);
477 seen_pointer = true;
478 state = fw_start;
479 break;
480 default:
481 isc_throw_assert(false);
482 }
483 }
484
485 if (!done) {
486 isc_throw(DNSMessageFORMERR, "incomplete wire-format name");
487 }
488
489 labelcount_ = offsets.size();
490 length_ = nused;
491 offsets_.assign(offsets.begin(), offsets.end());
492 buffer.setPosition(pos_begin + cused);
493}
494
495void
497 buffer.writeData(ndata_.data(), ndata_.size());
498}
499
500void
502 renderer.writeName(*this);
503}
504
505std::string
506Name::toText(bool omit_final_dot) const {
507 LabelSequence ls(*this);
508 return (ls.toText(omit_final_dot));
509}
510
511std::string
512Name::toRawText(bool omit_final_dot) const {
513 LabelSequence ls(*this);
514 return (ls.toRawText(omit_final_dot));
515}
516
518Name::compare(const Name& other) const {
519 const LabelSequence ls1(*this);
520 const LabelSequence ls2(other);
521 return (ls1.compare(ls2));
522}
523
524bool
525Name::equals(const Name& other) const {
526 if (length_ != other.length_ || labelcount_ != other.labelcount_) {
527 return (false);
528 }
529
530 for (unsigned int l = labelcount_, pos = 0; l > 0; --l) {
531 uint8_t count = ndata_[pos];
532 if (count != other.ndata_[pos]) {
533 return (false);
534 }
535 ++pos;
536
537 while (count-- > 0) {
538 uint8_t label1 = ndata_[pos];
539 uint8_t label2 = other.ndata_[pos];
540
541 if (maptolower[label1] != maptolower[label2]) {
542 return (false);
543 }
544 ++pos;
545 }
546 }
547
548 return (true);
549}
550
551bool
552Name::leq(const Name& other) const {
553 return (compare(other).getOrder() <= 0);
554}
555
556bool
557Name::geq(const Name& other) const {
558 return (compare(other).getOrder() >= 0);
559}
560
561bool
562Name::lthan(const Name& other) const {
563 return (compare(other).getOrder() < 0);
564}
565
566bool
567Name::gthan(const Name& other) const {
568 return (compare(other).getOrder() > 0);
569}
570
571bool
573 return (length_ >= 2 && ndata_[0] == 1 && ndata_[1] == '*');
574}
575
576Name
577Name::concatenate(const Name& suffix) const {
578 isc_throw_assert(length_ > 0 && suffix.length_ > 0);
579 isc_throw_assert(labelcount_ > 0 && suffix.labelcount_ > 0);
580
581 unsigned int length = length_ + suffix.length_ - 1;
582 if (length > Name::MAX_WIRE) {
583 isc_throw(TooLongName, "names are too long to concatenate");
584 }
585
586 Name retname;
587 retname.ndata_.reserve(length);
588 retname.ndata_.assign(ndata_, 0, length_ - 1);
589 retname.ndata_.insert(retname.ndata_.end(),
590 suffix.ndata_.begin(), suffix.ndata_.end());
591 isc_throw_assert(retname.ndata_.size() == length);
592 retname.length_ = length;
593
594 //
595 // Setup the offsets vector. Copy the offsets of this (prefix) name,
596 // excluding that for the trailing dot, and append the offsets of the
597 // suffix name with the additional offset of the length of the prefix.
598 //
599 unsigned int labels = labelcount_ + suffix.labelcount_ - 1;
601 retname.offsets_.reserve(labels);
602 retname.offsets_.assign(&offsets_[0], &offsets_[0] + labelcount_ - 1);
603 transform(suffix.offsets_.begin(), suffix.offsets_.end(),
604 back_inserter(retname.offsets_),
605 [this] (char x) { return (x + length_ - 1); });
606 isc_throw_assert(retname.offsets_.size() == labels);
607 retname.labelcount_ = labels;
608
609 return (retname);
610}
611
612Name
614 Name retname;
615 //
616 // Set up offsets: The size of the string and number of labels will
617 // be the same in as in the original.
618 //
619 retname.offsets_.reserve(labelcount_);
620 retname.ndata_.reserve(length_);
621
622 // Copy the original name, label by label, from tail to head.
623 NameOffsets::const_reverse_iterator rit0 = offsets_.rbegin();
624 NameOffsets::const_reverse_iterator rit1 = rit0 + 1;
625 NameString::const_iterator n0 = ndata_.begin();
626 retname.offsets_.push_back(0);
627 while (rit1 != offsets_.rend()) {
628 retname.ndata_.append(n0 + *rit1, n0 + *rit0);
629 retname.offsets_.push_back(retname.ndata_.size());
630 ++rit0;
631 ++rit1;
632 }
633 retname.ndata_.push_back(0);
634
635 retname.labelcount_ = labelcount_;
636 retname.length_ = length_;
637
638 return (retname);
639}
640
641Name
642Name::split(const unsigned int first, const unsigned int n) const {
643 if (n == 0 || n > labelcount_ || first > labelcount_ - n) {
644 isc_throw(OutOfRange, "Name::split: invalid split range");
645 }
646
647 Name retname;
648 // If the specified range doesn't include the trailing dot, we need one
649 // more label for that.
650 unsigned int newlabels = (first + n == labelcount_) ? n : n + 1;
651
652 //
653 // Set up offsets: copy the corresponding range of the original offsets
654 // with subtracting an offset of the prefix length.
655 //
656 retname.offsets_.reserve(newlabels);
657 transform(offsets_.begin() + first, offsets_.begin() + first + newlabels,
658 back_inserter(retname.offsets_),
659 [&](char x) { return (x - offsets_[first]); });
660
661 //
662 // Set up the new name. At this point the tail of the new offsets specifies
663 // the position of the trailing dot, which should be equal to the length of
664 // the extracted portion excluding the dot. First copy that part from the
665 // original name, and append the trailing dot explicitly.
666 //
667 retname.ndata_.reserve(retname.offsets_.back() + 1);
668 retname.ndata_.assign(ndata_, offsets_[first], retname.offsets_.back());
669 retname.ndata_.push_back(0);
670
671 retname.length_ = retname.ndata_.size();
672 retname.labelcount_ = retname.offsets_.size();
673 isc_throw_assert(retname.labelcount_ == newlabels);
674
675 return (retname);
676}
677
678Name
679Name::split(const unsigned int level) const {
680 if (level >= getLabelCount()) {
681 isc_throw(OutOfRange, "invalid level for name split (" << level
682 << ") for name " << *this);
683 }
684
685 return (split(level, getLabelCount() - level));
686}
687
688Name&
690 unsigned int nlen = length_;
691 unsigned int labels = labelcount_;
692 unsigned int pos = 0;
693
694 while (labels > 0 && nlen > 0) {
695 --labels;
696 --nlen;
697
698 // we assume a valid name, and do abort() if the assumption fails
699 // rather than throwing an exception.
700 unsigned int count = ndata_.at(pos++);
702 isc_throw_assert(nlen >= count);
703
704 while (count > 0) {
705 ndata_.at(pos) =
706 maptolower[ndata_.at(pos)];
707 ++pos;
708 --nlen;
709 --count;
710 }
711 }
712
713 return (*this);
714}
715
716std::ostream&
717operator<<(std::ostream& os, const Name& name) {
718 os << name.toText();
719 return (os);
720}
721
722}
723}
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
The AbstractMessageRenderer class is an abstract base class that provides common interfaces for rende...
virtual void writeName(const Name &name, bool compress=true)=0
Write a Name object into the internal buffer in wire format, with or without name compression.
A standard DNS module exception that is thrown if the name parser fails to decode a back-slash escape...
Definition: name.h:72
A standard DNS module exception that is thrown if the name parser encounters an obsolete or incomplet...
Definition: name.h:62
A standard DNS module exception that is thrown if the name parser encounters an empty label in the mi...
Definition: name.h:30
A standard DNS module exception that is thrown if the name parser finds the input (string or wire-for...
Definition: name.h:85
Light-weight Accessor to Name data.
Definition: labelsequence.h:35
std::string toRawText(bool omit_final_dot) const
Convert the LabelSequence to a string without escape sequences.
NameComparisonResult compare(const LabelSequence &other, bool case_sensitive=false) const
Compares two label sequences.
std::string toText() const
Convert the LabelSequence to a string.
Thrown when origin is NULL and is needed.
Definition: name.h:96
This is a supplemental class used only as a return value of Name::compare() and LabelSequence::compar...
Definition: name.h:117
The Name class encapsulates DNS names.
Definition: name.h:223
static const size_t MAX_LABELLEN
Max allowable length of labels of a domain name.
Definition: name.h:708
Name reverse() const
Reverse the labels of a name.
Definition: name.cc:613
bool lthan(const Name &other) const
Less-than comparison for Name against other
Definition: name.cc:562
NameComparisonResult compare(const Name &other) const
Compare two Names.
Definition: name.cc:518
bool equals(const Name &other) const
Return true iff two names are equal.
Definition: name.cc:525
bool geq(const Name &other) const
Greater-than or equal comparison for Name against other
Definition: name.cc:557
static const size_t MAX_WIRE
Max allowable length of domain names.
Definition: name.h:699
Name split(unsigned int first, unsigned int n) const
Extract a specified subpart of Name.
Definition: name.cc:642
std::string toText(bool omit_final_dot=false) const
Convert the Name to a string.
Definition: name.cc:506
void toWire(AbstractMessageRenderer &renderer) const
Render the Name in the wire format with compression.
Definition: name.cc:501
unsigned int getLabelCount() const
Returns the number of labels contained in the Name.
Definition: name.h:370
static const size_t MAX_LABELS
Max allowable labels of domain names.
Definition: name.h:705
bool gthan(const Name &other) const
Greater-than comparison for Name against other
Definition: name.cc:567
Name concatenate(const Name &suffix) const
Concatenate two names.
Definition: name.cc:577
std::string toRawText(bool omit_final_dot=false) const
Convert the LabelSequence to a string without escape sequences.
Definition: name.cc:512
static const uint16_t COMPRESS_POINTER_MARK8
A 8-bit masked value indicating a start of compression pointer.
Definition: name.h:717
bool leq(const Name &other) const
Less-than or equal comparison for Name against other
Definition: name.cc:552
Name & downcase()
Downcase all upper case alphabet characters in the name.
Definition: name.cc:689
bool isWildcard() const
Test if this is a wildcard name.
Definition: name.cc:572
A standard DNS module exception that is thrown if the name parser encounters too long a label.
Definition: name.h:50
A standard DNS module exception that is thrown if the name parser encounters too long a name.
Definition: name.h:40
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition: buffer.h:81
void setPosition(size_t position)
Set the read position of the buffer to the given value.
Definition: buffer.h:115
size_t getPosition() const
Return the current read position.
Definition: buffer.h:102
uint8_t readUint8()
Read an unsigned 8-bit integer from the buffer and return it.
Definition: buffer.h:130
size_t getLength() const
Return the length of the data stored in the buffer.
Definition: buffer.h:100
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition: buffer.h:550
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define isc_throw_assert(expr)
Replacement for assert() that throws if the expression is false.
Definition: isc_assert.h:18
const uint8_t maptolower[]
Definition: name.cc:73
ostream & operator<<(std::ostream &os, const EDNS &edns)
Insert the EDNS as a string into stream.
Definition: edns.cc:172
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.