Branch data Line data Source code
1 : : // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #ifndef __LABELSEQUENCE_H
16 : : #define __LABELSEQUENCE_H 1
17 : :
18 : : #include <dns/name.h>
19 : : #include <util/buffer.h>
20 : :
21 : : namespace isc {
22 : : namespace dns {
23 : :
24 : : /// \brief Light-weight Accessor to Name object
25 : : ///
26 : : /// The purpose of this class is to easily match Names and parts of Names,
27 : : /// without needing to copy the underlying data on each label strip.
28 : : ///
29 : : /// It can only work on existing Name objects, and the Name object MUST
30 : : /// remain in scope during the entire lifetime of its associated
31 : : /// LabelSequence(s).
32 : : ///
33 : : /// Upon creation of a LabelSequence, it records the offsets of the
34 : : /// labels in the wireformat data of the Name. When stripLeft() or
35 : : /// stripRight() is called on the LabelSequence, no changes in the
36 : : /// Name's data occur, but the internal pointers of the
37 : : /// LabelSequence are modified.
38 : : ///
39 : : /// LabelSequences can be compared to other LabelSequences, and their
40 : : /// data can be requested (which then points to part of the original
41 : : /// data of the associated Name object).
42 : : ///
43 : : class LabelSequence {
44 : : public:
45 : : /// \brief Constructs a LabelSequence for the given name
46 : : ///
47 : : /// \note The associated Name MUST remain in scope during the lifetime
48 : : /// of this LabelSequence, since getData() refers to data from the
49 : : /// Name object (the only data the LabelSequence stores are pointers
50 : : /// to the labels in the Name object).
51 : : ///
52 : : /// \param name The Name to construct a LabelSequence for
53 : : LabelSequence(const Name& name): name_(name),
54 : : first_label_(0),
55 : 12462 : last_label_(name.getLabelCount())
56 : : {}
57 : :
58 : : /// \brief Return the wire-format data for this LabelSequence
59 : : ///
60 : : /// The data, is returned as a pointer to the original wireformat
61 : : /// data of the original Name object, and the given len value is
62 : : /// set to the number of octets that match this labelsequence.
63 : : ///
64 : : /// \note The data pointed to is only valid if the original Name
65 : : /// object is still in scope
66 : : ///
67 : : /// \param len Pointer to a size_t where the length of the data
68 : : /// will be stored (in number of octets)
69 : : /// \return Pointer to the wire-format data of this label sequence
70 : : const char* getData(size_t* len) const;
71 : :
72 : : /// \brief Return the length of the wire-format data of this LabelSequence
73 : : ///
74 : : /// This method returns the number of octets for the data that would
75 : : /// be returned by the \c getData() method.
76 : : ///
77 : : /// Note that the return value of this method is always positive.
78 : : /// Note also that if the return value of this method is 1, it means the
79 : : /// sequence consists of the null label, i.e., a single "dot", and vice
80 : : /// versa.
81 : : ///
82 : : /// \note The data pointed to is only valid if the original Name
83 : : /// object is still in scope
84 : : ///
85 : : /// \return The length of the data of the label sequence in octets.
86 : : size_t getDataLength() const;
87 : :
88 : : /// \brief Compares two label sequences.
89 : : ///
90 : : /// Performs a (optionally case-insensitive) comparison between this
91 : : /// LabelSequence and another LabelSequence.
92 : : ///
93 : : /// \param other The LabelSequence to compare with
94 : : /// \param case_sensitive If true, comparison is case-insensitive
95 : : /// \return true if The label sequences consist are the same length,
96 : : /// and contain the same data.
97 : : bool equals(const LabelSequence& other, bool case_sensitive = false) const;
98 : :
99 : : /// \brief Remove labels from the front of this LabelSequence
100 : : ///
101 : : /// \note No actual memory is changed, this operation merely updates the
102 : : /// internal pointers based on the offsets in the Name object.
103 : : ///
104 : : /// \exeption OutOfRange if i is greater than or equal to the number
105 : : /// of labels currently pointed to by this LabelSequence
106 : : ///
107 : : /// \param i The number of labels to remove.
108 : : void stripLeft(size_t i);
109 : :
110 : : /// \brief Remove labels from the end of this LabelSequence
111 : : ///
112 : : /// \note No actual memory is changed, this operation merely updates the
113 : : /// internal pointers based on the offsets in the Name object.
114 : : ///
115 : : /// \exeption OutOfRange if i is greater than or equal to the number
116 : : /// of labels currently pointed to by this LabelSequence
117 : : ///
118 : : /// \param i The number of labels to remove.
119 : : void stripRight(size_t i);
120 : :
121 : : /// \brief Returns the current number of labels for this LabelSequence
122 : : ///
123 : : /// \return The number of labels
124 : 0 : size_t getLabelCount() const { return (last_label_ - first_label_); }
125 : :
126 : : /// \brief Returns the original Name object associated with this
127 : : /// LabelSequence
128 : : ///
129 : : /// While the Name should still be in scope during the lifetime of
130 : : /// the LabelSequence, it can still be useful to have access to it,
131 : : /// for instance in helper functions that are only passed the
132 : : /// LabelSequence itself.
133 : : ///
134 : : /// \return Reference to the original Name object
135 : 0 : const Name& getName() const { return (name_); }
136 : :
137 : : /// \brief Calculate a simple hash for the label sequence.
138 : : ///
139 : : /// This method calculates a hash value for the label sequence as binary
140 : : /// data. If \c case_sensitive is false, it ignores the case stored in
141 : : /// the labels; specifically, it normalizes the labels by converting all
142 : : /// upper case characters to lower case ones and calculates the hash value
143 : : /// for the result.
144 : : ///
145 : : /// This method is intended to provide a lightweight way to store a
146 : : /// relatively small number of label sequences in a hash table.
147 : : /// For this reason it only takes into account data up to 16 octets
148 : : /// (16 was derived from BIND 9's implementation). Also, the function does
149 : : /// not provide any unpredictability; a specific sequence will always have
150 : : /// the same hash value. It should therefore not be used in the context
151 : : /// where an untrusted third party can mount a denial of service attack by
152 : : /// forcing the application to create a very large number of label
153 : : /// sequences that have the same hash value and expected to be stored in
154 : : /// a hash table.
155 : : ///
156 : : /// \exception None
157 : : ///
158 : : /// \param case_sensitive
159 : : /// \return A hash value for this label sequence.
160 : : size_t getHash(bool case_sensitive) const;
161 : :
162 : : /// \brief Checks whether the label sequence is absolute
163 : : ///
164 : : /// \return true if the last label is the root label
165 : : bool isAbsolute() const;
166 : :
167 : : private:
168 : : const Name& name_;
169 : : size_t first_label_;
170 : : size_t last_label_;
171 : : };
172 : :
173 : :
174 : : } // end namespace dns
175 : : } // end namespace isc
176 : :
177 : : #endif
|