rrcollator.cc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright (C) 2012 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 <dns/name.h>
  15. #include <dns/rdataclass.h>
  16. #include <dns/rrcollator.h>
  17. #include <dns/rrclass.h>
  18. #include <dns/rrtype.h>
  19. #include <dns/rrttl.h>
  20. #include <dns/rdata.h>
  21. #include <dns/rrset.h>
  22. #include <boost/bind.hpp>
  23. #include <algorithm>
  24. namespace isc {
  25. namespace dns {
  26. using namespace rdata;
  27. class RRCollator::Impl {
  28. public:
  29. Impl(const AddRRsetCallback& callback,
  30. const MasterLoaderCallbacks& issue_callback) :
  31. callback_(callback), issue_callback_(issue_callback)
  32. {}
  33. void addRR(const Name& name, const RRClass& rrclass,
  34. const RRType& rrtype, const RRTTL& rrttl,
  35. const RdataPtr& rdata);
  36. RRsetPtr current_rrset_;
  37. AddRRsetCallback callback_;
  38. private:
  39. MasterLoaderCallbacks issue_callback_;
  40. };
  41. namespace {
  42. inline bool
  43. isSameType(RRType type1, const ConstRdataPtr& rdata1,
  44. const ConstRRsetPtr& rrset)
  45. {
  46. if (type1 != rrset->getType()) {
  47. return (false);
  48. }
  49. if (type1 == RRType::RRSIG()) {
  50. RdataIteratorPtr rit = rrset->getRdataIterator();
  51. return (dynamic_cast<const generic::RRSIG&>(*rdata1).typeCovered()
  52. == dynamic_cast<const generic::RRSIG&>(
  53. rit->getCurrent()).typeCovered());
  54. }
  55. return (true);
  56. }
  57. }
  58. void
  59. RRCollator::Impl::addRR(const Name& name, const RRClass& rrclass,
  60. const RRType& rrtype, const RRTTL& rrttl,
  61. const RdataPtr& rdata)
  62. {
  63. if (current_rrset_ && (!isSameType(rrtype, rdata, current_rrset_) ||
  64. current_rrset_->getClass() != rrclass ||
  65. current_rrset_->getName() != name)) {
  66. callback_(current_rrset_);
  67. current_rrset_.reset();
  68. }
  69. if (!current_rrset_) {
  70. current_rrset_ = RRsetPtr(new RRset(name, rrclass, rrtype, rrttl));
  71. } else if (current_rrset_->getTTL() != rrttl) {
  72. // RRs with different TTLs are given. Smaller TTL should win.
  73. const RRTTL min_ttl(std::min(current_rrset_->getTTL(), rrttl));
  74. issue_callback_.warning("<unknown source>", 0,
  75. "Different TTLs for the same RRset: " +
  76. name.toText(true) + "/" +
  77. rrclass.toText() + "/" + rrtype.toText() +
  78. ", set to " + min_ttl.toText());
  79. current_rrset_->setTTL(min_ttl);
  80. }
  81. current_rrset_->addRdata(rdata);
  82. }
  83. RRCollator::RRCollator(const AddRRsetCallback& callback,
  84. const MasterLoaderCallbacks& issue_callback) :
  85. impl_(new Impl(callback, issue_callback))
  86. {}
  87. RRCollator::~RRCollator() {
  88. delete impl_;
  89. }
  90. AddRRCallback
  91. RRCollator::getCallback() {
  92. return (boost::bind(&RRCollator::Impl::addRR, this->impl_,
  93. _1, _2, _3, _4, _5));
  94. }
  95. void
  96. RRCollator::flush() {
  97. if (impl_->current_rrset_) {
  98. impl_->callback_(impl_->current_rrset_);
  99. impl_->current_rrset_.reset();
  100. }
  101. }
  102. } // end namespace dns
  103. } // end namespace isc