labelsequence.h 8.78 KB
Newer Older
Jelte Jansen's avatar
Jelte Jansen committed
1
// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
Jelte Jansen's avatar
Jelte Jansen committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef __LABELSEQUENCE_H
#define __LABELSEQUENCE_H 1

#include <dns/name.h>
#include <util/buffer.h>

namespace isc {
namespace dns {

Jelte Jansen's avatar
Jelte Jansen committed
24
25
26
/// \brief Light-weight Accessor to Name object
///
/// The purpose of this class is to easily match Names and parts of Names,
Jelte Jansen's avatar
Jelte Jansen committed
27
/// without needing to copy the underlying data on each label strip.
Jelte Jansen's avatar
Jelte Jansen committed
28
29
30
31
32
33
///
/// It can only work on existing Name objects, and the Name object MUST
/// remain in scope during the entire lifetime of its associated
/// LabelSequence(s).
///
/// Upon creation of a LabelSequence, it records the offsets of the
Jelte Jansen's avatar
Jelte Jansen committed
34
35
36
37
/// labels in the wireformat data of the Name. When stripLeft() or
/// stripRight() is called on the LabelSequence, no changes in the
/// Name's data occur, but the internal pointers of the
/// LabelSequence are modified.
Jelte Jansen's avatar
Jelte Jansen committed
38
39
40
41
42
///
/// LabelSequences can be compared to other LabelSequences, and their
/// data can be requested (which then points to part of the original
/// data of the associated Name object).
///
Jelte Jansen's avatar
Jelte Jansen committed
43
class LabelSequence {
44
45
46
    // Name calls the private toText(bool) method of LabelSequence.
    friend std::string Name::toText(bool) const;

Jelte Jansen's avatar
Jelte Jansen committed
47
public:
Jelte Jansen's avatar
Jelte Jansen committed
48
49
50
51
52
53
54
55
    /// \brief Constructs a LabelSequence for the given name
    ///
    /// \note The associated Name MUST remain in scope during the lifetime
    /// of this LabelSequence, since getData() refers to data from the
    /// Name object (the only data the LabelSequence stores are pointers
    /// to the labels in the Name object).
    ///
    /// \param name The Name to construct a LabelSequence for
56
    LabelSequence(const Name& name): name_(name),
Jelte Jansen's avatar
Jelte Jansen committed
57
58
59
                                     first_label_(0),
                                     last_label_(name.getLabelCount())
    {}
Jelte Jansen's avatar
Jelte Jansen committed
60
61
62
63
64
65
66
67
68
69
70

    /// \brief Return the wire-format data for this LabelSequence
    ///
    /// The data, is returned as a pointer to the original wireformat
    /// data of the original Name object, and the given len value is
    /// set to the number of octets that match this labelsequence.
    ///
    /// \note The data pointed to is only valid if the original Name
    /// object is still in scope
    ///
    /// \param len Pointer to a size_t where the length of the data
Jelte Jansen's avatar
Jelte Jansen committed
71
    ///        will be stored (in number of octets)
Jelte Jansen's avatar
Jelte Jansen committed
72
    /// \return Pointer to the wire-format data of this label sequence
73
    const uint8_t* getData(size_t* len) const;
Jelte Jansen's avatar
Jelte Jansen committed
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    /// \brief Return the length of the wire-format data of this LabelSequence
    ///
    /// This method returns the number of octets for the data that would
    /// be returned by the \c getData() method.
    ///
    /// Note that the return value of this method is always positive.
    /// Note also that if the return value of this method is 1, it means the
    /// sequence consists of the null label, i.e., a single "dot", and vice
    /// versa.
    ///
    /// \note The data pointed to is only valid if the original Name
    /// object is still in scope
    ///
    /// \return The length of the data of the label sequence in octets.
    size_t getDataLength() const;

Jelte Jansen's avatar
Jelte Jansen committed
91
92
93
94
95
96
97
98
99
    /// \brief Compares two label sequences.
    ///
    /// Performs a (optionally case-insensitive) comparison between this
    /// LabelSequence and another LabelSequence.
    ///
    /// \param other The LabelSequence to compare with
    /// \param case_sensitive If true, comparison is case-insensitive
    /// \return true if The label sequences consist are the same length,
    ///         and contain the same data.
Jelte Jansen's avatar
Jelte Jansen committed
100
101
    bool equals(const LabelSequence& other, bool case_sensitive = false) const;

Jelte Jansen's avatar
Jelte Jansen committed
102
    /// \brief Remove labels from the front of this LabelSequence
Jelte Jansen's avatar
Jelte Jansen committed
103
    ///
Jelte Jansen's avatar
Jelte Jansen committed
104
105
106
    /// \note No actual memory is changed, this operation merely updates the
    /// internal pointers based on the offsets in the Name object.
    ///
107
    /// \exception OutOfRange if i is greater than or equal to the number
Jelte Jansen's avatar
Jelte Jansen committed
108
109
110
    ///           of labels currently pointed to by this LabelSequence
    ///
    /// \param i The number of labels to remove.
Jelte Jansen's avatar
Jelte Jansen committed
111
    void stripLeft(size_t i);
Jelte Jansen's avatar
Jelte Jansen committed
112
113

    /// \brief Remove labels from the end of this LabelSequence
Jelte Jansen's avatar
Jelte Jansen committed
114
115
    ///
    /// \note No actual memory is changed, this operation merely updates the
Jelte Jansen's avatar
Jelte Jansen committed
116
    /// internal pointers based on the offsets in the Name object.
Jelte Jansen's avatar
Jelte Jansen committed
117
    ///
118
    /// \exception OutOfRange if i is greater than or equal to the number
Jelte Jansen's avatar
Jelte Jansen committed
119
    ///           of labels currently pointed to by this LabelSequence
Jelte Jansen's avatar
Jelte Jansen committed
120
    ///
Jelte Jansen's avatar
Jelte Jansen committed
121
    /// \param i The number of labels to remove.
Jelte Jansen's avatar
Jelte Jansen committed
122
    void stripRight(size_t i);
Jelte Jansen's avatar
Jelte Jansen committed
123

Jelte Jansen's avatar
Jelte Jansen committed
124
125
126
    /// \brief Returns the current number of labels for this LabelSequence
    ///
    /// \return The number of labels
127
    size_t getLabelCount() const { return (last_label_ - first_label_); }
128

129
130
131
132
    /// \brief Convert the LabelSequence to a string.
    ///
    /// This method returns a <code>std::string</code> object representing the
    /// LabelSequence as a string.  The returned string ends with a dot
133
    /// '.' if the label sequence is absolute.
134
135
136
137
138
139
140
141
142
    ///
    /// This function assumes the underlying name is in proper
    /// uncompressed wire format.  If it finds an unexpected label
    /// character including compression pointer, an exception of class
    /// \c BadLabelType will be thrown.  In addition, if resource
    /// allocation for the result string fails, a corresponding standard
    /// exception will be thrown.
    //
    /// \return a string representation of the <code>LabelSequence</code>.
143
    std::string toText() const;
144

145
private:
146
147
    /// \brief Convert the LabelSequence to a string.
    ///
148
149
150
151
    /// This method is a version of the zero-argument toText() method,
    /// that accepts a <code>omit_final_dot</code> argument. The
    /// returned string ends with a dot '.' if
    /// <code>omit_final_dot</code> is <code>false</code>.
152
    ///
153
    /// \param omit_final_dot whether to omit the trailing dot in the output.
154
    /// \return a string representation of the <code>LabelSequence</code>.
155
    std::string toText(bool omit_final_dot) const;
156

157
public:
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    /// \brief Calculate a simple hash for the label sequence.
    ///
    /// This method calculates a hash value for the label sequence as binary
    /// data.  If \c case_sensitive is false, it ignores the case stored in
    /// the labels; specifically, it normalizes the labels by converting all
    /// upper case characters to lower case ones and calculates the hash value
    /// for the result.
    ///
    /// This method is intended to provide a lightweight way to store a
    /// relatively small number of label sequences in a hash table.
    /// For this reason it only takes into account data up to 16 octets
    /// (16 was derived from BIND 9's implementation).  Also, the function does
    /// not provide any unpredictability; a specific sequence will always have
    /// the same hash value.  It should therefore not be used in the context
    /// where an untrusted third party can mount a denial of service attack by
    /// forcing the application to create a very large number of label
    /// sequences that have the same hash value and expected to be stored in
    /// a hash table.
    ///
    /// \exception None
    ///
    /// \param case_sensitive
    /// \return A hash value for this label sequence.
    size_t getHash(bool case_sensitive) const;

Jelte Jansen's avatar
Jelte Jansen committed
183
184
185
186
187
    /// \brief Checks whether the label sequence is absolute
    ///
    /// \return true if the last label is the root label
    bool isAbsolute() const;

Jelte Jansen's avatar
Jelte Jansen committed
188
private:
189
    const Name& name_;
Jelte Jansen's avatar
Jelte Jansen committed
190
191
192
193
194
    size_t first_label_;
    size_t last_label_;
};


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
///
/// \brief Insert the label sequence as a string into stream.
///
/// This method convert the \c label_sequence into a string and inserts
/// it into the output stream \c os.
///
/// This function overloads the global operator<< to behave as described in
/// ostream::operator<< but applied to \c LabelSequence objects.
///
/// \param os A \c std::ostream object on which the insertion operation is
/// performed.
/// \param name The \c LabelSequence object output by the operation.
/// \return A reference to the same \c std::ostream object referenced by
/// parameter \c os after the insertion operation.
std::ostream&
operator<<(std::ostream& os, const LabelSequence& label_sequence);

Jelte Jansen's avatar
Jelte Jansen committed
212
213
214
215
} // end namespace dns
} // end namespace isc

#endif