labelsequence.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright (C) 2012 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 __LABELSEQUENCE_H
  15. #define __LABELSEQUENCE_H 1
  16. #include <dns/name.h>
  17. #include <util/buffer.h>
  18. namespace isc {
  19. namespace dns {
  20. /// \brief Light-weight Accessor to Name object
  21. ///
  22. /// The purpose of this class is to easily match Names and parts of Names,
  23. /// without needing to copy the underlying data on each label strip.
  24. ///
  25. /// It can only work on existing Name objects, and the Name object MUST
  26. /// remain in scope during the entire lifetime of its associated
  27. /// LabelSequence(s).
  28. ///
  29. /// Upon creation of a LabelSequence, it records the offsets of the
  30. /// labels in the wireformat data of the Name. When stripLeft() or
  31. /// stripRight() is called on the LabelSequence, no changes in the
  32. /// Name's data occur, but the internal pointers of the
  33. /// LabelSequence are modified.
  34. ///
  35. /// LabelSequences can be compared to other LabelSequences, and their
  36. /// data can be requested (which then points to part of the original
  37. /// data of the associated Name object).
  38. ///
  39. class LabelSequence {
  40. public:
  41. /// \brief Constructs a LabelSequence for the given name
  42. ///
  43. /// \note The associated Name MUST remain in scope during the lifetime
  44. /// of this LabelSequence, since getData() refers to data from the
  45. /// Name object (the only data the LabelSequence stores are pointers
  46. /// to the labels in the Name object).
  47. ///
  48. /// \param name The Name to construct a LabelSequence for
  49. LabelSequence(const Name& name): name_(name),
  50. first_label_(0),
  51. last_label_(name.getLabelCount())
  52. {}
  53. /// \brief Return the wire-format data for this LabelSequence
  54. ///
  55. /// The data, is returned as a pointer to the original wireformat
  56. /// data of the original Name object, and the given len value is
  57. /// set to the number of octets that match this labelsequence.
  58. ///
  59. /// \note The data pointed to is only valid if the original Name
  60. /// object is still in scope
  61. ///
  62. /// \param len Pointer to a size_t where the length of the data
  63. /// will be stored (in number of octets)
  64. /// \return Pointer to the wire-format data of this label sequence
  65. const char* getData(size_t* len) const;
  66. /// \brief Return the length of the wire-format data of this LabelSequence
  67. ///
  68. /// This method returns the number of octets for the data that would
  69. /// be returned by the \c getData() method.
  70. ///
  71. /// Note that the return value of this method is always positive.
  72. /// Note also that if the return value of this method is 1, it means the
  73. /// sequence consists of the null label, i.e., a single "dot", and vice
  74. /// versa.
  75. ///
  76. /// \note The data pointed to is only valid if the original Name
  77. /// object is still in scope
  78. ///
  79. /// \return The length of the data of the label sequence in octets.
  80. size_t getDataLength() const;
  81. /// \brief Compares two label sequences.
  82. ///
  83. /// Performs a (optionally case-insensitive) comparison between this
  84. /// LabelSequence and another LabelSequence.
  85. ///
  86. /// \param other The LabelSequence to compare with
  87. /// \param case_sensitive If true, comparison is case-insensitive
  88. /// \return true if The label sequences consist are the same length,
  89. /// and contain the same data.
  90. bool equals(const LabelSequence& other, bool case_sensitive = false) const;
  91. /// \brief Remove labels from the front of this LabelSequence
  92. ///
  93. /// \note No actual memory is changed, this operation merely updates the
  94. /// internal pointers based on the offsets in the Name object.
  95. ///
  96. /// \exeption OutOfRange if i is greater than or equal to the number
  97. /// of labels currently pointed to by this LabelSequence
  98. ///
  99. /// \param i The number of labels to remove.
  100. void stripLeft(size_t i);
  101. /// \brief Remove labels from the end of this LabelSequence
  102. ///
  103. /// \note No actual memory is changed, this operation merely updates the
  104. /// internal pointers based on the offsets in the Name object.
  105. ///
  106. /// \exeption OutOfRange if i is greater than or equal to the number
  107. /// of labels currently pointed to by this LabelSequence
  108. ///
  109. /// \param i The number of labels to remove.
  110. void stripRight(size_t i);
  111. /// \brief Returns the current number of labels for this LabelSequence
  112. ///
  113. /// \return The number of labels
  114. size_t getLabelCount() const { return (last_label_ - first_label_); }
  115. /// \brief Returns the original Name object associated with this
  116. /// LabelSequence
  117. ///
  118. /// While the Name should still be in scope during the lifetime of
  119. /// the LabelSequence, it can still be useful to have access to it,
  120. /// for instance in helper functions that are only passed the
  121. /// LabelSequence itself.
  122. ///
  123. /// \return Reference to the original Name object
  124. const Name& getName() const { return (name_); }
  125. /// \brief Calculate a simple hash for the label sequence.
  126. ///
  127. /// This method calculates a hash value for the label sequence as binary
  128. /// data. If \c case_sensitive is false, it ignores the case stored in
  129. /// the labels; specifically, it normalizes the labels by converting all
  130. /// upper case characters to lower case ones and calculates the hash value
  131. /// for the result.
  132. ///
  133. /// This method is intended to provide a lightweight way to store a
  134. /// relatively small number of label sequences in a hash table.
  135. /// For this reason it only takes into account data up to 16 octets
  136. /// (16 was derived from BIND 9's implementation). Also, the function does
  137. /// not provide any unpredictability; a specific sequence will always have
  138. /// the same hash value. It should therefore not be used in the context
  139. /// where an untrusted third party can mount a denial of service attack by
  140. /// forcing the application to create a very large number of label
  141. /// sequences that have the same hash value and expected to be stored in
  142. /// a hash table.
  143. ///
  144. /// \exception None
  145. ///
  146. /// \param case_sensitive
  147. /// \return A hash value for this label sequence.
  148. size_t getHash(bool case_sensitive) const;
  149. /// \brief Checks whether the label sequence is absolute
  150. ///
  151. /// \return true if the last label is the root label
  152. bool isAbsolute() const;
  153. private:
  154. const Name& name_;
  155. size_t first_label_;
  156. size_t last_label_;
  157. };
  158. } // end namespace dns
  159. } // end namespace isc
  160. #endif