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:
|