Kea  2.1.7-git
isc::dns::Name Class Reference

The Name class encapsulates DNS names. More...

#include <name.h>

Public Member Functions

Getter Methods

We use the default copy constructor intentionally.

We use the default copy assignment operator intentionally.

uint8_t at (size_t pos) const
 Provides one-byte name data in wire format at the specified position. More...
 
size_t getLength () const
 Gets the length of the Name in its wire format. More...
 
unsigned int getLabelCount () const
 Returns the number of labels contained in the Name. More...
 
Converter methods
std::string toText (bool omit_final_dot=false) const
 Convert the Name to a string. More...
 
std::string toRawText (bool omit_final_dot=false) const
 Convert the LabelSequence to a string without escape sequences. More...
 
void toWire (AbstractMessageRenderer &renderer) const
 Render the Name in the wire format with compression. More...
 
void toWire (isc::util::OutputBuffer &buffer) const
 Render the Name in the wire format without compression. More...
 
Comparison methods
NameComparisonResult compare (const Name &other) const
 Compare two Names. More...
 
bool equals (const Name &other) const
 Return true iff two names are equal. More...
 
bool operator== (const Name &other) const
 Same as equals() More...
 
bool nequals (const Name &other) const
 Return true iff two names are not equal. More...
 
bool operator!= (const Name &other) const
 Same as nequals() More...
 
bool leq (const Name &other) const
 Less-than or equal comparison for Name against other More...
 
bool operator<= (const Name &other) const
 Same as leq() More...
 
bool geq (const Name &other) const
 Greater-than or equal comparison for Name against other More...
 
bool operator>= (const Name &other) const
 Same as geq() More...
 
bool lthan (const Name &other) const
 Less-than comparison for Name against other More...
 
bool operator< (const Name &other) const
 Same as lthan() More...
 
bool gthan (const Name &other) const
 Greater-than comparison for Name against other More...
 
bool operator> (const Name &other) const
 Same as gthan() More...
 
Transformer methods
Name split (unsigned int first, unsigned int n) const
 Extract a specified subpart of Name. More...
 
Name split (unsigned int level) const
 Extract a specified super domain name of Name. More...
 
Name reverse () const
 Reverse the labels of a name. More...
 
Name concatenate (const Name &suffix) const
 Concatenate two names. More...
 
Namedowncase ()
 Downcase all upper case alphabet characters in the name. More...
 
Testing methods
bool isWildcard () const
 Test if this is a wildcard name. More...
 

Static Public Member Functions

Well-known name constants
static const NameROOT_NAME ()
 Root name (i.e. "."). More...
 

Static Public Attributes

Protocol constants
static const size_t MAX_WIRE = 255
 Max allowable length of domain names. More...
 
static const size_t MAX_LABELS = 128
 Max allowable labels of domain names. More...
 
static const size_t MAX_LABELLEN = 63
 Max allowable length of labels of a domain name. More...
 
static const uint16_t MAX_COMPRESS_POINTER = 0x3fff
 Max possible pointer value for name compression. More...
 
static const uint16_t COMPRESS_POINTER_MARK8 = 0xc0
 A 8-bit masked value indicating a start of compression pointer. More...
 
static const uint16_t COMPRESS_POINTER_MARK16 = 0xc000
 A 16-bit masked value indicating a start of compression pointer. More...
 

Friends

class LabelSequence
 

Constructors and Destructor

 Name (const std::string &namestr, bool downcase=false)
 Constructor from a string. More...
 
 Name (const char *name_data, size_t data_len, const Name *origin, bool downcase=false)
 Constructor for master file parser. More...
 
 Name (isc::util::InputBuffer &buffer, bool downcase=false)
 Constructor from wire-format data. More...
 

Detailed Description

The Name class encapsulates DNS names.

It provides interfaces to construct a name from string or wire-format data, transform a name into a string or wire-format data, compare two names, get access to various properties of a name, etc.

Notes to developers: Internally, a name object maintains the name data in wire format as an instance of std::string. Since many string implementations adopt copy-on-write data sharing, we expect this approach will make copying a name less expensive in typical cases. If this is found to be a significant performance bottleneck later, we may reconsider the internal representation or perhaps the API.

A name object also maintains a vector of offsets (offsets_ member), each of which is the offset to a label of the name: The n-th element of the vector specifies the offset to the n-th label. For example, if the object represents "www.example.com", the elements of the offsets vector are 0, 4, 12, and 16. Note that the offset to the trailing dot (16) is included. In the BIND9 DNS library from which this implementation is derived, the offsets are optional, probably due to performance considerations (in fact, offsets can always be calculated from the name data, and in that sense are redundant). In our implementation, however, we always build and maintain the offsets. We believe we need more low level, specialized data structure and interface where we really need to pursue performance, and would rather keep this generic API and implementation simpler.

While many other DNS APIs introduce an "absolute or relative" attribute of names as defined in RFC1035, names are always "absolute" in the initial design of this API. In fact, separating absolute and relative would confuse API users unnecessarily. For example, it's not so intuitive to consider the comparison result of an absolute name with a relative name. We've looked into how the concept of absolute names is used in BIND9, and found that in many cases names are generally absolute. The only reasonable case of separating absolute and relative is in a master file parser, where a relative name must be a complete name with an "origin" name, which must be absolute. So, in this initial design, we chose a simpler approach: the API generally handles names as absolute; when we introduce a parser of master files, we'll introduce the notion of relative names as a special case.

Definition at line 223 of file name.h.

Constructor & Destructor Documentation

◆ Name() [1/3]

isc::dns::Name::Name ( const std::string &  namestr,
bool  downcase = false 
)
explicit

Constructor from a string.

If the given string does not represent a valid DNS name, an exception of class EmptyLabel, TooLongLabel, BadLabelType, BadEscape, TooLongName, or IncompleteName will be thrown. In addition, if resource allocation for the new name fails, a corresponding standard exception will be thrown.

Parameters
namestrA string representation of the name to be constructed.
downcaseWhether to convert upper case alphabets to lower case.

Definition at line 293 of file name.cc.

References isc_throw_assert.

◆ Name() [2/3]

isc::dns::Name::Name ( const char *  name_data,
size_t  data_len,
const Name origin,
bool  downcase = false 
)

Constructor for master file parser.

This acts similar to the above. But the data is passed as raw C-string instead of wrapped-up C++ std::string.

Also, when the origin is non-NULL and the name_data is not ending with a dot, it is considered relative and the origin is appended to it.

If the name_data is equal to "@", the content of origin is copied.

Parameters
name_dataThe raw data of the name.
data_lenHow many bytes in name_data is valid and considered part of the name.
originIf non-NULL, it is taken as the origin to complete relative names.
downcaseWhether to convert upper case letters to lower case.
Exceptions
NameParserExceptionor any of its descendants in case the input data is invalid.
isc::InvalidParameterIn case name_data is NULL or data_len is 0.
std::bad_allocIn case allocation fails.
Note
This constructor is specially designed for the use of master file parser. It mimics the behaviour of names in the master file and accepts raw data. It is not recommended to be used by anything else.
Todo:
Should we make it private and the parser a friend, to hide the constructor?

Definition at line 313 of file name.cc.

References isc_throw, and isc_throw_assert.

◆ Name() [3/3]

isc::dns::Name::Name ( isc::util::InputBuffer buffer,
bool  downcase = false 
)
explicit

Constructor from wire-format data.

The buffer parameter normally stores a complete DNS message containing the name to be constructed. The current read position of the buffer points to the head of the name.

The input data may or may not be compressed; if it's compressed, this method will automatically decompress it.

If the given data does not represent a valid DNS name, an exception of class DNSMessageFORMERR will be thrown. In addition, if resource allocation for the new name fails, a corresponding standard exception will be thrown.

Parameters
bufferA buffer storing the wire format data.
downcaseWhether to convert upper case alphabets to lower case.

Definition at line 389 of file name.cc.

References isc::util::InputBuffer::getLength(), isc::util::InputBuffer::getPosition(), isc_throw, isc_throw_assert, isc::dns::name::internal::maptolower, isc::util::InputBuffer::readUint8(), and isc::util::InputBuffer::setPosition().

+ Here is the call graph for this function:

Member Function Documentation

◆ at()

uint8_t isc::dns::Name::at ( size_t  pos) const
inline

Provides one-byte name data in wire format at the specified position.

This method returns the unsigned 8-bit value of wire-format Name data at the given position from the head.

For example, if n is a Name object for "example.com", n.at(3) would return 'a', and n.at(7) would return 'e'. Note that n.at(0) would be 7 (decimal), the label length of "example", instead of 'e', because it returns a data portion in wire-format. Likewise, n.at(8) would return 3 (decimal) instead of '.'

This method would be useful for an application to examine the wire-format name data without dumping the data into a buffer, which would involve data copies and would be less efficient. One common usage of this method would be something like this:

for (size_t i = 0; i < name.getLength(); ++i) {
uint8_t c = name.at(i);
// do something with c
}

Parameter pos must be in the valid range of the name data, that is, must be less than Name.getLength(). Otherwise, an exception of class OutOfRange will be thrown. This method never throws an exception in other ways.

Parameters
posThe position in the wire format name data to be returned.
Returns
An unsigned 8-bit integer corresponding to the name data at the position of pos.

Definition at line 346 of file name.h.

Referenced by isc::dns::rdata::compareNames(), and downcase().

◆ compare()

NameComparisonResult isc::dns::Name::compare ( const Name other) const

Compare two Names.

This method compares the Name and other and returns the result in the form of a NameComparisonResult object.

Note that this is case-insensitive comparison.

This method never throws an exception.

Parameters
otherthe right-hand operand to compare against.
Returns
a NameComparisonResult object representing the comparison result.

Definition at line 519 of file name.cc.

References isc::dns::LabelSequence::compare().

+ Here is the call graph for this function:

◆ concatenate()

Name isc::dns::Name::concatenate ( const Name suffix) const

Concatenate two names.

This method appends suffix to this Name. The trailing dot of this Name will be removed. For example, if this is "www." and suffix is "example.com.", a successful return of this method will be a name of "www.example.com."

The resulting length of the concatenated name must not exceed Name::MAX_WIRE; otherwise an exception of class TooLongName will be thrown.

Parameters
suffixa Name object to be appended to the Name.
Returns
a new Name object concatenating suffix to this Name.

Definition at line 578 of file name.cc.

References isc_throw, and isc_throw_assert.

◆ downcase()

Name & isc::dns::Name::downcase ( )

Downcase all upper case alphabet characters in the name.

This method modifies the calling object so that it can perform the conversion as fast as possible and can be exception free.

The return value of this version of downcase() is a reference to the calling object (i.e., *this) so that the caller can use the result of downcasing in a single line. For example, if variable n is a Name class object possibly containing upper case characters, and b is an OutputBuffer class object, then the following code will dump the name in wire format to b with downcasing upper case characters:

n.downcase().toWire(b);

Since this method modifies the calling object, a const name object cannot call it. If n is a const Name class object, it must first be copied to a different object and the latter must be used for the downcase modification.

Returns
A reference to the calling object with being downcased.

Definition at line 690 of file name.cc.

References at(), isc_throw_assert, and isc::dns::name::internal::maptolower.

+ Here is the call graph for this function:

◆ equals()

bool isc::dns::Name::equals ( const Name other) const

Return true iff two names are equal.

Semantically this could be implemented based on the result of the compare() method, but the actual implementation uses different code that simply performs character-by-character comparison (case insensitive for the name label parts) on the two names. This is because it would be much faster and the simple equality check would be pretty common.

This method never throws an exception.

Parameters
otherthe Name object to compare against.
Returns
true if the two names are equal; otherwise false.

Definition at line 526 of file name.cc.

References isc::dns::name::internal::maptolower.

◆ geq()

bool isc::dns::Name::geq ( const Name other) const

Greater-than or equal comparison for Name against other

The comparison is based on the result of the compare() method.

This method never throws an exception.

Parameters
otherthe Name object to compare against.
Returns
true if compare(other).getOrder() >= 0; otherwise false.

Definition at line 558 of file name.cc.

◆ getLabelCount()

unsigned int isc::dns::Name::getLabelCount ( ) const
inline

Returns the number of labels contained in the Name.

Note that an empty label (corresponding to a trailing '.') is counted as a single label, so the return value of this method must be >0.

This method never throws an exception.

Returns
the number of labels

Definition at line 370 of file name.h.

Referenced by isc::dhcp::OptionDataTypeUtil::getLabelCount().

◆ getLength()

size_t isc::dns::Name::getLength ( ) const
inline

Gets the length of the Name in its wire format.

This method never throws an exception.

Returns
the length (the number of octets in wire format) of the Name

Definition at line 360 of file name.h.

Referenced by isc::dns::rdata::compareNames(), isc::dns::TSIGContext::getTSIGLength(), and isc::dns::TSIGRecord::getTTL().

◆ gthan()

bool isc::dns::Name::gthan ( const Name other) const

Greater-than comparison for Name against other

The comparison is based on the result of the compare() method.

This method never throws an exception.

Parameters
otherthe Name object to compare against.
Returns
true if compare(other).getOrder() > 0; otherwise false.

Definition at line 568 of file name.cc.

◆ isWildcard()

bool isc::dns::Name::isWildcard ( ) const

Test if this is a wildcard name.

Returns
true if the least significant label of this Name is '*'; otherwise false.

Definition at line 573 of file name.cc.

◆ leq()

bool isc::dns::Name::leq ( const Name other) const

Less-than or equal comparison for Name against other

The comparison is based on the result of the compare() method.

This method never throws an exception.

Parameters
otherthe Name object to compare against.
Returns
true if compare(other).getOrder() <= 0; otherwise false.

Definition at line 553 of file name.cc.

◆ lthan()

bool isc::dns::Name::lthan ( const Name other) const

Less-than comparison for Name against other

The comparison is based on the result of the compare() method.

This method never throws an exception.

Parameters
otherthe Name object to compare against.
Returns
true if compare(other).getOrder() < 0; otherwise false.

Definition at line 563 of file name.cc.

◆ nequals()

bool isc::dns::Name::nequals ( const Name other) const
inline

Return true iff two names are not equal.

This method simply negates the result of equal() method, and in that sense it's redundant. The separate method is provided just for convenience.

Definition at line 474 of file name.h.

◆ operator!=()

bool isc::dns::Name::operator!= ( const Name other) const
inline

Same as nequals()

Definition at line 477 of file name.h.

◆ operator<()

bool isc::dns::Name::operator< ( const Name other) const
inline

Same as lthan()

Definition at line 520 of file name.h.

◆ operator<=()

bool isc::dns::Name::operator<= ( const Name other) const
inline

Same as leq()

Definition at line 491 of file name.h.

◆ operator==()

bool isc::dns::Name::operator== ( const Name other) const
inline

Same as equals()

Definition at line 467 of file name.h.

◆ operator>()

bool isc::dns::Name::operator> ( const Name other) const
inline

Same as gthan()

Definition at line 534 of file name.h.

◆ operator>=()

bool isc::dns::Name::operator>= ( const Name other) const
inline

Same as geq()

Definition at line 506 of file name.h.

◆ reverse()

Name isc::dns::Name::reverse ( ) const

Reverse the labels of a name.

This method reverses the labels of a name. For example, if this is "www.example.com.", this method will return "com.example.www." (This is useful because DNSSEC sort order is equivalent to a lexical sort of label-reversed names.)

Definition at line 614 of file name.cc.

◆ ROOT_NAME()

const Name & isc::dns::Name::ROOT_NAME ( )
inlinestatic

Root name (i.e. ".").

Definition at line 738 of file name.h.

References isc::util::operator<<().

Referenced by isc::dns::EDNS::EDNS(), and isc::dns::EDNS::toText().

+ Here is the call graph for this function:

◆ split() [1/2]

Name isc::dns::Name::split ( unsigned int  first,
unsigned int  n 
) const

Extract a specified subpart of Name.

name.split(first, n) constructs a new name starting from the first-th label of the name, and subsequent n labels including the first one. Since names in this current implementation are always "absolute", if the specified range doesn't contain the trailing dot of the original name, then a dot will be appended to the resulting name. As a result, the number of labels will be n + 1, rather than n. For example, when n is Name("www.example.com"), both n.split(1, 2) and n.split(1, 3) will produce a name corresponding to "example.com.", which has 3 labels. Note also that labels are counted from 0, and so first = 1 in this example specified the label "example", not "www".

Parameter n must be larger than 0, and the range specified by first and n must not exceed the valid range of the original name; otherwise, an exception of class OutOfRange will be thrown.

Note to developers: we may want to have different versions (signatures) of this method. For example, we want to split the Name based on a given suffix name.

Parameters
firstThe start position (in labels) of the extracted name
nNumber of labels of the extracted name
Returns
A new Name object based on the Name containing n labels including and following the first label.

Definition at line 643 of file name.cc.

References isc_throw, and isc_throw_assert.

◆ split() [2/2]

Name isc::dns::Name::split ( unsigned int  level) const

Extract a specified super domain name of Name.

This function constructs a new Name object that is a super domain of this name. The new name is level labels upper than this name. For example, when name is www.example.com, name.split(1) will return a Name object for example.com. level can be 0, in which case this method returns a copy of this name. The possible maximum value for level is this->getLabelCount()-1, in which case this method returns a root name.

One common expected usage of this method is to iterate over super domains of a given name, label by label, as shown in the following sample code:

// if name is www.example.com...
for (int i = 0; i < name.getLabelCount(); ++i) {
Name upper_name(name.split(i));
// upper_name'll be www.example.com., example.com., com., and then .
}

level must be smaller than the number of labels of this name; otherwise an exception of class OutOfRange will be thrown. In addition, if resource allocation for the new name fails, a corresponding standard exception will be thrown.

Note to developers: probably as easily imagined, this method is a simple wrapper to one usage of the other split(unsigned int, unsigned int) const method and is redundant in some sense. We provide the "redundant" method for convenience, however, because the expected usage shown above seems to be common, and the parameters to the other split(unsigned int, unsigned int) const to implement it may not be very intuitive.

We are also aware that it is generally discouraged to add a public member function that could be implemented using other member functions. We considered making it a non member function, but we could not come up with an intuitive function name to represent the specific service. Some other developers argued, probably partly because of the counter intuitive function name, a different signature of split would be better to improve code readability. While that may be a matter of personal preference, we accepted the argument. One major goal of public APIs like this is wider acceptance from internal/external developers, so unless there is a clear advantage it would be better to respect the preference of the API users.

Since this method doesn't have to be a member function in other way, it is intentionally implemented only using public interfaces of the Name class; it doesn't refer to private members of the class even if it could. This way we hope we can avoid damaging the class encapsulation, which is a major drawback of public member functions. As such if and when this "method" has to be extended, it should be implemented without the privilege of being a member function unless there is a very strong reason to do so. In particular a minor performance advantage shouldn't justify that approach.

Parameters
levelThe number of labels to be removed from this name to create the super domain name. (0 <= level < this->getLabelCount())
Returns
A new Name object to be created.

Definition at line 680 of file name.cc.

References isc_throw.

◆ toRawText()

std::string isc::dns::Name::toRawText ( bool  omit_final_dot = false) const

Convert the LabelSequence to a string without escape sequences.

The string returned will contain a single character value for any escape sequences in the label(s).

Parameters
omit_final_dotwhether to omit the trailing dot in the output.
Returns
a string representation of the LabelSequence that does not contain escape sequences. Default value is false.

Definition at line 513 of file name.cc.

References isc::dns::LabelSequence::toRawText().

Referenced by isc::dhcp::D2ClientMgr::adjustDomainName().

+ Here is the call graph for this function:

◆ toText()

std::string isc::dns::Name::toText ( bool  omit_final_dot = false) const

Convert the Name to a string.

This method returns a std::string object representing the Name as a string. Unless omit_final_dot is true, the returned string ends with a dot '.'; the default is false. The default value of this parameter is true; converted names will have a trailing dot by default.

This function assumes the name is in proper uncompressed wire format. If it finds an unexpected label character including compression pointer, an exception of class BadLabelType will be thrown. In addition, if resource allocation for the result string fails, a corresponding standard exception will be thrown.

Parameters
omit_final_dotwhether to omit the trailing dot in the output.
Returns
a string representation of the Name.

Definition at line 507 of file name.cc.

References isc::dns::LabelSequence::toText().

Referenced by isc::dns::operator<<(), isc::dhcp::OptionDataTypeUtil::readFqdn(), isc::d2::D2TsigKey::resetStats(), isc::dhcp_ddns::NameChangeRequest::setFqdn(), isc::d2::TSIGKeyInfo::stringToAlgorithmName(), isc::d2::D2Zone::toText(), isc::dns::Question::toText(), isc::dns::TSIGRecord::toText(), and isc::d2::D2TsigKey::~D2TsigKey().

+ Here is the call graph for this function:

◆ toWire() [1/2]

void isc::dns::Name::toWire ( AbstractMessageRenderer renderer) const

Render the Name in the wire format with compression.

This method dumps the Name in wire format with help of renderer, which encapsulates output buffer and name compression algorithm to render the name.

If resource allocation in rendering process fails, a corresponding standard exception will be thrown.

Parameters
rendererDNS message rendering context that encapsulates the output buffer and name compression information.

Definition at line 502 of file name.cc.

References isc::dns::AbstractMessageRenderer::writeName().

Referenced by isc::dns::AbstractRRset::toText(), isc::dns::BasicRRsetImpl::toWire(), isc::dns::Question::toWire(), and isc::dns::TSIGRecord::toWire().

+ Here is the call graph for this function:

◆ toWire() [2/2]

void isc::dns::Name::toWire ( isc::util::OutputBuffer buffer) const

Render the Name in the wire format without compression.

If resource allocation in rendering process fails, a corresponding standard exception will be thrown. This can be avoided by preallocating a sufficient size of buffer. Specifically, if buffer.getCapacity() - buffer.getLength() >= Name::MAX_WIRE then this method should not throw an exception.

Parameters
bufferAn output buffer to store the wire data.

Definition at line 497 of file name.cc.

References isc::util::OutputBuffer::writeData().

+ Here is the call graph for this function:

Friends And Related Function Documentation

◆ LabelSequence

friend class LabelSequence
friend

Definition at line 227 of file name.h.

Member Data Documentation

◆ COMPRESS_POINTER_MARK16

const uint16_t isc::dns::Name::COMPRESS_POINTER_MARK16 = 0xc000
static

A 16-bit masked value indicating a start of compression pointer.

Definition at line 719 of file name.h.

Referenced by isc::dns::MessageRenderer::writeName().

◆ COMPRESS_POINTER_MARK8

const uint16_t isc::dns::Name::COMPRESS_POINTER_MARK8 = 0xc0
static

A 8-bit masked value indicating a start of compression pointer.

Definition at line 717 of file name.h.

◆ MAX_COMPRESS_POINTER

const uint16_t isc::dns::Name::MAX_COMPRESS_POINTER = 0x3fff
static

Max possible pointer value for name compression.

This is the highest number of 14-bit unsigned integer. Name compression pointers are identified as a 2-byte value starting with the upper two bit being 11.

Definition at line 715 of file name.h.

Referenced by isc::dns::MessageRenderer::writeName().

◆ MAX_LABELLEN

const size_t isc::dns::Name::MAX_LABELLEN = 63
static

Max allowable length of labels of a domain name.

Definition at line 708 of file name.h.

Referenced by isc::dns::LabelSequence::compare(), isc::dns::LabelSequence::LabelSequence(), and isc::dns::LabelSequence::toRawText().

◆ MAX_LABELS

const size_t isc::dns::Name::MAX_LABELS = 128
static

Max allowable labels of domain names.

This is ceil(MAX_WIRE / 2), and is equal to the number of labels of name "a.a.a.a....a." (127 "a"'s and trailing dot).

Definition at line 705 of file name.h.

Referenced by isc::dns::LabelSequence::extend(), and isc::dns::LabelSequence::LabelSequence().

◆ MAX_WIRE

const size_t isc::dns::Name::MAX_WIRE = 255
static

Max allowable length of domain names.

Definition at line 699 of file name.h.

Referenced by isc::dns::LabelSequence::extend(), and isc::dns::LabelSequence::LabelSequence().


The documentation for this class was generated from the following files: