static_datasrc.cc 9.25 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Copyright (C) 2010  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.

15
#include <config.h>
16

17
18
#include <cassert>

19
20
21
22
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrset.h>
23
#include <dns/rrsetlist.h>
24
25
#include <dns/rrtype.h>
#include <dns/rrttl.h>
26

27
28
#include <datasrc/data_source.h>
#include <datasrc/static_datasrc.h>
29
#include <datasrc/logger.h>
30

31
32
using namespace std;
using namespace isc::dns;
33
34
using namespace isc::dns::rdata;

35
namespace isc {
Evan Hunt's avatar
Evan Hunt committed
36
namespace datasrc {
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
// This class stores the "static" data for the built-in static data source.
// Since it's static, it could be literally static, i.e, defined as static
// objects.  But to avoid the static initialization order fiasco, which would
// be unlikely to happen for this class in practice but is still possible,
// we took a safer approach.  A downside of this approach is that redundant
// copies of exactly the same content of these objects can be created.
// In practice, however, there's normally at most one StaticDataSrc object,
// so this should be acceptable (if this turns out to be a real concern we
// might consider making this class a singleton).
// We use the "pimpl" idiom for this class.  Operations for this class is
// not expected to be performance sensitive, so the overhead due to the pimpl
// should be okay, and it's more beneficial to hide details and minimize
// inter module dependencies in header files.
struct StaticDataSrcImpl {
52
public:
53
54
55
56
57
58
59
60
    StaticDataSrcImpl();
    const Name authors_name;
    const Name version_name;
    // XXX: unfortunately these can't be ConstRRsetPtr because they'll be
    // passed to RRsetList::addRRset(), which expect non const RRsetPtr.
    // We should revisit this design later.
    RRsetPtr authors;
    RRsetPtr authors_ns;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
61
    RRsetPtr authors_soa;
62
63
    RRsetPtr version;
    RRsetPtr version_ns;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
64
    RRsetPtr version_soa;
65
};
66
67
68
69
70
71

StaticDataSrcImpl::StaticDataSrcImpl() :
    authors_name("authors.bind"), version_name("version.bind")
{
    authors = RRsetPtr(new RRset(authors_name, RRClass::CH(),
                                 RRType::TXT(), RRTTL(0)));
72
    authors->addRdata(generic::TXT("Chen Zhengzhang")); // Jerry
73
    authors->addRdata(generic::TXT("Dmitriy Volodin"));
74
    authors->addRdata(generic::TXT("Evan Hunt"));
75
    authors->addRdata(generic::TXT("Haidong Wang")); // Ocean
76
    authors->addRdata(generic::TXT("Haikuo Zhang"));
77
78
79
    authors->addRdata(generic::TXT("Han Feng"));
    authors->addRdata(generic::TXT("Jelte Jansen"));
    authors->addRdata(generic::TXT("Jeremy C. Reed")); 
80
    authors->addRdata(generic::TXT("Xie Jiagui")); // Kevin Tes
81
82
83
84
    authors->addRdata(generic::TXT("Jin Jian"));
    authors->addRdata(generic::TXT("JINMEI Tatuya"));
    authors->addRdata(generic::TXT("Kazunori Fujiwara"));
    authors->addRdata(generic::TXT("Michael Graff"));
85
    authors->addRdata(generic::TXT("Michal Vaner"));
86
87
    authors->addRdata(generic::TXT("Naoki Kambe"));
    authors->addRdata(generic::TXT("Shane Kerr"));
88
89
    authors->addRdata(generic::TXT("Shen Tingting"));
    authors->addRdata(generic::TXT("Stephen Morris"));
90
    authors->addRdata(generic::TXT("Yoshitaka Aharen"));
91
92
93
94
95
96
    authors->addRdata(generic::TXT("Zhang Likun"));

    authors_ns = RRsetPtr(new RRset(authors_name, RRClass::CH(),
                                    RRType::NS(), RRTTL(0)));
    authors_ns->addRdata(generic::NS(authors_name));

JINMEI Tatuya's avatar
JINMEI Tatuya committed
97
    authors_soa = RRsetPtr(new RRset(authors_name, RRClass::CH(),
98
                                     RRType::SOA(), RRTTL(0)));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
99
100
101
102
    authors_soa->addRdata(generic::SOA(
                              "authors.bind. hostmaster.authors.bind. "
                              "0 28800 7200 604800 86400"));

103
104
    version = RRsetPtr(new RRset(version_name, RRClass::CH(),
                                 RRType::TXT(), RRTTL(0)));
105
    version->addRdata(generic::TXT(PACKAGE_STRING));
106
107
108
109

    version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
                                    RRType::NS(), RRTTL(0)));
    version_ns->addRdata(generic::NS(version_name));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
110
111

    version_soa = RRsetPtr(new RRset(version_name, RRClass::CH(),
112
                                     RRType::SOA(), RRTTL(0)));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
113
114
115
    version_soa->addRdata(generic::SOA(
                              "version.bind. hostmaster.version.bind. "
                               "0 28800 7200 604800 86400"));
116
117
}

118
StaticDataSrc::StaticDataSrc() {
119
    LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_STATIC_CREATE);
120
    setClass(RRClass::CH());
121
122
123
    impl_ = new StaticDataSrcImpl;
}

124
StaticDataSrc::~StaticDataSrc() {
125
    delete impl_;
126
127
}

128
129
130
131
132
133
134
135
136
137
namespace {
bool
isSubdomain(const Name& qname, const Name& zone) {
    const NameComparisonResult::NameRelation cmp =
        qname.compare(zone).getRelation();
    return (cmp == NameComparisonResult::EQUAL ||
            cmp == NameComparisonResult::SUBDOMAIN);
}
}

138
void
Evan Hunt's avatar
Evan Hunt committed
139
140
StaticDataSrc::findClosestEnclosure(DataSrcMatch& match) const {
    const Name& qname = match.getName();
141

Evan Hunt's avatar
Evan Hunt committed
142
    if (match.getClass() != getClass() && match.getClass() != RRClass::ANY()) {
143
144
145
        return;
    }

146
    if (isSubdomain(qname, impl_->version_name)) {
147
        match.update(*this, impl_->version_name);
148
        return;
149
150
    }

151
    if (isSubdomain(qname, impl_->authors_name)) {
152
        match.update(*this, impl_->authors_name);
153
154
        return;
    }
155
156
}

157
DataSrc::Result
158
StaticDataSrc::findRRset(const Name& qname,
159
                         const RRClass& qclass, const RRType& qtype,
160
                         RRsetList& target, uint32_t& flags,
161
                         const Name* const zonename) const
162
{
163
    LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_STATIC_FIND).arg(qname).
164
        arg(qtype);
165
    flags = 0;
166
    if (qclass != getClass() && qclass != RRClass::ANY()) {
167
        LOG_ERROR(logger, DATASRC_STATIC_CLASS_NOT_CH);
168
        return (ERROR);
169
170
    }

171
172
173
174
175
176
177
178
179
    // Identify the appropriate zone.
    bool is_versionname = false, is_authorsname = false;
    if (zonename != NULL) {
        if (*zonename == impl_->version_name &&
            isSubdomain(qname, impl_->version_name)) {
            is_versionname = true;
        } else if (*zonename == impl_->authors_name &&
                   isSubdomain(qname, impl_->authors_name)) {
            is_authorsname = true;
180
        } else {
181
            flags = NO_SUCH_ZONE;
182
            return (SUCCESS);
183
184
185
186
187
188
189
190
        }
    } else {
        if (isSubdomain(qname, impl_->version_name)) {
            is_versionname = true;
        } else if (isSubdomain(qname, impl_->authors_name)) {
            is_authorsname = true;
        } else {
            flags = NO_SUCH_ZONE;
191
            return (SUCCESS);
192
193
194
195
196
197
198
199
200
        }
    }

    const bool any = (qtype == RRType::ANY());

    if (is_versionname) {
        if (qname == impl_->version_name) {
            if (qtype == RRType::TXT() || any) {
                target.addRRset(impl_->version);
201
202
            }
            if (qtype == RRType::NS() || any) {
203
                target.addRRset(impl_->version_ns);
204
205
            }
            if (qtype == RRType::SOA() || any) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
206
                target.addRRset(impl_->version_soa);
207
208
            }
            if (target.size() == 0) {
209
210
                flags = TYPE_NOT_FOUND;
            }
211
        } else {
212
            flags = NAME_NOT_FOUND;
213
214
        }
    } else {
215
216
217
218
        assert(is_authorsname);
        if (qname == impl_->authors_name) {
            if (qtype == RRType::TXT() || any) {
                target.addRRset(impl_->authors);
219
220
            }
            if (qtype == RRType::NS() || any) {
221
                target.addRRset(impl_->authors_ns);
222
223
            }
            if (qtype == RRType::SOA() || any) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
224
                target.addRRset(impl_->authors_soa);
225
226
            }
            if (target.size() == 0 ) {
227
228
229
230
231
                flags = TYPE_NOT_FOUND;
            }
        } else {
            flags = NAME_NOT_FOUND;
        }
232
233
234
    }

    return (SUCCESS);
235
236
}

237
DataSrc::Result
238
StaticDataSrc::findExactRRset(const Name& qname,
239
240
                              const RRClass& qclass, const RRType& qtype,
                              RRsetList& target, uint32_t& flags,
241
                              const Name* zonename) const
242
{
243
    return (findRRset(qname, qclass, qtype, target, flags, zonename));
244
245
246
}

DataSrc::Result
247
StaticDataSrc::findPreviousName(const Name&, Name&, const Name*) const {
248
249
250
    return (NOT_IMPLEMENTED);
}

Evan Hunt's avatar
Evan Hunt committed
251
DataSrc::Result
252
StaticDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
Evan Hunt's avatar
Evan Hunt committed
253
254
255
   return (NOT_IMPLEMENTED);
}

256
DataSrc::Result
257
StaticDataSrc::init() {
258
259
260
    return (SUCCESS);
}

261
262
// Static data source is "configuration less", so the \c config parameter
// is intentionally ignored.
263
DataSrc::Result
264
StaticDataSrc::init(isc::data::ConstElementPtr) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
265
    return (init());
266
267
268
269
}

DataSrc::Result
StaticDataSrc::close() {
270
271
272
    return (SUCCESS);
}

273
274
}
}