49const signed char digitvalue[256] = {
 
   50    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 
   51    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 
   52    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 
   53     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, 
 
   54    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 
   55    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -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, 
 
   72    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 
   73    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 
   74    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
 
   75    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 
   76    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
 
   77    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
 
   78    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
 
   79    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
 
   80    0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
 
   81    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 
 
   82    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
 
   83    0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
 
   84    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
 
   85    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 
   86    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
 
   87    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
 
   88    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
 
   89    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 
   90    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
 
   91    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 
   92    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 
   93    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 
   94    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
 
   95    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 
   96    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 
   97    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 
   98    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 
   99    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 
  100    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 
  101    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 
  102    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 
  103    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
 
 
 
 
  124template<
class Iterator, 
class Offsets, 
class Data>
 
  126stringParse(Iterator s, Iterator send, 
bool downcase, Offsets& offsets,
 
  129    const Iterator orig_s(s);
 
  133    unsigned int digits = 0;
 
  134    unsigned int value = 0;
 
  135    unsigned int count = 0;
 
  141    bool is_root = 
false;
 
  142    const bool empty = s == send;
 
  143    ft_state state = ft_init;
 
  147    offsets.push_back(0);
 
  156        unsigned char c = *s++;
 
  166                              "non terminating empty label in " <<
 
  167                              string(orig_s, send));
 
  170            } 
else if (c == 
'@' && s == send) {
 
  186                state = ft_initialescape;
 
  196                              "duplicate period in " << 
string(orig_s, send));
 
  198                ndata.at(offsets.back()) = count;
 
  199                offsets.push_back(ndata.size());
 
  205            } 
else if (c == 
'\\') {
 
  210                              "label is too long in " << 
string(orig_s, send));
 
  212                ndata.push_back(downcase ? 
maptolower[c] : c);
 
  215        case ft_initialescape:
 
  220                          "invalid label type in " << 
string(orig_s, send));
 
  224            if (!isdigit(c & 0xff)) {
 
  227                              "label is too long in " << 
string(orig_s, send));
 
  229                ndata.push_back(downcase ? 
maptolower[c] : c);
 
  235            state = ft_escdecimal;
 
  238            if (!isdigit(c & 0xff)) {
 
  240                          "mixture of escaped digit and non-digit in " 
  241                          << 
string(orig_s, send));
 
  244            value += digitvalue[c];
 
  249                              "escaped decimal is too large in " 
  250                              << 
string(orig_s, send));
 
  254                              "label is too long in " << 
string(orig_s, send));
 
  256                ndata.push_back(downcase ? 
maptolower[value] : value);
 
  269                      "name is too long for termination in " <<
 
  270                      string(orig_s, send));
 
  273        if (state != ft_ordinary) {
 
  275                      "incomplete textual name in " <<
 
  276                      (empty ? 
"<empty>" : 
string(orig_s, send)));
 
  278        if (state == ft_ordinary) {
 
  280            ndata.at(offsets.back()) = count;
 
  282            offsets.push_back(ndata.size());
 
  284            ndata.push_back(
'\0');
 
  291Name::Name(
const std::string &namestring, 
bool downcase) {
 
  293    const std::string::const_iterator s = namestring.begin();
 
  294    const std::string::const_iterator send = namestring.end();
 
  301    stringParse(s, send, 
downcase, offsets, ndata);
 
  304    labelcount_ = offsets.size();
 
  306    ndata_.assign(ndata.data(), ndata.data() + ndata.size());
 
  307    length_ = ndata_.size();
 
  308    offsets_.assign(offsets.begin(), offsets.end());
 
 
  311Name::Name(
const char* namedata, 
size_t data_len, 
const Name* origin,
 
  314    if (!namedata || data_len == 0) {
 
  316                  "No data provided to Name constructor");
 
  320    const bool absolute = (namedata[data_len - 1] == 
'.');
 
  322    if (!absolute && !origin) {
 
  324                  "No origin available and name is relative");
 
  327    const char* end = namedata + data_len;
 
  334    stringParse(namedata, end, 
downcase, offsets, ndata);
 
  337    labelcount_ = offsets.size();
 
  339    ndata_.assign(ndata.data(), ndata.data() + ndata.size());
 
  340    length_ = ndata_.size();
 
  341    offsets_.assign(offsets.begin(), offsets.end());
 
  349        ndata_.erase(ndata_.end() - 1);
 
  350        ndata_.insert(ndata_.end(), origin->ndata_.begin(), origin->ndata_.end());
 
  354        size_t offset = offsets_.back();
 
  356        size_t offset_count = offsets_.size();
 
  357        offsets_.insert(offsets_.end(), origin->offsets_.begin(),
 
  358                        origin->offsets_.end());
 
  359        for (
auto it(offsets_.begin() + offset_count); it != offsets_.end(); ++it) {
 
  364        length_ = ndata_.size();
 
  365        labelcount_ = offsets_.size();
 
 
  398    unsigned int nused = 0;
 
  399    bool seen_pointer = 
false;
 
  400    fw_state state = fw_start;
 
  402    unsigned int cused = 0;     
 
  404    unsigned int pos_begin = current;
 
  405    unsigned int biggest_pointer = current;
 
  410    unsigned int new_current = 0;
 
  416    while (current < buffer.
getLength() && !done) {
 
  426                offsets.push_back(nused);
 
  429                              << nused + c + 1 << 
" bytes");
 
  444                state = fw_newcurrent;
 
  466            if (new_current >= biggest_pointer) {
 
  468                          "bad compression pointer (out of range): " <<
 
  471            biggest_pointer = new_current;
 
  472            current = new_current;
 
  486    labelcount_ = offsets.size();
 
  488    offsets_.assign(offsets.begin(), offsets.end());
 
 
  494    buffer.
writeData(ndata_.data(), ndata_.size());
 
 
  505    return (ls.
toText(omit_final_dot));
 
 
  523    if (length_ != other.length_ || labelcount_ != other.labelcount_) {
 
  527    for (
unsigned int l = labelcount_, pos = 0; l > 0; --l) {
 
  528        uint8_t count = ndata_[pos];
 
  529        if (count != other.ndata_[pos]) {
 
  534        while (count-- > 0) {
 
  535            uint8_t label1 = ndata_[pos];
 
  536            uint8_t label2 = other.ndata_[pos];
 
 
  550    return (
compare(other).getOrder() <= 0);
 
 
  555    return (
compare(other).getOrder() >= 0);
 
 
  560    return (
compare(other).getOrder() < 0);
 
 
  565    return (
compare(other).getOrder() > 0);
 
 
  570    return (length_ >= 2 && ndata_[0] == 1 && ndata_[1] == 
'*');
 
 
  578    unsigned int length = length_ + suffix.length_ - 1;
 
  584    retname.ndata_.reserve(length);
 
  585    retname.ndata_.assign(ndata_.data(), ndata_.data() + length_ - 1);
 
  586    retname.ndata_.insert(retname.ndata_.end(),
 
  587                          suffix.ndata_.begin(), suffix.ndata_.end());
 
  589    retname.length_ = length;
 
  596    unsigned int labels = labelcount_ + suffix.labelcount_ - 1;
 
  598    retname.offsets_.reserve(labels);
 
  599    retname.offsets_.assign(&offsets_[0], &offsets_[0] + labelcount_ - 1);
 
  600    transform(suffix.offsets_.begin(), suffix.offsets_.end(),
 
  601              back_inserter(retname.offsets_),
 
  602              [
this] (
char x) { return (x + length_ - 1); });
 
  604    retname.labelcount_ = labels;
 
 
  616    retname.offsets_.reserve(labelcount_);
 
  617    retname.ndata_.reserve(length_);
 
  620    NameOffsets::const_reverse_iterator rit0 = offsets_.rbegin();
 
  621    NameOffsets::const_reverse_iterator rit1 = rit0 + 1;
 
  622    NameString::const_iterator n0 = ndata_.begin();
 
  623    retname.offsets_.push_back(0);
 
  624    while (rit1 != offsets_.rend()) {
 
  625        retname.ndata_.insert(retname.ndata_.end(), n0 + *rit1, n0 + *rit0);
 
  626        retname.offsets_.push_back(retname.ndata_.size());
 
  630    retname.ndata_.push_back(0);
 
  632    retname.labelcount_ = labelcount_;
 
  633    retname.length_ = length_;
 
 
  639Name::split(
const unsigned int first, 
const unsigned int n)
 const {
 
  640    if (n == 0 || n > labelcount_ || first > labelcount_ - n) {
 
  647    unsigned int newlabels = (first + n == labelcount_) ? n : n + 1;
 
  653    retname.offsets_.reserve(newlabels);
 
  654    transform(offsets_.begin() + first, offsets_.begin() + first + newlabels,
 
  655              back_inserter(retname.offsets_),
 
  656              [&](
char x) { return (x - offsets_[first]); });
 
  664    retname.ndata_.reserve(retname.offsets_.back() + 1);
 
  665    auto it = ndata_.data() + offsets_[first];
 
  666    retname.ndata_.assign(it, it + retname.offsets_.back());
 
  667    retname.ndata_.push_back(0);
 
  669    retname.length_ = retname.ndata_.size();
 
  670    retname.labelcount_ = retname.offsets_.size();
 
 
  680                  << 
") for name " << *
this);
 
 
  688    unsigned int nlen = length_;
 
  689    unsigned int labels = labelcount_;
 
  690    unsigned int pos = 0;
 
  692    while (labels > 0 && nlen > 0) {
 
  698        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.
A standard DNS module exception that is thrown if the name parser fails to decode a back-slash escape...
A standard DNS module exception that is thrown if the name parser encounters an obsolete or incomplet...
A standard DNS module exception that is thrown if the name parser encounters an empty label in the mi...
A standard DNS module exception that is thrown if the name parser finds the input (string or wire-for...
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.
friend class LabelSequence
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.