51const signed char digitvalue[256] = {
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
54 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
55 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
56 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
57 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
58 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
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,
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,
83 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
84 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
85 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
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
126template<
class Iterator,
class Offsets,
class Data>
128stringParse(Iterator s, Iterator send,
bool downcase, Offsets& offsets,
131 const Iterator orig_s(s);
135 unsigned int digits = 0;
136 unsigned int value = 0;
137 unsigned int count = 0;
143 bool is_root =
false;
144 const bool empty = s == send;
145 ft_state state = ft_init;
149 offsets.push_back(0);
158 unsigned char c = *s++;
168 "non terminating empty label in " <<
169 string(orig_s, send));
172 }
else if (c ==
'@' && s == send) {
188 state = ft_initialescape;
198 "duplicate period in " <<
string(orig_s, send));
200 ndata.at(offsets.back()) = count;
201 offsets.push_back(ndata.size());
207 }
else if (c ==
'\\') {
212 "label is too long in " <<
string(orig_s, send));
214 ndata.push_back(downcase ?
maptolower[c] : c);
217 case ft_initialescape:
222 "invalid label type in " <<
string(orig_s, send));
226 if (!isdigit(c & 0xff)) {
229 "label is too long in " <<
string(orig_s, send));
231 ndata.push_back(downcase ?
maptolower[c] : c);
237 state = ft_escdecimal;
240 if (!isdigit(c & 0xff)) {
242 "mixture of escaped digit and non-digit in "
243 <<
string(orig_s, send));
246 value += digitvalue[c];
251 "escaped decimal is too large in "
252 <<
string(orig_s, send));
256 "label is too long in " <<
string(orig_s, send));
258 ndata.push_back(downcase ?
maptolower[value] : value);
271 "name is too long for termination in " <<
272 string(orig_s, send));
275 if (state != ft_ordinary) {
277 "incomplete textual name in " <<
278 (empty ?
"<empty>" :
string(orig_s, send)));
280 if (state == ft_ordinary) {
282 ndata.at(offsets.back()) = count;
284 offsets.push_back(ndata.size());
286 ndata.push_back(
'\0');
293Name::Name(
const std::string &namestring,
bool downcase) {
295 const std::string::const_iterator s = namestring.begin();
296 const std::string::const_iterator send = namestring.end();
303 stringParse(s, send,
downcase, offsets, ndata);
306 labelcount_ = offsets.size();
308 ndata_.assign(ndata.data(), ndata.size());
309 length_ = ndata_.size();
310 offsets_.assign(offsets.begin(), offsets.end());
313Name::Name(
const char* namedata,
size_t data_len,
const Name* origin,
317 if (namedata == NULL || data_len == 0) {
319 "No data provided to Name constructor");
323 const bool absolute = (namedata[data_len - 1] ==
'.');
325 if (!absolute && origin == NULL) {
327 "No origin available and name is relative");
330 const char* end = namedata + data_len;
337 stringParse(namedata, end,
downcase, offsets, ndata);
340 labelcount_ = offsets.size();
342 ndata_.assign(ndata.data(), ndata.size());
343 length_ = ndata_.size();
344 offsets_.assign(offsets.begin(), offsets.end());
352 ndata_.erase(ndata_.end() - 1);
353 ndata_.append(origin->ndata_);
357 size_t offset = offsets_.back();
359 size_t offset_count = offsets_.size();
360 offsets_.insert(offsets_.end(), origin->offsets_.begin(),
361 origin->offsets_.end());
362 for (NameOffsets::iterator it(offsets_.begin() + offset_count);
363 it != offsets_.end(); ++it) {
368 length_ = ndata_.size();
369 labelcount_ = offsets_.size();
402 unsigned int nused = 0;
403 bool seen_pointer =
false;
404 fw_state state = fw_start;
406 unsigned int cused = 0;
408 unsigned int pos_begin = current;
409 unsigned int biggest_pointer = current;
414 unsigned int new_current = 0;
420 while (current < buffer.
getLength() && !done) {
430 offsets.push_back(nused);
433 << nused + c + 1 <<
" bytes");
446 new_current = c & ~COMPRESS_POINTER_MARK8;
448 state = fw_newcurrent;
470 if (new_current >= biggest_pointer) {
472 "bad compression pointer (out of range): " <<
475 biggest_pointer = new_current;
476 current = new_current;
490 labelcount_ = offsets.size();
492 offsets_.assign(offsets.begin(), offsets.end());
498 buffer.
writeData(ndata_.data(), ndata_.size());
509 return (ls.
toText(omit_final_dot));
527 if (length_ != other.length_ || labelcount_ != other.labelcount_) {
531 for (
unsigned int l = labelcount_, pos = 0; l > 0; --l) {
532 uint8_t count = ndata_[pos];
533 if (count != other.ndata_[pos]) {
538 while (count-- > 0) {
539 uint8_t label1 = ndata_[pos];
540 uint8_t label2 = other.ndata_[pos];
554 return (
compare(other).getOrder() <= 0);
559 return (
compare(other).getOrder() >= 0);
564 return (
compare(other).getOrder() < 0);
569 return (
compare(other).getOrder() > 0);
574 return (length_ >= 2 && ndata_[0] == 1 && ndata_[1] ==
'*');
582 unsigned int length = length_ + suffix.length_ - 1;
588 retname.ndata_.reserve(length);
589 retname.ndata_.assign(ndata_, 0, length_ - 1);
590 retname.ndata_.insert(retname.ndata_.end(),
591 suffix.ndata_.begin(), suffix.ndata_.end());
593 retname.length_ = length;
600 unsigned int labels = labelcount_ + suffix.labelcount_ - 1;
602 retname.offsets_.reserve(labels);
603 retname.offsets_.assign(&offsets_[0], &offsets_[0] + labelcount_ - 1);
604 transform(suffix.offsets_.begin(), suffix.offsets_.end(),
605 back_inserter(retname.offsets_),
606 [
this] (
char x) { return (x + length_ - 1); });
608 retname.labelcount_ = labels;
620 retname.offsets_.reserve(labelcount_);
621 retname.ndata_.reserve(length_);
624 NameOffsets::const_reverse_iterator rit0 = offsets_.rbegin();
625 NameOffsets::const_reverse_iterator rit1 = rit0 + 1;
626 NameString::const_iterator n0 = ndata_.begin();
627 retname.offsets_.push_back(0);
628 while (rit1 != offsets_.rend()) {
629 retname.ndata_.append(n0 + *rit1, n0 + *rit0);
630 retname.offsets_.push_back(retname.ndata_.size());
634 retname.ndata_.push_back(0);
636 retname.labelcount_ = labelcount_;
637 retname.length_ = length_;
643Name::split(
const unsigned int first,
const unsigned int n)
const {
644 if (n == 0 || n > labelcount_ || first > labelcount_ - n) {
651 unsigned int newlabels = (first + n == labelcount_) ? n : n + 1;
657 retname.offsets_.reserve(newlabels);
658 transform(offsets_.begin() + first, offsets_.begin() + first + newlabels,
659 back_inserter(retname.offsets_),
660 [&](
char x) { return (x - offsets_[first]); });
668 retname.ndata_.reserve(retname.offsets_.back() + 1);
669 retname.ndata_.assign(ndata_, offsets_[first], retname.offsets_.back());
670 retname.ndata_.push_back(0);
672 retname.length_ = retname.ndata_.size();
673 retname.labelcount_ = retname.offsets_.size();
683 <<
") for name " << *
this);
691 unsigned int nlen = length_;
692 unsigned int labels = labelcount_;
693 unsigned int pos = 0;
695 while (labels > 0 && nlen > 0) {
701 unsigned int count = ndata_.at(pos++);
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.
Light-weight Accessor to Name data.
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.
This is a supplemental class used only as a return value of Name::compare() and LabelSequence::compar...
The Name class encapsulates DNS names.
static const size_t MAX_LABELLEN
Max allowable length of labels of a domain name.
Name reverse() const
Reverse the labels of a name.
bool lthan(const Name &other) const
Less-than comparison for Name against other
NameComparisonResult compare(const Name &other) const
Compare two Names.
bool equals(const Name &other) const
Return true iff two names are equal.
bool geq(const Name &other) const
Greater-than or equal comparison for Name against other
static const size_t MAX_WIRE
Max allowable length of domain names.
Name split(unsigned int first, unsigned int n) const
Extract a specified subpart of Name.
std::string toText(bool omit_final_dot=false) const
Convert the Name to a string.
void toWire(AbstractMessageRenderer &renderer) const
Render the Name in the wire format with compression.
unsigned int getLabelCount() const
Returns the number of labels contained in the Name.
static const size_t MAX_LABELS
Max allowable labels of domain names.
bool gthan(const Name &other) const
Greater-than comparison for Name against other
Name concatenate(const Name &suffix) const
Concatenate two names.
std::string toRawText(bool omit_final_dot=false) const
Convert the LabelSequence to a string without escape sequences.
static const uint16_t COMPRESS_POINTER_MARK8
A 8-bit masked value indicating a start of compression pointer.
bool leq(const Name &other) const
Less-than or equal comparison for Name against other
Name & downcase()
Downcase all upper case alphabet characters in the name.
bool isWildcard() const
Test if this is a wildcard name.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
#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.
const uint8_t maptolower[]
ostream & operator<<(std::ostream &os, const EDNS &edns)
Insert the EDNS as a string into stream.
Defines the logger used by the top-level component of kea-lfc.