treenode_rrset.h 10.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
//
// 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 DATASRC_MEMORY_TREENODE_RRSET_H
#define DATASRC_MEMORY_TREENODE_RRSET_H 1

#include <util/buffer.h>

#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
#include <dns/rdata.h>
#include <dns/rrset.h>

#include <datasrc/memory/zone_data.h>
#include <datasrc/memory/rdataset.h>

#include <string>

namespace isc {
namespace datasrc {
namespace memory {

JINMEI Tatuya's avatar
JINMEI Tatuya committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/// \brief Special RRset for optimizing memory datasource requirement
///
/// This is a derived class of \c dns::AbstractRRset intended to be used
/// by the in-memory data source finder implementation.  It is designed
/// so performance sensitive operations will be lightweight; for example,
/// (in the general case) the construction is just set up references to
/// pre-loaded in-memory objects, not involving any dynamic memory allocation.
/// Its \c toWire() method is also customized so it won't have to use
/// the generic but expensive \c dns::RdataIterator.
///
/// On the other hand, some other performance-insensitive methods could be
/// even less efficient than the generic version.  Those include \c getName(),
/// \c toText(), and \c getRdataIterator() methods.
///
/// \note Right now, the authoritative server's query processing still needs
/// to use \c getRdataIterator() and \c getName() for relatively rare case
/// operations.  We should revise that part of the authoritative server
/// implementation in the next phase in order to eliminate the bottleneck.
///
/// Since this class is assumed to be instantiated only from the in-memory
/// zone finder, which only returns immutable (const) \c RRset objects,
/// we skip implementing non const virtual methods of this class.
/// Unless the application intentionally breaks the constness or the class
/// is abused outside of the in-memory data source implementation, this
/// should be safe because such methods should never be called.
///
/// Some other const member methods are still incomplete; if they are called
/// it will result in an exception.  In the expected usage of this class
/// it should be safe, but we should eventually provide complete
/// implementations of these methods.
///
/// \note This class is exposed in this separate header file so that other
/// part of the in-memory data source implementation and test code
/// can refer to its definition, and only for that purpose.  Otherwise this is
/// essentially a private class of the in-memory data source implementation,
/// and an application shouldn't directly refer to this class.
73
74
class TreeNodeRRset : public dns::AbstractRRset {
public:
JINMEI Tatuya's avatar
JINMEI Tatuya committed
75
76
77
    /// \brief Normal case constructor.
    ///
    /// This class object is basically defined with a \c ZoneNode and
78
    /// \c RdataSet.  The former determines the owner name of the RRset,
JINMEI Tatuya's avatar
JINMEI Tatuya committed
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    /// and the latter provides the rest of the RRset parameters.
    /// Since the RR class is maintained outside of the \c ZoneData,
    /// it must be explicitly given as a constructor parameter.
    ///
    /// The \c RdataSet may or may not be associated with RRSIGs.  It's
    /// fixed at the load time, but depending on the query context they
    /// may or may not be requested (and supposed to be visible to the
    /// caller).  Since \c rdataset cannot be modified at the time of
    /// construction, a separate parameter (\c dnssec_ok) controls this
    /// policy.  Any associated RRSIGs are visible if and only if \c dnssec_ok
    /// is true.  If the RRset is not associated with RRSIGs, the value
    /// does not have any effect.
    ///
    /// In some rare cases \c rdataset may only consist of RRSIGs (when
    /// the zone contains an RRSIG that doesn't have covered RRsets).
    /// This class works for such cases, too.
    ///
    /// \throw none
    ///
    /// \param rrclass The RR class of the RRset.  This must be consistent
    /// with the corresponding zone class.
    /// \param node The \c ZoneNode for the \c RRset.  Must not be NULL.
    /// \param rdataset The \c RdataSet for the \c RRset.  Must not be NULL.
    /// \param dnssec_ok Whether the RRSIGs for the RRset (if associated)
    /// should be visible to the caller.
JINMEI Tatuya's avatar
JINMEI Tatuya committed
104
    TreeNodeRRset(const dns::RRClass& rrclass, const ZoneNode* node,
105
                  const RdataSet* rdataset, bool dnssec_ok) :
106
107
        node_(node), rdataset_(rdataset),
        rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
108
        dnssec_ok_(dnssec_ok), name_(NULL), realname_(NULL)
109
110
    {}

JINMEI Tatuya's avatar
JINMEI Tatuya committed
111
112
113
114
115
116
117
118
119
120
121
122
    /// \brief Constructor for wildcard-expanded owner name.
    ///
    /// This constructor is mostly the same as the other version, but takes
    /// an extra parameter, \c realname.  It effectively overrides the owner
    /// name of the RRset; wherever the owner name is used (e.g., in the
    /// \c toWire() method), the specified name will be used instead of
    /// the name associated with \c node.
    ///
    /// The expected usage is \c node has a wildcard name (such as
    /// *.example.com), but this constructor does not enforce the assumption.
    ///
    /// \throw std::bad_alloc Memory allocation fails
JINMEI Tatuya's avatar
JINMEI Tatuya committed
123
    TreeNodeRRset(const dns::Name& realname, const dns::RRClass& rrclass,
124
                  const ZoneNode* node, const RdataSet* rdataset,
125
126
127
128
129
                  bool dnssec_ok) :
        node_(node), rdataset_(rdataset),
        rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
        dnssec_ok_(dnssec_ok), name_(NULL), realname_(new dns::Name(realname))
    {}
130

JINMEI Tatuya's avatar
JINMEI Tatuya committed
131
    virtual ~TreeNodeRRset() {
132
        delete realname_;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
133
134
        delete name_;
    }
135
136
137
138
139
140
141
142
143
144
145
146
147
148

    virtual unsigned int getRdataCount() const {
        return (rdataset_->getRdataCount());
    }

    virtual const dns::Name& getName() const;
    virtual const dns::RRClass& getClass() const {
        return (rrclass_);
    }

    virtual const dns::RRType& getType() const {
        return (rdataset_->type);
    }

JINMEI Tatuya's avatar
JINMEI Tatuya committed
149
150
151
    /// \brief Specialized version of \c getTTL() for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
152
    virtual const dns::RRTTL& getTTL() const;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
153
154
155
156

    /// \brief Specialized version of \c setName() for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
157
    virtual void setName(const dns::Name& name);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
158
159
160
161

    /// \brief Specialized version of \c setName() for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
162
    virtual void setTTL(const dns::RRTTL& ttl);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
163

164
165
166
    virtual std::string toText() const;

    virtual unsigned int toWire(dns::AbstractMessageRenderer& renderer) const;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
167
168
169
170

    /// \brief Specialized version of \c toWire(buffer) for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
171
    virtual unsigned int toWire(util::OutputBuffer& buffer) const;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
172
173
174
175

    /// \brief Specialized version of \c addRdata() for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
176
    virtual void addRdata(dns::rdata::ConstRdataPtr rdata);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
177
178
179
180

    /// \brief Specialized version of \c addRdata() for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
181
182
183
    virtual void addRdata(const dns::rdata::Rdata& rdata);

    virtual dns::RdataIteratorPtr getRdataIterator() const;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
184
185
186
187

    /// \brief Specialized version of \c getRRsig() for \c TreeNodeRRset.
    ///
    /// It throws \c isc::Unexpected unconditionally.
188
189
190
    virtual dns::RRsetPtr getRRsig() const;

    virtual unsigned int getRRsigDataCount() const {
191
        return (dnssec_ok_ ? rrsig_count_ : 0);
192
193
    }

JINMEI Tatuya's avatar
JINMEI Tatuya committed
194
195
196
197
198
199
200
    ///
    /// \name Specialized version of RRsig related methods for
    /// \c TreeNodeRRset.
    ///
    /// These throw \c isc::Unexpected unconditionally.
    ////
    //@{
201
202
203
204
205
206
    virtual void addRRsig(const dns::rdata::ConstRdataPtr& rdata);
    virtual void addRRsig(const dns::rdata::RdataPtr& rdata);
    virtual void addRRsig(const dns::AbstractRRset& sigs);
    virtual void addRRsig(const dns::ConstRRsetPtr& sigs);
    virtual void addRRsig(const dns::RRsetPtr& sigs);
    virtual void removeRRsig();
JINMEI Tatuya's avatar
JINMEI Tatuya committed
207
    //@}
208

JINMEI Tatuya's avatar
JINMEI Tatuya committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    /// \brief Specialized version of \c isSameKind() for \c TreeNodeRRset.
    ///
    /// As a kind of optimization, this implementation exploits the assumption
    /// of how \c TreeNodeRRset objects are created: They must be always
    /// created inside the in-memory data source finder implementation,
    /// and they are constructed with the \c realname parameter if and only
    /// if the corresponding query name is subject to wildcard substitution.
    ///
    /// So, if the given RRset is of \c TreeNodeRRset, and one and only one of
    /// of them has \c realname, they are considered to have different names.
    ///
    /// Also, this implementation does not compare RR classes explicitly;
    /// if two \c TreeNodeRRset objects belong to different RR classes,
    /// they should belong to different zone trees (according to the assumption
    /// of how the zone data are built), and therefore they cannot be at
    /// same zone node.  So it's sufficient to compare the (address of the)
    /// node; if they are different they cannot be of the same kind.
    virtual bool isSameKind(const dns::AbstractRRset& abs_other) const;
227
228

private:
JINMEI Tatuya's avatar
JINMEI Tatuya committed
229
    dns::RdataIteratorPtr getSigRdataIterator() const;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
230
231

    // Common backend for getRdataIterator() and getSigRdataIterator()
JINMEI Tatuya's avatar
JINMEI Tatuya committed
232
233
    dns::RdataIteratorPtr getRdataIteratorInternal(bool is_rrsig,
                                                   size_t count) const;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
234
235
236

    // Return \c LabelSequence for the owner name regardless of how this
    /// class is constructed (with or without 'realname')
237
238
239
    dns::LabelSequence getOwnerLabels(
        uint8_t labels_buf[dns::LabelSequence::MAX_SERIALIZED_LENGTH]) const
    {
240
241
        if (realname_ != NULL) {
            return (dns::LabelSequence(*realname_));
242
243
244
        }
        return (node_->getAbsoluteLabels(labels_buf));
    }
JINMEI Tatuya's avatar
JINMEI Tatuya committed
245

246
247
    const ZoneNode* node_;
    const RdataSet* rdataset_;
248
    const size_t rrsig_count_;
249
250
    const dns::RRClass rrclass_;
    const bool dnssec_ok_;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
251
    mutable dns::Name* name_;
252
    const dns::Name* const realname_;
253
254
255
256
257
258
259
260
261
262
263
};

} // namespace memory
} // namespace datasrc
} // namespace isc

#endif // DATASRC_MEMORY_TREENODE_RRSET_H

// Local Variables:
// mode: c++
// End: