name.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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 __NAME_H
  15. #define __NAME_H 1
  16. #include <stdint.h>
  17. #include <string>
  18. #include <vector>
  19. #include <exceptions/exceptions.h>
  20. namespace isc {
  21. namespace util {
  22. class InputBuffer;
  23. class OutputBuffer;
  24. }
  25. namespace dns {
  26. class AbstractMessageRenderer;
  27. ///
  28. /// \brief Base class for name parser exceptions.
  29. ///
  30. class NameParserException : public Exception {
  31. public:
  32. NameParserException(const char* file, size_t line, const char* what) :
  33. isc::Exception(file, line, what) {}
  34. };
  35. ///
  36. /// \brief A standard DNS module exception that is thrown if the name parser
  37. /// encounters an empty label in the middle of a name.
  38. ///
  39. class EmptyLabel : public NameParserException {
  40. public:
  41. EmptyLabel(const char* file, size_t line, const char* what) :
  42. NameParserException(file, line, what) {}
  43. };
  44. ///
  45. /// \brief A standard DNS module exception that is thrown if the name parser
  46. /// encounters too long a name.
  47. ///
  48. class TooLongName : public NameParserException {
  49. public:
  50. TooLongName(const char* file, size_t line, const char* what) :
  51. NameParserException(file, line, what) {}
  52. };
  53. ///
  54. /// \brief A standard DNS module exception that is thrown if the name parser
  55. /// encounters too long a label.
  56. ///
  57. class TooLongLabel : public NameParserException {
  58. public:
  59. TooLongLabel(const char* file, size_t line, const char* what) :
  60. NameParserException(file, line, what) {}
  61. };
  62. ///
  63. /// \brief A standard DNS module exception that is thrown if the name parser
  64. /// encounters an obsolete or incomplete label type. In effect "obsolete" only
  65. /// applies to bitstring labels, which would begin with "\[". Incomplete cases
  66. /// include an incomplete escaped sequence such as "\12".
  67. ///
  68. class BadLabelType : public NameParserException {
  69. public:
  70. BadLabelType(const char* file, size_t line, const char* what) :
  71. NameParserException(file, line, what) {}
  72. };
  73. ///
  74. /// \brief A standard DNS module exception that is thrown if the name parser
  75. /// fails to decode a "\"-escaped sequence.
  76. ///
  77. class BadEscape : public NameParserException {
  78. public:
  79. BadEscape(const char* file, size_t line, const char* what) :
  80. NameParserException(file, line, what) {}
  81. };
  82. ///
  83. /// \brief A standard DNS module exception that is thrown if the name parser
  84. /// finds the input (string or wire-format %data) is incomplete.
  85. ///
  86. /// An attempt of constructing a name from an empty string will trigger this
  87. /// exception.
  88. ///
  89. class IncompleteName : public NameParserException {
  90. public:
  91. IncompleteName(const char* file, size_t line, const char* what) :
  92. NameParserException(file, line, what) {}
  93. };
  94. ///
  95. /// This is a supplemental class used only as a return value of Name::compare().
  96. /// It encapsulate a tuple of the comparison: ordering, number of common labels,
  97. /// and relationship as follows:
  98. /// - ordering: relative ordering under the DNSSEC order relation
  99. /// - labels: the number of common significant labels of the two names being
  100. /// compared
  101. /// - relationship: see NameComparisonResult::NameRelation
  102. ///
  103. class NameComparisonResult {
  104. public:
  105. /// The relation of two names under comparison.
  106. /// Its semantics for the case of
  107. /// <code>name1->compare(name2)</code> (where name1 and name2 are instances
  108. /// of the Name class) is as follows:
  109. /// - SUPERDOMAIN: name1 properly contains name2; name2 is a proper
  110. /// subdomain of name1
  111. /// - SUBDOMAIN: name1 is a proper subdomain of name2
  112. /// - EQUAL: name1 and name2 are equal
  113. /// - COMMONANCESTOR: name1 and name2 share a common ancestor
  114. ///
  115. /// Note that in our implementation there's always a hierarchical
  116. /// relationship between any two names since all names are absolute and
  117. /// they at least share the trailing empty label.
  118. /// So, for example, the relationship between "com." and "net." is
  119. /// "commonancestor". This may be counter intuitive and inconvenient, but
  120. /// we'll keep this design at the moment until we decide whether and how to
  121. /// handle "non absolute" names (see the description of the \c Name class).
  122. /// If we want to (re)introduce the notion of non absolute names, we'll
  123. /// want to distinguish "com" and "com.", and the current definition would
  124. /// be more compatible for that purpose.
  125. /// If, on the other hand, we finally decide we really don't need that
  126. /// notion, we'll probably reconsider the design here, too.
  127. enum NameRelation {
  128. SUPERDOMAIN = 0,
  129. SUBDOMAIN = 1,
  130. EQUAL = 2,
  131. COMMONANCESTOR = 3
  132. };
  133. ///
  134. /// \name Constructors and Destructor
  135. ///
  136. //@{
  137. /// \brief Constructor from a comparison tuple
  138. ///
  139. /// This constructor simply initializes the object in the straightforward
  140. /// way.
  141. NameComparisonResult(int order, unsigned int nlabels,
  142. NameRelation relation) :
  143. order_(order), nlabels_(nlabels), relation_(relation) {}
  144. //@}
  145. ///
  146. /// \name Getter Methods
  147. ///
  148. //@{
  149. /// Returns the ordering of the comparison result
  150. int getOrder() const { return (order_); }
  151. /// Returns the number of common labels of the comparison result
  152. unsigned int getCommonLabels() const { return (nlabels_); }
  153. /// Returns the NameRelation of the comparison result
  154. NameRelation getRelation() const { return (relation_); }
  155. //@}
  156. private:
  157. int order_;
  158. unsigned int nlabels_;
  159. NameRelation relation_;
  160. };
  161. ///
  162. /// The \c Name class encapsulates DNS names.
  163. ///
  164. /// It provides interfaces to construct a name from string or wire-format %data,
  165. /// transform a name into a string or wire-format %data, compare two names, get
  166. /// access to various properties of a name, etc.
  167. ///
  168. /// Notes to developers: Internally, a name object maintains the name %data
  169. /// in wire format as an instance of \c std::string. Since many string
  170. /// implementations adopt copy-on-write %data sharing, we expect this approach
  171. /// will make copying a name less expensive in typical cases. If this is
  172. /// found to be a significant performance bottleneck later, we may reconsider
  173. /// the internal representation or perhaps the API.
  174. ///
  175. /// A name object also maintains a vector of offsets (\c offsets_ member),
  176. /// each of which is the offset to a label of the name: The n-th element of
  177. /// the vector specifies the offset to the n-th label. For example, if the
  178. /// object represents "www.example.com", the elements of the offsets vector
  179. /// are 0, 4, 12, and 16. Note that the offset to the trailing dot (16) is
  180. /// included. In the BIND9 DNS library from which this implementation is
  181. /// derived, the offsets are optional, probably due to performance
  182. /// considerations (in fact, offsets can always be calculated from the name
  183. /// %data, and in that sense are redundant). In our implementation, however,
  184. /// we always build and maintain the offsets. We believe we need more low
  185. /// level, specialized %data structure and interface where we really need to
  186. /// pursue performance, and would rather keep this generic API and
  187. /// implementation simpler.
  188. ///
  189. /// While many other DNS APIs introduce an "absolute or relative"
  190. /// attribute of names as defined in RFC1035, names are always "absolute" in
  191. /// the initial design of this API.
  192. /// In fact, separating absolute and relative would confuse API users
  193. /// unnecessarily. For example, it's not so intuitive to consider the
  194. /// comparison result of an absolute name with a relative name.
  195. /// We've looked into how the concept of absolute names is used in BIND9,
  196. /// and found that in many cases names are generally absolute.
  197. /// The only reasonable case of separating absolute and relative is in a master
  198. /// file parser, where a relative name must be a complete name with an "origin"
  199. /// name, which must be absolute. So, in this initial design, we chose a
  200. /// simpler approach: the API generally handles names as absolute; when we
  201. /// introduce a parser of master files, we'll introduce the notion of relative
  202. /// names as a special case.
  203. ///
  204. class Name {
  205. // LabelSequences use knowledge about the internal data structure
  206. // of this class for efficiency (they use the offsets_ vector and
  207. // the ndata_ string)
  208. friend class LabelSequence;
  209. ///
  210. /// \name Constructors and Destructor
  211. ///
  212. //@{
  213. private:
  214. /// \brief Name data string
  215. typedef std::basic_string<uint8_t> NameString;
  216. /// \brief Name offsets type
  217. typedef std::vector<uint8_t> NameOffsets;
  218. /// The default constructor
  219. ///
  220. /// This is used internally in the class implementation, but at least at
  221. /// the moment defined as private because it will construct an incomplete
  222. /// object in that it doesn't have any labels. We may reconsider this
  223. /// design choice as we see more applications of the class.
  224. Name() : length_(0), labelcount_(0) {}
  225. public:
  226. /// Constructor from a string
  227. ///
  228. /// If the given string does not represent a valid DNS name, an exception
  229. /// of class \c EmptyLabel, \c TooLongLabel, \c BadLabelType, \c BadEscape,
  230. /// \c TooLongName, or \c IncompleteName will be thrown.
  231. /// In addition, if resource allocation for the new name fails, a
  232. /// corresponding standard exception will be thrown.
  233. ///
  234. /// \param namestr A string representation of the name to be constructed.
  235. /// \param downcase Whether to convert upper case alphabets to lower case.
  236. explicit Name(const std::string& namestr, bool downcase = false);
  237. /// Constructor from wire-format %data.
  238. ///
  239. /// The \c buffer parameter normally stores a complete DNS message
  240. /// containing the name to be constructed. The current read position of
  241. /// the buffer points to the head of the name.
  242. ///
  243. /// The input %data may or may not be compressed; if it's compressed, this
  244. /// method will automatically decompress it.
  245. ///
  246. /// If the given %data does not represent a valid DNS name, an exception
  247. /// of class \c DNSMessageFORMERR will be thrown.
  248. /// In addition, if resource allocation for the new name fails, a
  249. /// corresponding standard exception will be thrown.
  250. ///
  251. /// \param buffer A buffer storing the wire format %data.
  252. /// \param downcase Whether to convert upper case alphabets to lower case.
  253. explicit Name(isc::util::InputBuffer& buffer, bool downcase = false);
  254. ///
  255. /// We use the default copy constructor intentionally.
  256. //@}
  257. /// We use the default copy assignment operator intentionally.
  258. ///
  259. ///
  260. /// \name Getter Methods
  261. ///
  262. //@{
  263. /// \brief Provides one-byte name %data in wire format at the specified
  264. /// position.
  265. ///
  266. /// This method returns the unsigned 8-bit value of wire-format \c Name
  267. /// %data at the given position from the head.
  268. ///
  269. /// For example, if \c n is a \c Name object for "example.com",
  270. /// \c n.at(3) would return \c 'a', and \c n.at(7) would return \c 'e'.
  271. /// Note that \c n.at(0) would be 7 (decimal), the label length of
  272. /// "example", instead of \c 'e', because it returns a %data portion
  273. /// in wire-format. Likewise, \c n.at(8) would return 3 (decimal)
  274. /// instead of <code>'.'</code>
  275. ///
  276. /// This method would be useful for an application to examine the
  277. /// wire-format name %data without dumping the %data into a buffer,
  278. /// which would involve %data copies and would be less efficient.
  279. /// One common usage of this method would be something like this:
  280. /// \code for (size_t i = 0; i < name.getLength(); ++i) {
  281. /// uint8_t c = name.at(i);
  282. /// // do something with c
  283. /// } \endcode
  284. ///
  285. /// Parameter \c pos must be in the valid range of the name %data, that is,
  286. /// must be less than \c Name.getLength(). Otherwise, an exception of
  287. /// class \c OutOfRange will be thrown.
  288. /// This method never throws an exception in other ways.
  289. ///
  290. /// \param pos The position in the wire format name %data to be returned.
  291. /// \return An unsigned 8-bit integer corresponding to the name %data
  292. /// at the position of \c pos.
  293. uint8_t at(size_t pos) const
  294. {
  295. if (pos >= length_) {
  296. isc_throw(OutOfRange, "Out of range access in Name::at()");
  297. }
  298. return (ndata_[pos]);
  299. }
  300. /// \brief Gets the length of the <code>Name</code> in its wire format.
  301. ///
  302. /// This method never throws an exception.
  303. ///
  304. /// \return the length (the number of octets in wire format) of the
  305. /// <code>Name</code>
  306. size_t getLength() const { return (length_); }
  307. /// \brief Returns the number of labels contained in the <code>Name</code>.
  308. ///
  309. /// Note that an empty label (corresponding to a trailing '.') is counted
  310. /// as a single label, so the return value of this method must be >0.
  311. ///
  312. /// This method never throws an exception.
  313. ///
  314. /// \return the number of labels
  315. unsigned int getLabelCount() const { return (labelcount_); }
  316. //@}
  317. ///
  318. /// \name Converter methods
  319. ///
  320. //@{
  321. /// \brief Convert the Name to a string.
  322. ///
  323. /// This method returns a <code>std::string</code> object representing the
  324. /// Name as a string. Unless <code>omit_final_dot</code> is
  325. /// <code>true</code>, the returned string ends with a dot '.'; the default
  326. /// is <code>false</code>. The default value of this parameter is
  327. /// <code>true</code>; converted names will have a trailing dot by default.
  328. ///
  329. /// This function assumes the name is in proper uncompressed wire format.
  330. /// If it finds an unexpected label character including compression pointer,
  331. /// an exception of class \c BadLabelType will be thrown.
  332. /// In addition, if resource allocation for the result string fails, a
  333. /// corresponding standard exception will be thrown.
  334. //
  335. /// \param omit_final_dot whether to omit the trailing dot in the output.
  336. /// \return a string representation of the <code>Name</code>.
  337. std::string toText(bool omit_final_dot = false) const;
  338. private:
  339. /// \brief Convert the Name to a string.
  340. ///
  341. /// This method returns a <code>std::string</code> object representing the
  342. /// Name as a string. Unless <code>omit_final_dot</code> is
  343. /// <code>true</code>, the returned string ends with a dot '.'; the default
  344. /// is <code>false</code>. The default value of this parameter is
  345. /// <code>true</code>; converted names will have a trailing dot by default.
  346. ///
  347. /// This function assumes the name is in proper uncompressed wire format.
  348. /// If it finds an unexpected label character including compression pointer,
  349. /// an exception of class \c BadLabelType will be thrown.
  350. /// In addition, if resource allocation for the result string fails, a
  351. /// corresponding standard exception will be thrown.
  352. ///
  353. /// This function only returns a string for the range of labels
  354. /// between <code>first_label</code> and <code>last_label</code>.
  355. //
  356. /// \param omit_final_dot whether to omit the trailing dot in the output.
  357. /// \param first_label the first label which should be contained in the result.
  358. /// \param last_label the last label which should be contained in the result.
  359. /// \return a string representation of the <code>Name</code>.
  360. std::string toText(bool omit_final_dot,
  361. unsigned int first_label,
  362. unsigned int last_label) const;
  363. public:
  364. /// \brief Render the <code>Name</code> in the wire format with compression.
  365. ///
  366. /// This method dumps the Name in wire format with help of \c renderer,
  367. /// which encapsulates output buffer and name compression algorithm to
  368. /// render the name.
  369. ///
  370. /// If resource allocation in rendering process fails, a corresponding
  371. /// standard exception will be thrown.
  372. ///
  373. /// \param renderer DNS message rendering context that encapsulates the
  374. /// output buffer and name compression information.
  375. void toWire(AbstractMessageRenderer& renderer) const;
  376. /// \brief Render the <code>Name</code> in the wire format without
  377. /// compression.
  378. ///
  379. /// If resource allocation in rendering process fails, a corresponding
  380. /// standard exception will be thrown. This can be avoided by preallocating
  381. /// a sufficient size of \c buffer. Specifically, if
  382. /// <code>buffer.getCapacity() - buffer.getLength() >= Name::MAX_WIRE</code>
  383. /// then this method should not throw an exception.
  384. ///
  385. /// \param buffer An output buffer to store the wire %data.
  386. void toWire(isc::util::OutputBuffer& buffer) const;
  387. //@}
  388. ///
  389. /// \name Comparison methods
  390. ///
  391. //@{
  392. /// \brief Compare two <code>Name</code>s.
  393. ///
  394. /// This method compares the <code>Name</code> and <code>other</code> and
  395. /// returns the result in the form of a <code>NameComparisonResult</code>
  396. /// object.
  397. ///
  398. /// Note that this is case-insensitive comparison.
  399. ///
  400. /// This method never throws an exception.
  401. ///
  402. /// \param other the right-hand operand to compare against.
  403. /// \return a <code>NameComparisonResult</code> object representing the
  404. /// comparison result.
  405. NameComparisonResult compare(const Name& other) const;
  406. /// \brief Return true iff two names are equal.
  407. ///
  408. /// Semantically this could be implemented based on the result of the
  409. /// \c compare() method, but the actual implementation uses different code
  410. /// that simply performs character-by-character comparison (case
  411. /// insensitive for the name label parts) on the two names. This is because
  412. /// it would be much faster and the simple equality check would be pretty
  413. /// common.
  414. ///
  415. /// This method never throws an exception.
  416. ///
  417. /// \param other the <code>Name</code> object to compare against.
  418. /// \return true if the two names are equal; otherwise false.
  419. bool equals(const Name& other) const;
  420. /// Same as equals()
  421. bool operator==(const Name& other) const { return (equals(other)); }
  422. /// \brief Return true iff two names are not equal.
  423. ///
  424. /// This method simply negates the result of \c equal() method, and in that
  425. /// sense it's redundant. The separate method is provided just for
  426. /// convenience.
  427. bool nequals(const Name& other) const { return (!(equals(other))); }
  428. /// Same as nequals()
  429. bool operator!=(const Name& other) const { return (nequals(other)); }
  430. /// \brief Less-than or equal comparison for Name against <code>other</code>
  431. ///
  432. /// The comparison is based on the result of the \c compare() method.
  433. ///
  434. /// This method never throws an exception.
  435. ///
  436. /// \param other the <code>Name</code> object to compare against.
  437. /// \return true if <code>compare(other).getOrder() <= 0</code>;
  438. /// otherwise false.
  439. bool leq(const Name& other) const;
  440. /// Same as leq()
  441. bool operator<=(const Name& other) const { return (leq(other)); }
  442. /// \brief Greater-than or equal comparison for Name against
  443. /// <code>other</code>
  444. ///
  445. /// The comparison is based on the result of the \c compare() method.
  446. ///
  447. /// This method never throws an exception.
  448. ///
  449. /// \param other the <code>Name</code> object to compare against.
  450. /// \return true if <code>compare(other).getOrder() >= 0</code>;
  451. /// otherwise false.
  452. bool geq(const Name& other) const;
  453. /// Same as geq()
  454. bool operator>=(const Name& other) const { return (geq(other)); }
  455. /// \brief Less-than comparison for Name against <code>other</code>
  456. ///
  457. /// The comparison is based on the result of the \c compare() method.
  458. ///
  459. /// This method never throws an exception.
  460. ///
  461. /// \param other the <code>Name</code> object to compare against.
  462. /// \return true if <code>compare(other).getOrder() < 0</code>;
  463. /// otherwise false.
  464. bool lthan(const Name& other) const;
  465. /// Same as lthan()
  466. bool operator<(const Name& other) const { return (lthan(other)); }
  467. /// \brief Greater-than comparison for Name against <code>other</code>
  468. ///
  469. /// The comparison is based on the result of the \c compare() method.
  470. ////
  471. /// This method never throws an exception.
  472. ///
  473. /// \param other the <code>Name</code> object to compare against.
  474. /// \return true if <code>compare(other).getOrder() > 0</code>;
  475. /// otherwise false.
  476. bool gthan(const Name& other) const;
  477. /// Same as gthan()
  478. bool operator>(const Name& other) const { return (gthan(other)); }
  479. //@}
  480. ///
  481. /// \name Transformer methods
  482. ///
  483. //@{
  484. /// \brief Extract a specified subpart of Name.
  485. ///
  486. /// <code>name.split(first, n)</code> constructs a new name starting from
  487. /// the <code>first</code>-th label of the \c name, and subsequent \c n
  488. /// labels including the \c first one. Since names in this current
  489. /// implementation are always "absolute", if the specified range doesn't
  490. /// contain the trailing dot of the original \c name, then a dot will be
  491. /// appended to the resulting name. As a result, the number of labels
  492. /// will be <code>n + 1</code>, rather than \c n. For example,
  493. /// when \c n is <code>Name("www.example.com")</code>,
  494. /// both <code>n.split(1, 2)</code> and <code>n.split(1, 3)</code>
  495. /// will produce a name corresponding to "example.com.", which has 3 labels.
  496. /// Note also that labels are counted from 0, and so <code>first = 1</code>
  497. /// in this example specified the label "example", not "www".
  498. ///
  499. /// Parameter \c n must be larger than 0, and the range specified by
  500. /// \c first and \c n must not exceed the valid range of the original name;
  501. /// otherwise, an exception of class \c OutOfRange will be thrown.
  502. ///
  503. /// Note to developers: we may want to have different versions (signatures)
  504. /// of this method. For example, we want to split the Name based on a given
  505. /// suffix name.
  506. ///
  507. /// \param first The start position (in labels) of the extracted name
  508. /// \param n Number of labels of the extracted name
  509. /// \return A new Name object based on the Name containing <code>n</code>
  510. /// labels including and following the <code>first</code> label.
  511. Name split(unsigned int first, unsigned int n) const;
  512. /// \brief Extract a specified super domain name of Name.
  513. ///
  514. /// This function constructs a new \c Name object that is a super domain
  515. /// of \c this name.
  516. /// The new name is \c level labels upper than \c this name.
  517. /// For example, when \c name is www.example.com,
  518. /// <code>name.split(1)</code> will return a \c Name object for example.com.
  519. /// \c level can be 0, in which case this method returns a copy of
  520. /// \c this name.
  521. /// The possible maximum value for \c level is
  522. /// <code>this->getLabelCount()-1</code>, in which case this method
  523. /// returns a root name.
  524. ///
  525. /// One common expected usage of this method is to iterate over super
  526. /// domains of a given name, label by label, as shown in the following
  527. /// sample code:
  528. /// \code // if name is www.example.com...
  529. /// for (int i = 0; i < name.getLabelCount(); ++i) {
  530. /// Name upper_name(name.split(i));
  531. /// // upper_name'll be www.example.com., example.com., com., and then .
  532. /// }
  533. /// \endcode
  534. ///
  535. /// \c level must be smaller than the number of labels of \c this name;
  536. /// otherwise an exception of class \c OutOfRange will be thrown.
  537. /// In addition, if resource allocation for the new name fails, a
  538. /// corresponding standard exception will be thrown.
  539. ///
  540. /// Note to developers: probably as easily imagined, this method is a
  541. /// simple wrapper to one usage of the other
  542. /// <code>split(unsigned int, unsigned int) const</code> method and is
  543. /// redundant in some sense.
  544. /// We provide the "redundant" method for convenience, however, because
  545. /// the expected usage shown above seems to be common, and the parameters
  546. /// to the other \c split(unsigned int, unsigned int) const to implement
  547. /// it may not be very intuitive.
  548. ///
  549. /// We are also aware that it is generally discouraged to add a public
  550. /// member function that could be implemented using other member functions.
  551. /// We considered making it a non member function, but we could not come
  552. /// up with an intuitive function name to represent the specific service.
  553. /// Some other BIND 10 developers argued, probably partly because of the
  554. /// counter intuitive function name, a different signature of \c split
  555. /// would be better to improve code readability.
  556. /// While that may be a matter of personal preference, we accepted the
  557. /// argument. One major goal of public APIs like this is wider acceptance
  558. /// from internal/external developers, so unless there is a clear advantage
  559. /// it would be better to respect the preference of the API users.
  560. ///
  561. /// Since this method doesn't have to be a member function in other way,
  562. /// it is intentionally implemented only using public interfaces of the
  563. /// \c Name class; it doesn't refer to private members of the class even if
  564. /// it could.
  565. /// This way we hope we can avoid damaging the class encapsulation,
  566. /// which is a major drawback of public member functions.
  567. /// As such if and when this "method" has to be extended, it should be
  568. /// implemented without the privilege of being a member function unless
  569. /// there is a very strong reason to do so. In particular a minor
  570. /// performance advantage shouldn't justify that approach.
  571. ///
  572. /// \param level The number of labels to be removed from \c this name to
  573. /// create the super domain name.
  574. /// (0 <= \c level < <code>this->getLabelCount()</code>)
  575. /// \return A new \c Name object to be created.
  576. Name split(unsigned int level) const;
  577. /// \brief Reverse the labels of a name
  578. ///
  579. /// This method reverses the labels of a name. For example, if
  580. /// \c this is "www.example.com.", this method will return
  581. /// "com.example.www." (This is useful because DNSSEC sort order
  582. /// is equivalent to a lexical sort of label-reversed names.)
  583. Name reverse() const;
  584. /// \brief Concatenate two names.
  585. ///
  586. /// This method appends \c suffix to \c this Name. The trailing dot of
  587. /// \c this Name will be removed. For example, if \c this is "www."
  588. /// and \c suffix is "example.com.", a successful return of this method
  589. /// will be a name of "www.example.com."
  590. ///
  591. ///The resulting length of the concatenated name must not exceed
  592. /// \c Name::MAX_WIRE; otherwise an exception of class
  593. /// \c TooLongName will be thrown.
  594. ///
  595. /// \param suffix a Name object to be appended to the Name.
  596. /// \return a new Name object concatenating \c suffix to \c this Name.
  597. Name concatenate(const Name& suffix) const;
  598. /// \brief Downcase all upper case alphabet characters in the name.
  599. ///
  600. /// This method modifies the calling object so that it can perform the
  601. /// conversion as fast as possible and can be exception free.
  602. ///
  603. /// The return value of this version of \c downcase() is a reference to
  604. /// the calling object (i.e., \c *this) so that the caller can use the
  605. /// result of downcasing in a single line. For example, if variable
  606. /// \c n is a \c Name class object possibly containing upper case
  607. /// characters, and \c b is an \c OutputBuffer class object, then the
  608. /// following code will dump the name in wire format to \c b with
  609. /// downcasing upper case characters:
  610. ///
  611. /// \code n.downcase().toWire(b); \endcode
  612. ///
  613. /// Since this method modifies the calling object, a \c const name object
  614. /// cannot call it. If \c n is a \c const Name class object, it must first
  615. /// be copied to a different object and the latter must be used for the
  616. /// downcase modification.
  617. ///
  618. /// \return A reference to the calling object with being downcased.
  619. Name& downcase();
  620. //@}
  621. ///
  622. /// \name Testing methods
  623. ///
  624. //@{
  625. /// \brief Test if this is a wildcard name.
  626. ///
  627. /// \return \c true if the least significant label of this Name is
  628. /// <code>'*'</code>; otherwise \c false.
  629. bool isWildcard() const;
  630. //@}
  631. ///
  632. /// \name Protocol constants
  633. ///
  634. //@{
  635. /// \brief Max allowable length of domain names.
  636. static const size_t MAX_WIRE = 255;
  637. /// \brief Max allowable labels of domain names.
  638. ///
  639. /// This is <code>ceil(MAX_WIRE / 2)</code>, and is equal to the number of
  640. /// labels of name "a.a.a.a....a." (127 "a"'s and trailing dot).
  641. static const size_t MAX_LABELS = 128;
  642. /// \brief Max allowable length of labels of a domain name.
  643. static const size_t MAX_LABELLEN = 63;
  644. /// \brief Max possible pointer value for name compression.
  645. ///
  646. /// This is the highest number of 14-bit unsigned integer. Name compression
  647. /// pointers are identified as a 2-byte value starting with the upper two
  648. /// bit being 11.
  649. static const uint16_t MAX_COMPRESS_POINTER = 0x3fff;
  650. /// \brief A 8-bit masked value indicating a start of compression pointer.
  651. static const uint16_t COMPRESS_POINTER_MARK8 = 0xc0;
  652. /// \brief A 16-bit masked value indicating a start of compression pointer.
  653. static const uint16_t COMPRESS_POINTER_MARK16 = 0xc000;
  654. //@}
  655. ///
  656. /// \name Well-known name constants
  657. ///
  658. //@{
  659. /// \brief Root name (i.e. ".").
  660. static const Name& ROOT_NAME();
  661. //@}
  662. private:
  663. NameString ndata_;
  664. NameOffsets offsets_;
  665. unsigned int length_;
  666. unsigned int labelcount_;
  667. };
  668. inline const Name&
  669. Name::ROOT_NAME() {
  670. static Name root_name(".");
  671. return (root_name);
  672. }
  673. ///
  674. /// \brief Insert the name as a string into stream.
  675. ///
  676. /// This method convert the \c name into a string and inserts it into the
  677. /// output stream \c os.
  678. ///
  679. /// This function overloads the global operator<< to behave as described in
  680. /// ostream::operator<< but applied to \c Name objects.
  681. ///
  682. /// \param os A \c std::ostream object on which the insertion operation is
  683. /// performed.
  684. /// \param name The \c Name object output by the operation.
  685. /// \return A reference to the same \c std::ostream object referenced by
  686. /// parameter \c os after the insertion operation.
  687. std::ostream&
  688. operator<<(std::ostream& os, const Name& name);
  689. }
  690. }
  691. #endif // __NAME_H
  692. // Local Variables:
  693. // mode: c++
  694. // End: