Kea: isc::dns::Question Class Reference

| Kea 3.2.0-git

isc::dns::Question Class Reference

The `Question` class encapsulates the common search key of DNS lookup, consisting of owner name, RR type and RR class. More...

`#include <question.h>`

## Public Member Functions
Constructors and Destructor
We use the default versions of destructor, copy constructor, and assignment operator. The default constructor is hidden as a result of defining the other constructors. This is intentional; we don't want to allow a `Question` object to be constructed with an invalid state.
| Question (isc::util::InputBuffer &buff)
| Constructor from wire-format data.
| Question (const Name &name, const RRClass &rrclass, const RRType &rrtype)
| Constructor from fixed parameters of the `Question`.
Getter Methods
const Name & | getName () const
| Returns the owner name of the `Question`.
const RRType & | getType () const
| Returns the RR Class of the `Question`.
const RRClass & | getClass () const
| Returns the RR Type of the `Question`.
Converter Methods
std::string | toText (bool newline=false) const
| Convert the Question to a string.
uint32_t | toWire (AbstractMessageRenderer &renderer) const
| Render the Question in the wire format with name compression.
uint32_t | toWire (isc::util::OutputBuffer &buffer) const
| Render the Question in the wire format without name compression.

## Comparison Operators
bool | operator< (const Question &rhs) const
| A "less than" operator is needed for this class so it can function as an index to std::map.
bool | operator== (const Question &rhs) const
| Equality operator.
bool | operator!= (const Question &rhs) const
| Inequality operator.

## Detailed Description

The `Question` class encapsulates the common search key of DNS lookup, consisting of owner name, RR type and RR class.

The primarily intended use case of this class is an entry of the question section of DNS messages. This could also be used as a general purpose lookup key, e.g., in a custom implementation of DNS database.

In this initial implementation, the `Question` class is defined as a concrete class; it's not expected to be inherited by a user-defined customized class. It may be worth noting that it's different from the design of the RRset classes (`AbstractRRset` and its derived classes). The RRset classes form an inheritance hierarchy from the base abstract class. This may look odd in that an "RRset" and "Question" are similar from the protocol point of view: Both are used as a semantics unit of DNS messages; both share the same set of components (name, RR type and RR class).

In fact, BIND9 didn't introduce a separate data structure for Questions, and use the same `"rdataset"` structure for both RRsets and Questions. We could take the same approach, but chose to adopt the different design. One reason for that is because a Question and an RRset are still different, and a Question might not be cleanly defined, e.g., if it were a derived class of some "RRset-like" class. For example, we couldn't give a reasonable semantics for `getTTL`() or `setTTL`() methods for a Question, since it's not associated with the TTL. In fact, the BIND9 implementation ended up often separating the case where a `"rdataset"` is from the Question section of a DNS message and the case where it comes from other sections. If we cannot treat them completely transparently anyway, separating the class (type) would make more sense because we can exploit compilation time type checks.

On the other hand, we do not expect a strong need for customizing the `Question` class, unlike the RRset. Handling the "Question" section of a DNS message is relatively a simple work comparing to RRset-involved operations, so a unified straightforward implementation should suffice for any use cases including performance sensitive ones.

We may, however, still want to have a customized version of Question for, e.g, highly optimized behavior, and may revisit this design choice as we have more experience with this implementation.

One disadvantage of defining RRsets and Questions as unrelated classes is that we cannot handle them in a polymorphic way. For example, we might want to iterate over DNS message sections and render the data in the wire format, whether it's an RRset or a Question. If a `Question` were a derived class of some common RRset-like class, we could do this by calling `rrset_or_question->toWire()`. But the actual design doesn't allow this approach, which may require duplicate code for almost the same operation. To mitigate this problem, we intentionally used the same names with the same signature for some common methods of `Question` and `AbstractRRset` such as `getName`() or `toWire`(). So the user class may use a template function that is applicable to both `Question` and `RRset` to avoid writing duplicate code logic.

Definition at line 88 of file question.h.

## Constructor & Destructor Documentation

## ◆ Question() [1/2]

isc::dns::Question::Question | ( | isc::util::InputBuffer & | buff | ) |

Constructor from wire-format data.

It simply constructs a set of `Name`, `RRType`, and `RRClass` object from the `buffer` in this order, and constructs a `Question` object in a straightforward way.

It may throw an exception if the construction of these component classes fails.

Parameters

  buff | A buffer storing the wire format data.

Definition at line 25 of file question.cc.

Referenced by operator!=(), operator<(), and operator==().

## ◆ Question() [2/2]

isc::dns::Question::Question | ( | const Name & | name,
|  | const RRClass & | rrclass,
|  | const RRType & | rrtype )
| inline

Constructor from fixed parameters of the `Question`.

This constructor is basically expected to be exception free, but copying the name may involve resource allocation, and if it fails the corresponding standard exception will be thrown.

Parameters

  name | The owner name of the `Question`.
  rrclass | The RR class of the `Question`.
  rrtype | The RR type of the `Question`.

Definition at line 121 of file question.h.

## Member Function Documentation

## ◆ getClass()

const RRClass & isc::dns::Question::getClass | ( |  | ) | const
| inline

Returns the RR Type of the `Question`.

This method never throws an exception.

Returns
  A reference to a `RRType` class object corresponding to the RR type of the `Question`.

Definition at line 156 of file question.h.

Referenced by isc::d2::D2UpdateMessage::setZone().

## ◆ getName()

const Name & isc::dns::Question::getName | ( |  | ) | const
| inline

Returns the owner name of the `Question`.

This method never throws an exception.

Returns
  A reference to a `Name` class object corresponding to the `Question` owner name.

Definition at line 136 of file question.h.

Referenced by isc::d2::D2UpdateMessage::setZone().

## ◆ getType()

const RRType & isc::dns::Question::getType | ( |  | ) | const
| inline

Returns the RR Class of the `Question`.

This method never throws an exception.

Returns
  A reference to a `RRClass` class object corresponding to the RR class of the `Question`.

Definition at line 146 of file question.h.

## ◆ operator!=()

bool isc::dns::Question::operator!= | ( | const Question & | rhs | ) | const
| inline

Inequality operator.

Primarily used to compare the question section in a response to that in the query.

Parameters

  rhs | Question to compare against

Returns
  true if one or more of the name, class and type do not match, false otherwise.

Definition at line 258 of file question.h.

References Question().

Here is the call graph for this function:

## ◆ operator<()

bool isc::dns::Question::operator< | ( | const Question & | rhs | ) | const
| inline

A "less than" operator is needed for this class so it can function as an index to std::map.

Definition at line 235 of file question.h.

References Question().

Here is the call graph for this function:

## ◆ operator==()

bool isc::dns::Question::operator== | ( | const Question & | rhs | ) | const
| inline

Equality operator.

Primarily used to compare the question section in a response to that in the query.

Parameters

  rhs | Question to compare against

Returns
  true if name, class and type are equal, false otherwise

Definition at line 247 of file question.h.

References Question().

Here is the call graph for this function:

## ◆ toText()

std::string isc::dns::Question::toText | ( | bool | newline = false | ) | const

Convert the Question to a string.

When `newline` argument is `true`, this method terminates the resulting string with a trailing newline character (following the BIND9 convention).

This method simply calls the `toText`() methods of the corresponding `Name`, `RRType` and `RRClass` classes for this `Question`, and these methods may throw an exception. In particular, if resource allocation fails, a corresponding standard exception will be thrown.

Parameters

  newline | Whether to add a trailing newline. If true, a trailing newline is added. If false, no trailing newline is added.

Returns
  A string representation of the `Question`.

Definition at line 38 of file question.cc.

Referenced by isc::dns::operator<<().

## ◆ toWire() [1/2]

uint32_t isc::dns::Question::toWire | ( | AbstractMessageRenderer & | renderer | ) | const

Render the Question in the wire format with name compression.

This method simply calls the `toWire`() methods of the corresponding `Name`, `RRType` and `RRClass` classes for this `Question`, and these methods may throw an exception. In particular, if resource allocation fails, a corresponding standard exception will be thrown.

This method returns 1, which is the number of "questions" contained in the `Question`. This is a meaningless value, but is provided to be consistent with the corresponding method of `AbstractRRset` (see the detailed class description).

The owner name will be compressed if possible, although it's an unlikely event in practice because the Question section a DNS message normally doesn't contain multiple question entries and it's located right after the Header section. Nevertheless, `renderer` records the information of the owner name so that it can be pointed by other RRs in other sections (which is more likely to happen).

It could be possible, though very rare in practice, that an attempt to render a Question may cause truncation (when the Question section contains a large number of entries). In such a case this method avoid the rendering and indicate the truncation in the `renderer`. This method returns 0 in this case.

Parameters

  renderer | DNS message rendering context that encapsulates the output buffer and name compression information.

Returns
  1 on success; 0 if it causes truncation

Definition at line 58 of file question.cc.

References isc::dns::AbstractMessageRenderer::getLength(), isc::dns::AbstractMessageRenderer::getLengthLimit(), isc::dns::AbstractMessageRenderer::setTruncated(), isc::dns::AbstractMessageRenderer::trim(), and isc::dns::AbstractMessageRenderer::writeName().

Here is the call graph for this function:

## ◆ toWire() [2/2]

uint32_t isc::dns::Question::toWire | ( | isc::util::OutputBuffer & | buffer | ) | const

Render the Question in the wire format without name compression.

This method behaves like the render version except it doesn't compress the owner name. See `toWire(AbstractMessageRenderer& renderer)const`.

Parameters

  buffer | An output buffer to store the wire data.

Returns
  1

Definition at line 49 of file question.cc.

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

- question.h
- question.cc