static_datasrc.cc 9.1 KB

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