static_datasrc.cc 9.0 KB

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