message.h 27 KB

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