The Name
class encapsulates DNS names.
More...
Public Member Functions | |
Getter Methods | |
size_t | getLength () const |
Gets the length of the Name in its wire format. | |
unsigned int | getLabels () 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. | |
void | toWire (MessageRenderer &renderer) const |
Render the Name in the wire format with compression. | |
void | toWire (OutputBuffer &buffer) 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 | 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. | |
Constructors and Destructor | |
| |
Name (const std::string &namestr, bool downcase=false) | |
Constructor from a string. | |
Name (InputBuffer &buffer, bool downcase=false) | |
Constructor from wire-format data. |
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.
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.
namestr | A string representation of the name to be constructed. | |
downcase | Whether to convert upper case alphabets to lower case. |
References dns_throw, MAX_LABELLEN, MAX_LABELS, and MAX_WIRE.
isc::dns::Name::Name | ( | 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 TooLongName
, BadLabelType
, BadPointer
, or IncompleteName
will be thrown. In addition, if resource allocation for the new name fails, a corresponding standard exception will be thrown.
buffer | A buffer storing the wire format data. | |
downcase | Whether to convert upper case alphabets to lower case. |
References COMPRESS_POINTER_MARK8, dns_throw, isc::dns::InputBuffer::getLength(), isc::dns::InputBuffer::getPosition(), MAX_LABELLEN, MAX_LABELS, MAX_WIRE, isc::dns::InputBuffer::readUint8(), and isc::dns::InputBuffer::setPosition().
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. References isc::dns::NameComparisonResult::COMMONANCESTOR, isc::dns::NameComparisonResult::EQUAL, MAX_LABELLEN, isc::dns::NameComparisonResult::SUBDOMAIN, and isc::dns::NameComparisonResult::SUPERDOMAIN.
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.
References dns_throw, 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:
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.
References 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. |
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. References compare().
Referenced by operator>=().
unsigned int isc::dns::Name::getLabels | ( | ) | const |
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.
size_t isc::dns::Name::getLength | ( | ) | const |
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. References compare().
Referenced by operator>().
bool isc::dns::Name::isWildcard | ( | ) | const |
Test if this is a wildcard name.
true
if the least significant label of this Name is '*'
; otherwise false
. 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. 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. References compare().
Referenced by operator<().
bool isc::dns::Name::nequals | ( | const Name & | other | ) | const |
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.
References equals().
Referenced by operator!=().
bool isc::dns::Name::operator!= | ( | const Name & | other | ) | const |
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. References dns_throw.
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
. References dns_throw, and MAX_LABELLEN.
void isc::dns::Name::toWire | ( | 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.
References isc::dns::OutputBuffer::writeData().
void isc::dns::Name::toWire | ( | MessageRenderer & | 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. |
References isc::dns::MessageRenderer::writeName().
Referenced by isc::dns::MessageRenderer::writeName().
const uint16_t isc::dns::Name::COMPRESS_POINTER_MARK16 = 0xc000 [static] |
A 16-bit masked value indicating a start of compression pointer.
Referenced by isc::dns::MessageRenderer::writeName().
const uint16_t isc::dns::Name::COMPRESS_POINTER_MARK8 = 0xc0 [static] |
A 8-bit masked value indicating a start of compression pointer.
Referenced by Name().
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.
Referenced by isc::dns::MessageRenderer::writeName().
const size_t isc::dns::Name::MAX_LABELLEN = 63 [static] |
Max allowable length of labels of a domain name.
Referenced by compare(), downcase(), Name(), and toText().
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).
Referenced by concatenate(), and Name().
const size_t isc::dns::Name::MAX_WIRE = 255 [static] |
Max allowable length of domain names.
Referenced by concatenate(), and Name().