util::OutputBuffer rrsig_buffer_;
vector<uint16_t> rrsig_lengths_;
+ // Placeholder for the RR class and type of the current session;
+ // initially null, and will be (re)set at the beginning of each session.
boost::optional<RRClass> current_class_;
boost::optional<RRType> current_type_;
+ // Parameters corresponding to the previously encoded data in the
+ // merge mode.
size_t old_varlen_count_;
size_t old_sig_count_;
size_t old_data_len_;
}
namespace {
+// Helper callbacks used in the merge mode of start(). These re-construct
+// each RDATA and RRSIG in the wire-format, counting the total length of the
+// encoded data fields.
void
decodeName(const LabelSequence& name_labels, RdataNameAttributes,
util::OutputBuffer* buffer, size_t* total_len)
{
impl_->start(rrclass, rrtype);
+ // Identify start points of various fields of the encoded data and
+ // remember it in class variables.
const uint8_t* cp = static_cast<const uint8_t*>(old_data);
impl_->old_varlen_count_ =
impl_->encode_spec_->varlen_count * old_rdata_count;
impl_->old_data_ = cp;
impl_->old_sig_count_ = old_sig_count;
+ // Re-construct RDATAs and RRSIGs in the form of Rdata objects, and
+ // keep them in rdatas_ and rrsigs_ so we can detect and ignore duplicate
+ // data with the existing one later. We'll also figure out the lengths
+ // of the RDATA and RRSIG part of the data by iterating over the data
+ // fields.
size_t total_len = 0;
RdataReader reader(rrclass, rrtype, old_data, old_rdata_count,
old_sig_count,
/// \brief Start the encoding session in the merge mode.
///
- /// TBD for details.
+ /// This method is similar to the other version, but begins with a copy
+ /// of previously encoded data and merges Rdata and RRSIGs into it
+ /// that will be given via subsequent calls to \c addRdata() and
+ /// \c addSIGRdata(). \c old_data, \c old_rdata_count, and
+ /// \c old_sig_count correspond to parameters given to the
+ /// \c RdataReader constructor, and must have valid values for encoded
+ /// data by this class for the same \c rrclass and \c rrtype.
+ /// It's the caller's responsibility to ensure this condition; if it's
+ /// not met, the behavior will be undefined.
+ ///
+ /// The caller must also ensure that previously encoded data (pointed
+ /// to by \c old_data) will be valid and intact throughout the encoding
+ /// session started by this method.
+ ///
+ /// \param rrclass The RR class of RDATA to be encoded in the session.
+ /// \param rrtype The RR type of RDATA to be encoded in the session.
+ /// \param old_data Point to previously encoded data for the same RR
+ /// class and type.
+ /// \param old_rdata_count The number of RDATAs stored in \c old_data.
+ /// \param old_sig_count The number of RRSIGs stored in \c old_data.
void start(dns::RRClass rrclass, dns::RRType rrtype,
- const void* old_data, size_t rdata_count, size_t sig_count);
+ const void* old_data, size_t old_rdata_count,
+ size_t old_sig_count);
/// \brief Add an RDATA for encoding.
///
struct MergeTestData {
const char* const type_txt; // "AAAA", "NS", etc
- const char* const rdata_txt1;
- const char* const rdata_txt2;
- const char* const rdata_txt3;
+ const char* const rdata_txt1; // RDATA possibly used for old data
+ const char* const rdata_txt2; // RDATA possibly used for new data
+ const char* const rdata_txt3; // optional data to check with multi-RDATAs
const size_t varlen_fields; // number of variable-len fields in RDATA
} merge_test_data[] = {
// For test with fixed-length RDATA