LCOV - code coverage report
Current view: top level - dns - rrset.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 99 100 99.0 %
Date: 2012-05-15 Functions: 32 34 94.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 91 162 56.2 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #include <algorithm>
      16                 :            : #include <string>
      17                 :            : #include <vector>
      18                 :            : 
      19                 :            : #include <boost/shared_ptr.hpp>
      20                 :            : 
      21                 :            : #include <util/buffer.h>
      22                 :            : #include <dns/messagerenderer.h>
      23                 :            : #include <dns/name.h>
      24                 :            : #include <dns/rrclass.h>
      25                 :            : #include <dns/rrtype.h>
      26                 :            : #include <dns/rrttl.h>
      27                 :            : #include <dns/rrset.h>
      28                 :            : 
      29                 :            : using namespace std;
      30                 :            : using namespace isc::dns;
      31                 :            : using namespace isc::util;
      32                 :            : using namespace isc::dns::rdata;
      33                 :            : 
      34                 :            : namespace isc {
      35                 :            : namespace dns {
      36                 :            : void
      37                 :       8965 : AbstractRRset::addRdata(const Rdata& rdata) {
      38         [ +  - ]:      17928 :     addRdata(createRdata(getType(), getClass(), rdata));
      39                 :       8963 : }
      40                 :            : 
      41                 :            : string
      42                 :       4305 : AbstractRRset::toText() const {
      43                 :          3 :     string s;
      44         [ +  - ]:       4305 :     RdataIteratorPtr it = getRdataIterator();
      45                 :            : 
      46 [ +  - ][ +  + ]:       4305 :     if (it->isLast()) {
      47 [ +  - ][ +  - ]:       4308 :         isc_throw(EmptyRRset, "ToText() is attempted for an empty RRset");
      48                 :            :     }
      49                 :            : 
      50         [ +  + ]:       4859 :     do {
      51 [ +  - ][ +  - ]:      14577 :         s += getName().toText() + " " + getTTL().toText() + " " +
      52 [ +  - ][ +  - ]:      19436 :             getClass().toText() + " " + getType().toText() + " " +
      53 [ +  - ][ +  - ]:      34013 :             it->getCurrent().toText() + "\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
      54         [ +  - ]:       4859 :         it->next();
      55         [ +  - ]:       4859 :     } while (!it->isLast());
      56                 :            : 
      57                 :       4302 :     return (s);
      58                 :            : }   
      59                 :            : 
      60                 :            : namespace {
      61                 :            : template <typename T>
      62                 :            : inline unsigned int
      63                 :        674 : rrsetToWire(const AbstractRRset& rrset, T& output, const size_t limit) {
      64                 :        674 :     unsigned int n = 0;
      65                 :        674 :     RdataIteratorPtr it = rrset.getRdataIterator();
      66                 :            : 
      67         [ +  - ]:        674 :     if (it->isLast()) {
           [ +  +  +  - ]
                 [ +  + ]
      68 [ +  - ][ +  - ]:        681 :         isc_throw(EmptyRRset, "ToWire() is attempted for an empty RRset");
         [ +  - ][ +  - ]
      69                 :            :     }
      70                 :            : 
      71                 :            :     // sort the set of Rdata based on rrset-order and sortlist, and possible
      72                 :            :     // other options.  Details to be considered.
      73 [ +  + ][ +  + ]:        696 :     do {
      74                 :        708 :         const size_t pos0 = output.getLength();
      75 [ -  + ][ -  + ]:        708 :         assert(pos0 < 65536);
      76                 :            : 
      77 [ +  - ][ +  - ]:        708 :         rrset.getName().toWire(output);
         [ +  - ][ +  - ]
      78 [ +  - ][ +  - ]:        708 :         rrset.getType().toWire(output);
         [ +  - ][ +  - ]
      79 [ +  - ][ +  - ]:        708 :         rrset.getClass().toWire(output);
         [ +  - ][ +  - ]
      80 [ +  - ][ +  - ]:        708 :         rrset.getTTL().toWire(output);
         [ +  - ][ +  - ]
      81                 :            : 
      82                 :        708 :         const size_t pos = output.getLength();
      83         [ +  - ]:         68 :         output.skip(sizeof(uint16_t)); // leave the space for RDLENGTH
      84 [ +  - ][ +  - ]:        708 :         it->getCurrent().toWire(output);
         [ +  - ][ +  - ]
      85         [ +  - ]:         68 :         output.writeUint16At(output.getLength() - pos - sizeof(uint16_t), pos);
      86                 :            : 
      87 [ +  - ][ +  + ]:        708 :         if (limit > 0 && output.getLength() > limit) {
         [ +  + ][ -  + ]
         [ #  # ][ -  + ]
      88                 :            :             // truncation is needed
      89         [ #  # ]:          0 :             output.trim(output.getLength() - pos0);
      90                 :            :             return (n);
      91                 :            :         }
      92                 :            : 
      93 [ +  - ][ +  - ]:        696 :         it->next();
      94 [ +  - ][ +  - ]:        696 :         ++n;
      95                 :            :     } while (!it->isLast());
      96                 :            : 
      97                 :            :     return (n);
      98                 :            : }
      99                 :            : }
     100                 :            : 
     101                 :            : unsigned int
     102                 :         68 : AbstractRRset::toWire(OutputBuffer& buffer) const {
     103                 :         68 :     return (rrsetToWire<OutputBuffer>(*this, buffer, 0));
     104                 :            : }
     105                 :            : 
     106                 :            : unsigned int
     107                 :        606 : AbstractRRset::toWire(AbstractMessageRenderer& renderer) const {
     108                 :            :     const unsigned int rrs_written = rrsetToWire<AbstractMessageRenderer>(
     109                 :        606 :         *this, renderer, renderer.getLengthLimit());
     110         [ +  + ]:        602 :     if (getRdataCount() > rrs_written) {
     111                 :         12 :         renderer.setTruncated();
     112                 :            :     }
     113                 :        602 :     return (rrs_written);
     114                 :            : }
     115                 :            : 
     116                 :            : bool
     117                 :        389 : AbstractRRset::isSameKind(const AbstractRRset& other) const {
     118                 :            :   // Compare classes last as they're likely to be identical. Compare
     119                 :            :   // names late in the list too, as these are expensive. So we compare
     120                 :            :   // types first, names second and classes last.
     121                 :        389 :   return (getType() == other.getType() &&
     122                 :         81 :           getName() == other.getName() &&
     123   [ +  +  +  + ]:        470 :           getClass() == other.getClass());
                 [ +  + ]
     124                 :            : }
     125                 :            : 
     126                 :            : ostream&
     127                 :        432 : operator<<(ostream& os, const AbstractRRset& rrset) {
     128         [ +  - ]:        432 :     os << rrset.toText();
     129                 :        432 :     return (os);
     130                 :            : }
     131                 :            : 
     132                 :            : /// \brief This encapsulates the actual implementation of the \c BasicRRset
     133                 :            : /// class.  It's hidden from applications.
     134                 :      24688 : class BasicRRsetImpl {
     135                 :            : public:
     136                 :            :     BasicRRsetImpl(const Name& name, const RRClass& rrclass,
     137                 :            :                    const RRType& rrtype, const RRTTL& ttl) :
     138                 :      49388 :         name_(name), rrclass_(rrclass), rrtype_(rrtype), ttl_(ttl) {}
     139                 :            :     Name name_;
     140                 :            :     RRClass rrclass_;
     141                 :            :     RRType rrtype_;
     142                 :            :     RRTTL ttl_;
     143                 :            :     // XXX: "list" is not a good name: It in fact isn't a list; more conceptual
     144                 :            :     // name than a data structure name is generally better.  But since this
     145                 :            :     // is only used in the internal implementation we'll live with it.
     146                 :            :     vector<ConstRdataPtr> rdatalist_;
     147                 :            : };
     148                 :            : 
     149                 :      24694 : BasicRRset::BasicRRset(const Name& name, const RRClass& rrclass,
     150                 :      49388 :                        const RRType& rrtype, const RRTTL& ttl)
     151                 :            : {
     152         [ +  - ]:      24694 :     impl_ = new BasicRRsetImpl(name, rrclass, rrtype, ttl);
     153                 :      24694 : }
     154                 :            : 
     155                 :      24688 : BasicRRset::~BasicRRset() {
     156         [ +  - ]:      49376 :     delete impl_;
     157                 :      24688 : }
     158                 :            : 
     159                 :            : void
     160                 :      30652 : BasicRRset::addRdata(ConstRdataPtr rdata) {
     161                 :      30652 :     impl_->rdatalist_.push_back(rdata);
     162                 :      30652 : }
     163                 :            : 
     164                 :            : void
     165                 :       8965 : BasicRRset::addRdata(const Rdata& rdata) {
     166                 :       8965 :     AbstractRRset::addRdata(rdata);
     167                 :       8963 : }
     168                 :            : 
     169                 :            : unsigned int
     170                 :       6928 : BasicRRset::getRdataCount() const {
     171                 :       6928 :     return (impl_->rdatalist_.size());
     172                 :            : }
     173                 :            : 
     174                 :            : const Name&
     175                 :      53623 : BasicRRset::getName() const {
     176                 :      53623 :     return (impl_->name_);
     177                 :            : }
     178                 :            : 
     179                 :            : const RRClass&
     180                 :      33628 : BasicRRset::getClass() const {
     181                 :      33628 :     return (impl_->rrclass_);
     182                 :            : }
     183                 :            : 
     184                 :            : const RRType&
     185                 :     102614 : BasicRRset::getType() const {
     186                 :     102614 :     return (impl_->rrtype_);
     187                 :            : }
     188                 :            : 
     189                 :            : const RRTTL&
     190                 :      20339 : BasicRRset::getTTL() const {
     191                 :      20339 :     return (impl_->ttl_);
     192                 :            : }
     193                 :            : 
     194                 :            : void
     195                 :         18 : BasicRRset::setName(const Name& name) {
     196                 :         18 :     impl_->name_ = name;
     197                 :         18 : }
     198                 :            : 
     199                 :            : void
     200                 :        374 : BasicRRset::setTTL(const RRTTL& ttl) {
     201                 :        374 :     impl_->ttl_ = ttl;
     202                 :        374 : }
     203                 :            : 
     204                 :            : string
     205                 :       4305 : BasicRRset::toText() const {
     206                 :       4305 :     return (AbstractRRset::toText());
     207                 :            : }
     208                 :            : 
     209                 :            : unsigned int
     210                 :         68 : BasicRRset::toWire(OutputBuffer& buffer) const {
     211                 :         68 :     return (AbstractRRset::toWire(buffer));
     212                 :            : }
     213                 :            : 
     214                 :            : unsigned int
     215                 :        606 : BasicRRset::toWire(AbstractMessageRenderer& renderer) const {
     216                 :        606 :     return (AbstractRRset::toWire(renderer));
     217                 :            : }
     218                 :            : 
     219                 :      24694 : RRset::RRset(const Name& name, const RRClass& rrclass,
     220                 :            :             const RRType& rrtype, const RRTTL& ttl) :
     221                 :      24694 :     BasicRRset(name, rrclass, rrtype, ttl)
     222                 :            : {
     223         [ +  - ]:      24694 :     rrsig_ = RRsetPtr();
     224                 :      24694 : }
     225                 :            : 
     226                 :      49286 : RRset::~RRset() {}
     227                 :            : 
     228                 :            : namespace {
     229                 :            : class BasicRdataIterator : public RdataIterator {
     230                 :            : private:
     231                 :            :     BasicRdataIterator() {}
     232                 :            : public:
     233                 :            :     BasicRdataIterator(const std::vector<rdata::ConstRdataPtr>& datavector) :
     234                 :      44787 :         datavector_(&datavector), it_(datavector_->begin())
     235                 :            :     {}
     236                 :      14929 :     ~BasicRdataIterator() {}
     237                 :       1890 :     virtual void first() { it_ = datavector_->begin(); }
     238                 :      16453 :     virtual void next() { ++it_; }
     239                 :      18906 :     virtual const rdata::Rdata& getCurrent() const { return (**it_); }
     240                 :      32168 :     virtual bool isLast() const { return (it_ == datavector_->end()); }
     241                 :            : private:
     242                 :            :     const std::vector<rdata::ConstRdataPtr>* datavector_;
     243                 :            :     std::vector<rdata::ConstRdataPtr>::const_iterator it_;
     244                 :            : };
     245                 :            : }
     246                 :            : 
     247                 :            : RdataIteratorPtr
     248                 :      14929 : BasicRRset::getRdataIterator() const {
     249                 :      29858 :     return (RdataIteratorPtr(new BasicRdataIterator(impl_->rdatalist_)));
     250                 :            : }
     251                 :            : }
     252                 :        144 : }

Generated by: LCOV version 1.9