LCOV - code coverage report
Current view: top level - dns - question.h (source / functions) Hit Total Coverage
Test: report.info Lines: 14 14 100.0 %
Date: 2012-05-15 Functions: 5 5 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 39 74 52.7 %

           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                 :            : #ifndef __QUESTION_H
      16                 :            : #define __QUESTION_H 1
      17                 :            : 
      18                 :            : #include <iostream>
      19                 :            : #include <string>
      20                 :            : 
      21                 :            : #include <boost/shared_ptr.hpp>
      22                 :            : 
      23                 :            : #include <dns/name.h>
      24                 :            : #include <dns/rrclass.h>
      25                 :            : #include <dns/rrtype.h>
      26                 :            : 
      27                 :            : namespace isc {
      28                 :            : namespace util {
      29                 :            : class InputBuffer;
      30                 :            : class OutputBuffer;
      31                 :            : }
      32                 :            : 
      33                 :            : namespace dns {
      34                 :            : 
      35                 :            : class AbstractMessageRenderer;
      36                 :            : class Question;
      37                 :            : 
      38                 :            : /// \brief A pointer-like type pointing to an \c Question object.
      39                 :            : typedef boost::shared_ptr<Question> QuestionPtr;
      40                 :            : 
      41                 :            : /// \brief A pointer-like type pointing to an (immutable) \c Question object.
      42                 :            : typedef boost::shared_ptr<const Question> ConstQuestionPtr;
      43                 :            : 
      44                 :            : /// \brief The \c Question class encapsulates the common search key of DNS
      45                 :            : /// lookup, consisting of owner name, RR type and RR class.
      46                 :            : ///
      47                 :            : /// The primarily intended use case of this class is an entry of the question
      48                 :            : /// section of DNS messages.
      49                 :            : /// This could also be used as a general purpose lookup key, e.g., in a
      50                 :            : /// custom implementation of DNS database.
      51                 :            : ///
      52                 :            : /// In this initial implementation, the \c Question class is defined as
      53                 :            : /// a <em>concrete class</em>; it's not expected to be inherited by
      54                 :            : /// a user-defined customized class.
      55                 :            : /// It may be worth noting that it's different from the design of the
      56                 :            : /// RRset classes (\c AbstractRRset and its derived classes).
      57                 :            : /// The RRset classes form an inheritance hierarchy from the base abstract
      58                 :            : /// class.
      59                 :            : /// This may look odd in that an "RRset" and "Question" are similar from the
      60                 :            : /// protocol point of view: Both are used as a semantics unit of DNS messages;
      61                 :            : /// both share the same set of components (name, RR type and RR class).
      62                 :            : ///
      63                 :            : /// In fact, BIND9 didn't introduce a separate data structure for Questions,
      64                 :            : /// and use the same \c "rdataset" structure for both RRsets and Questions.
      65                 :            : /// We could take the same approach, but chose to adopt the different design.
      66                 :            : /// One reason for that is because a Question and an RRset are still
      67                 :            : /// different, and a Question might not be cleanly defined, e.g., if it were
      68                 :            : /// a derived class of some "RRset-like" class.
      69                 :            : /// For example, we couldn't give a reasonable semantics for \c %getTTL() or
      70                 :            : /// \c %setTTL() methods for a Question, since it's not associated with the
      71                 :            : /// TTL.
      72                 :            : /// In fact, the BIND9 implementation ended up often separating the case where
      73                 :            : /// a \c "rdataset" is from the Question section of a DNS message and the
      74                 :            : /// case where it comes from other sections.
      75                 :            : /// If we cannot treat them completely transparently anyway, separating the
      76                 :            : /// class (type) would make more sense because we can exploit compilation
      77                 :            : /// time type checks.
      78                 :            : ///
      79                 :            : /// On the other hand, we do not expect a strong need for customizing the
      80                 :            : /// \c Question class, unlike the RRset.
      81                 :            : /// Handling the "Question" section of a DNS message is relatively a
      82                 :            : /// simple work comparing to RRset-involved operations, so a unified
      83                 :            : /// straightforward implementation should suffice for any use cases
      84                 :            : /// including performance sensitive ones.
      85                 :            : ///
      86                 :            : /// We may, however, still want to have a customized version of Question
      87                 :            : /// for, e.g, highly optimized behavior, and may revisit this design choice
      88                 :            : /// as we have more experience with this implementation.
      89                 :            : ///
      90                 :            : /// One disadvantage of defining RRsets and Questions as unrelated classes
      91                 :            : /// is that we cannot handle them in a polymorphic way.
      92                 :            : /// For example, we might want to iterate over DNS message sections and
      93                 :            : /// render the data in the wire format, whether it's an RRset or a Question.
      94                 :            : /// If a \c Question were a derived class of some common RRset-like class,
      95                 :            : /// we could do this by calling <code>rrset_or_question->%toWire()</code>.
      96                 :            : /// But the actual design doesn't allow this approach, which may require
      97                 :            : /// duplicate code for almost the same operation.
      98                 :            : /// To mitigate this problem, we intentionally used the same names
      99                 :            : /// with the same signature for some common methods of \c Question and
     100                 :            : /// \c AbstractRRset such as \c %getName() or \c %toWire().
     101                 :            : /// So the user class may use a template function that is applicable to both
     102                 :            : /// \c Question and \c RRset to avoid writing duplicate code logic.
     103 [ #  + ][ +  - ]:       5196 : class Question {
         [ +  - ][ +  - ]
            [ - ][ +  - ]
            [ #  # ][ + ]
                 [ +  - ]
     104                 :            :     ///
     105                 :            :     /// \name Constructors and Destructor
     106                 :            :     ///
     107                 :            :     /// We use the default versions of destructor, copy constructor,
     108                 :            :     /// and assignment operator.
     109                 :            :     ///
     110                 :            :     /// The default constructor is hidden as a result of defining the other
     111                 :            :     /// constructors.  This is intentional; we don't want to allow a
     112                 :            :     /// \c Question object to be constructed with an invalid state.
     113                 :            :     //@{
     114                 :            : public:
     115                 :            :     /// \brief Constructor from wire-format data.
     116                 :            :     ///
     117                 :            :     /// It simply constructs a set of \c Name, \c RRType, and \c RRClass
     118                 :            :     /// object from the \c buffer in this order, and constructs a
     119                 :            :     /// \c Question object in a straightforward way.
     120                 :            :     ///
     121                 :            :     /// It may throw an exception if the construction of these component
     122                 :            :     /// classes fails.
     123                 :            :     ///
     124                 :            :     /// \param buffer A buffer storing the wire format data.
     125                 :            :     Question(isc::util::InputBuffer& buffer);
     126                 :            : 
     127                 :            :     /// \brief Constructor from fixed parameters of the \c Question.
     128                 :            :     ///
     129                 :            :     /// This constructor is basically expected to be exception free, but
     130                 :            :     /// copying the name may involve resource allocation, and if it fails
     131                 :            :     /// the corresponding standard exception will be thrown.
     132                 :            :     ///
     133                 :            :     /// \param name The owner name of the \c Question.
     134                 :            :     /// \param rrclass The RR class of the \c Question.
     135                 :            :     /// \param rrtype The RR type of the \c Question.
     136                 :        269 :     Question(const Name& name, const RRClass& rrclass, const RRType& rrtype) :
     137 [ +  - ][ +  - ]:       3052 :         name_(name), rrtype_(rrtype), rrclass_(rrclass)
         [ +  - ][ +  - ]
           [ +  -  +  -  
             +  -  +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     138                 :        269 :     {}
     139                 :            :     //@}
     140                 :            : 
     141                 :            :     ///
     142                 :            :     /// \name Getter Methods
     143                 :            :     ///
     144                 :            :     //@{
     145                 :            :     /// \brief Returns the owner name of the \c Question.
     146                 :            :     ///
     147                 :            :     /// This method never throws an exception.
     148                 :            :     ///
     149                 :            :     /// \return A reference to a \c Name class object corresponding to the
     150                 :            :     /// \c Question owner name.
     151                 :            :     const Name& getName() const { return (name_); }
     152                 :            : 
     153                 :            :     /// \brief Returns the RR Class of the \c Question.
     154                 :            :     ///
     155                 :            :     /// This method never throws an exception.
     156                 :            :     ///
     157                 :            :     /// \return A reference to a \c RRClass class object corresponding to the
     158                 :            :     /// RR class of the \c Question.
     159                 :            :     const RRType& getType() const { return (rrtype_); }
     160                 :            : 
     161                 :            :     /// \brief Returns the RR Type of the \c Question.
     162                 :            :     ///
     163                 :            :     /// This method never throws an exception.
     164                 :            :     ///
     165                 :            :     /// \return A reference to a \c RRType class object corresponding to the
     166                 :            :     /// RR type of the \c Question.
     167                 :            :     const RRClass& getClass() const { return (rrclass_); }
     168                 :            :     //@}
     169                 :            : 
     170                 :            :     ///
     171                 :            :     /// \name Converter Methods
     172                 :            :     ///
     173                 :            :     //@{
     174                 :            :     /// \brief Convert the Question to a string.
     175                 :            :     ///
     176                 :            :     /// Unlike other similar methods of this library, this method terminates
     177                 :            :     /// the resulting string with a trailing newline character
     178                 :            :     /// (following the BIND9 convention).
     179                 :            :     ///
     180                 :            :     /// This method simply calls the \c %toText() methods of the corresponding
     181                 :            :     /// \c Name, \c RRType and \c RRClass classes for this \c Question, and
     182                 :            :     /// these methods may throw an exception.
     183                 :            :     /// In particular, if resource allocation fails, a corresponding standard
     184                 :            :     /// exception will be thrown.
     185                 :            :     ///
     186                 :            :     /// \return A string representation of the \c Question.
     187                 :            :     std::string toText() const;
     188                 :            : 
     189                 :            :     /// \brief Render the Question in the wire format with name compression.
     190                 :            :     ///
     191                 :            :     /// This method simply calls the \c %toWire() methods of the corresponding
     192                 :            :     /// \c Name, \c RRType and \c RRClass classes for this \c Question, and
     193                 :            :     /// these methods may throw an exception.
     194                 :            :     /// In particular, if resource allocation fails, a corresponding standard
     195                 :            :     /// exception will be thrown.
     196                 :            :     ///
     197                 :            :     /// This method returns 1, which is the number of "questions" contained
     198                 :            :     /// in the \c Question.
     199                 :            :     /// This is a meaningless value, but is provided to be consistent with
     200                 :            :     /// the corresponding method of \c AbstractRRset (see the detailed
     201                 :            :     /// class description).
     202                 :            :     ///
     203                 :            :     /// The owner name will be compressed if possible, although it's an
     204                 :            :     /// unlikely event in practice because the Question section a DNS
     205                 :            :     /// message normally doesn't contain multiple question entries and
     206                 :            :     /// it's located right after the Header section.
     207                 :            :     /// Nevertheless, \c renderer records the information of the owner name
     208                 :            :     /// so that it can be pointed by other RRs in other sections (which is
     209                 :            :     /// more likely to happen).
     210                 :            :     ///
     211                 :            :     /// It could be possible, though very rare in practice, that
     212                 :            :     /// an attempt to render a Question may cause truncation
     213                 :            :     /// (when the Question section contains a large number of entries).
     214                 :            :     /// In such a case this method avoid the rendering and indicate the
     215                 :            :     /// truncation in the \c renderer.  This method returns 0 in this case.
     216                 :            :     ///
     217                 :            :     /// \param renderer DNS message rendering context that encapsulates the
     218                 :            :     /// output buffer and name compression information.
     219                 :            :     ///
     220                 :            :     /// \return 1 on success; 0 if it causes truncation
     221                 :            :     unsigned int toWire(AbstractMessageRenderer& renderer) const;
     222                 :            : 
     223                 :            :     /// \brief Render the Question in the wire format without name compression.
     224                 :            :     ///
     225                 :            :     /// This method behaves like the render version except it doesn't compress
     226                 :            :     /// the owner name.
     227                 :            :     /// See \c toWire(AbstractMessageRenderer& renderer)const.
     228                 :            :     ///
     229                 :            :     /// \param buffer An output buffer to store the wire data.
     230                 :            :     /// \return 1
     231                 :            :     unsigned int toWire(isc::util::OutputBuffer& buffer) const;
     232                 :            :     //@}
     233                 :            : 
     234                 :            :     ///
     235                 :            :     /// \name Comparison Operators
     236                 :            :     ///
     237                 :            :     //@{
     238                 :            :     /// A "less than" operator is needed for this class so it can
     239                 :            :     /// function as an index to std::map.
     240                 :         16 :     bool operator <(const Question& rhs) const {
     241                 :       4509 :         return (rrclass_ < rhs.rrclass_ ||
     242                 :       4379 :                 (rrclass_ == rhs.rrclass_ &&
     243                 :       4347 :                  (rrtype_ < rhs.rrtype_ ||
     244 [ +  + ][ +  + ]:       5722 :                   (rrtype_ == rhs.rrtype_ && (name_ < rhs.name_)))));
                 [ +  + ]
           [ +  +  +  + ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     245                 :            :     }
     246                 :            : 
     247                 :            :     /// Equality operator.  Primarily used to compare the question section in
     248                 :            :     /// a response to that in the query.
     249                 :            :     ///
     250                 :            :     /// \param rhs Question to compare against
     251                 :            :     /// \return true if name, class and type are equal, false otherwise
     252                 :         16 :     bool operator==(const Question& rhs) const {
     253                 :        172 :         return ((rrclass_ == rhs.rrclass_) && (rrtype_ == rhs.rrtype_) &&
     254         [ +  + ]:        167 :                 (name_ == rhs.name_));
           [ +  +  +  + ]
         [ +  - ][ +  - ]
                 [ -  + ]
     255                 :            :     }
     256                 :            : 
     257                 :            :     /// Inequality operator.  Primarily used to compare the question section in
     258                 :            :     /// a response to that in the query.
     259                 :            :     ///
     260                 :            :     /// \param rhs Question to compare against
     261                 :            :     /// \return true if one or more of the name, class and type do not match,
     262                 :            :     /// false otherwise.
     263                 :          8 :     bool operator!=(const Question& rhs) const {
     264                 :          8 :         return (!operator==(rhs));
     265                 :            :     }
     266                 :            :     //@}
     267                 :            : 
     268                 :            : private:
     269                 :            :     Name name_;
     270                 :            :     RRType rrtype_;
     271                 :            :     RRClass rrclass_;
     272                 :            : };
     273                 :            : 
     274                 :            : /// \brief Insert the \c Question as a string into stream.
     275                 :            : ///
     276                 :            : /// This method convert the \c question into a string and inserts it into the
     277                 :            : /// output stream \c os.
     278                 :            : ///
     279                 :            : /// This function overloads the global \c operator<< to behave as described in
     280                 :            : /// \c %ostream::%operator<< but applied to Question objects.
     281                 :            : ///
     282                 :            : /// \param os A \c std::ostream object on which the insertion operation is
     283                 :            : /// performed.
     284                 :            : /// \param question A reference to a \c Question object output by the
     285                 :            : /// operation.
     286                 :            : /// \return A reference to the same \c std::ostream object referenced by
     287                 :            : /// parameter \c os after the insertion operation.
     288                 :            : std::ostream& operator<<(std::ostream& os, const Question& question);
     289                 :            : } // end of namespace dns
     290                 :            : } // end of namespace isc
     291                 :            : #endif  // __QUESTION_H
     292                 :            : 
     293                 :            : // Local Variables: 
     294                 :            : // mode: c++
     295                 :            : // End: 

Generated by: LCOV version 1.9