zone_data.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 <util/memory_segment.h>
  15. #include <dns/name.h>
  16. #include <dns/rrclass.h>
  17. #include <dns/rdataclass.h>
  18. #include "rdataset.h"
  19. #include "rdata_encoder.h"
  20. #include "zone_data.h"
  21. #include "segment_object_holder.h"
  22. #include <boost/bind.hpp>
  23. #include <boost/function.hpp>
  24. #include <cassert>
  25. #include <new> // for the placement new
  26. #include <vector>
  27. using namespace isc::dns;
  28. using namespace isc::dns::rdata;
  29. namespace isc {
  30. namespace datasrc {
  31. namespace memory {
  32. namespace {
  33. void
  34. rdataSetDeleter(RRClass rrclass, util::MemorySegment* mem_sgmt,
  35. RdataSet* rdataset_head)
  36. {
  37. for (RdataSet* rdataset = rdataset_head;
  38. rdataset != NULL;
  39. rdataset = rdataset->getNext()) {
  40. RdataSet::destroy(*mem_sgmt, rrclass, rdataset);
  41. }
  42. }
  43. void
  44. nullDeleter(RdataSet* rdataset_head) {
  45. assert(rdataset_head == NULL);
  46. }
  47. }
  48. NSEC3Data*
  49. NSEC3Data::create(util::MemorySegment& mem_sgmt,
  50. const generic::NSEC3PARAM& rdata)
  51. {
  52. return (NSEC3Data::create(mem_sgmt, rdata.getHashalg(), rdata.getFlags(),
  53. rdata.getIterations(), rdata.getSalt()));
  54. }
  55. NSEC3Data*
  56. NSEC3Data::create(util::MemorySegment& mem_sgmt, const generic::NSEC3& rdata) {
  57. return (NSEC3Data::create(mem_sgmt, rdata.getHashalg(), rdata.getFlags(),
  58. rdata.getIterations(), rdata.getSalt()));
  59. }
  60. NSEC3Data*
  61. NSEC3Data::create(util::MemorySegment& mem_sgmt, uint8_t hashalg,
  62. uint8_t flags, uint16_t iterations,
  63. const std::vector<uint8_t>& salt)
  64. {
  65. // NSEC3Data allocation can throw. To avoid leaking the tree, we manage
  66. // it in the holder.
  67. // Note: we won't add any RdataSet, so we use the NO-OP deleter
  68. // (with an assertion check for that).
  69. typedef boost::function<void(RdataSet*)> RdataSetDeleterType;
  70. detail::SegmentObjectHolder<ZoneTree, RdataSetDeleterType> holder(
  71. mem_sgmt, ZoneTree::create(mem_sgmt, true),
  72. boost::bind(nullDeleter, _1));
  73. const size_t salt_len = salt.size();
  74. void* p = mem_sgmt.allocate(sizeof(NSEC3Data) + salt_len + 1);
  75. NSEC3Data* const param_data =
  76. new(p) NSEC3Data(holder.release(), hashalg, flags, iterations);
  77. uint8_t* dp = param_data->getSaltBuf();
  78. *dp++ = salt_len;
  79. if (salt_len > 0) {
  80. memcpy(dp, &salt.at(0), salt_len); // use at for safety
  81. }
  82. return (param_data);
  83. }
  84. void
  85. NSEC3Data::destroy(util::MemorySegment& mem_sgmt, NSEC3Data* data,
  86. RRClass nsec3_class)
  87. {
  88. ZoneTree::destroy(mem_sgmt, data->nsec3_tree_.get(),
  89. boost::bind(rdataSetDeleter, nsec3_class, &mem_sgmt,
  90. _1));
  91. mem_sgmt.deallocate(data, sizeof(NSEC3Data) + 1 + data->getSaltLen());
  92. }
  93. ZoneData*
  94. ZoneData::create(util::MemorySegment& mem_sgmt, const Name& zone_origin) {
  95. // ZoneTree::insert() and ZoneData allocation can throw. See also
  96. // NSEC3Data::create().
  97. typedef boost::function<void(RdataSet*)> RdataSetDeleterType;
  98. detail::SegmentObjectHolder<ZoneTree, RdataSetDeleterType> holder(
  99. mem_sgmt, ZoneTree::create(mem_sgmt, true),
  100. boost::bind(nullDeleter, _1));
  101. ZoneTree* tree = holder.get();
  102. ZoneNode* origin_node = NULL;
  103. const ZoneTree::Result result =
  104. tree->insert(mem_sgmt, zone_origin, &origin_node);
  105. assert(result == ZoneTree::SUCCESS);
  106. void* p = mem_sgmt.allocate(sizeof(ZoneData));
  107. ZoneData* zone_data = new(p) ZoneData(holder.release(), origin_node);
  108. return (zone_data);
  109. }
  110. void
  111. ZoneData::destroy(util::MemorySegment& mem_sgmt, RRClass zone_class,
  112. ZoneData* zone_data)
  113. {
  114. ZoneTree::destroy(mem_sgmt, zone_data->zone_tree_.get(),
  115. boost::bind(rdataSetDeleter, zone_class, &mem_sgmt,
  116. _1));
  117. mem_sgmt.deallocate(zone_data, sizeof(ZoneData));
  118. }
  119. void
  120. ZoneData::insertName(util::MemorySegment& mem_sgmt, const Name& name,
  121. ZoneNode** node)
  122. {
  123. const ZoneTree::Result result = zone_tree_->insert(mem_sgmt, name, node);
  124. // This should be ensured by the API:
  125. assert((result == ZoneTree::SUCCESS ||
  126. result == ZoneTree::ALREADYEXISTS) && node!= NULL);
  127. }
  128. } // namespace memory
  129. } // namespace datasrc
  130. } // datasrc isc