diff options
Diffstat (limited to 'src/lib/dns/rdatafields.cc')
-rw-r--r-- | src/lib/dns/rdatafields.cc | 216 |
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 |