rdataset.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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 <dns/rdata.h>
  16. #include <dns/rdataclass.h>
  17. #include <dns/rrclass.h>
  18. #include <dns/rrtype.h>
  19. #include <dns/rrset.h>
  20. #include "rdataset.h"
  21. #include "rdata_serialization.h"
  22. #include <boost/static_assert.hpp>
  23. #include <stdint.h>
  24. #include <cstring>
  25. #include <typeinfo> // for bad_cast
  26. #include <new> // for the placement new
  27. using namespace isc::dns;
  28. using namespace isc::dns::rdata;
  29. namespace isc {
  30. namespace datasrc {
  31. namespace memory {
  32. namespace {
  33. RRType
  34. getCoveredType(const Rdata& rdata) {
  35. try {
  36. const generic::RRSIG& rrsig_rdata =
  37. dynamic_cast<const generic::RRSIG&>(rdata);
  38. return (rrsig_rdata.typeCovered());
  39. } catch (const std::bad_cast&) {
  40. isc_throw(BadValue, "Non RRSIG is given where it's expected");
  41. }
  42. }
  43. }
  44. RdataSet*
  45. RdataSet::create(util::MemorySegment& mem_sgmt, RdataEncoder& encoder,
  46. ConstRRsetPtr rrset, ConstRRsetPtr sig_rrset)
  47. {
  48. // Check basic validity
  49. if (!rrset && !sig_rrset) {
  50. isc_throw(BadValue, "Both RRset and RRSIG are NULL");
  51. }
  52. if (rrset && rrset->getRdataCount() == 0) {
  53. isc_throw(BadValue, "Empty RRset");
  54. }
  55. if (sig_rrset && sig_rrset->getRdataCount() == 0) {
  56. isc_throw(BadValue, "Empty SIG RRset");
  57. }
  58. if (rrset && sig_rrset && rrset->getClass() != sig_rrset->getClass()) {
  59. isc_throw(BadValue, "RR class doesn't match between RRset and RRSIG");
  60. }
  61. // Check assumptions on the number of RDATAs
  62. if (rrset && rrset->getRdataCount() > MAX_RDATA_COUNT) {
  63. isc_throw(RdataSetError, "Too many RDATAs for RdataSet: "
  64. << rrset->getRdataCount() << ", must be <= "
  65. << MAX_RDATA_COUNT);
  66. }
  67. if (sig_rrset && sig_rrset->getRdataCount() > MAX_RRSIG_COUNT) {
  68. isc_throw(RdataSetError, "Too many RRSIGs for RdataSet: "
  69. << sig_rrset->getRdataCount() << ", must be <= "
  70. << MAX_RRSIG_COUNT);
  71. }
  72. const RRClass rrclass = rrset ? rrset->getClass() : sig_rrset->getClass();
  73. const RRType rrtype = rrset ? rrset->getType() :
  74. getCoveredType(sig_rrset->getRdataIterator()->getCurrent());
  75. const RRTTL rrttl = rrset ? rrset->getTTL() : sig_rrset->getTTL();
  76. encoder.start(rrclass, rrtype);
  77. if (rrset) {
  78. for (RdataIteratorPtr it = rrset->getRdataIterator();
  79. !it->isLast();
  80. it->next()) {
  81. encoder.addRdata(it->getCurrent());
  82. }
  83. }
  84. if (sig_rrset) {
  85. for (RdataIteratorPtr it = sig_rrset->getRdataIterator();
  86. !it->isLast();
  87. it->next())
  88. {
  89. if (getCoveredType(it->getCurrent()) != rrtype) {
  90. isc_throw(BadValue, "Type covered doesn't match");
  91. }
  92. encoder.addSIGRdata(it->getCurrent());
  93. }
  94. }
  95. const size_t rrsig_count = sig_rrset ? sig_rrset->getRdataCount() : 0;
  96. const size_t ext_rrsig_count_len =
  97. rrsig_count >= MANY_RRSIG_COUNT ? sizeof(uint16_t) : 0;
  98. const size_t data_len = encoder.getStorageLength();
  99. void* p = mem_sgmt.allocate(sizeof(RdataSet) + ext_rrsig_count_len +
  100. data_len);
  101. RdataSet* rdataset = new(p) RdataSet(rrtype,
  102. rrset ? rrset->getRdataCount() : 0,
  103. rrsig_count, rrttl);
  104. if (rrsig_count >= MANY_RRSIG_COUNT) {
  105. *rdataset->getExtSIGCountBuf() = rrsig_count;
  106. }
  107. encoder.encode(rdataset->getDataBuf(), data_len);
  108. return (rdataset);
  109. }
  110. RdataSet*
  111. RdataSet::create(util::MemorySegment& mem_sgmt, RdataEncoder& encoder,
  112. const RdataSet& old_rdataset, ConstRRsetPtr rrset,
  113. ConstRRsetPtr sig_rrset)
  114. {
  115. // TODO: consistency check and taking min
  116. // Check basic validity
  117. if (!rrset && !sig_rrset) {
  118. isc_throw(BadValue, "Both RRset and RRSIG are NULL");
  119. }
  120. if (rrset && rrset->getRdataCount() == 0) {
  121. isc_throw(BadValue, "Empty RRset");
  122. }
  123. if (sig_rrset && sig_rrset->getRdataCount() == 0) {
  124. isc_throw(BadValue, "Empty SIG RRset");
  125. }
  126. if (rrset && sig_rrset && rrset->getClass() != sig_rrset->getClass()) {
  127. isc_throw(BadValue, "RR class doesn't match between RRset and RRSIG");
  128. }
  129. // Check assumptions on the number of RDATAs
  130. const size_t old_rdata_count = old_rdataset.getRdataCount();
  131. const size_t old_sig_count = old_rdataset.getSigRdataCount();
  132. if (rrset && (rrset->getRdataCount() + old_rdata_count) > MAX_RDATA_COUNT)
  133. {
  134. isc_throw(RdataSetError, "Too many RDATAs for RdataSet: "
  135. << rrset->getRdataCount() << ", must be <= "
  136. << MAX_RDATA_COUNT);
  137. }
  138. if (sig_rrset && (sig_rrset->getRdataCount() + old_sig_count) >
  139. MAX_RRSIG_COUNT) {
  140. isc_throw(RdataSetError, "Too many RRSIGs for RdataSet: "
  141. << sig_rrset->getRdataCount() << ", must be <= "
  142. << MAX_RRSIG_COUNT);
  143. }
  144. const RRClass rrclass = rrset ? rrset->getClass() : sig_rrset->getClass();
  145. const RRType rrtype = rrset ? rrset->getType() :
  146. getCoveredType(sig_rrset->getRdataIterator()->getCurrent());
  147. const RRTTL rrttl = rrset ? rrset->getTTL() : sig_rrset->getTTL();
  148. encoder.start(rrclass, rrtype, old_rdataset.getDataBuf(), old_rdata_count,
  149. old_sig_count);
  150. if (rrset) {
  151. for (RdataIteratorPtr it = rrset->getRdataIterator();
  152. !it->isLast();
  153. it->next()) {
  154. encoder.addRdata(it->getCurrent());
  155. }
  156. }
  157. if (sig_rrset) {
  158. for (RdataIteratorPtr it = sig_rrset->getRdataIterator();
  159. !it->isLast();
  160. it->next())
  161. {
  162. if (getCoveredType(it->getCurrent()) != rrtype) {
  163. isc_throw(BadValue, "Type covered doesn't match");
  164. }
  165. encoder.addSIGRdata(it->getCurrent());
  166. }
  167. }
  168. const size_t rrsig_count =
  169. old_sig_count + (sig_rrset ? sig_rrset->getRdataCount() : 0);
  170. const size_t ext_rrsig_count_len =
  171. rrsig_count >= MANY_RRSIG_COUNT ? sizeof(uint16_t) : 0;
  172. const size_t data_len = encoder.getStorageLength();
  173. void* p = mem_sgmt.allocate(sizeof(RdataSet) + ext_rrsig_count_len +
  174. data_len);
  175. const size_t rdata_count =
  176. old_rdata_count + (rrset ? rrset->getRdataCount() : 0);
  177. RdataSet* rdataset = new(p) RdataSet(rrtype, rdata_count, rrsig_count,
  178. rrttl);
  179. if (rrsig_count >= MANY_RRSIG_COUNT) {
  180. *rdataset->getExtSIGCountBuf() = rrsig_count;
  181. }
  182. encoder.encode(rdataset->getDataBuf(), data_len);
  183. return (rdataset);
  184. }
  185. void
  186. RdataSet::destroy(util::MemorySegment& mem_sgmt, RdataSet* rdataset,
  187. RRClass rrclass)
  188. {
  189. const size_t data_len =
  190. RdataReader(rrclass, rdataset->type,
  191. reinterpret_cast<const uint8_t*>(rdataset->getDataBuf()),
  192. rdataset->getRdataCount(), rdataset->getSigRdataCount(),
  193. &RdataReader::emptyNameAction,
  194. &RdataReader::emptyDataAction).getSize();
  195. const size_t ext_rrsig_count_len =
  196. rdataset->sig_rdata_count_ == MANY_RRSIG_COUNT ? sizeof(uint16_t) : 0;
  197. rdataset->~RdataSet();
  198. mem_sgmt.deallocate(rdataset,
  199. sizeof(RdataSet) + ext_rrsig_count_len + data_len);
  200. }
  201. namespace {
  202. // Convert the given RRTTL into the corresponding 32-bit unsigned integer,
  203. // in the network byte order. We do not use htonl() to be as portable as
  204. // possible.
  205. uint32_t
  206. convertTTL(RRTTL ttl) {
  207. const uint32_t ttl_val = ttl.getValue();
  208. uint8_t buf[4];
  209. buf[0] = (ttl_val & 0xff000000) >> 24;
  210. buf[1] = (ttl_val & 0x00ff0000) >> 16;
  211. buf[2] = (ttl_val & 0x0000ff00) >> 8;
  212. buf[3] = (ttl_val & 0x000000ff);
  213. uint32_t ret;
  214. std::memcpy(&ret, buf, sizeof(ret));
  215. return (ret);
  216. }
  217. }
  218. RdataSet::RdataSet(RRType type_param, size_t rdata_count,
  219. size_t sig_rdata_count, RRTTL ttl) :
  220. type(type_param),
  221. sig_rdata_count_(sig_rdata_count >= MANY_RRSIG_COUNT ?
  222. MANY_RRSIG_COUNT : sig_rdata_count),
  223. rdata_count_(rdata_count), ttl_(convertTTL(ttl))
  224. {
  225. // Make sure an RRType object is essentially a plain 16-bit value, so
  226. // our assumption of the size of RdataSet holds. If it's not the case
  227. // we should use the bare value instead of the class object.
  228. BOOST_STATIC_ASSERT(sizeof(type) == sizeof(uint16_t));
  229. // Confirm we meet the alignment requirement for RdataEncoder
  230. // ("this + 1" should be safely passed to the encoder).
  231. BOOST_STATIC_ASSERT(sizeof(RdataSet) % sizeof(uint16_t) == 0);
  232. }
  233. } // namespace memory
  234. } // namespace datasrc
  235. } // datasrc isc