LCOV - code coverage report
Current view: top level - dns - message.h (source / functions) Hit Total Coverage
Test: report.info Lines: 8 9 88.9 %
Date: 2012-05-15 Functions: 4 11 36.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 3 6 50.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2009  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 __MESSAGE_H
      16                 :            : #define __MESSAGE_H 1
      17                 :            : 
      18                 :            : #include <stdint.h>
      19                 :            : 
      20                 :            : #include <iterator>
      21                 :            : #include <string>
      22                 :            : #include <ostream>
      23                 :            : 
      24                 :            : #include <exceptions/exceptions.h>
      25                 :            : 
      26                 :            : #include <dns/edns.h>
      27                 :            : #include <dns/question.h>
      28                 :            : #include <dns/rrset.h>
      29                 :            : 
      30                 :            : namespace isc {
      31                 :            : namespace util {
      32                 :            : class InputBuffer;
      33                 :            : }
      34                 :            : 
      35                 :            : namespace dns {
      36                 :            : class TSIGContext;
      37                 :            : class TSIGRecord;
      38                 :            : 
      39                 :            : ///
      40                 :            : /// \brief A standard DNS module exception that is thrown if a wire format
      41                 :            : /// message parser encounters a short length of data that don't even contain
      42                 :            : /// the full header section.
      43                 :            : ///
      44                 :         10 : class MessageTooShort : public Exception {
      45                 :            : public:
      46                 :            :     MessageTooShort(const char* file, size_t line, const char* what) :
      47         [ +  - ]:         10 :         isc::Exception(file, line, what) {}
      48                 :            : };
      49                 :            : 
      50                 :            : ///
      51                 :            : /// \brief A standard DNS module exception that is thrown if a section iterator
      52                 :            : /// is being constructed for an incompatible section.  Specifically, this
      53                 :            : /// happens RRset iterator is being constructed for a Question section.
      54                 :            : ///
      55                 :          2 : class InvalidMessageSection : public Exception {
      56                 :            : public:
      57                 :            :     InvalidMessageSection(const char* file, size_t line, const char* what) :
      58 [ +  - ][ +  - ]:          2 :         isc::Exception(file, line, what) {}
      59                 :            : };
      60                 :            : 
      61                 :            : ///
      62                 :            : /// \brief A standard DNS module exception that is thrown if a \c Message
      63                 :            : /// class method is called that is prohibited for the current mode of
      64                 :            : /// the message.
      65                 :            : ///
      66                 :         29 : class InvalidMessageOperation : public Exception {
      67                 :            : public:
      68                 :         29 :     InvalidMessageOperation(const char* file, size_t line, const char* what) :
      69                 :         29 :         isc::Exception(file, line, what) {}
      70                 :            : };
      71                 :            : 
      72                 :            : ///
      73                 :            : /// \brief A standard DNS module exception that is thrown if a UDP buffer size
      74                 :            : /// smaller than the standard default maximum (DEFAULT_MAX_UDPSIZE) is
      75                 :            : /// being specified for the message.
      76                 :            : ///
      77                 :          0 : class InvalidMessageUDPSize : public Exception {
      78                 :            : public:
      79                 :            :     InvalidMessageUDPSize(const char* file, size_t line, const char* what) :
      80                 :            :         isc::Exception(file, line, what) {}
      81                 :            : };
      82                 :            : 
      83                 :            : typedef uint16_t qid_t;
      84                 :            : 
      85                 :            : class AbstractMessageRenderer;
      86                 :            : class Message;
      87                 :            : class MessageImpl;
      88                 :            : class Opcode;
      89                 :            : class Rcode;
      90                 :            : 
      91                 :            : template <typename T>
      92                 :            : struct SectionIteratorImpl;
      93                 :            : 
      94                 :            : /// \c SectionIterator is a templated class to provide standard-compatible
      95                 :            : /// iterators for Questions and RRsets for a given DNS message section.
      96                 :            : /// The template parameter is either \c QuestionPtr (for the question section)
      97                 :            : /// or \c RRsetPtr (for the answer, authority, or additional section).
      98                 :            : template <typename T>
      99                 :            : class SectionIterator : public std::iterator<std::input_iterator_tag, T> {
     100                 :            : public:
     101                 :        222 :     SectionIterator<T>() : impl_(NULL) {}
     102                 :            :     SectionIterator<T>(const SectionIteratorImpl<T>& impl);
     103                 :            :     ~SectionIterator<T>();
     104                 :            :     SectionIterator<T>(const SectionIterator<T>& source);
     105                 :            :     void operator=(const SectionIterator<T>& source);
     106                 :            :     SectionIterator<T>& operator++();
     107                 :            :     SectionIterator<T> operator++(int);
     108                 :            :     const T& operator*() const;
     109                 :            :     const T* operator->() const;
     110                 :            :     bool operator==(const SectionIterator<T>& other) const;
     111                 :            :     bool operator!=(const SectionIterator<T>& other) const;
     112                 :            : private:
     113                 :            :     SectionIteratorImpl<T>* impl_;
     114                 :            : };
     115                 :            : 
     116                 :            : typedef SectionIterator<QuestionPtr> QuestionIterator;
     117                 :            : typedef SectionIterator<RRsetPtr> RRsetIterator;
     118                 :            : 
     119                 :            : /// \brief The \c Message class encapsulates a standard DNS message.
     120                 :            : ///
     121                 :            : /// Details of the design and interfaces of this class are still in flux.
     122                 :            : /// Here are some notes about the current design.
     123                 :            : ///
     124                 :            : /// Since many realistic DNS applications deal with messages, message objects
     125                 :            : /// will be frequently used, and can be performance sensitive.  To minimize
     126                 :            : /// the performance overhead of constructing and destructing the objects,
     127                 :            : /// this class is designed to be reusable.  The \c clear() method is provided
     128                 :            : /// for this purpose.
     129                 :            : ///
     130                 :            : /// A \c Message class object is in either the \c PARSE or the \c RENDER mode.
     131                 :            : /// A \c PARSE mode object is intended to be used to convert wire-format
     132                 :            : /// message data into a complete \c Message object.
     133                 :            : /// A \c RENDER mode object is intended to be used to convert a \c Message
     134                 :            : /// object into wire-format data.
     135                 :            : /// Some of the method functions of this class are limited to a specific mode.
     136                 :            : /// In general, "set" type operations are only allowed for \c RENDER mode
     137                 :            : /// objects.
     138                 :            : /// The initial mode must be specified on construction, and can be changed
     139                 :            : /// through some method functions.
     140                 :            : ///
     141                 :            : /// This class uses the "pimpl" idiom, and hides detailed implementation
     142                 :            : /// through the \c impl_ pointer.  Since a \c Message object is expected to
     143                 :            : /// be reused, the construction overhead of this approach should be acceptable.
     144                 :            : ///
     145                 :            : /// Open issues (among other things):
     146                 :            : /// - We may want to provide an "iterator" for all RRsets/RRs for convenience.
     147                 :            : ///   This will be for applications that do not care about performance much,
     148                 :            : ///   so the implementation can only be moderately efficient.
     149                 :            : /// - We may want to provide a "find" method for a specified type
     150                 :            : ///   of RR in the message.
     151                 :            : class Message {
     152                 :            : public:
     153                 :            :     /// Constants to specify the operation mode of the \c Message.
     154                 :            :     enum Mode {
     155                 :            :         PARSE = 0,              ///< Parse mode (handling an incoming message)
     156                 :            :         RENDER = 1              ///< Render mode (building an outgoing message)
     157                 :            :     };
     158                 :            : 
     159                 :            :     /// \brief Constants for flag bit fields of a DNS message header.
     160                 :            :     ///
     161                 :            :     /// Only the defined constants are valid where a header flag is required
     162                 :            :     /// in this library (e.g., in \c Message::setHeaderFlag()).
     163                 :            :     /// Since these are enum constants, however, an invalid value could be
     164                 :            :     /// passed via casting without an error at compilation time.
     165                 :            :     /// It is generally the callee's responsibility to check and reject invalid
     166                 :            :     /// values.
     167                 :            :     /// Of course, applications shouldn't pass invalid values even if the
     168                 :            :     /// callee does not perform proper validation; the result in such usage
     169                 :            :     /// is undefined.
     170                 :            :     ///
     171                 :            :     /// In the current implementation, the defined values happen to be
     172                 :            :     /// a 16-bit integer with one bit being set corresponding to the
     173                 :            :     /// specified flag in the second 16 bits of the DNS Header section
     174                 :            :     /// in order to make the internal implementation simpler.
     175                 :            :     /// For example, \c HEADERFLAG_QR is defined to be 0x8000 as the QR
     176                 :            :     /// bit is the most significant bit of the second 16 bits of the header.
     177                 :            :     /// However, applications should not assume this coincidence and
     178                 :            :     /// must solely use the enum representations.
     179                 :            :     /// Any usage based on the assumption of the underlying values is invalid
     180                 :            :     /// and the result is undefined.
     181                 :            :     ///
     182                 :            :     /// Likewise, bit wise operations such as AND or OR on the flag values
     183                 :            :     /// are invalid and are not guaranteed to work, even if it could compile
     184                 :            :     /// with casting.
     185                 :            :     /// For example, the following code will compile:
     186                 :            :     /// \code const uint16_t combined_flags =
     187                 :            :     ///           static_cast<uint16_t>(Message::HEADERFLAG_AA) |
     188                 :            :     ///           static_cast<uint16_t>(Message::HEADERFLAG_CD);
     189                 :            :     /// message->setHeaderFlag(static_cast<Message::HeaderFlag>(combined_flags));
     190                 :            :     /// \endcode
     191                 :            :     /// and (with the current definition) happens to work as if it were
     192                 :            :     /// validly written as follows:
     193                 :            :     /// \code message->setHeaderFlag(Message::HEADERFLAG_AA);
     194                 :            :     /// message->setHeaderFlag(Message::HEADERFLAG_CD);
     195                 :            :     /// \endcode
     196                 :            :     /// But the former notation is invalid and may not work in future versions.
     197                 :            :     /// We did not try to prohibit such usage at compilation time, e.g., by
     198                 :            :     /// introducing a separately defined class considering the balance
     199                 :            :     /// between the complexity and advantage, but hopefully the cast notation
     200                 :            :     /// is sufficiently ugly to prevent proliferation of the usage.
     201                 :            :     enum HeaderFlag {
     202                 :            :         HEADERFLAG_QR = 0x8000, ///< Query (if cleared) or response (if set)
     203                 :            :         HEADERFLAG_AA = 0x0400, ///< Authoritative answer
     204                 :            :         HEADERFLAG_TC = 0x0200, ///< Truncation
     205                 :            :         HEADERFLAG_RD = 0x0100, ///< Recursion desired
     206                 :            :         HEADERFLAG_RA = 0x0080, ///< Recursion available
     207                 :            :         HEADERFLAG_AD = 0x0020, ///< Authentic %data (RFC4035)
     208                 :            :         HEADERFLAG_CD = 0x0010  ///< DNSSEC checking disabled (RFC4035)
     209                 :            :     };
     210                 :            : 
     211                 :            :     /// \brief Constants to specify sections of a DNS message.
     212                 :            :     ///
     213                 :            :     /// The sections are those defined in RFC 1035 excluding the Header
     214                 :            :     /// section; the fields of the Header section are accessed via specific
     215                 :            :     /// methods of the \c Message class (e.g., \c getQid()).
     216                 :            :     ///
     217                 :            :     /// <b>Open Design Issue:</b>
     218                 :            :     /// In the current implementation the values for the constants are
     219                 :            :     /// sorted in the order of appearance in DNS messages, i.e.,
     220                 :            :     /// from %Question to Additional.
     221                 :            :     /// So, for example,
     222                 :            :     /// code <code>section >= Message::SECTION_AUTHORITY</code> can be
     223                 :            :     /// used to do something in or after the Authority section.
     224                 :            :     /// This would be convenient, but it is not clear if it's really a good
     225                 :            :     /// idea to rely on relationship between the underlying values of enum
     226                 :            :     /// constants.  At the moment, applications are discouraged to rely on
     227                 :            :     /// this implementation detail.  We will see if such usage is sufficiently
     228                 :            :     /// common to officially support it.
     229                 :            :     ///
     230                 :            :     /// Note also that since we don't define \c operator++ for this enum,
     231                 :            :     /// the following code intending to iterate over all sections will
     232                 :            :     /// \b not compile:
     233                 :            :     /// \code for (Section s; s <= SECTION_ADDITIONAL; ++s) { // ++s undefined
     234                 :            :     ///     // do something
     235                 :            :     /// } \endcode
     236                 :            :     /// This is intentional at this moment, and we'll see if we need to allow
     237                 :            :     /// that as we have more experiences with this library.
     238                 :            :     ///
     239                 :            :     /// <b>Future Extension:</b> We'll probably also define constants for
     240                 :            :     /// the section names used in dynamic updates in future versions.
     241                 :            :     enum Section {
     242                 :            :         SECTION_QUESTION = 0,   ///< %Question section
     243                 :            :         SECTION_ANSWER = 1,     ///< Answer section
     244                 :            :         SECTION_AUTHORITY = 2,  ///< Authority section
     245                 :            :         SECTION_ADDITIONAL = 3  ///< Additional section
     246                 :            :     };
     247                 :            : 
     248                 :            :     ///
     249                 :            :     /// \name Constructors and Destructor
     250                 :            :     ///
     251                 :            :     /// Note: The copy constructor and the assignment operator are
     252                 :            :     /// intentionally defined as private.
     253                 :            :     /// The intended use case wouldn't require copies of a \c Message object;
     254                 :            :     /// once created, it would normally be expected to be reused, changing the
     255                 :            :     /// mode from \c PARSE to \c RENDER, and vice versa.
     256                 :            :     //@{
     257                 :            : public:
     258                 :            :     /// \brief The constructor.
     259                 :            :     /// The mode of the message is specified by the \c mode parameter.
     260                 :            :     Message(Mode mode);
     261                 :            :     /// \brief The destructor.
     262                 :            :     ~Message();
     263                 :            : private:
     264                 :            :     Message(const Message& source);
     265                 :            :     Message& operator=(const Message& source);
     266                 :            :     //@}
     267                 :            : public:
     268                 :            :     /// \brief Return whether the specified header flag bit is set in the
     269                 :            :     /// header section.
     270                 :            :     ///
     271                 :            :     /// This method is basically exception free, but if
     272                 :            :     /// \c flag is not a valid constant of the \c HeaderFlag type,
     273                 :            :     /// an exception of class \c InvalidParameter will be thrown.
     274                 :            :     ///
     275                 :            :     /// \param flag The header flag constant to test.
     276                 :            :     /// \return \c true if the specified flag is set; otherwise \c false.
     277                 :            :     bool getHeaderFlag(const HeaderFlag flag) const;
     278                 :            : 
     279                 :            :     /// \brief Set or clear the specified header flag bit in the header
     280                 :            :     /// section.
     281                 :            :     ///
     282                 :            :     /// The optional parameter \c on indicates the operation mode,
     283                 :            :     /// set or clear; if it's \c true the corresponding flag will be set;
     284                 :            :     /// otherwise the flag will be cleared.
     285                 :            :     /// In either case the original state of the flag does not affect the
     286                 :            :     /// operation; for example, if a flag is already set and the "set"
     287                 :            :     /// operation is attempted, it effectively results in no operation.
     288                 :            :     ///
     289                 :            :     /// The parameter \c on can be omitted, in which case a value of \c true
     290                 :            :     /// (i.e., set operation) will be assumed.
     291                 :            :     /// This is based on the observation that the flag would have to be set
     292                 :            :     /// in the vast majority of the cases where an application needs to
     293                 :            :     /// use this method.
     294                 :            :     ///
     295                 :            :     /// This method is only allowed in the \c RENDER mode;
     296                 :            :     /// if the \c Message is in other mode, an exception of class
     297                 :            :     /// InvalidMessageOperation will be thrown.
     298                 :            :     ///
     299                 :            :     /// If \c flag is not a valid constant of the \c HeaderFlag type,
     300                 :            :     /// an exception of class \c InvalidParameter will be thrown.
     301                 :            :     ///
     302                 :            :     /// \param flag The header flag constant to set or clear.
     303                 :            :     /// \param on If \c true the flag will be set; otherwise the flag will be
     304                 :            :     /// cleared.
     305                 :            :     void setHeaderFlag(const HeaderFlag flag, const bool on = true);
     306                 :            : 
     307                 :            :     /// \brief Return the query ID given in the header section of the message.
     308                 :            :     qid_t getQid() const;
     309                 :            : 
     310                 :            :     /// \brief Set the query ID of the header section of the message.
     311                 :            :     ///
     312                 :            :     /// This method is only allowed in the \c RENDER mode;
     313                 :            :     /// if the \c Message is in other mode, an exception of class
     314                 :            :     /// InvalidMessageOperation will be thrown.
     315                 :            :     void setQid(qid_t qid);
     316                 :            : 
     317                 :            :     /// \brief Return the Response Code of the message.
     318                 :            :     ///
     319                 :            :     /// This includes extended codes specified by an EDNS OPT RR (when
     320                 :            :     /// included).  In the \c PARSE mode, if the received message contains
     321                 :            :     /// an EDNS OPT RR, the corresponding extended code is identified and
     322                 :            :     /// returned.
     323                 :            :     ///
     324                 :            :     /// The message must have been properly parsed (in the case of the
     325                 :            :     /// \c PARSE mode) or an \c Rcode has been set (in the case of the
     326                 :            :     /// \c RENDER mode) beforehand.  Otherwise, an exception of class
     327                 :            :     /// \c InvalidMessageOperation will be thrown.
     328                 :            :     const Rcode& getRcode() const;
     329                 :            : 
     330                 :            :     /// \brief Set the Response Code of the message.
     331                 :            :     ///
     332                 :            :     /// This method is only allowed in the \c RENDER mode;
     333                 :            :     /// if the \c Message is in other mode, an exception of class
     334                 :            :     /// InvalidMessageOperation will be thrown.
     335                 :            :     ///
     336                 :            :     /// If the specified code is an EDNS extended RCODE, an EDNS OPT RR will be
     337                 :            :     /// included in the message.
     338                 :            :     void setRcode(const Rcode& rcode);
     339                 :            : 
     340                 :            :     /// \brief Return the OPCODE given in the header section of the message.
     341                 :            :     ///
     342                 :            :     /// The message must have been properly parsed (in the case of the
     343                 :            :     /// \c PARSE mode) or an \c Opcode has been set (in the case of the
     344                 :            :     /// \c RENDER mode) beforehand.  Otherwise, an exception of class
     345                 :            :     /// \c InvalidMessageOperation will be thrown.
     346                 :            :     const Opcode& getOpcode() const;
     347                 :            : 
     348                 :            :     /// \brief Set the OPCODE of the header section of the message.
     349                 :            :     ///
     350                 :            :     /// This method is only allowed in the \c RENDER mode;
     351                 :            :     /// if the \c Message is in other mode, an exception of class
     352                 :            :     /// InvalidMessageOperation will be thrown.
     353                 :            :     void setOpcode(const Opcode& opcode);
     354                 :            : 
     355                 :            :     /// \brief Return, if any, the EDNS associated with the message.
     356                 :            :     ///
     357                 :            :     /// This method never throws an exception.
     358                 :            :     ///
     359                 :            :     /// \return A shared pointer to the EDNS.  This will be a null shared
     360                 :            :     /// pointer if the message is not associated with EDNS.
     361                 :            :     ConstEDNSPtr getEDNS() const;
     362                 :            : 
     363                 :            :     /// \brief Set EDNS for the message.
     364                 :            :     ///
     365                 :            :     /// This method is only allowed in the \c RENDER mode;
     366                 :            :     /// if the \c Message is in other mode, an exception of class
     367                 :            :     /// InvalidMessageOperation will be thrown.
     368                 :            :     ///
     369                 :            :     /// \param edns A shared pointer to an \c EDNS object to be set in
     370                 :            :     /// \c Message.
     371                 :            :     void setEDNS(ConstEDNSPtr edns);
     372                 :            : 
     373                 :            :     /// \brief Return, if any, the TSIG record contained in the received
     374                 :            :     /// message.
     375                 :            :     ///
     376                 :            :     /// Currently, this method is only intended to return a TSIG record
     377                 :            :     /// for an incoming message built via the \c fromWire() method in the
     378                 :            :     /// PARSE mode.  A call to this method in the RENDER mode is invalid and
     379                 :            :     /// result in an exception.  Also, calling this method is meaningless
     380                 :            :     /// unless \c fromWire() is performed.
     381                 :            :     ///
     382                 :            :     /// The returned pointer is valid only during the lifetime of the
     383                 :            :     /// \c Message object and until \c clear() is called.  The \c Message
     384                 :            :     /// object retains the ownership of \c TSIGRecord; the caller must not
     385                 :            :     /// try to delete it.
     386                 :            :     ///
     387                 :            :     /// \exception InvalidMessageOperation Message is not in the PARSE mode.
     388                 :            :     ///
     389                 :            :     /// \return A pointer to the stored \c TSIGRecord or \c NULL.
     390                 :            :     const TSIGRecord* getTSIGRecord() const;
     391                 :            : 
     392                 :            :     /// \brief Returns the number of RRs contained in the given section.
     393                 :            :     ///
     394                 :            :     /// In the \c PARSE mode, the returned value may not be identical to
     395                 :            :     /// the actual number of RRs of the incoming message that is parsed.
     396                 :            :     /// The \c Message class handles some "meta" RRs such as EDNS OPT RR
     397                 :            :     /// separately.  This method doesn't include such RRs.
     398                 :            :     /// Also, a future version of the parser will detect and unify duplicate
     399                 :            :     /// RRs (which should be rare in practice though), in which case
     400                 :            :     /// the stored RRs in the \c Message object will be fewer than the RRs
     401                 :            :     /// originally contained in the incoming message.
     402                 :            :     ///
     403                 :            :     /// Likewise, in the \c RENDER mode, even if \c EDNS is set in the
     404                 :            :     /// \c Message, this method doesn't count the corresponding OPT RR
     405                 :            :     /// in the Additional section.
     406                 :            :     ///
     407                 :            :     /// This method is basically exception free, but if
     408                 :            :     /// \c section is not a valid constant of the \c Section type,
     409                 :            :     /// an exception of class \c OutOfRange will be thrown.
     410                 :            :     ///
     411                 :            :     /// \param section The section in the message where RRs should be
     412                 :            :     /// counted.
     413                 :            :     /// \return The number of RRs stored in the specified section of the
     414                 :            :     /// message.
     415                 :            :     unsigned int getRRCount(const Section section) const;
     416                 :            : 
     417                 :            :     /// \brief Return an iterator corresponding to the beginning of the
     418                 :            :     /// Question section of the message.
     419                 :            :     const QuestionIterator beginQuestion() const;
     420                 :            : 
     421                 :            :     /// \brief Return an iterator corresponding to the end of the
     422                 :            :     /// Question section of the message.
     423                 :            :     const QuestionIterator endQuestion() const;
     424                 :            : 
     425                 :            :     /// \brief Return an iterator corresponding to the beginning of the
     426                 :            :     /// given section (other than Question) of the message.
     427                 :            :     ///
     428                 :            :     /// \c section must be a valid constant of the \c Section type;
     429                 :            :     /// otherwise, an exception of class \c OutOfRange will be thrown.
     430                 :            :     const RRsetIterator beginSection(const Section section) const;
     431                 :            : 
     432                 :            :     /// \brief Return an iterator corresponding to the end of the
     433                 :            :     /// given section (other than Question) of the message.
     434                 :            :     ///
     435                 :            :     /// \c section must be a valid constant of the \c Section type;
     436                 :            :     /// otherwise, an exception of class \c OutOfRange will be thrown.
     437                 :            :     const RRsetIterator endSection(const Section section) const;
     438                 :            : 
     439                 :            :     /// \brief Add a (pointer like object of) Question to the message.
     440                 :            :     ///
     441                 :            :     /// This method is only allowed in the \c RENDER mode;
     442                 :            :     /// if the \c Message is in other mode, an exception of class
     443                 :            :     /// InvalidMessageOperation will be thrown.
     444                 :            :     void addQuestion(QuestionPtr question);
     445                 :            : 
     446                 :            :     /// \brief Add a (pointer like object of) Question to the message.
     447                 :            :     ///
     448                 :            :     /// This version internally creates a \c QuestionPtr object from the
     449                 :            :     /// given \c question and calls the other version of this method.
     450                 :            :     /// So this is inherently less efficient, but is provided because this
     451                 :            :     /// form may be more intuitive and may make more sense for performance
     452                 :            :     /// insensitive applications.
     453                 :            :     ///
     454                 :            :     /// This method is only allowed in the \c RENDER mode;
     455                 :            :     /// if the \c Message is in other mode, an exception of class
     456                 :            :     /// InvalidMessageOperation will be thrown.
     457                 :            :     void addQuestion(const Question& question);
     458                 :            : 
     459                 :            :     /// \brief Add a (pointer like object of) RRset to the given section
     460                 :            :     /// of the message.
     461                 :            :     ///
     462                 :            :     /// This interface takes into account the RRSIG possibly attached to
     463                 :            :     /// \c rrset.  This interface design needs to be revisited later.
     464                 :            :     ///
     465                 :            :     /// Note that \c addRRset() does not currently check for duplicate
     466                 :            :     /// data before inserting RRsets.  The caller is responsible for
     467                 :            :     /// checking for these (see \c hasRRset() below).
     468                 :            :     ///
     469                 :            :     /// \throw InvalidParameter rrset is NULL
     470                 :            :     /// \throw InvalidMessageOperation The message is not in the \c RENDER
     471                 :            :     /// mode.
     472                 :            :     /// \throw OutOfRange \c section doesn't specify a valid \c Section value.
     473                 :            :     ///
     474                 :            :     /// \param section The message section to which the rrset is to be added
     475                 :            :     /// \param rrset The rrset to be added.  Must not be NULL.
     476                 :            :     /// \param sign If true, and if \c rrset has associated RRSIGs, the
     477                 :            :     /// RRSIGs will also be added to the same section of the message.
     478                 :            :     void addRRset(const Section section, RRsetPtr rrset, bool sign = false);
     479                 :            : 
     480                 :            :     /// \brief Determine whether the given section already has an RRset
     481                 :            :     /// matching the given name, RR class and RR type.
     482                 :            :     ///
     483                 :            :     /// \c section must be a valid constant of the \c Section type;
     484                 :            :     /// otherwise, an exception of class \c OutOfRange will be thrown.
     485                 :            :     ///
     486                 :            :     /// This should probably be extended to be a "find" method that returns
     487                 :            :     /// a matching RRset if found.
     488                 :            :     bool hasRRset(const Section section, const Name& name,
     489                 :            :                   const RRClass& rrclass, const RRType& rrtype);
     490                 :            : 
     491                 :            :     /// \brief Determine whether the given section already has an RRset
     492                 :            :     /// matching the one pointed to by the argumet
     493                 :            :     ///
     494                 :            :     /// \c section must be a valid constant of the \c Section type;
     495                 :            :     /// otherwise, an exception of class \c OutOfRange will be thrown.
     496                 :            :     bool hasRRset(const Section section, const RRsetPtr& rrset);
     497                 :            : 
     498                 :            :     /// \brief Remove RRSet from Message
     499                 :            :     ///
     500                 :            :     /// Removes the RRset identified by the section iterator from the message.
     501                 :            :     /// Note: if,.for some reason, the RRset is duplicated in the section, only
     502                 :            :     /// one occurrence is removed.
     503                 :            :     ///
     504                 :            :     /// If the operation is successful, all iterators into the section are
     505                 :            :     /// invalidated.
     506                 :            :     ///
     507                 :            :     /// \param section Section to which the iterator belongs
     508                 :            :     /// \param iterator Iterator pointing to the element to be removed
     509                 :            :     ///
     510                 :            :     /// \return true if the element was removed, false if the iterator was not
     511                 :            :     /// found in the specified section.
     512                 :            :     bool removeRRset(const Section section, RRsetIterator& iterator);
     513                 :            : 
     514                 :            :     /// \brief Remove all RRSets from the given Section
     515                 :            :     ///
     516                 :            :     /// \param section Section to remove all rrsets from
     517                 :            :     void clearSection(const Section section);
     518                 :            : 
     519                 :            :     // The following methods are not currently implemented.
     520                 :            :     //void removeQuestion(QuestionPtr question);
     521                 :            :     // notyet:
     522                 :            :     //void addRR(const Section section, const RR& rr);
     523                 :            :     //void removeRR(const Section section, const RR& rr);
     524                 :            : 
     525                 :            :     /// \brief Clear the message content (if any) and reinitialize it in the
     526                 :            :     /// specified mode.
     527                 :            :     void clear(Mode mode);
     528                 :            : 
     529                 :            :     /// \brief Adds all rrsets from the source the given section in the
     530                 :            :     /// source message to the same section of this message
     531                 :            :     ///
     532                 :            :     /// \param section the section to append
     533                 :            :     /// \param source The source Message
     534                 :            :     void appendSection(const Section section, const Message& source);
     535                 :            : 
     536                 :            :     /// \brief Prepare for making a response from a request.
     537                 :            :     ///
     538                 :            :     /// This will clear the DNS header except those fields that should be kept
     539                 :            :     /// for the response, and clear answer and the following sections.
     540                 :            :     /// See also dns_message_reply() of BIND9.
     541                 :            :     void makeResponse();
     542                 :            : 
     543                 :            :     /// \brief Convert the Message to a string.
     544                 :            :     ///
     545                 :            :     /// At least \c Opcode and \c Rcode must be validly set in the \c Message
     546                 :            :     /// (as a result of parse in the \c PARSE mode or by explicitly setting
     547                 :            :     /// in the \c RENDER mode);  otherwise, an exception of
     548                 :            :     /// class \c InvalidMessageOperation will be thrown.
     549                 :            :     std::string toText() const;
     550                 :            : 
     551                 :            :     /// \brief Render the message in wire formant into a message renderer
     552                 :            :     /// object.
     553                 :            :     ///
     554                 :            :     /// This \c Message must be in the \c RENDER mode and both \c Opcode and
     555                 :            :     /// \c Rcode must have been set beforehand; otherwise, an exception of
     556                 :            :     /// class \c InvalidMessageOperation will be thrown.
     557                 :            :     ///
     558                 :            :     /// \param renderer DNS message rendering context that encapsulates the
     559                 :            :     /// output buffer and name compression information.
     560                 :            :     void toWire(AbstractMessageRenderer& renderer);
     561                 :            : 
     562                 :            :     /// \brief Render the message in wire formant into a message renderer
     563                 :            :     /// object with TSIG.
     564                 :            :     ///
     565                 :            :     /// This method is similar to the other version of \c toWire(), but
     566                 :            :     /// it will also add a TSIG RR with (in many cases) the TSIG MAC for
     567                 :            :     /// the message along with the given TSIG context (\c tsig_ctx).
     568                 :            :     /// The TSIG RR will be placed at the end of \c renderer.
     569                 :            :     /// \c tsig_ctx will be updated based on the fact it was used for signing
     570                 :            :     /// and with the latest MAC.
     571                 :            :     ///
     572                 :            :     /// \exception InvalidMessageOperation The message is not in the Render
     573                 :            :     /// mode, or either Rcode or Opcode is not set.
     574                 :            :     /// \exception InvalidParameter The allowable limit of \c renderer is too
     575                 :            :     /// small for a TSIG or the Header section.  Note that this shouldn't
     576                 :            :     /// happen with parameters as defined in the standard protocols,
     577                 :            :     /// so it's more likely a program bug.
     578                 :            :     /// \exception Unexpected Rendering the TSIG RR fails.  The implementation
     579                 :            :     /// internally makes sure this doesn't happen, so if that ever occurs
     580                 :            :     /// it should mean a bug either in the TSIG context or in the renderer
     581                 :            :     /// implementation.
     582                 :            :     ///
     583                 :            :     /// \param renderer See the other version
     584                 :            :     /// \param tsig_ctx A TSIG context that is to be used for signing the
     585                 :            :     /// message
     586                 :            :     void toWire(AbstractMessageRenderer& renderer, TSIGContext& tsig_ctx);
     587                 :            : 
     588                 :            :     /// Parse options.
     589                 :            :     ///
     590                 :            :     /// describe PRESERVE_ORDER: note doesn't affect EDNS or TSIG.
     591                 :            :     ///
     592                 :            :     /// The option values are used as a parameter for \c fromWire().
     593                 :            :     /// These are values of a bitmask type.  Bitwise operations can be
     594                 :            :     /// performed on these values to express compound options.
     595                 :            :     enum ParseOptions {
     596                 :            :         PARSE_DEFAULT = 0,       ///< The default options
     597                 :            :         PRESERVE_ORDER = 1       ///< Preserve RR order and don't combine them
     598                 :            :     };
     599                 :            : 
     600                 :            :     /// \brief Parse the header section of the \c Message.
     601                 :            :     void parseHeader(isc::util::InputBuffer& buffer);
     602                 :            : 
     603                 :            :     /// \brief (Re)build a \c Message object from wire-format data.
     604                 :            :     ///
     605                 :            :     /// This method parses the given wire format data to build a
     606                 :            :     /// complete Message object.  On success, the values of the header section
     607                 :            :     /// fields can be accessible via corresponding get methods, and the
     608                 :            :     /// question and following sections can be accessible via the
     609                 :            :     /// corresponding iterators.  If the message contains an EDNS or TSIG,
     610                 :            :     /// they can be accessible via \c getEDNS() and \c getTSIGRecord(),
     611                 :            :     /// respectively.
     612                 :            :     ///
     613                 :            :     /// This \c Message must be in the \c PARSE mode.
     614                 :            :     ///
     615                 :            :     /// This method performs strict validation on the given message based
     616                 :            :     /// on the DNS protocol specifications.  If the given message data is
     617                 :            :     /// invalid, this method throws an exception (see the exception list).
     618                 :            :     ///
     619                 :            :     /// By default, this method combines RRs of the same name, RR type and
     620                 :            :     /// RR class in a section into a single RRset, even if they are interleaved
     621                 :            :     /// with a different type of RR (though it would be a rare case in
     622                 :            :     /// practice).  If the \c PRESERVE_ORDER option is specified, it handles
     623                 :            :     /// each RR separately, in the appearing order, and converts it to a
     624                 :            :     /// separate RRset (so this RRset should contain exactly one Rdata).
     625                 :            :     /// This mode will be necessary when the higher level protocol is
     626                 :            :     /// ordering conscious.  For example, in AXFR and IXFR, the position of
     627                 :            :     /// the SOA RRs are crucial.
     628                 :            :     ///
     629                 :            :     /// \exception InvalidMessageOperation \c Message is in the RENDER mode
     630                 :            :     /// \exception DNSMessageFORMERR The given message data is syntactically
     631                 :            :     /// \exception MessageTooShort The given data is shorter than a valid
     632                 :            :     /// header section
     633                 :            :     /// \exception std::bad_alloc Memory allocation failure
     634                 :            :     /// \exception Others \c Name, \c Rdata, and \c EDNS classes can also throw
     635                 :            :     ///
     636                 :            :     /// \param buffer A input buffer object that stores the wire data
     637                 :            :     /// \param options Parse options
     638                 :            :     void fromWire(isc::util::InputBuffer& buffer, ParseOptions options
     639                 :            :         = PARSE_DEFAULT);
     640                 :            : 
     641                 :            :     ///
     642                 :            :     /// \name Protocol constants
     643                 :            :     ///
     644                 :            :     //@{
     645                 :            :     /// \brief The default maximum size of UDP DNS messages that don't cause
     646                 :            :     /// truncation.
     647                 :            :     ///
     648                 :            :     /// With EDNS the maximum size can be increased per message.
     649                 :            :     static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
     650                 :            : 
     651                 :            :     /// \brief The default maximum size of UDP DNS messages we can handle
     652                 :            :     static const uint16_t DEFAULT_MAX_EDNS0_UDPSIZE = 4096;
     653                 :            :     //@}
     654                 :            : 
     655                 :            : private:
     656                 :            :     MessageImpl* impl_;
     657                 :            : };
     658                 :            : 
     659                 :            : /// \brief Pointer-like type pointing to a \c Message
     660                 :            : ///
     661                 :            : /// This type is expected to be used as an argument in asynchronous
     662                 :            : /// callback functions.  The internal reference-counting will ensure that
     663                 :            : /// that ongoing state information will not be lost if the object
     664                 :            : /// that originated the asynchronous call falls out of scope.
     665                 :            : typedef boost::shared_ptr<Message> MessagePtr;
     666                 :            : typedef boost::shared_ptr<const Message> ConstMessagePtr;
     667                 :            : 
     668                 :            : /// Insert the \c Message as a string into stream.
     669                 :            : ///
     670                 :            : /// This method convert \c message into a string and inserts it into the
     671                 :            : /// output stream \c os.
     672                 :            : ///
     673                 :            : /// \param os A \c std::ostream object on which the insertion operation is
     674                 :            : /// performed.
     675                 :            : /// \param message A \c Message object output by the operation.
     676                 :            : /// \return A reference to the same \c std::ostream object referenced by
     677                 :            : /// parameter \c os after the insertion operation.
     678                 :            : std::ostream& operator<<(std::ostream& os, const Message& message);
     679                 :            : }
     680                 :            : }
     681                 :            : #endif  // __MESSAGE_H
     682                 :            : 
     683                 :            : // Local Variables:
     684                 :            : // mode: c++
     685                 :            : // End:

Generated by: LCOV version 1.9