Commit d267c051 authored by Dima Volodin's avatar Dima Volodin
Browse files

[1144] Merge branch 'trac1144'

parents eb4917ae 33c0d213
292. [func] dvv
Implement the DLV rrtype according to RFC4431.
(Trac #1144, git TBD)
291. [func] naokikambe
Statistics items are specified by each module's spec file.
Stats module can read these through the config manager. Stats
......
......@@ -24,6 +24,9 @@ EXTRA_DIST += rdata/generic/cname_5.h
EXTRA_DIST += rdata/generic/detail/nsec_bitmap.cc
EXTRA_DIST += rdata/generic/detail/nsec_bitmap.h
EXTRA_DIST += rdata/generic/detail/txt_like.h
EXTRA_DIST += rdata/generic/detail/ds_like.h
EXTRA_DIST += rdata/generic/dlv_32769.cc
EXTRA_DIST += rdata/generic/dlv_32769.h
EXTRA_DIST += rdata/generic/dname_39.cc
EXTRA_DIST += rdata/generic/dname_39.h
EXTRA_DIST += rdata/generic/dnskey_48.cc
......@@ -107,6 +110,7 @@ libdns___la_SOURCES += character_string.h character_string.cc
libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.h
libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.cc
libdns___la_SOURCES += rdata/generic/detail/txt_like.h
libdns___la_SOURCES += rdata/generic/detail/ds_like.h
libdns___la_CPPFLAGS = $(AM_CPPFLAGS)
# Most applications of libdns++ will only implicitly rely on libcryptolink,
......
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __DS_LIKE_H
#define __DS_LIKE_H 1
#include <stdint.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <exceptions/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
namespace isc {
namespace dns {
namespace rdata {
namespace generic {
namespace detail {
/// \brief \c rdata::DSLikeImpl class represents the DS-like RDATA for DS
/// and DLV types.
///
/// This class implements the basic interfaces inherited by the DS and DLV
/// classes from the abstract \c rdata::Rdata class, and provides trivial
/// accessors to DS-like RDATA.
template <class Type, uint16_t typeCode> class DSLikeImpl {
// Common sequence of toWire() operations used for the two versions of
// toWire().
template <typename Output>
void
toWireCommon(Output& output) const {
output.writeUint16(tag_);
output.writeUint8(algorithm_);
output.writeUint8(digest_type_);
output.writeData(&digest_[0], digest_.size());
}
public:
/// \brief Constructor from string.
///
/// <b>Exceptions</b>
///
/// \c InvalidRdataText is thrown if the method cannot process the
/// parameter data for any of the number of reasons.
DSLikeImpl(const std::string& ds_str) {
std::istringstream iss(ds_str);
// peekc should be of iss's char_type for isspace to work
std::istringstream::char_type peekc;
std::stringbuf digestbuf;
uint32_t tag, algorithm, digest_type;
iss >> tag >> algorithm >> digest_type;
if (iss.bad() || iss.fail()) {
isc_throw(InvalidRdataText,
"Invalid " << RRType(typeCode) << " text");
}
if (tag > 0xffff) {
isc_throw(InvalidRdataText,
RRType(typeCode) << " tag out of range");
}
if (algorithm > 0xff) {
isc_throw(InvalidRdataText,
RRType(typeCode) << " algorithm out of range");
}
if (digest_type > 0xff) {
isc_throw(InvalidRdataText,
RRType(typeCode) << " digest type out of range");
}
iss.read(&peekc, 1);
if (!iss.good() || !isspace(peekc, iss.getloc())) {
isc_throw(InvalidRdataText,
RRType(typeCode) << " presentation format error");
}
iss >> &digestbuf;
tag_ = tag;
algorithm_ = algorithm;
digest_type_ = digest_type;
decodeHex(digestbuf.str(), digest_);
}
/// \brief Constructor from wire-format data.
///
/// \param buffer A buffer storing the wire format data.
/// \param rdata_len The length of the RDATA in bytes, normally expected
/// to be the value of the RDLENGTH field of the corresponding RR.
///
/// <b>Exceptions</b>
///
/// \c InvalidRdataLength is thrown if the input data is too short for the
/// type.
DSLikeImpl(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len < 4) {
isc_throw(InvalidRdataLength, RRType(typeCode) << " too short");
}
tag_ = buffer.readUint16();
algorithm_ = buffer.readUint8();
digest_type_ = buffer.readUint8();
rdata_len -= 4;
digest_.resize(rdata_len);
buffer.readData(&digest_[0], rdata_len);
}
/// \brief The copy constructor.
///
/// Trivial for now, we could've used the default one.
DSLikeImpl(const DSLikeImpl& source) {
digest_ = source.digest_;
tag_ = source.tag_;
algorithm_ = source.algorithm_;
digest_type_ = source.digest_type_;
}
/// \brief Convert the DS-like data to a string.
///
/// \return A \c string object that represents the DS-like data.
std::string
toText() const {
using namespace boost;
return (lexical_cast<string>(static_cast<int>(tag_)) +
" " + lexical_cast<string>(static_cast<int>(algorithm_)) +
" " + lexical_cast<string>(static_cast<int>(digest_type_)) +
" " + encodeHex(digest_));
}
/// \brief Render the DS-like data in the wire format to an OutputBuffer
/// object.
///
/// \param buffer An output buffer to store the wire data.
void
toWire(OutputBuffer& buffer) const {
toWireCommon(buffer);
}
/// \brief Render the DS-like data in the wire format to an
/// AbstractMessageRenderer object.
///
/// \param renderer A renderer object to send the wire data to.
void
toWire(AbstractMessageRenderer& renderer) const {
toWireCommon(renderer);
}
/// \brief Compare two instances of DS-like RDATA.
///
/// It is up to the caller to make sure that \c other is an object of the
/// same \c DSLikeImpl class.
///
/// \param other the right-hand operand to compare against.
/// \return < 0 if \c this would be sorted before \c other.
/// \return 0 if \c this is identical to \c other in terms of sorting
/// order.
/// \return > 0 if \c this would be sorted after \c other.
int
compare(const DSLikeImpl& other_ds) const {
if (tag_ != other_ds.tag_) {
return (tag_ < other_ds.tag_ ? -1 : 1);
}
if (algorithm_ != other_ds.algorithm_) {
return (algorithm_ < other_ds.algorithm_ ? -1 : 1);
}
if (digest_type_ != other_ds.digest_type_) {
return (digest_type_ < other_ds.digest_type_ ? -1 : 1);
}
size_t this_len = digest_.size();
size_t other_len = other_ds.digest_.size();
size_t cmplen = min(this_len, other_len);
int cmp = memcmp(&digest_[0], &other_ds.digest_[0], cmplen);
if (cmp != 0) {
return (cmp);
} else {
return ((this_len == other_len)
? 0 : (this_len < other_len) ? -1 : 1);
}
}
/// \brief Accessors
uint16_t
getTag() const {
return (tag_);
}
private:
// straightforward representation of DS RDATA fields
uint16_t tag_;
uint8_t algorithm_;
uint8_t digest_type_;
std::vector<uint8_t> digest_;
};
}
}
}
}
}
#endif // __DS_LIKE_H
// Local Variables:
// mode: c++
// End:
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <string>
#include <util/buffer.h>
#include <util/encode/hex.h>
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdata/generic/detail/ds_like.h>
using namespace std;
using namespace isc::util;
using namespace isc::util::encode;
using namespace isc::dns::rdata::generic::detail;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
/// \brief Constructor from string.
///
/// A copy of the implementation object is allocated and constructed.
DLV::DLV(const string& ds_str) :
impl_(new DLVImpl(ds_str))
{}
/// \brief Constructor from wire-format data.
///
/// A copy of the implementation object is allocated and constructed.
DLV::DLV(InputBuffer& buffer, size_t rdata_len) :
impl_(new DLVImpl(buffer, rdata_len))
{}
/// \brief Copy constructor
///
/// A copy of the implementation object is allocated and constructed.
DLV::DLV(const DLV& source) :
Rdata(), impl_(new DLVImpl(*source.impl_))
{}
/// \brief Assignment operator
///
/// PIMPL-induced logic
DLV&
DLV::operator=(const DLV& source) {
if (impl_ == source.impl_) {
return (*this);
}
DLVImpl* newimpl = new DLVImpl(*source.impl_);
delete impl_;
impl_ = newimpl;
return (*this);
}
/// \brief Destructor
///
/// Deallocates an internal resource.
DLV::~DLV() {
delete impl_;
}
/// \brief Convert the \c DLV to a string.
///
/// A pass-thru to the corresponding implementation method.
string
DLV::toText() const {
return (impl_->toText());
}
/// \brief Render the \c DLV in the wire format to a OutputBuffer object
///
/// A pass-thru to the corresponding implementation method.
void
DLV::toWire(OutputBuffer& buffer) const {
impl_->toWire(buffer);
}
/// \brief Render the \c DLV in the wire format to a AbstractMessageRenderer
/// object
///
/// A pass-thru to the corresponding implementation method.
void
DLV::toWire(AbstractMessageRenderer& renderer) const {
impl_->toWire(renderer);
}
/// \brief Compare two instances of \c DLV RDATA.
///
/// The type check is performed here. Otherwise, a pass-thru to the
/// corresponding implementation method.
int
DLV::compare(const Rdata& other) const {
const DLV& other_ds = dynamic_cast<const DLV&>(other);
return (impl_->compare(*other_ds.impl_));
}
/// \brief Tag accessor
uint16_t
DLV::getTag() const {
return (impl_->getTag());
}
// END_RDATA_NAMESPACE
// END_ISC_NAMESPACE
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// BEGIN_HEADER_GUARD
#include <stdint.h>
#include <string>
#include <dns/name.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
#include <dns/rdata.h>
// BEGIN_ISC_NAMESPACE
// BEGIN_COMMON_DECLARATIONS
// END_COMMON_DECLARATIONS
// BEGIN_RDATA_NAMESPACE
namespace detail {
template <class Type, uint16_t typeCode> class DSLikeImpl;
}
/// \brief \c rdata::generic::DLV class represents the DLV RDATA as defined in
/// RFC4431.
///
/// This class implements the basic interfaces inherited from the abstract
/// \c rdata::Rdata class, and provides trivial accessors specific to the
/// DLV RDATA.
class DLV : public Rdata {
public:
// BEGIN_COMMON_MEMBERS
// END_COMMON_MEMBERS
/// \brief Assignment operator.
///
/// It internally allocates a resource, and if it fails a corresponding
/// standard exception will be thrown.
/// This operator never throws an exception otherwise.
///
/// This operator provides the strong exception guarantee: When an
/// exception is thrown the content of the assignment target will be
/// intact.
DLV& operator=(const DLV& source);
/// \brief The destructor.
~DLV();
/// \brief Return the value of the Tag field.
///
/// This method never throws an exception.
uint16_t getTag() const;
private:
typedef detail::DSLikeImpl<DLV, 32769> DLVImpl;
DLVImpl* impl_;
};
// END_RDATA_NAMESPACE
// END_ISC_NAMESPACE
// END_HEADER_GUARD
// Local Variables:
// mode: c++
// End:
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -12,87 +12,32 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <util/buffer.h>
#include <util/encode/hex.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <stdio.h>
#include <time.h>
#include <dns/rdata/generic/detail/ds_like.h>
using namespace std;
using namespace isc::util;
using namespace isc::util::encode;
using namespace isc::dns::rdata::generic::detail;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
struct DSImpl {
// straightforward representation of DS RDATA fields
DSImpl(uint16_t tag, uint8_t algorithm, uint8_t digest_type,
const vector<uint8_t>& digest) :
tag_(tag), algorithm_(algorithm), digest_type_(digest_type),
digest_(digest)
{}
uint16_t tag_;
uint8_t algorithm_;
uint8_t digest_type_;
const vector<uint8_t> digest_;
};
DS::DS(const string& ds_str) :
impl_(NULL)
{
istringstream iss(ds_str);
unsigned int tag, algorithm, digest_type;
stringbuf digestbuf;
iss >> tag >> algorithm >> digest_type >> &digestbuf;
if (iss.bad() || iss.fail()) {
isc_throw(InvalidRdataText, "Invalid DS text");
}
if (tag > 0xffff) {
isc_throw(InvalidRdataText, "DS tag out of range");
}
if (algorithm > 0xff) {
isc_throw(InvalidRdataText, "DS algorithm out of range");
}
if (digest_type > 0xff) {
isc_throw(InvalidRdataText, "DS digest type out of range");
}
vector<uint8_t> digest;
decodeHex(digestbuf.str(), digest);
impl_ = new DSImpl(tag, algorithm, digest_type, digest);
}
DS::DS(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len < 4) {
isc_throw(InvalidRdataLength, "DS too short");
}
uint16_t tag = buffer.readUint16();
uint16_t algorithm = buffer.readUint8();
uint16_t digest_type = buffer.readUint8();
rdata_len -= 4;
vector<uint8_t> digest(rdata_len);
buffer.readData(&digest[0], rdata_len);
impl_(new DSImpl(ds_str))
{}
impl_ = new DSImpl(tag, algorithm, digest_type, digest);
}
DS::DS(InputBuffer& buffer, size_t rdata_len) :
impl_(new DSImpl(buffer, rdata_len))
{}
DS::DS(const DS& source) :
Rdata(), impl_(new DSImpl(*source.impl_))
......@@ -117,57 +62,29 @@ DS::~DS() {
string
DS::toText() const {
using namespace boost;
return (lexical_cast<string>(static_cast<int>(impl_->tag_)) +
" " + lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
" " + lexical_cast<string>(static_cast<int>(impl_->digest_type_)) +
" " + encodeHex(impl_->digest_));
return (impl_->toText());
}
void
DS::toWire(OutputBuffer& buffer) const {
buffer.writeUint16(impl_->tag_);
buffer.writeUint8(impl_->algorithm_);
buffer.writeUint8(impl_->digest_type_);
buffer.writeData(&impl_->digest_[0], impl_->digest_.size());
impl_->toWire(buffer);
}
void
DS::toWire(AbstractMessageRenderer& renderer) const {
renderer.writeUint16(impl_->tag_);
renderer.writeUint8(impl_->algorithm_);
renderer.writeUint8(impl_->digest_type_);
renderer.writeData(&impl_->digest_[0], impl_->digest_.size());
impl_->toWire(renderer);
}
int
DS::compare(const Rdata& other) const {
const DS& other_ds = dynamic_cast<const DS&>(other);
if (impl_->tag_ != other_ds.impl_->tag_) {
return (impl_->tag_ < other_ds.impl_->tag_ ? -1 : 1);
}
if (impl_->algorithm_ != other_ds.impl_->algorithm_) {
return (impl_->algorithm_ < other_ds.impl_->algorithm_ ? -1 : 1);
}
if (impl_->digest_type_ != other_ds.impl_->digest_type_) {
return (impl_->digest_type_ < other_ds.impl_->digest_type_ ? -1 : 1);
}
size_t this_len = impl_->digest_.size();
size_t other_len = other_ds.impl_->digest_.size();
size_t cmplen = min(this_len, other_len);
int cmp = memcmp(&impl_->digest_[0], &other_ds.impl_->digest_[0], cmplen);
if (cmp != 0) {
return (cmp);
} else {
return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
}
return (impl_->compare(*other_ds.impl_));
}
uint16_t
DS::getTag() const {
return (impl_->tag_);
return (impl_->getTag());
}
// END_RDATA_NAMESPACE
......