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