Branch data Line data Source code
1 : : // Copyright (C) 2010 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 : : #include <config.h>
16 : :
17 : : #include <cassert>
18 : :
19 : : #include <dns/name.h>
20 : : #include <dns/rdataclass.h>
21 : : #include <dns/rrclass.h>
22 : : #include <dns/rrset.h>
23 : : #include <dns/rrsetlist.h>
24 : : #include <dns/rrtype.h>
25 : : #include <dns/rrttl.h>
26 : :
27 : : #include <datasrc/data_source.h>
28 : : #include <datasrc/static_datasrc.h>
29 : : #include <datasrc/logger.h>
30 : :
31 : : using namespace std;
32 : : using namespace isc::dns;
33 : : using namespace isc::dns::rdata;
34 : :
35 : : namespace isc {
36 : : namespace datasrc {
37 : :
38 : : // This class stores the "static" data for the built-in static data source.
39 : : // Since it's static, it could be literally static, i.e, defined as static
40 : : // objects. But to avoid the static initialization order fiasco, which would
41 : : // be unlikely to happen for this class in practice but is still possible,
42 : : // we took a safer approach. A downside of this approach is that redundant
43 : : // copies of exactly the same content of these objects can be created.
44 : : // In practice, however, there's normally at most one StaticDataSrc object,
45 : : // so this should be acceptable (if this turns out to be a real concern we
46 : : // might consider making this class a singleton).
47 : : // We use the "pimpl" idiom for this class. Operations for this class is
48 : : // not expected to be performance sensitive, so the overhead due to the pimpl
49 : : // should be okay, and it's more beneficial to hide details and minimize
50 : : // inter module dependencies in header files.
51 : 163 : struct StaticDataSrcImpl {
52 : : public:
53 : : StaticDataSrcImpl();
54 : : const Name authors_name;
55 : : const Name version_name;
56 : : // XXX: unfortunately these can't be ConstRRsetPtr because they'll be
57 : : // passed to RRsetList::addRRset(), which expect non const RRsetPtr.
58 : : // We should revisit this design later.
59 : : RRsetPtr authors;
60 : : RRsetPtr authors_ns;
61 : : RRsetPtr authors_soa;
62 : : RRsetPtr version;
63 : : RRsetPtr version_ns;
64 : : RRsetPtr version_soa;
65 : : };
66 : :
67 : 163 : StaticDataSrcImpl::StaticDataSrcImpl() :
68 [ + - ][ + - ]: 163 : authors_name("authors.bind"), version_name("version.bind")
[ + - ]
69 : : {
70 : : authors = RRsetPtr(new RRset(authors_name, RRClass::CH(),
71 [ + - ][ + - ]: 163 : RRType::TXT(), RRTTL(0)));
[ + - ][ + - ]
72 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Chen Zhengzhang")); // Jerry
[ + - ][ + - ]
73 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Dmitriy Volodin"));
[ + - ][ + - ]
74 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Evan Hunt"));
[ + - ][ + - ]
75 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Haidong Wang")); // Ocean
[ + - ][ + - ]
76 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Haikuo Zhang"));
[ + - ][ + - ]
77 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Han Feng"));
[ + - ][ + - ]
78 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Jelte Jansen"));
[ + - ][ + - ]
79 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Jeremy C. Reed"));
[ + - ][ + - ]
80 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Xie Jiagui")); // Kevin Tes
[ + - ][ + - ]
81 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Jin Jian"));
[ + - ][ + - ]
82 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("JINMEI Tatuya"));
[ + - ][ + - ]
83 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Kazunori Fujiwara"));
[ + - ][ + - ]
84 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Michael Graff"));
[ + - ][ + - ]
85 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Michal Vaner"));
[ + - ][ + - ]
86 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Mukund Sivaraman"));
[ + - ][ + - ]
87 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Naoki Kambe"));
[ + - ][ + - ]
88 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Shane Kerr"));
[ + - ][ + - ]
89 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Shen Tingting"));
[ + - ][ + - ]
90 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Stephen Morris"));
[ + - ][ + - ]
91 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Yoshitaka Aharen"));
[ + - ][ + - ]
92 [ + - ][ + - ]: 163 : authors->addRdata(generic::TXT("Zhang Likun"));
[ + - ][ + - ]
93 : :
94 : : authors_ns = RRsetPtr(new RRset(authors_name, RRClass::CH(),
95 [ + - ][ + - ]: 163 : RRType::NS(), RRTTL(0)));
[ + - ][ + - ]
96 [ + - ][ + - ]: 163 : authors_ns->addRdata(generic::NS(authors_name));
97 : :
98 : : authors_soa = RRsetPtr(new RRset(authors_name, RRClass::CH(),
99 [ + - ][ + - ]: 163 : RRType::SOA(), RRTTL(0)));
[ + - ][ + - ]
100 : 163 : authors_soa->addRdata(generic::SOA(
101 : : "authors.bind. hostmaster.authors.bind. "
102 [ + - ][ + - ]: 163 : "0 28800 7200 604800 86400"));
[ + - ]
103 : :
104 : : version = RRsetPtr(new RRset(version_name, RRClass::CH(),
105 [ + - ][ + - ]: 163 : RRType::TXT(), RRTTL(0)));
[ + - ][ + - ]
106 [ + - ][ + - ]: 163 : version->addRdata(generic::TXT(PACKAGE_STRING));
[ + - ][ + - ]
107 : :
108 : : version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
109 [ + - ][ + - ]: 163 : RRType::NS(), RRTTL(0)));
[ + - ][ + - ]
110 [ + - ][ + - ]: 163 : version_ns->addRdata(generic::NS(version_name));
111 : :
112 : : version_soa = RRsetPtr(new RRset(version_name, RRClass::CH(),
113 [ + - ][ + - ]: 163 : RRType::SOA(), RRTTL(0)));
[ + - ][ + - ]
114 : 163 : version_soa->addRdata(generic::SOA(
115 : : "version.bind. hostmaster.version.bind. "
116 [ + - ][ + - ]: 163 : "0 28800 7200 604800 86400"));
[ + - ]
117 : 163 : }
118 : :
119 : 326 : StaticDataSrc::StaticDataSrc() {
120 [ + - ][ + - ]: 163 : LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_STATIC_CREATE);
[ + - ][ + - ]
121 : 163 : setClass(RRClass::CH());
122 [ + - ][ + - ]: 163 : impl_ = new StaticDataSrcImpl;
123 : 163 : }
124 : :
125 : 302 : StaticDataSrc::~StaticDataSrc() {
126 [ + - ]: 326 : delete impl_;
127 : 302 : }
128 : :
129 : : namespace {
130 : : bool
131 : 138 : isSubdomain(const Name& qname, const Name& zone) {
132 : : const NameComparisonResult::NameRelation cmp =
133 : 138 : qname.compare(zone).getRelation();
134 : : return (cmp == NameComparisonResult::EQUAL ||
135 : 138 : cmp == NameComparisonResult::SUBDOMAIN);
136 : : }
137 : : }
138 : :
139 : : void
140 : 203 : StaticDataSrc::findClosestEnclosure(DataSrcMatch& match) const {
141 : 203 : const Name& qname = match.getName();
142 : :
143 [ + + ][ + + ]: 203 : if (match.getClass() != getClass() && match.getClass() != RRClass::ANY()) {
[ + + ]
144 : : return;
145 : : }
146 : :
147 [ + + ]: 42 : if (isSubdomain(qname, impl_->version_name)) {
148 : 12 : match.update(*this, impl_->version_name);
149 : 12 : return;
150 : : }
151 : :
152 [ + + ]: 30 : if (isSubdomain(qname, impl_->authors_name)) {
153 : 2 : match.update(*this, impl_->authors_name);
154 : 203 : return;
155 : : }
156 : : }
157 : :
158 : : DataSrc::Result
159 : 62 : StaticDataSrc::findRRset(const Name& qname,
160 : : const RRClass& qclass, const RRType& qtype,
161 : : RRsetList& target, uint32_t& flags,
162 : : const Name* const zonename) const
163 : : {
164 [ + - ][ + - ]: 124 : LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_STATIC_FIND).arg(qname).
165 [ + - ]: 62 : arg(qtype);
166 : 62 : flags = 0;
167 [ + + ][ + + ]: 62 : if (qclass != getClass() && qclass != RRClass::ANY()) {
[ + + ]
168 [ + - ]: 1 : LOG_ERROR(logger, DATASRC_STATIC_CLASS_NOT_CH);
169 : : return (ERROR);
170 : : }
171 : :
172 : : // Identify the appropriate zone.
173 : 61 : bool is_versionname = false, is_authorsname = false;
174 [ + + ]: 61 : if (zonename != NULL) {
175 [ + + + + ]: 85 : if (*zonename == impl_->version_name &&
[ + + ]
176 : 38 : isSubdomain(qname, impl_->version_name)) {
177 : : is_versionname = true;
178 [ + + + + ]: 17 : } else if (*zonename == impl_->authors_name &&
[ + + ]
179 : 7 : isSubdomain(qname, impl_->authors_name)) {
180 : : is_authorsname = true;
181 : : } else {
182 : 4 : flags = NO_SUCH_ZONE;
183 : 4 : return (SUCCESS);
184 : : }
185 : : } else {
186 [ + + ]: 14 : if (isSubdomain(qname, impl_->version_name)) {
187 : : is_versionname = true;
188 [ + + ]: 7 : } else if (isSubdomain(qname, impl_->authors_name)) {
189 : : is_authorsname = true;
190 : : } else {
191 : 1 : flags = NO_SUCH_ZONE;
192 : 1 : return (SUCCESS);
193 : : }
194 : : }
195 : :
196 : 112 : const bool any = (qtype == RRType::ANY());
197 : :
198 [ + + ]: 56 : if (is_versionname) {
199 [ + + ]: 44 : if (qname == impl_->version_name) {
200 [ + + ][ + + ]: 39 : if (qtype == RRType::TXT() || any) {
[ + + ]
201 [ + - ]: 10 : target.addRRset(impl_->version);
202 : : }
203 [ + + ][ + + ]: 39 : if (qtype == RRType::NS() || any) {
[ + + ]
204 [ + - ]: 8 : target.addRRset(impl_->version_ns);
205 : : }
206 [ + + ][ + + ]: 39 : if (qtype == RRType::SOA() || any) {
[ + + ]
207 [ + - ]: 5 : target.addRRset(impl_->version_soa);
208 : : }
209 [ + + ]: 39 : if (target.size() == 0) {
210 : 12 : flags = TYPE_NOT_FOUND;
211 : : }
212 : : } else {
213 : 5 : flags = NAME_NOT_FOUND;
214 : : }
215 : : } else {
216 [ - + ]: 12 : assert(is_authorsname);
217 [ + + ]: 12 : if (qname == impl_->authors_name) {
218 [ + + ][ + + ]: 10 : if (qtype == RRType::TXT() || any) {
[ + + ]
219 [ + - ]: 4 : target.addRRset(impl_->authors);
220 : : }
221 [ + + ][ + + ]: 10 : if (qtype == RRType::NS() || any) {
[ + + ]
222 [ + - ]: 4 : target.addRRset(impl_->authors_ns);
223 : : }
224 [ + + ][ + + ]: 10 : if (qtype == RRType::SOA() || any) {
[ + + ]
225 [ + - ]: 4 : target.addRRset(impl_->authors_soa);
226 : : }
227 [ + + ]: 10 : if (target.size() == 0 ) {
228 : 2 : flags = TYPE_NOT_FOUND;
229 : : }
230 : : } else {
231 : 62 : flags = NAME_NOT_FOUND;
232 : : }
233 : : }
234 : :
235 : : return (SUCCESS);
236 : : }
237 : :
238 : : DataSrc::Result
239 : 24 : StaticDataSrc::findExactRRset(const Name& qname,
240 : : const RRClass& qclass, const RRType& qtype,
241 : : RRsetList& target, uint32_t& flags,
242 : : const Name* zonename) const
243 : : {
244 : 24 : return (findRRset(qname, qclass, qtype, target, flags, zonename));
245 : : }
246 : :
247 : : DataSrc::Result
248 : 3 : StaticDataSrc::findPreviousName(const Name&, Name&, const Name*) const {
249 : 3 : return (NOT_IMPLEMENTED);
250 : : }
251 : :
252 : : DataSrc::Result
253 : 1 : StaticDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
254 : 1 : return (NOT_IMPLEMENTED);
255 : : }
256 : :
257 : : DataSrc::Result
258 : 2 : StaticDataSrc::init() {
259 : 2 : return (SUCCESS);
260 : : }
261 : :
262 : : // Static data source is "configuration less", so the \c config parameter
263 : : // is intentionally ignored.
264 : : DataSrc::Result
265 : 0 : StaticDataSrc::init(isc::data::ConstElementPtr) {
266 : 0 : return (init());
267 : : }
268 : :
269 : : DataSrc::Result
270 : 0 : StaticDataSrc::close() {
271 : 0 : return (SUCCESS);
272 : : }
273 : :
274 : : }
275 : 107 : }
|