Kea 2.7.6
|
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. | |
size_t | getLength () const |
Gets the length of the Name in its wire format. | |
unsigned int | getLabelCount () const |
Returns the number of labels contained in the Name . | |
Converter methods | |
std::string | toText (bool omit_final_dot=false) const |
Convert the Name to a string. | |
std::string | toRawText (bool omit_final_dot=false) const |
Convert the LabelSequence to a string without escape sequences. | |
void | toWire (AbstractMessageRenderer &renderer) const |
Render the Name in the wire format with compression. | |
void | toWire (isc::util::OutputBuffer &buff) const |
Render the Name in the wire format without compression. | |
Comparison methods | |
NameComparisonResult | compare (const Name &other) const |
Compare two Name s. | |
bool | equals (const Name &other) const |
Return true iff two names are equal. | |
bool | operator== (const Name &other) const |
Same as equals() | |
bool | nequals (const Name &other) const |
Return true iff two names are not equal. | |
bool | operator!= (const Name &other) const |
Same as nequals() | |
bool | leq (const Name &other) const |
Less-than or equal comparison for Name against other | |
bool | operator<= (const Name &other) const |
Same as leq() | |
bool | geq (const Name &other) const |
Greater-than or equal comparison for Name against other | |
bool | operator>= (const Name &other) const |
Same as geq() | |
bool | lthan (const Name &other) const |
Less-than comparison for Name against other | |
bool | operator< (const Name &other) const |
Same as lthan() | |
bool | gthan (const Name &other) const |
Greater-than comparison for Name against other | |
bool | operator> (const Name &other) const |
Same as gthan() | |
Transformer methods | |
Name | split (unsigned int first, unsigned int n) const |
Extract a specified subpart of Name. | |
Name | split (unsigned int level) const |
Extract a specified super domain name of Name. | |
Name | reverse () const |
Reverse the labels of a name. | |
Name | concatenate (const Name &suffix) const |
Concatenate two names. | |
Name & | downcase () |
Downcase all upper case alphabet characters in the name. | |
Testing methods | |
bool | isWildcard () const |
Test if this is a wildcard name. | |
Static Public Attributes | |
Protocol constants | |
static const size_t | MAX_WIRE = 255 |
Max allowable length of domain names. | |
static const size_t | MAX_LABELS = 128 |
Max allowable labels of domain names. | |
static const size_t | MAX_LABELLEN = 63 |
Max allowable length of labels of a domain name. | |
static const uint16_t | MAX_COMPRESS_POINTER = 0x3fff |
Max possible pointer value for name compression. | |
static const uint16_t | COMPRESS_POINTER_MARK8 = 0xc0 |
A 8-bit masked value indicating a start of compression pointer. | |
static const uint16_t | COMPRESS_POINTER_MARK16 = 0xc000 |
A 16-bit masked value indicating a start of compression pointer. | |
Friends | |
class | LabelSequence |
Constructors and Destructor | |
Name (const std::string &namestr, bool downcase=false) | |
Constructor from a string. | |
Name (const char *name_data, size_t data_len, const Name *origin, bool downcase=false) | |
Constructor for master file parser. | |
Name (isc::util::InputBuffer &buff, bool downcase=false) | |
Constructor from wire-format data. | |
Well-known name constants | |
static const Name & | ROOT_NAME () |
Root name (i.e. "."). | |
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.
|
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.
namestr | A string representation of the name to be constructed. |
downcase | Whether to convert upper case alphabets to lower case. |
Definition at line 291 of file name.cc.
References downcase(), isc_throw_assert, and MAX_LABELS.
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.
name_data | The raw data of the name. |
data_len | How many bytes in name_data is valid and considered part of the name. |
origin | If non-null, it is taken as the origin to complete relative names. |
downcase | Whether to convert upper case letters to lower case. |
NameParserException | or any of its descendants in case the input data is invalid. |
isc::InvalidParameter | In case name_data is null or data_len is 0. |
std::bad_alloc | In case allocation fails. |
Definition at line 311 of file name.cc.
References downcase(), isc_throw, isc_throw_assert, MAX_LABELS, and MAX_WIRE.
|
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.
buff | A buffer storing the wire format data. |
downcase | Whether to convert upper case alphabets to lower case. |
Definition at line 385 of file name.cc.
References COMPRESS_POINTER_MARK8, downcase(), isc::util::InputBuffer::getLength(), isc::util::InputBuffer::getPosition(), isc_throw, isc_throw_assert, MAX_LABELLEN, MAX_LABELS, MAX_WIRE, isc::util::InputBuffer::readUint8(), and isc::util::InputBuffer::setPosition().
|
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:
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.
pos | The position in the wire format name data to be returned. |
pos
. Definition at line 342 of file name.h.
References isc_throw.
Referenced by isc::dns::rdata::compareNames().
NameComparisonResult isc::dns::Name::compare | ( | const Name & | other | ) | const |
Compare two Name
s.
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.
other | the right-hand operand to compare against. |
NameComparisonResult
object representing the comparison result. Definition at line 515 of file name.cc.
References isc::dns::LabelSequence::compare().
Referenced by geq(), gthan(), leq(), and lthan().
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.
Definition at line 574 of file name.cc.
References isc_throw, isc_throw_assert, MAX_LABELS, and MAX_WIRE.
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:
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.
Definition at line 687 of file name.cc.
References isc_throw_assert, and MAX_LABELLEN.
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.
other | the Name object to compare against. |
Definition at line 522 of file name.cc.
Referenced by nequals(), and operator==().
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.
other | the Name object to compare against. |
compare(other).getOrder() >= 0
; otherwise false. Definition at line 554 of file name.cc.
References compare().
Referenced by operator>=().
|
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.
Definition at line 366 of file name.h.
Referenced by isc::dhcp::OptionDataTypeUtil::getLabelCount(), and split().
|
inline |
Gets the length of the Name
in its wire format.
This method never throws an exception.
Name
Definition at line 356 of file name.h.
Referenced by isc::dns::rdata::compareNames(), and isc::dns::BasicRRset::getLength().
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.
other | the Name object to compare against. |
compare(other).getOrder() > 0
; otherwise false. Definition at line 564 of file name.cc.
References compare().
Referenced by operator>().
bool isc::dns::Name::isWildcard | ( | ) | const |
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.
other | the Name object to compare against. |
compare(other).getOrder() <= 0
; otherwise false. Definition at line 549 of file name.cc.
References compare().
Referenced by operator<=().
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.
other | the Name object to compare against. |
compare(other).getOrder() < 0
; otherwise false. Definition at line 559 of file name.cc.
References compare().
Referenced by operator<().
|
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 470 of file name.h.
References equals().
Referenced by operator!=().
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Name isc::dns::Name::reverse | ( | ) | const |
|
inlinestatic |
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.
first | The start position (in labels) of the extracted name |
n | Number of labels of the extracted name |
n
labels including and following the first
label. Definition at line 639 of file name.cc.
References isc_throw, and isc_throw_assert.
Referenced by split().
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:
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.
level | The number of labels to be removed from this name to create the super domain name. (0 <= level < this->getLabelCount() ) |
Name
object to be created. Definition at line 677 of file name.cc.
References getLabelCount(), isc_throw, and split().
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).
omit_final_dot | whether to omit the trailing dot in the output. |
LabelSequence
that does not contain escape sequences. Default value is false. Definition at line 509 of file name.cc.
References isc::dns::LabelSequence::toRawText().
Referenced by isc::dhcp::D2ClientMgr::adjustDomainName().
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.
omit_final_dot | whether to omit the trailing dot in the output. |
Name
. Definition at line 503 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::D2Zone::toText(), isc::dns::AbstractRRset::toText(), isc::dns::Question::toText(), and isc::dns::TSIGRecord::toText().
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.
renderer | DNS message rendering context that encapsulates the output buffer and name compression information. |
Definition at line 498 of file name.cc.
References isc::dns::AbstractMessageRenderer::writeName().
Referenced by isc::dns::BasicRRsetImpl::toWire(), isc::dns::Question::toWire(), and isc::dns::TSIGRecord::toWire().
void isc::dns::Name::toWire | ( | isc::util::OutputBuffer & | buff | ) | 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.
buff | An output buffer to store the wire data. |
Definition at line 493 of file name.cc.
References isc::util::OutputBuffer::writeData().
|
friend |
|
static |
A 16-bit masked value indicating a start of compression pointer.
Definition at line 715 of file name.h.
Referenced by isc::dns::MessageRenderer::writeName().
|
static |
|
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 711 of file name.h.
Referenced by isc::dns::MessageRenderer::writeName().
|
static |
Max allowable length of labels of a domain name.
Definition at line 704 of file name.h.
Referenced by isc::dns::LabelSequence::LabelSequence(), Name(), isc::dns::LabelSequence::compare(), downcase(), and isc::dns::LabelSequence::toRawText().
|
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 701 of file name.h.
Referenced by isc::dns::LabelSequence::LabelSequence(), Name(), Name(), Name(), concatenate(), and isc::dns::LabelSequence::extend().
|
static |
Max allowable length of domain names.
Definition at line 695 of file name.h.
Referenced by isc::dns::LabelSequence::LabelSequence(), Name(), Name(), concatenate(), and isc::dns::LabelSequence::extend().