labelsequence.h 7.64 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
44
class LabelSequence {
public:
45
46
47
48
49
50
51
52
53
54
    /// \brief The default constructor
    ///
    /// A LabelSequence is expected to be stored in STL containers and
    /// has to have a default constructor.  A LabelSequence object generated
    /// by this constructor is only usable as a placeholder; method calls
    /// on such an object can return a bogus value or result in crash.
    /// It's caller's responsibility to avoid such invaild usage.
    LabelSequence() : name_(NULL), first_label_(0), last_label_(0)
    {}

Jelte Jansen's avatar
Jelte Jansen committed
55
56
57
58
59
60
61
62
    /// \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
63
    LabelSequence(const Name& name): name_(&name),
Jelte Jansen's avatar
Jelte Jansen committed
64
65
66
                                     first_label_(0),
                                     last_label_(name.getLabelCount())
    {}
Jelte Jansen's avatar
Jelte Jansen committed
67
68
69
70
71
72
73
74
75
76
77

    /// \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
78
    ///        will be stored (in number of octets)
Jelte Jansen's avatar
Jelte Jansen committed
79
    /// \return Pointer to the wire-format data of this label sequence
Jelte Jansen's avatar
Jelte Jansen committed
80
81
    const char* getData(size_t* len) const;

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    /// \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
98
99
100
101
102
103
104
105
106
    /// \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
107
108
    bool equals(const LabelSequence& other, bool case_sensitive = false) const;

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

    /// \brief Remove labels from the end of this LabelSequence
Jelte Jansen's avatar
Jelte Jansen committed
121
122
    ///
    /// \note No actual memory is changed, this operation merely updates the
Jelte Jansen's avatar
Jelte Jansen committed
123
    /// internal pointers based on the offsets in the Name object.
Jelte Jansen's avatar
Jelte Jansen committed
124
    ///
Jelte Jansen's avatar
Jelte Jansen committed
125
126
    /// \exeption OutOfRange if i is greater than or equal to the number
    ///           of labels currently pointed to by this LabelSequence
Jelte Jansen's avatar
Jelte Jansen committed
127
    ///
Jelte Jansen's avatar
Jelte Jansen committed
128
    /// \param i The number of labels to remove.
Jelte Jansen's avatar
Jelte Jansen committed
129
    void stripRight(size_t i);
Jelte Jansen's avatar
Jelte Jansen committed
130

Jelte Jansen's avatar
Jelte Jansen committed
131
132
133
    /// \brief Returns the current number of labels for this LabelSequence
    ///
    /// \return The number of labels
134
    size_t getLabelCount() const { return (last_label_ - first_label_); }
135

Jelte Jansen's avatar
Jelte Jansen committed
136
137
138
139
140
141
142
143
144
    /// \brief Returns the original Name object associated with this
    ///        LabelSequence
    ///
    /// While the Name should still be in scope during the lifetime of
    /// the LabelSequence, it can still be useful to have access to it,
    /// for instance in helper functions that are only passed the
    /// LabelSequence itself.
    ///
    /// \return Reference to the original Name object
145
    const Name& getName() const { return (*name_); }
Jelte Jansen's avatar
Jelte Jansen committed
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    /// \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
172
173
174
175
176
    /// \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
177
private:
178
    const Name* name_;
Jelte Jansen's avatar
Jelte Jansen committed
179
180
181
182
183
184
185
186
187
    size_t first_label_;
    size_t last_label_;
};


} // end namespace dns
} // end namespace isc

#endif