summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/rrset.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/rrset.cc')
-rw-r--r--src/lib/dns/rrset.cc99
1 files changed, 75 insertions, 24 deletions
diff --git a/src/lib/dns/rrset.cc b/src/lib/dns/rrset.cc
index 7ea01d0ee5..8dfe884dac 100644
--- a/src/lib/dns/rrset.cc
+++ b/src/lib/dns/rrset.cc
@@ -17,6 +17,7 @@
#include <vector>
#include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
#include <util/buffer.h>
#include <dns/messagerenderer.h>
@@ -71,7 +72,10 @@ AbstractRRset::toText() const {
return (s);
}
-namespace {
+namespace { // unnamed namespace
+
+// FIXME: This method's code should somehow be unified with
+// BasicRRsetImpl::toWire() below to avoid duplication.
template <typename T>
inline unsigned int
rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit) {
@@ -124,7 +128,8 @@ rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit) {
return (n);
}
-}
+
+} // end of unnamed namespace
unsigned int
AbstractRRset::toWire(OutputBuffer& buffer) const {
@@ -164,6 +169,9 @@ public:
BasicRRsetImpl(const Name& name, const RRClass& rrclass,
const RRType& rrtype, const RRTTL& ttl) :
name_(name), rrclass_(rrclass), rrtype_(rrtype), ttl_(ttl) {}
+
+ unsigned int toWire(AbstractMessageRenderer& renderer, size_t limit) const;
+
Name name_;
RRClass rrclass_;
RRType rrtype_;
@@ -174,6 +182,58 @@ public:
vector<ConstRdataPtr> rdatalist_;
};
+// FIXME: This method's code should somehow be unified with
+// rrsetToWire() above to avoid duplication.
+unsigned int
+BasicRRsetImpl::toWire(AbstractMessageRenderer& renderer, size_t limit) const {
+ if (rdatalist_.empty()) {
+ // empty rrsets are only allowed for classes ANY and NONE
+ if (rrclass_ != RRClass::ANY() &&
+ rrclass_ != RRClass::NONE()) {
+ isc_throw(EmptyRRset, "toWire() is attempted for an empty RRset");
+ }
+
+ // For an empty RRset, write the name, type, class and TTL once,
+ // followed by empty rdata.
+ name_.toWire(renderer);
+ rrtype_.toWire(renderer);
+ rrclass_.toWire(renderer);
+ ttl_.toWire(renderer);
+ renderer.writeUint16(0);
+ // Still counts as 1 'rr'; it does show up in the message
+ return (1);
+ }
+
+ unsigned int n = 0;
+
+ // sort the set of Rdata based on rrset-order and sortlist, and possible
+ // other options. Details to be considered.
+ BOOST_FOREACH(const ConstRdataPtr& rdata, rdatalist_) {
+ const size_t pos0 = renderer.getLength();
+ assert(pos0 < 65536);
+
+ name_.toWire(renderer);
+ rrtype_.toWire(renderer);
+ rrclass_.toWire(renderer);
+ ttl_.toWire(renderer);
+
+ const size_t pos = renderer.getLength();
+ renderer.skip(sizeof(uint16_t)); // leave the space for RDLENGTH
+ rdata->toWire(renderer);
+ renderer.writeUint16At(renderer.getLength() - pos - sizeof(uint16_t),
+ pos);
+
+ if (limit > 0 && renderer.getLength() > limit) {
+ // truncation is needed
+ renderer.trim(renderer.getLength() - pos0);
+ return (n);
+ }
+ ++n;
+ }
+
+ return (n);
+}
+
BasicRRset::BasicRRset(const Name& name, const RRClass& rrclass,
const RRType& rrtype, const RRTTL& ttl)
{
@@ -220,11 +280,6 @@ BasicRRset::getTTL() const {
}
void
-BasicRRset::setName(const Name& name) {
- impl_->name_ = name;
-}
-
-void
BasicRRset::setTTL(const RRTTL& ttl) {
impl_->ttl_ = ttl;
}
@@ -241,7 +296,12 @@ BasicRRset::toWire(OutputBuffer& buffer) const {
unsigned int
BasicRRset::toWire(AbstractMessageRenderer& renderer) const {
- return (AbstractRRset::toWire(renderer));
+ const unsigned int rrs_written = impl_->toWire(renderer,
+ renderer.getLengthLimit());
+ if (impl_->rdatalist_.size() > rrs_written) {
+ renderer.setTruncated();
+ }
+ return (rrs_written);
}
RRset::RRset(const Name& name, const RRClass& rrclass,
@@ -264,15 +324,13 @@ RRset::getRRsigDataCount() const {
unsigned int
RRset::toWire(OutputBuffer& buffer) const {
- unsigned int rrs_written;
-
- rrs_written = rrsetToWire<OutputBuffer>(*this, buffer, 0);
+ unsigned int rrs_written = BasicRRset::toWire(buffer);
if (getRdataCount() > rrs_written) {
return (rrs_written);
}
if (rrsig_) {
- rrs_written += rrsetToWire<OutputBuffer>(*(rrsig_.get()), buffer, 0);
+ rrs_written += rrsig_->toWire(buffer);
}
return (rrs_written);
@@ -280,24 +338,17 @@ RRset::toWire(OutputBuffer& buffer) const {
unsigned int
RRset::toWire(AbstractMessageRenderer& renderer) const {
- unsigned int rrs_written;
-
- rrs_written =
- rrsetToWire<AbstractMessageRenderer>(*this, renderer,
- renderer.getLengthLimit());
+ unsigned int rrs_written = BasicRRset::toWire(renderer);
if (getRdataCount() > rrs_written) {
- renderer.setTruncated();
return (rrs_written);
}
if (rrsig_) {
- rrs_written +=
- rrsetToWire<AbstractMessageRenderer>(*(rrsig_.get()), renderer,
- renderer.getLengthLimit());
- }
+ rrs_written += rrsig_->toWire(renderer);
- if (getRdataCount() + getRRsigDataCount() > rrs_written) {
- renderer.setTruncated();
+ if (getRdataCount() + getRRsigDataCount() > rrs_written) {
+ renderer.setTruncated();
+ }
}
return (rrs_written);