summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/rdatafields.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/rdatafields.cc')
-rw-r--r--src/lib/dns/rdatafields.cc216
1 files changed, 0 insertions, 216 deletions
diff --git a/src/lib/dns/rdatafields.cc b/src/lib/dns/rdatafields.cc
deleted file mode 100644
index e02ec8ff87..0000000000
--- a/src/lib/dns/rdatafields.cc
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (C) 2010-2015,2017 Internet Systems Consortium, Inc. ("ISC")
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include <config.h>
-
-#include <stdint.h>
-
-#include <cassert>
-#include <vector>
-
-#include <exceptions/exceptions.h>
-
-#include <util/buffer.h>
-#include <dns/messagerenderer.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdatafields.h>
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::dns::rdata;
-using isc::util::OutputBuffer;
-using isc::util::InputBuffer;
-
-namespace isc {
-namespace dns {
-namespace rdata {
-
-/// This is a helper class for \c RdataFields.
-///
-/// It manages a local storage for the data when \c RdataFields is constructed
-/// from an \c Rdata.
-/// To minimize construction overhead in the other case, an instance of
-/// this class is instantiated only when necessary - we don't need the vectors
-/// when only rendering.
-struct RdataFields::RdataFieldsDetail {
- RdataFieldsDetail(const vector<FieldSpec>& fields,
- const uint8_t* data, size_t data_length) :
- allocated_fields_(fields),
- allocated_data_(data, data + data_length)
- {}
- const vector<FieldSpec> allocated_fields_;
- const vector<uint8_t> allocated_data_;
-};
-
-namespace {
-// This class is used to divide the content of RDATA into \c RdataField
-// fields via message rendering logic.
-// The idea is to identify domain name fields in the writeName() method,
-// and determine whether they are compressible using the "compress"
-// parameter.
-// Other types of data are simply copied into the internal buffer, and
-// consecutive such fields are combined into a single \c RdataField field.
-//
-// Technically, this use of inheritance may be considered a violation of
-// Liskov Substitution Principle in that it doesn't actually compress domain
-// names, and some of the methods are not expected to be used.
-// In fact, skip() or trim() may not be make much sense in this context.
-// Nevertheless we keep this idea at the moment. Since the usage is limited
-// (it's only used within this file, and only used with \c Rdata variants),
-// it's hopefully an acceptable practice.
-class RdataFieldComposer : public AbstractMessageRenderer {
-public:
- RdataFieldComposer() :
- truncated_(false), length_limit_(65535),
- mode_(CASE_INSENSITIVE), last_data_pos_(0)
- {}
- virtual ~RdataFieldComposer() {}
- virtual bool isTruncated() const { return (truncated_); }
- virtual size_t getLengthLimit() const { return (length_limit_); }
- virtual CompressMode getCompressMode() const { return (mode_); }
- virtual void setTruncated() { truncated_ = true; }
- virtual void setLengthLimit(size_t len) { length_limit_ = len; }
- virtual void setCompressMode(CompressMode mode) { mode_ = mode; }
- virtual void writeName(const LabelSequence&, bool) {}
- virtual void writeName(const Name& name, bool compress) {
- extendData();
- const RdataFields::Type field_type =
- compress ? RdataFields::COMPRESSIBLE_NAME :
- RdataFields::INCOMPRESSIBLE_NAME;
- // TODO: When we get rid of need for getBuffer, we can output the name
- // to a buffer and then write the buffer inside
- name.toWire(getBuffer());
- fields_.push_back(RdataFields::FieldSpec(field_type,
- name.getLength()));
- last_data_pos_ = getLength();
- }
-
- virtual void clear() {
- isc_throw(Unexpected, "unexpected clear() for RdataFieldComposer");
- }
- bool truncated_;
- size_t length_limit_;
- CompressMode mode_;
- vector<RdataFields::FieldSpec> fields_;
- vector<RdataFields::FieldSpec>& getFields() {
- extendData();
- return (fields_);
- }
- // We use generic write* methods, with the exception of writeName.
- // So new data can arrive without us knowing it, this considers all new
- // data to be just data and extends the fields to take it into account.
- size_t last_data_pos_;
- void extendData() {
- // No news, return to work
- if (getLength() == last_data_pos_) {
- return;
- }
- // The new bytes are just ordinary uninteresting data
- if (fields_.empty() || fields_.back().type != RdataFields::DATA) {
- fields_.push_back(RdataFields::FieldSpec(RdataFields::DATA, 0));
- }
- // We added this much data from last time
- fields_.back().len += getLength() - last_data_pos_;
- last_data_pos_ = getLength();
- }
-};
-
-}
-
-RdataFields::RdataFields(const Rdata& rdata) {
- RdataFieldComposer field_composer;
- rdata.toWire(field_composer);
- nfields_ = field_composer.getFields().size();
- data_length_ = field_composer.getLength();
- if (nfields_ > 0) {
- assert(data_length_ > 0);
- detail_ = new RdataFieldsDetail(field_composer.getFields(),
- static_cast<const uint8_t*>
- (field_composer.getData()),
- field_composer.getLength());
- data_ = &detail_->allocated_data_[0];
- fields_ = &detail_->allocated_fields_[0];
- } else {
- assert(data_length_ == 0);
- detail_ = NULL;
- data_ = NULL;
- fields_ = NULL;
- }
-}
-
-RdataFields::RdataFields(const void* fields, const unsigned int fields_length,
- const void* data, const size_t data_length) :
- fields_(static_cast<const FieldSpec*>(fields)),
- nfields_(fields_length / sizeof(*fields_)),
- data_(static_cast<const uint8_t*>(data)),
- data_length_(data_length),
- detail_(NULL)
-{
- if ((fields_ == NULL && nfields_ > 0) ||
- (fields_ != NULL && nfields_ == 0)) {
- isc_throw(InvalidParameter,
- "Inconsistent parameters for RdataFields: fields_length ("
- << fields_length << ") and fields conflict each other");
- }
- if ((data_ == NULL && data_length_ > 0) ||
- (data_ != NULL && data_length_ == 0)) {
- isc_throw(InvalidParameter,
- "Inconsistent parameters for RdataFields: data length ("
- << data_length_ << ") and data conflict each other");
- }
-
- size_t total_length = 0;
- for (unsigned int i = 0; i < nfields_; ++i) {
- total_length += fields_[i].len;
- }
- if (total_length != data_length_) {
- isc_throw(InvalidParameter,
- "Inconsistent parameters for RdataFields: "
- "fields len: " << total_length <<
- " data len: " << data_length_);
- }
-}
-
-RdataFields::~RdataFields() {
- delete detail_;
-}
-
-RdataFields::FieldSpec
-RdataFields::getFieldSpec(const unsigned int field_id) const {
- if (field_id >= nfields_) {
- isc_throw(OutOfRange, "Rdata field ID is out of range: " << field_id);
- }
- return (fields_[field_id]);
-}
-
-void
-RdataFields::toWire(AbstractMessageRenderer& renderer) const {
- size_t offset = 0;
-
- for (unsigned int i = 0; i < nfields_; ++i) {
- if (fields_[i].type == DATA) {
- renderer.writeData(data_ + offset, fields_[i].len);
- } else {
- // XXX: this is inefficient. Even if it's quite likely the
- // data is a valid wire representation of a name we parse
- // it to construct the Name object in the generic mode.
- // This should be improved in a future version.
- InputBuffer buffer(data_ + offset, fields_[i].len);
- renderer.writeName(Name(buffer),
- fields_[i].type == COMPRESSIBLE_NAME);
- }
- offset += fields_[i].len;
- }
-}
-
-void
-RdataFields::toWire(OutputBuffer& buffer) const {
- buffer.writeData(data_, data_length_);
-}
-} // end of namespace rdata
-} // end of namespace dns
-} // end of namespace isc