static_datasrc.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. #include <config.h>
  15. #include <cassert>
  16. #include <dns/name.h>
  17. #include <dns/rdataclass.h>
  18. #include <dns/rrclass.h>
  19. #include <dns/rrset.h>
  20. #include <dns/rrsetlist.h>
  21. #include <dns/rrtype.h>
  22. #include <dns/rrttl.h>
  23. #include <datasrc/data_source.h>
  24. #include <datasrc/static_datasrc.h>
  25. #include <datasrc/logger.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("Haidong Wang")); // Ocean
  67. authors->addRdata(generic::TXT("Han Feng"));
  68. authors->addRdata(generic::TXT("Jelte Jansen"));
  69. authors->addRdata(generic::TXT("Jeremy C. Reed"));
  70. authors->addRdata(generic::TXT("Jin Jian"));
  71. authors->addRdata(generic::TXT("JINMEI Tatuya"));
  72. authors->addRdata(generic::TXT("Kazunori Fujiwara"));
  73. authors->addRdata(generic::TXT("Michael Graff"));
  74. authors->addRdata(generic::TXT("Michal Vaner"));
  75. authors->addRdata(generic::TXT("Naoki Kambe"));
  76. authors->addRdata(generic::TXT("Shane Kerr"));
  77. authors->addRdata(generic::TXT("Shen Tingting"));
  78. authors->addRdata(generic::TXT("Stephen Morris"));
  79. authors->addRdata(generic::TXT("Yoshitaka Aharen"));
  80. authors->addRdata(generic::TXT("Zhang Likun"));
  81. authors_ns = RRsetPtr(new RRset(authors_name, RRClass::CH(),
  82. RRType::NS(), RRTTL(0)));
  83. authors_ns->addRdata(generic::NS(authors_name));
  84. authors_soa = RRsetPtr(new RRset(authors_name, RRClass::CH(),
  85. RRType::SOA(), RRTTL(0)));
  86. authors_soa->addRdata(generic::SOA(
  87. "authors.bind. hostmaster.authors.bind. "
  88. "0 28800 7200 604800 86400"));
  89. version = RRsetPtr(new RRset(version_name, RRClass::CH(),
  90. RRType::TXT(), RRTTL(0)));
  91. version->addRdata(generic::TXT(PACKAGE_STRING));
  92. version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
  93. RRType::NS(), RRTTL(0)));
  94. version_ns->addRdata(generic::NS(version_name));
  95. version_soa = RRsetPtr(new RRset(version_name, RRClass::CH(),
  96. RRType::SOA(), RRTTL(0)));
  97. version_soa->addRdata(generic::SOA(
  98. "version.bind. hostmaster.version.bind. "
  99. "0 28800 7200 604800 86400"));
  100. }
  101. StaticDataSrc::StaticDataSrc() {
  102. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_STATIC_CREATE);
  103. setClass(RRClass::CH());
  104. impl_ = new StaticDataSrcImpl;
  105. }
  106. StaticDataSrc::~StaticDataSrc() {
  107. delete impl_;
  108. }
  109. namespace {
  110. bool
  111. isSubdomain(const Name& qname, const Name& zone) {
  112. const NameComparisonResult::NameRelation cmp =
  113. qname.compare(zone).getRelation();
  114. return (cmp == NameComparisonResult::EQUAL ||
  115. cmp == NameComparisonResult::SUBDOMAIN);
  116. }
  117. }
  118. void
  119. StaticDataSrc::findClosestEnclosure(DataSrcMatch& match) const {
  120. const Name& qname = match.getName();
  121. if (match.getClass() != getClass() && match.getClass() != RRClass::ANY()) {
  122. return;
  123. }
  124. if (isSubdomain(qname, impl_->version_name)) {
  125. match.update(*this, impl_->version_name);
  126. return;
  127. }
  128. if (isSubdomain(qname, impl_->authors_name)) {
  129. match.update(*this, impl_->authors_name);
  130. return;
  131. }
  132. }
  133. DataSrc::Result
  134. StaticDataSrc::findRRset(const Name& qname,
  135. const RRClass& qclass, const RRType& qtype,
  136. RRsetList& target, uint32_t& flags,
  137. const Name* const zonename) const
  138. {
  139. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_STATIC_FIND).arg(qname).
  140. arg(qtype);
  141. flags = 0;
  142. if (qclass != getClass() && qclass != RRClass::ANY()) {
  143. LOG_ERROR(logger, DATASRC_STATIC_CLASS_NOT_CH);
  144. return (ERROR);
  145. }
  146. // Identify the appropriate zone.
  147. bool is_versionname = false, is_authorsname = false;
  148. if (zonename != NULL) {
  149. if (*zonename == impl_->version_name &&
  150. isSubdomain(qname, impl_->version_name)) {
  151. is_versionname = true;
  152. } else if (*zonename == impl_->authors_name &&
  153. isSubdomain(qname, impl_->authors_name)) {
  154. is_authorsname = true;
  155. } else {
  156. flags = NO_SUCH_ZONE;
  157. return (SUCCESS);
  158. }
  159. } else {
  160. if (isSubdomain(qname, impl_->version_name)) {
  161. is_versionname = true;
  162. } else if (isSubdomain(qname, impl_->authors_name)) {
  163. is_authorsname = true;
  164. } else {
  165. flags = NO_SUCH_ZONE;
  166. return (SUCCESS);
  167. }
  168. }
  169. const bool any = (qtype == RRType::ANY());
  170. if (is_versionname) {
  171. if (qname == impl_->version_name) {
  172. if (qtype == RRType::TXT() || any) {
  173. target.addRRset(impl_->version);
  174. }
  175. if (qtype == RRType::NS() || any) {
  176. target.addRRset(impl_->version_ns);
  177. }
  178. if (qtype == RRType::SOA() || any) {
  179. target.addRRset(impl_->version_soa);
  180. }
  181. if (target.size() == 0) {
  182. flags = TYPE_NOT_FOUND;
  183. }
  184. } else {
  185. flags = NAME_NOT_FOUND;
  186. }
  187. } else {
  188. assert(is_authorsname);
  189. if (qname == impl_->authors_name) {
  190. if (qtype == RRType::TXT() || any) {
  191. target.addRRset(impl_->authors);
  192. }
  193. if (qtype == RRType::NS() || any) {
  194. target.addRRset(impl_->authors_ns);
  195. }
  196. if (qtype == RRType::SOA() || any) {
  197. target.addRRset(impl_->authors_soa);
  198. }
  199. if (target.size() == 0 ) {
  200. flags = TYPE_NOT_FOUND;
  201. }
  202. } else {
  203. flags = NAME_NOT_FOUND;
  204. }
  205. }
  206. return (SUCCESS);
  207. }
  208. DataSrc::Result
  209. StaticDataSrc::findExactRRset(const Name& qname,
  210. const RRClass& qclass, const RRType& qtype,
  211. RRsetList& target, uint32_t& flags,
  212. const Name* zonename) const
  213. {
  214. return (findRRset(qname, qclass, qtype, target, flags, zonename));
  215. }
  216. DataSrc::Result
  217. StaticDataSrc::findPreviousName(const Name&, Name&, const Name*) const {
  218. return (NOT_IMPLEMENTED);
  219. }
  220. DataSrc::Result
  221. StaticDataSrc::findCoveringNSEC3(const Name&, string&, RRsetList&) const {
  222. return (NOT_IMPLEMENTED);
  223. }
  224. DataSrc::Result
  225. StaticDataSrc::init() {
  226. return (SUCCESS);
  227. }
  228. // Static data source is "configuration less", so the \c config parameter
  229. // is intentionally ignored.
  230. DataSrc::Result
  231. StaticDataSrc::init(isc::data::ConstElementPtr) {
  232. return (init());
  233. }
  234. DataSrc::Result
  235. StaticDataSrc::close() {
  236. return (SUCCESS);
  237. }
  238. }
  239. }