rdata_serialization.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  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 "rdata_serialization.h"
  15. #include <exceptions/exceptions.h>
  16. #include <util/buffer.h>
  17. #include <dns/name.h>
  18. #include <dns/labelsequence.h>
  19. #include <dns/messagerenderer.h>
  20. #include <dns/rdata.h>
  21. #include <dns/rrclass.h>
  22. #include <dns/rrtype.h>
  23. #include <boost/static_assert.hpp>
  24. #include <boost/function.hpp>
  25. #include <boost/bind.hpp>
  26. #include <boost/optional.hpp>
  27. #include <cassert>
  28. #include <cstring>
  29. #include <set>
  30. #include <vector>
  31. using namespace isc::dns;
  32. using namespace isc::dns::rdata;
  33. using std::vector;
  34. using std::set;
  35. namespace isc {
  36. namespace datasrc {
  37. namespace memory {
  38. #include "rdata_serialization_priv.cc"
  39. namespace {
  40. // Many types of RDATA can be treated as a single-field, variable length
  41. // field (in terms of our encoding). The following define such most general
  42. // form of field spec.
  43. const RdataFieldSpec generic_data_fields[] = {
  44. {RdataFieldSpec::VARLEN_DATA, 0, NAMEATTR_NONE}
  45. };
  46. const uint16_t n_generic_data_fields =
  47. sizeof(generic_data_fields) / sizeof(RdataFieldSpec);
  48. const RdataEncodeSpec generic_data_spec = {
  49. n_generic_data_fields, 0, 1, generic_data_fields
  50. };
  51. // RDATA consist of a single IPv4 address field.
  52. const RdataFieldSpec single_ipv4_fields[] = {
  53. {RdataFieldSpec::FIXEDLEN_DATA, sizeof(uint32_t), NAMEATTR_NONE}
  54. };
  55. const uint16_t n_ipv4_fields =
  56. sizeof(single_ipv4_fields) / sizeof(RdataFieldSpec);
  57. // RDATA consist of a single IPv6 address field.
  58. const RdataFieldSpec single_ipv6_fields[] = {
  59. {RdataFieldSpec::FIXEDLEN_DATA, 16, NAMEATTR_NONE} // 128bits = 16 bytes
  60. };
  61. const uint16_t n_ipv6_fields =
  62. sizeof(single_ipv6_fields) / sizeof(RdataFieldSpec);
  63. // There are several RR types that consist of a single domain name.
  64. const RdataFieldSpec single_noattr_name_fields[] = {
  65. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_NONE}
  66. };
  67. const RdataFieldSpec single_compressible_name_fields[] = {
  68. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_COMPRESSIBLE}
  69. };
  70. const RdataFieldSpec single_compadditional_name_fields[] = {
  71. {RdataFieldSpec::DOMAIN_NAME, 0,
  72. static_cast<RdataNameAttributes>(
  73. static_cast<unsigned int>(NAMEATTR_COMPRESSIBLE) |
  74. static_cast<unsigned int>(NAMEATTR_ADDITIONAL))}
  75. };
  76. const uint16_t n_single_name_fields =
  77. sizeof(single_noattr_name_fields) / sizeof(RdataFieldSpec);
  78. // RDATA consisting of two names. There are some of this type.
  79. const RdataFieldSpec double_compressible_name_fields[] = {
  80. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_COMPRESSIBLE},
  81. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_COMPRESSIBLE}
  82. };
  83. const RdataFieldSpec double_noattr_name_fields[] = {
  84. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_NONE},
  85. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_NONE}
  86. };
  87. const uint16_t n_double_name_fields =
  88. sizeof(double_compressible_name_fields) / sizeof(RdataFieldSpec);
  89. // SOA specific: two compressible names + 5*32-bit data
  90. const RdataFieldSpec soa_fields[] = {
  91. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_COMPRESSIBLE},
  92. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_COMPRESSIBLE},
  93. {RdataFieldSpec::FIXEDLEN_DATA, sizeof(uint32_t) * 5, NAMEATTR_NONE}
  94. };
  95. const uint16_t n_soa_fields = sizeof(soa_fields) / sizeof(RdataFieldSpec);
  96. // MX specific: 16-bit data + compressible/additional name
  97. const RdataFieldSpec mx_fields[] = {
  98. {RdataFieldSpec::FIXEDLEN_DATA, sizeof(uint16_t), NAMEATTR_NONE},
  99. {RdataFieldSpec::DOMAIN_NAME, 0,
  100. static_cast<RdataNameAttributes>(
  101. static_cast<unsigned int>(NAMEATTR_COMPRESSIBLE) |
  102. static_cast<unsigned int>(NAMEATTR_ADDITIONAL))}
  103. };
  104. const uint16_t n_mx_fields = sizeof(mx_fields) / sizeof(RdataFieldSpec);
  105. // AFSDB specific: 16-bit data + no-attribute name
  106. const RdataFieldSpec afsdb_fields[] = {
  107. {RdataFieldSpec::FIXEDLEN_DATA, sizeof(uint16_t), NAMEATTR_NONE},
  108. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_NONE}
  109. };
  110. const uint16_t n_afsdb_fields = sizeof(afsdb_fields) / sizeof(RdataFieldSpec);
  111. // SRV specific: 3*16-bit data + additional name
  112. const RdataFieldSpec srv_fields[] = {
  113. {RdataFieldSpec::FIXEDLEN_DATA, sizeof(uint16_t) * 3, NAMEATTR_NONE},
  114. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_ADDITIONAL}
  115. };
  116. const uint16_t n_srv_fields = sizeof(srv_fields) / sizeof(RdataFieldSpec);
  117. // NAPTR specific: (multi-field) variable data + (additional) name
  118. // NAPTR requires complicated additional section handling; for now, we skip
  119. // the additional handling completely.
  120. const RdataFieldSpec naptr_fields[] = {
  121. {RdataFieldSpec::VARLEN_DATA, 0, NAMEATTR_NONE},
  122. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_NONE}
  123. };
  124. const uint16_t n_naptr_fields = sizeof(naptr_fields) / sizeof(RdataFieldSpec);
  125. // NSEC specific: no-attribute name + varlen data
  126. const RdataFieldSpec nsec_fields[] = {
  127. {RdataFieldSpec::DOMAIN_NAME, 0, NAMEATTR_NONE},
  128. {RdataFieldSpec::VARLEN_DATA, 0, NAMEATTR_NONE}
  129. };
  130. const uint16_t n_nsec_fields = sizeof(nsec_fields) / sizeof(RdataFieldSpec);
  131. // Class IN encode specs. This gives a shortcut to the encode spec for
  132. // some well-known types of RDATA specific to class IN (most of which are
  133. // generic and can be used for other classes). The array index is the
  134. // RR type code.
  135. const RdataEncodeSpec encode_spec_list_in[] = {
  136. generic_data_spec, // #0: (NONE)
  137. {n_ipv4_fields, 0, 0, single_ipv4_fields}, // #1: A
  138. {n_single_name_fields, 1, 0, single_compadditional_name_fields}, // #2: NS
  139. generic_data_spec, // #3
  140. generic_data_spec, // #4
  141. {n_single_name_fields, 1, 0, single_compressible_name_fields}, // #5: CNAME
  142. {n_soa_fields, 2, 0, soa_fields}, // #6: SOA
  143. generic_data_spec, // #7
  144. generic_data_spec, // #8
  145. generic_data_spec, // #9
  146. generic_data_spec, // #10
  147. generic_data_spec, // #11
  148. {n_single_name_fields, 1, 0, single_compressible_name_fields}, // #12: PTR
  149. generic_data_spec, // #13: HINFO
  150. {n_double_name_fields, 2, 0, double_compressible_name_fields}, // #14:HINFO
  151. {n_mx_fields, 1, 0, mx_fields}, // #15: MX
  152. generic_data_spec, // #16: TXT
  153. {n_double_name_fields, 2, 0, double_noattr_name_fields}, // 17: RP
  154. {n_afsdb_fields, 1, 0, afsdb_fields}, // #18: AFSDB
  155. // #19-#26
  156. generic_data_spec, generic_data_spec, generic_data_spec, generic_data_spec,
  157. generic_data_spec, generic_data_spec, generic_data_spec, generic_data_spec,
  158. generic_data_spec, // #27
  159. {n_ipv6_fields, 0, 0, single_ipv6_fields}, // #28: AAAA
  160. // #29-#32
  161. generic_data_spec, generic_data_spec, generic_data_spec, generic_data_spec,
  162. {n_srv_fields, 1, 0, srv_fields}, // #33: SRV
  163. generic_data_spec, // #34
  164. {n_naptr_fields, 1, 1, naptr_fields}, // #35: NAPTR
  165. generic_data_spec, // #36
  166. generic_data_spec, // #37
  167. generic_data_spec, // #38
  168. {n_single_name_fields, 1, 0, single_noattr_name_fields}, // #39 DNAME
  169. generic_data_spec, // #40
  170. generic_data_spec, // #41 (OPT)
  171. generic_data_spec, // #42
  172. generic_data_spec, // #43: DS (this is opaque for encoding purposes)
  173. generic_data_spec, // #44: SSHFP (this is opaque for encoding purposes)
  174. generic_data_spec, // #45
  175. generic_data_spec, // #46: RRSIG (this is opaque for encoding purposes)
  176. {n_nsec_fields, 1, 1, nsec_fields} // #47: NSEC
  177. // All others can be treated as single-field variable length data, at
  178. // least for currently supported RR types.
  179. };
  180. // # of entries in encode_spec_list_in
  181. const size_t encode_spec_list_in_size =
  182. sizeof(encode_spec_list_in) / sizeof(encode_spec_list_in[0]);
  183. BOOST_STATIC_ASSERT(encode_spec_list_in_size == 48);
  184. }
  185. /// \brief Get the spec for given class and type
  186. const RdataEncodeSpec&
  187. getRdataEncodeSpec(const RRClass& rrclass, const RRType& rrtype) {
  188. // Special case: for classes other than IN, we treat RDATA of RR types
  189. // that are class-IN specific as generic opaque data.
  190. if (rrclass != RRClass::IN() &&
  191. (rrtype == RRType::A() || rrtype == RRType::AAAA() ||
  192. rrtype == RRType::SRV())) {
  193. return (generic_data_spec);
  194. }
  195. // Otherwise, if the type is in the pre-defined range, we use the defined
  196. // spec; otherwise we treat it as opaque data.
  197. const uint16_t typecode = rrtype.getCode();
  198. if (typecode < encode_spec_list_in_size) {
  199. return (encode_spec_list_in[rrtype.getCode()]);
  200. }
  201. return (generic_data_spec);
  202. }
  203. namespace {
  204. // This class is a helper for RdataEncoder to divide the content of RDATA
  205. // fields for encoding by "abusing" the message rendering logic.
  206. // The idea is to identify domain name fields in the writeName() method,
  207. // while keeping track of the size and position of other types of data
  208. // around the names.
  209. //
  210. // Technically, this use of inheritance may be considered a violation of
  211. // Liskov Substitution Principle in that it doesn't actually compress domain
  212. // names, and some of the methods are not expected to be used.
  213. // In fact, skip() or trim() may not be make much sense in this context.
  214. // Nevertheless we keep this idea at the moment. Since the usage is limited
  215. // (it's only used within this file, and only used with \c Rdata variants),
  216. // it's hopefully an acceptable practice.
  217. class RdataFieldComposer : public AbstractMessageRenderer {
  218. public:
  219. RdataFieldComposer() : last_data_pos_(0), encode_spec_(NULL),
  220. current_field_(0)
  221. {}
  222. virtual ~RdataFieldComposer() {}
  223. virtual bool isTruncated() const { return (false); }
  224. virtual size_t getLengthLimit() const { return (65535); }
  225. virtual CompressMode getCompressMode() const { return (CASE_INSENSITIVE); }
  226. virtual void setTruncated() {}
  227. virtual void setLengthLimit(size_t) {}
  228. virtual void setCompressMode(CompressMode) {}
  229. virtual void writeName(const LabelSequence&, bool) {
  230. // We don't need this version of writeName
  231. isc_throw(Unexpected, "unexpected version of writeName is called");
  232. }
  233. // Called for each domain name in the RDATA, from the RDATA's toWire()
  234. // implementation.
  235. virtual void writeName(const Name& name, bool compress) {
  236. // First, see if we have other data already stored in the renderer's
  237. // buffer, and handle it appropriately.
  238. updateOtherData();
  239. // Then, we should still have a field in the spec, and it must be a
  240. // domain name field.
  241. if (current_field_ >= encode_spec_->field_count) {
  242. isc_throw(BadValue,
  243. "RDATA encoder encounters an unexpected name data: " <<
  244. name);
  245. }
  246. const RdataFieldSpec& field =
  247. encode_spec_->fields[current_field_++];
  248. // Since we know we've passed any prior data field, the next field
  249. // must be a domain name as long as it exists; otherwise it's a bug
  250. // in the spec (not a bogus input). So we assert() that condition.
  251. assert(field.type == RdataFieldSpec::DOMAIN_NAME);
  252. // It would be compressed iff the field has that attribute.
  253. if (compress !=
  254. ((field.name_attributes & NAMEATTR_COMPRESSIBLE) != 0)) {
  255. isc_throw(BadValue, "RDATA encoder error, inconsistent name "
  256. "compression policy: " << name);
  257. }
  258. const LabelSequence labels(name);
  259. labels.serialize(labels_placeholder_, sizeof(labels_placeholder_));
  260. writeData(labels_placeholder_, labels.getSerializedLength());
  261. last_data_pos_ += labels.getSerializedLength();
  262. }
  263. // Clear all internal states and resources for a new set of RDATA.
  264. void clearLocal(const RdataEncodeSpec* encode_spec) {
  265. AbstractMessageRenderer::clear();
  266. encode_spec_ = encode_spec;
  267. data_lengths_.clear();
  268. last_data_pos_ = 0;
  269. }
  270. // Called at the beginning of an RDATA.
  271. void startRdata() {
  272. current_field_ = 0;
  273. }
  274. // Called at the end of an RDATA.
  275. void endRdata() {
  276. // Handle any remaining data (there should be no more name). Then
  277. // we should reach the end of the fields.
  278. updateOtherData();
  279. if (current_field_ != encode_spec_->field_count) {
  280. isc_throw(BadValue,
  281. "RDATA encoder didn't find all expected fields");
  282. }
  283. }
  284. // Hold the lengths of variable length fields, in the order of their
  285. // appearance. For convenience, allow the encoder to refer to it
  286. // directly.
  287. vector<uint16_t> data_lengths_;
  288. private:
  289. // We use generict write* methods, with the exception of writeName.
  290. // So new data can arrive without us knowing it, this considers all new
  291. // data to be just data, checking consistency with the field spec, and
  292. // if it contains variable-length field, record its length.
  293. size_t last_data_pos_;
  294. void updateOtherData() {
  295. // If we've reached the end of the fields or we are expecting a
  296. // domain name, there's nothing to do here.
  297. if (current_field_ >= encode_spec_->field_count ||
  298. encode_spec_->fields[current_field_].type ==
  299. RdataFieldSpec::DOMAIN_NAME) {
  300. return;
  301. }
  302. const size_t cur_pos = getLength();
  303. const size_t data_len = cur_pos - last_data_pos_;
  304. const RdataFieldSpec& field = encode_spec_->fields[current_field_];
  305. if (field.type == RdataFieldSpec::FIXEDLEN_DATA) {
  306. // The data length of a fixed length field must be the one
  307. // specified in the field spec.
  308. if (data_len != field.fixeddata_len) {
  309. isc_throw(BadValue,
  310. "RDATA encoding: available data too short for the "
  311. "type");
  312. }
  313. } else {
  314. // For encoding purposes, a variable-length data field is
  315. // a single field covering all data, even if it may
  316. // consist of multiple fields as DNS RDATA (e.g. TXT).
  317. if (data_len > 0xffff) {
  318. isc_throw(RdataEncodingError, "RDATA field is too large: "
  319. << data_len << " bytes");
  320. }
  321. data_lengths_.push_back(data_len);
  322. }
  323. ++current_field_;
  324. last_data_pos_ = cur_pos;
  325. }
  326. // The RDATA field spec of the current session. Set at the beginning of
  327. // each session.
  328. const RdataEncodeSpec* encode_spec_;
  329. // the RDATA field (for encoding) currently handled. Reset to 0 for
  330. // each RDATA of the session.
  331. size_t current_field_;
  332. // Placeholder to convert a name object to a label sequence.
  333. uint8_t labels_placeholder_[LabelSequence::MAX_SERIALIZED_LENGTH];
  334. };
  335. } // end of unnamed namespace
  336. namespace {
  337. // A trivial comparison function used for std::set<ConstRdataPtr> below.
  338. bool
  339. RdataLess(const ConstRdataPtr& rdata1, const ConstRdataPtr& rdata2) {
  340. return (rdata1->compare(*rdata2) < 0);
  341. }
  342. }
  343. struct RdataEncoder::RdataEncoderImpl {
  344. RdataEncoderImpl() : encode_spec_(NULL), rrsig_buffer_(0),
  345. old_varlen_count_(0), old_sig_count_(0),
  346. old_data_len_(0), old_sig_len_(0),
  347. old_length_fields_(NULL), old_data_(NULL),
  348. old_sig_data_(NULL), olddata_buffer_(0),
  349. rdatas_(RdataLess), rrsigs_(RdataLess)
  350. {}
  351. // Common initialization for RdataEncoder::start().
  352. void start(RRClass rrclass, RRType rrtype) {
  353. if (rrtype == RRType::RRSIG()) {
  354. isc_throw(BadValue, "RRSIG cannot be encoded as main RDATA type");
  355. }
  356. encode_spec_ = &getRdataEncodeSpec(rrclass, rrtype);
  357. current_class_ = rrclass;
  358. current_type_ = rrtype;
  359. field_composer_.clearLocal(encode_spec_);
  360. rrsig_buffer_.clear();
  361. rrsig_lengths_.clear();
  362. old_varlen_count_ = 0;
  363. old_sig_count_ = 0;
  364. old_data_len_ = 0;
  365. old_sig_len_ = 0;
  366. old_length_fields_ = NULL;
  367. old_data_ = NULL;
  368. old_sig_data_ = NULL;
  369. olddata_buffer_.clear();
  370. rdatas_.clear();
  371. rrsigs_.clear();
  372. }
  373. const RdataEncodeSpec* encode_spec_; // encode spec of current RDATA set
  374. RdataFieldComposer field_composer_;
  375. util::OutputBuffer rrsig_buffer_;
  376. vector<uint16_t> rrsig_lengths_;
  377. // Placeholder for the RR class and type of the current session;
  378. // initially null, and will be (re)set at the beginning of each session.
  379. boost::optional<RRClass> current_class_;
  380. boost::optional<RRType> current_type_;
  381. // Parameters corresponding to the previously encoded data in the
  382. // merge mode.
  383. size_t old_varlen_count_;
  384. size_t old_sig_count_;
  385. size_t old_data_len_;
  386. size_t old_sig_len_;
  387. const void* old_length_fields_;
  388. const void* old_data_;
  389. const void* old_sig_data_;
  390. util::OutputBuffer olddata_buffer_;
  391. // Temporary storage of Rdata and RRSIGs to be encoded. They are used
  392. // to detect and ignore duplicate data.
  393. typedef boost::function<bool(const ConstRdataPtr&, const ConstRdataPtr&)>
  394. RdataCmp;
  395. // added unique Rdatas
  396. set<ConstRdataPtr, RdataCmp> rdatas_;
  397. // added unique RRSIG Rdatas
  398. set<ConstRdataPtr, RdataCmp> rrsigs_;
  399. };
  400. RdataEncoder::RdataEncoder() :
  401. impl_(new RdataEncoderImpl)
  402. {}
  403. RdataEncoder::~RdataEncoder() {
  404. delete impl_;
  405. }
  406. void
  407. RdataEncoder::start(RRClass rrclass, RRType rrtype) {
  408. impl_->start(rrclass, rrtype);
  409. }
  410. namespace {
  411. // Helper callbacks used in the merge mode of start(). These re-construct
  412. // each RDATA and RRSIG in the wire-format, counting the total length of the
  413. // encoded data fields.
  414. void
  415. decodeName(const LabelSequence& name_labels, RdataNameAttributes,
  416. util::OutputBuffer* buffer, size_t* total_len)
  417. {
  418. size_t name_dlen;
  419. const uint8_t* name_data = name_labels.getData(&name_dlen);
  420. buffer->writeData(name_data, name_dlen);
  421. *total_len += name_labels.getSerializedLength();
  422. }
  423. void
  424. decodeData(const void* data, size_t data_len, util::OutputBuffer* buffer,
  425. size_t* total_len)
  426. {
  427. buffer->writeData(data, data_len);
  428. *total_len += data_len;
  429. }
  430. }
  431. void
  432. RdataEncoder::start(RRClass rrclass, RRType rrtype, const void* old_data,
  433. size_t old_rdata_count, size_t old_sig_count)
  434. {
  435. impl_->start(rrclass, rrtype);
  436. // Identify start points of various fields of the encoded data and
  437. // remember it in class variables.
  438. const uint8_t* cp = static_cast<const uint8_t*>(old_data);
  439. impl_->old_varlen_count_ =
  440. impl_->encode_spec_->varlen_count * old_rdata_count;
  441. if (impl_->old_varlen_count_ > 0 || old_sig_count > 0) {
  442. impl_->old_length_fields_ = cp;
  443. cp += (impl_->old_varlen_count_ + old_sig_count) * sizeof(uint16_t);
  444. }
  445. impl_->old_data_ = cp;
  446. impl_->old_sig_count_ = old_sig_count;
  447. // Re-construct RDATAs and RRSIGs in the form of Rdata objects, and
  448. // keep them in rdatas_ and rrsigs_ so we can detect and ignore duplicate
  449. // data with the existing one later. We'll also figure out the lengths
  450. // of the RDATA and RRSIG part of the data by iterating over the data
  451. // fields. Note that the given old_data shouldn't contain duplicate
  452. // Rdata or RRSIG as they should have been generated by this own class,
  453. // which ensures that condition; if this assumption doesn't hold, we throw.
  454. size_t total_len = 0;
  455. RdataReader reader(rrclass, rrtype, old_data, old_rdata_count,
  456. old_sig_count,
  457. boost::bind(decodeName, _1, _2, &impl_->olddata_buffer_,
  458. &total_len),
  459. boost::bind(decodeData, _1, _2, &impl_->olddata_buffer_,
  460. &total_len));
  461. while (reader.iterateRdata()) {
  462. util::InputBuffer ibuffer(impl_->olddata_buffer_.getData(),
  463. impl_->olddata_buffer_.getLength());
  464. if (!impl_->rdatas_.insert(
  465. createRdata(rrtype, rrclass, ibuffer,
  466. impl_->olddata_buffer_.getLength())).second) {
  467. isc_throw(Unexpected, "duplicate RDATA found in merging RdataSet");
  468. }
  469. impl_->olddata_buffer_.clear();
  470. }
  471. impl_->old_data_len_ = total_len;
  472. total_len = 0;
  473. while (reader.iterateSingleSig()) {
  474. util::InputBuffer ibuffer(impl_->olddata_buffer_.getData(),
  475. impl_->olddata_buffer_.getLength());
  476. if (!impl_->rrsigs_.insert(
  477. createRdata(RRType::RRSIG(), rrclass, ibuffer,
  478. impl_->olddata_buffer_.getLength())).second) {
  479. isc_throw(Unexpected, "duplicate RRSIG found in merging RdataSet");
  480. }
  481. impl_->olddata_buffer_.clear();
  482. }
  483. impl_->old_sig_len_ = total_len;
  484. }
  485. bool
  486. RdataEncoder::addRdata(const Rdata& rdata) {
  487. if (impl_->encode_spec_ == NULL) {
  488. isc_throw(InvalidOperation,
  489. "RdataEncoder::addRdata performed before start");
  490. }
  491. // Simply ignore duplicate RDATA. Creating RdataPtr also checks the
  492. // given Rdata is of the correct RR type.
  493. ConstRdataPtr rdatap = createRdata(*impl_->current_type_,
  494. *impl_->current_class_, rdata);
  495. if (impl_->rdatas_.find(rdatap) != impl_->rdatas_.end()) {
  496. return (false);
  497. }
  498. impl_->field_composer_.startRdata();
  499. rdata.toWire(impl_->field_composer_);
  500. impl_->field_composer_.endRdata();
  501. impl_->rdatas_.insert(rdatap);
  502. return (true);
  503. }
  504. bool
  505. RdataEncoder::addSIGRdata(const Rdata& sig_rdata) {
  506. if (impl_->encode_spec_ == NULL) {
  507. isc_throw(InvalidOperation,
  508. "RdataEncoder::addSIGRdata performed before start");
  509. }
  510. // Ignore duplicate RRSIGs
  511. ConstRdataPtr rdatap = createRdata(RRType::RRSIG(), *impl_->current_class_,
  512. sig_rdata);
  513. if (impl_->rrsigs_.find(rdatap) != impl_->rrsigs_.end()) {
  514. return (false);
  515. }
  516. const size_t cur_pos = impl_->rrsig_buffer_.getLength();
  517. sig_rdata.toWire(impl_->rrsig_buffer_);
  518. const size_t rrsig_datalen = impl_->rrsig_buffer_.getLength() - cur_pos;
  519. if (rrsig_datalen > 0xffff) {
  520. isc_throw(RdataEncodingError, "RRSIG is too large: "
  521. << rrsig_datalen << " bytes");
  522. }
  523. impl_->rrsigs_.insert(rdatap);
  524. impl_->rrsig_lengths_.push_back(rrsig_datalen);
  525. return (true);
  526. }
  527. size_t
  528. RdataEncoder::getStorageLength() const {
  529. if (impl_->encode_spec_ == NULL) {
  530. isc_throw(InvalidOperation,
  531. "RdataEncoder::getStorageLength performed before start");
  532. }
  533. return (sizeof(uint16_t) * (impl_->old_varlen_count_ +
  534. impl_->old_sig_count_ +
  535. impl_->field_composer_.data_lengths_.size() +
  536. impl_->rrsig_lengths_.size()) +
  537. impl_->old_data_len_ + impl_->old_sig_len_ +
  538. impl_->rrsig_buffer_.getLength() +
  539. impl_->field_composer_.getLength());
  540. }
  541. void
  542. RdataEncoder::encode(void* buf, size_t buf_len) const {
  543. if (impl_->encode_spec_ == NULL) {
  544. isc_throw(InvalidOperation,
  545. "RdataEncoder::encode performed before start");
  546. }
  547. if (buf == NULL) {
  548. isc_throw(BadValue,
  549. "RdataEncoder::encode NULL buffer is given");
  550. }
  551. if (getStorageLength() > buf_len) {
  552. isc_throw(BadValue, "RdataEncoder::encode short buffer given");
  553. }
  554. uint8_t* const dp_beg = reinterpret_cast<uint8_t*>(buf);
  555. uint8_t* dp = dp_beg;
  556. uint16_t* lenp = reinterpret_cast<uint16_t*>(buf);
  557. // Encode list of lengths for variable length fields for old data (if any)
  558. const size_t old_varlen_fields_len =
  559. impl_->old_varlen_count_ * sizeof(uint16_t);
  560. std::memcpy(lenp, impl_->old_length_fields_, old_varlen_fields_len);
  561. lenp += impl_->old_varlen_count_;
  562. dp += old_varlen_fields_len;
  563. // Encode list of lengths for variable length fields (if any)
  564. if (!impl_->field_composer_.data_lengths_.empty()) {
  565. const size_t varlen_fields_len =
  566. impl_->field_composer_.data_lengths_.size() * sizeof(uint16_t);
  567. std::memcpy(lenp, &impl_->field_composer_.data_lengths_[0],
  568. varlen_fields_len);
  569. lenp += impl_->field_composer_.data_lengths_.size();
  570. dp += varlen_fields_len;
  571. }
  572. // Encode list of lengths for old RRSIGs (if any)
  573. const size_t old_rrsigs_len = impl_->old_sig_count_ * sizeof(uint16_t);
  574. std::memcpy(lenp, static_cast<const uint8_t*>(impl_->old_length_fields_) +
  575. old_varlen_fields_len, old_rrsigs_len);
  576. lenp += impl_->old_sig_count_;
  577. dp += old_rrsigs_len;
  578. // Encode list of lengths for RRSIGs (if any)
  579. if (!impl_->rrsig_lengths_.empty()) {
  580. const size_t rrsigs_len =
  581. impl_->rrsig_lengths_.size() * sizeof(uint16_t);
  582. std::memcpy(lenp, &impl_->rrsig_lengths_[0], rrsigs_len);
  583. dp += rrsigs_len;
  584. }
  585. // Encode main old RDATA, if any
  586. std::memcpy(dp, impl_->old_data_, impl_->old_data_len_);
  587. dp += impl_->old_data_len_;
  588. // Encode main RDATA
  589. std::memcpy(dp, impl_->field_composer_.getData(),
  590. impl_->field_composer_.getLength());
  591. dp += impl_->field_composer_.getLength();
  592. // Encode old RRSIGs, if any
  593. std::memcpy(dp, static_cast<const uint8_t*>(impl_->old_data_) +
  594. impl_->old_data_len_, impl_->old_sig_len_);
  595. dp += impl_->old_sig_len_;
  596. // Encode RRSIGs, if any
  597. std::memcpy(dp, impl_->rrsig_buffer_.getData(),
  598. impl_->rrsig_buffer_.getLength());
  599. dp += impl_->rrsig_buffer_.getLength();
  600. // The validation at the entrance must ensure this
  601. assert(buf_len >= dp - dp_beg);
  602. }
  603. RdataReader::RdataReader(const RRClass& rrclass, const RRType& rrtype,
  604. const void* data,
  605. size_t rdata_count, size_t sig_count,
  606. const NameAction& name_action,
  607. const DataAction& data_action) :
  608. name_action_(name_action),
  609. data_action_(data_action),
  610. spec_(getRdataEncodeSpec(rrclass, rrtype)),
  611. var_count_total_(spec_.varlen_count * rdata_count),
  612. sig_count_(sig_count),
  613. spec_count_(spec_.field_count * rdata_count),
  614. // The lengths are stored first
  615. lengths_(reinterpret_cast<const uint16_t*>(data)),
  616. // And the data just after all the lengths
  617. data_(reinterpret_cast<const uint8_t*>(data) +
  618. (var_count_total_ + sig_count_) * sizeof(uint16_t)),
  619. sigs_(NULL)
  620. {
  621. rewind();
  622. }
  623. void
  624. RdataReader::rewind() {
  625. data_pos_ = 0;
  626. spec_pos_ = 0;
  627. length_pos_ = 0;
  628. sig_data_pos_ = 0;
  629. sig_pos_ = 0;
  630. }
  631. RdataReader::Boundary
  632. RdataReader::nextInternal(const NameAction& name_action,
  633. const DataAction& data_action)
  634. {
  635. if (spec_pos_ < spec_count_) {
  636. const RdataFieldSpec& spec(spec_.fields[(spec_pos_++) %
  637. spec_.field_count]);
  638. if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
  639. const LabelSequence sequence(data_ + data_pos_);
  640. data_pos_ += sequence.getSerializedLength();
  641. name_action(sequence, spec.name_attributes);
  642. } else {
  643. const size_t length(spec.type == RdataFieldSpec::FIXEDLEN_DATA ?
  644. spec.fixeddata_len : lengths_[length_pos_++]);
  645. const uint8_t* const pos = data_ + data_pos_;
  646. data_pos_ += length;
  647. data_action(pos, length);
  648. }
  649. return (spec_pos_ % spec_.field_count == 0 ?
  650. RDATA_BOUNDARY : NO_BOUNDARY);
  651. } else {
  652. sigs_ = data_ + data_pos_;
  653. return (RRSET_BOUNDARY);
  654. }
  655. }
  656. RdataReader::Boundary
  657. RdataReader::next() {
  658. return (nextInternal(name_action_, data_action_));
  659. }
  660. void
  661. RdataReader::emptyNameAction(const LabelSequence&, RdataNameAttributes) {
  662. // Do nothing here.
  663. }
  664. void
  665. RdataReader::emptyDataAction(const void*, size_t) {
  666. // Do nothing here.
  667. }
  668. RdataReader::Boundary
  669. RdataReader::nextSig() {
  670. if (sig_pos_ < sig_count_) {
  671. if (sigs_ == NULL) {
  672. // We didn't find where the signatures start yet. We do it
  673. // by iterating the whole data and then returning the state
  674. // back.
  675. const size_t data_pos = data_pos_;
  676. const size_t spec_pos = spec_pos_;
  677. const size_t length_pos = length_pos_;
  678. // When the next() gets to the last item, it sets the sigs_
  679. while (nextInternal(emptyNameAction, emptyDataAction) !=
  680. RRSET_BOUNDARY) {}
  681. assert(sigs_ != NULL);
  682. // Return the state
  683. data_pos_ = data_pos;
  684. spec_pos_ = spec_pos;
  685. length_pos_ = length_pos;
  686. }
  687. // Extract the result
  688. const size_t length = lengths_[var_count_total_ + sig_pos_];
  689. const uint8_t* const pos = sigs_ + sig_data_pos_;
  690. // Move the position of iterator.
  691. sig_data_pos_ += lengths_[var_count_total_ + sig_pos_];
  692. ++sig_pos_;
  693. // Call the callback
  694. data_action_(pos, length);
  695. return (RDATA_BOUNDARY);
  696. } else {
  697. return (RRSET_BOUNDARY);
  698. }
  699. }
  700. size_t
  701. RdataReader::getSize() const {
  702. size_t storage_size = 0; // this will be the end result
  703. size_t data_pos = 0;
  704. size_t length_pos = 0;
  705. // Go over all data fields, adding their lengths to storage_size
  706. for (size_t spec_pos = 0; spec_pos < spec_count_; ++spec_pos) {
  707. const RdataFieldSpec& spec =
  708. spec_.fields[spec_pos % spec_.field_count];
  709. if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
  710. const size_t seq_len =
  711. LabelSequence(data_ + data_pos).getSerializedLength();
  712. data_pos += seq_len;
  713. storage_size += seq_len;
  714. } else {
  715. const size_t data_len =
  716. (spec.type == RdataFieldSpec::FIXEDLEN_DATA ?
  717. spec.fixeddata_len : lengths_[length_pos++]);
  718. data_pos += data_len;
  719. storage_size += data_len;
  720. }
  721. }
  722. // Same for all RRSIG data
  723. for (size_t sig_pos = 0; sig_pos < sig_count_; ++sig_pos) {
  724. const size_t sig_data_len = lengths_[length_pos++];
  725. storage_size += sig_data_len;
  726. }
  727. // Finally, add the size for 16-bit length fields
  728. storage_size += (var_count_total_ * sizeof(uint16_t) +
  729. sig_count_ * sizeof(uint16_t));
  730. return (storage_size);
  731. }
  732. } // namespace memory
  733. } // namespace datasrc
  734. } // datasrc isc