rdata_serialization.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  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_(boost::bind(RdataLess, _1, _2)),
  350. rrsigs_(boost::bind(RdataLess, _1, _2))
  351. {}
  352. // Common initialization for RdataEncoder::start().
  353. void start(RRClass rrclass, RRType rrtype) {
  354. if (rrtype == RRType::RRSIG()) {
  355. isc_throw(BadValue, "RRSIG cannot be encoded as main RDATA type");
  356. }
  357. encode_spec_ = &getRdataEncodeSpec(rrclass, rrtype);
  358. current_class_ = rrclass;
  359. current_type_ = rrtype;
  360. field_composer_.clearLocal(encode_spec_);
  361. rrsig_buffer_.clear();
  362. rrsig_lengths_.clear();
  363. old_varlen_count_ = 0;
  364. old_sig_count_ = 0;
  365. old_data_len_ = 0;
  366. old_sig_len_ = 0;
  367. old_length_fields_ = NULL;
  368. old_data_ = NULL;
  369. old_sig_data_ = NULL;
  370. olddata_buffer_.clear();
  371. rdatas_.clear();
  372. rrsigs_.clear();
  373. }
  374. const RdataEncodeSpec* encode_spec_; // encode spec of current RDATA set
  375. RdataFieldComposer field_composer_;
  376. util::OutputBuffer rrsig_buffer_;
  377. vector<uint16_t> rrsig_lengths_;
  378. boost::optional<RRClass> current_class_;
  379. boost::optional<RRType> current_type_;
  380. size_t old_varlen_count_;
  381. size_t old_sig_count_;
  382. size_t old_data_len_;
  383. size_t old_sig_len_;
  384. const void* old_length_fields_;
  385. const void* old_data_;
  386. const void* old_sig_data_;
  387. util::OutputBuffer olddata_buffer_;
  388. // Temporary storage of Rdata and RRSIGs to be encoded. They are used
  389. // to detect and ignore duplicate data.
  390. typedef boost::function<bool(const ConstRdataPtr&, const ConstRdataPtr&)>
  391. RdataCmp;
  392. // added unique Rdatas
  393. set<ConstRdataPtr, RdataCmp> rdatas_;
  394. // added unique RRSIG Rdatas
  395. set<ConstRdataPtr, RdataCmp> rrsigs_;
  396. };
  397. RdataEncoder::RdataEncoder() :
  398. impl_(new RdataEncoderImpl)
  399. {}
  400. RdataEncoder::~RdataEncoder() {
  401. delete impl_;
  402. }
  403. void
  404. RdataEncoder::start(RRClass rrclass, RRType rrtype) {
  405. impl_->start(rrclass, rrtype);
  406. }
  407. namespace {
  408. void
  409. decodeName(const LabelSequence& name_labels, RdataNameAttributes,
  410. util::OutputBuffer* buffer, size_t* total_len)
  411. {
  412. size_t name_dlen;
  413. const uint8_t* name_data = name_labels.getData(&name_dlen);
  414. buffer->writeData(name_data, name_dlen);
  415. *total_len += name_labels.getSerializedLength();
  416. }
  417. void
  418. decodeData(const void* data, size_t data_len, util::OutputBuffer* buffer,
  419. size_t* total_len)
  420. {
  421. buffer->writeData(data, data_len);
  422. *total_len += data_len;
  423. }
  424. }
  425. void
  426. RdataEncoder::start(RRClass rrclass, RRType rrtype, const void* old_data,
  427. size_t old_rdata_count, size_t old_sig_count)
  428. {
  429. impl_->start(rrclass, rrtype);
  430. const uint8_t* cp = static_cast<const uint8_t*>(old_data);
  431. impl_->old_varlen_count_ =
  432. impl_->encode_spec_->varlen_count * old_rdata_count;
  433. if (impl_->old_varlen_count_ > 0 || old_sig_count > 0) {
  434. impl_->old_length_fields_ = cp;
  435. cp += (impl_->old_varlen_count_ + old_sig_count) * sizeof(uint16_t);
  436. }
  437. impl_->old_data_ = cp;
  438. impl_->old_sig_count_ = old_sig_count;
  439. size_t total_len = 0;
  440. RdataReader reader(rrclass, rrtype, old_data, old_rdata_count,
  441. old_sig_count,
  442. boost::bind(decodeName, _1, _2, &impl_->olddata_buffer_,
  443. &total_len),
  444. boost::bind(decodeData, _1, _2, &impl_->olddata_buffer_,
  445. &total_len));
  446. while (reader.iterateRdata()) {
  447. util::InputBuffer ibuffer(impl_->olddata_buffer_.getData(),
  448. impl_->olddata_buffer_.getLength());
  449. impl_->rdatas_.insert(createRdata(rrtype, rrclass, ibuffer,
  450. impl_->olddata_buffer_.getLength()));
  451. impl_->olddata_buffer_.clear();
  452. }
  453. impl_->old_data_len_ = total_len;
  454. total_len = 0;
  455. while (reader.iterateSingleSig()) {
  456. util::InputBuffer ibuffer(impl_->olddata_buffer_.getData(),
  457. impl_->olddata_buffer_.getLength());
  458. impl_->rrsigs_.insert(createRdata(RRType::RRSIG(), rrclass, ibuffer,
  459. impl_->olddata_buffer_.getLength()));
  460. impl_->olddata_buffer_.clear();
  461. }
  462. impl_->old_sig_len_ = total_len;
  463. }
  464. void
  465. RdataEncoder::addRdata(const Rdata& rdata) {
  466. if (impl_->encode_spec_ == NULL) {
  467. isc_throw(InvalidOperation,
  468. "RdataEncoder::addRdata performed before start");
  469. }
  470. // Simply ignore duplicate RDATA. Creating RdataPtr also checks the
  471. // given Rdata is of the correct RR type.
  472. ConstRdataPtr rdatap = createRdata(*impl_->current_type_,
  473. *impl_->current_class_, rdata);
  474. if (impl_->rdatas_.find(rdatap) != impl_->rdatas_.end()) {
  475. return;
  476. }
  477. impl_->field_composer_.startRdata();
  478. rdata.toWire(impl_->field_composer_);
  479. impl_->field_composer_.endRdata();
  480. impl_->rdatas_.insert(rdatap);
  481. }
  482. void
  483. RdataEncoder::addSIGRdata(const Rdata& sig_rdata) {
  484. if (impl_->encode_spec_ == NULL) {
  485. isc_throw(InvalidOperation,
  486. "RdataEncoder::addSIGRdata performed before start");
  487. }
  488. // Ignore duplicate RRSIGs
  489. ConstRdataPtr rdatap = createRdata(RRType::RRSIG(), *impl_->current_class_,
  490. sig_rdata);
  491. if (impl_->rrsigs_.find(rdatap) != impl_->rrsigs_.end()) {
  492. return;
  493. }
  494. const size_t cur_pos = impl_->rrsig_buffer_.getLength();
  495. sig_rdata.toWire(impl_->rrsig_buffer_);
  496. const size_t rrsig_datalen = impl_->rrsig_buffer_.getLength() - cur_pos;
  497. if (rrsig_datalen > 0xffff) {
  498. isc_throw(RdataEncodingError, "RRSIG is too large: "
  499. << rrsig_datalen << " bytes");
  500. }
  501. impl_->rrsigs_.insert(rdatap);
  502. impl_->rrsig_lengths_.push_back(rrsig_datalen);
  503. }
  504. size_t
  505. RdataEncoder::getStorageLength() const {
  506. if (impl_->encode_spec_ == NULL) {
  507. isc_throw(InvalidOperation,
  508. "RdataEncoder::getStorageLength performed before start");
  509. }
  510. return (sizeof(uint16_t) * (impl_->old_varlen_count_ +
  511. impl_->old_sig_count_ +
  512. impl_->field_composer_.data_lengths_.size() +
  513. impl_->rrsig_lengths_.size()) +
  514. impl_->old_data_len_ + impl_->old_sig_len_ +
  515. impl_->rrsig_buffer_.getLength() +
  516. impl_->field_composer_.getLength());
  517. }
  518. void
  519. RdataEncoder::encode(void* buf, size_t buf_len) const {
  520. if (impl_->encode_spec_ == NULL) {
  521. isc_throw(InvalidOperation,
  522. "RdataEncoder::encode performed before start");
  523. }
  524. if (buf == NULL) {
  525. isc_throw(BadValue,
  526. "RdataEncoder::encode NULL buffer is given");
  527. }
  528. if (getStorageLength() > buf_len) {
  529. isc_throw(BadValue, "RdataEncoder::encode short buffer given");
  530. }
  531. uint8_t* const dp_beg = reinterpret_cast<uint8_t*>(buf);
  532. uint8_t* dp = dp_beg;
  533. uint16_t* lenp = reinterpret_cast<uint16_t*>(buf);
  534. // Encode list of lengths for variable length fields for old data (if any)
  535. const size_t old_varlen_fields_len =
  536. impl_->old_varlen_count_ * sizeof(uint16_t);
  537. std::memcpy(lenp, impl_->old_length_fields_, old_varlen_fields_len);
  538. lenp += impl_->old_varlen_count_;
  539. dp += old_varlen_fields_len;
  540. // Encode list of lengths for variable length fields (if any)
  541. if (!impl_->field_composer_.data_lengths_.empty()) {
  542. const size_t varlen_fields_len =
  543. impl_->field_composer_.data_lengths_.size() * sizeof(uint16_t);
  544. std::memcpy(lenp, &impl_->field_composer_.data_lengths_[0],
  545. varlen_fields_len);
  546. lenp += impl_->field_composer_.data_lengths_.size();
  547. dp += varlen_fields_len;
  548. }
  549. // Encode list of lengths for old RRSIGs (if any)
  550. const size_t old_rrsigs_len = impl_->old_sig_count_ * sizeof(uint16_t);
  551. std::memcpy(lenp, static_cast<const uint8_t*>(impl_->old_length_fields_) +
  552. old_varlen_fields_len, old_rrsigs_len);
  553. lenp += impl_->old_sig_count_;
  554. dp += old_rrsigs_len;
  555. // Encode list of lengths for RRSIGs (if any)
  556. if (!impl_->rrsig_lengths_.empty()) {
  557. const size_t rrsigs_len =
  558. impl_->rrsig_lengths_.size() * sizeof(uint16_t);
  559. std::memcpy(lenp, &impl_->rrsig_lengths_[0], rrsigs_len);
  560. dp += rrsigs_len;
  561. }
  562. // Encode main old RDATA, if any
  563. std::memcpy(dp, impl_->old_data_, impl_->old_data_len_);
  564. dp += impl_->old_data_len_;
  565. // Encode main RDATA
  566. std::memcpy(dp, impl_->field_composer_.getData(),
  567. impl_->field_composer_.getLength());
  568. dp += impl_->field_composer_.getLength();
  569. // Encode old RRSIGs, if any
  570. std::memcpy(dp, static_cast<const uint8_t*>(impl_->old_data_) +
  571. impl_->old_data_len_, impl_->old_sig_len_);
  572. dp += impl_->old_sig_len_;
  573. // Encode RRSIGs, if any
  574. std::memcpy(dp, impl_->rrsig_buffer_.getData(),
  575. impl_->rrsig_buffer_.getLength());
  576. dp += impl_->rrsig_buffer_.getLength();
  577. // The validation at the entrance must ensure this
  578. assert(buf_len >= dp - dp_beg);
  579. }
  580. RdataReader::RdataReader(const RRClass& rrclass, const RRType& rrtype,
  581. const void* data,
  582. size_t rdata_count, size_t sig_count,
  583. const NameAction& name_action,
  584. const DataAction& data_action) :
  585. name_action_(name_action),
  586. data_action_(data_action),
  587. spec_(getRdataEncodeSpec(rrclass, rrtype)),
  588. var_count_total_(spec_.varlen_count * rdata_count),
  589. sig_count_(sig_count),
  590. spec_count_(spec_.field_count * rdata_count),
  591. // The lengths are stored first
  592. lengths_(reinterpret_cast<const uint16_t*>(data)),
  593. // And the data just after all the lengths
  594. data_(reinterpret_cast<const uint8_t*>(data) +
  595. (var_count_total_ + sig_count_) * sizeof(uint16_t)),
  596. sigs_(NULL)
  597. {
  598. rewind();
  599. }
  600. void
  601. RdataReader::rewind() {
  602. data_pos_ = 0;
  603. spec_pos_ = 0;
  604. length_pos_ = 0;
  605. sig_data_pos_ = 0;
  606. sig_pos_ = 0;
  607. }
  608. RdataReader::Boundary
  609. RdataReader::nextInternal(const NameAction& name_action,
  610. const DataAction& data_action)
  611. {
  612. if (spec_pos_ < spec_count_) {
  613. const RdataFieldSpec& spec(spec_.fields[(spec_pos_++) %
  614. spec_.field_count]);
  615. if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
  616. const LabelSequence sequence(data_ + data_pos_);
  617. data_pos_ += sequence.getSerializedLength();
  618. name_action(sequence, spec.name_attributes);
  619. } else {
  620. const size_t length(spec.type == RdataFieldSpec::FIXEDLEN_DATA ?
  621. spec.fixeddata_len : lengths_[length_pos_++]);
  622. const uint8_t* const pos = data_ + data_pos_;
  623. data_pos_ += length;
  624. data_action(pos, length);
  625. }
  626. return (spec_pos_ % spec_.field_count == 0 ?
  627. RDATA_BOUNDARY : NO_BOUNDARY);
  628. } else {
  629. sigs_ = data_ + data_pos_;
  630. return (RRSET_BOUNDARY);
  631. }
  632. }
  633. RdataReader::Boundary
  634. RdataReader::next() {
  635. return (nextInternal(name_action_, data_action_));
  636. }
  637. void
  638. RdataReader::emptyNameAction(const LabelSequence&, RdataNameAttributes) {
  639. // Do nothing here.
  640. }
  641. void
  642. RdataReader::emptyDataAction(const void*, size_t) {
  643. // Do nothing here.
  644. }
  645. RdataReader::Boundary
  646. RdataReader::nextSig() {
  647. if (sig_pos_ < sig_count_) {
  648. if (sigs_ == NULL) {
  649. // We didn't find where the signatures start yet. We do it
  650. // by iterating the whole data and then returning the state
  651. // back.
  652. const size_t data_pos = data_pos_;
  653. const size_t spec_pos = spec_pos_;
  654. const size_t length_pos = length_pos_;
  655. // When the next() gets to the last item, it sets the sigs_
  656. while (nextInternal(emptyNameAction, emptyDataAction) !=
  657. RRSET_BOUNDARY) {}
  658. assert(sigs_ != NULL);
  659. // Return the state
  660. data_pos_ = data_pos;
  661. spec_pos_ = spec_pos;
  662. length_pos_ = length_pos;
  663. }
  664. // Extract the result
  665. const size_t length = lengths_[var_count_total_ + sig_pos_];
  666. const uint8_t* const pos = sigs_ + sig_data_pos_;
  667. // Move the position of iterator.
  668. sig_data_pos_ += lengths_[var_count_total_ + sig_pos_];
  669. ++sig_pos_;
  670. // Call the callback
  671. data_action_(pos, length);
  672. return (RDATA_BOUNDARY);
  673. } else {
  674. return (RRSET_BOUNDARY);
  675. }
  676. }
  677. size_t
  678. RdataReader::getSize() const {
  679. size_t storage_size = 0; // this will be the end result
  680. size_t data_pos = 0;
  681. size_t length_pos = 0;
  682. // Go over all data fields, adding their lengths to storage_size
  683. for (size_t spec_pos = 0; spec_pos < spec_count_; ++spec_pos) {
  684. const RdataFieldSpec& spec =
  685. spec_.fields[spec_pos % spec_.field_count];
  686. if (spec.type == RdataFieldSpec::DOMAIN_NAME) {
  687. const size_t seq_len =
  688. LabelSequence(data_ + data_pos).getSerializedLength();
  689. data_pos += seq_len;
  690. storage_size += seq_len;
  691. } else {
  692. const size_t data_len =
  693. (spec.type == RdataFieldSpec::FIXEDLEN_DATA ?
  694. spec.fixeddata_len : lengths_[length_pos++]);
  695. data_pos += data_len;
  696. storage_size += data_len;
  697. }
  698. }
  699. // Same for all RRSIG data
  700. for (size_t sig_pos = 0; sig_pos < sig_count_; ++sig_pos) {
  701. const size_t sig_data_len = lengths_[length_pos++];
  702. storage_size += sig_data_len;
  703. }
  704. // Finally, add the size for 16-bit length fields
  705. storage_size += (var_count_total_ * sizeof(uint16_t) +
  706. sig_count_ * sizeof(uint16_t));
  707. return (storage_size);
  708. }
  709. } // namespace memory
  710. } // namespace datasrc
  711. } // datasrc isc