rrcollator.cc 3.2 KB

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