recursive_query.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright (C) 2011 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 __RECURSIVE_QUERY_H
  15. #define __RECURSIVE_QUERY_H 1
  16. #include <asiodns/dns_service.h>
  17. #include <asiodns/dns_server.h>
  18. #include <dns/buffer.h>
  19. #include <nsas/nameserver_address_store.h>
  20. #include <cache/resolver_cache.h>
  21. namespace isc {
  22. namespace asiodns {
  23. /// \brief RTT Recorder
  24. ///
  25. /// Used for testing, this class will hold the set of round-trip times to
  26. /// nameservers for the current recursive query.
  27. ///
  28. /// A pointer to an object of this class is passed to RecursiveQuery which in
  29. /// turn passes it to the created RunningQuery class. When a running query
  30. /// completes, its RTT is passed to the RTT Recorder object.
  31. class RttRecorder {
  32. public:
  33. /// \brief Record Time
  34. ///
  35. /// Adds a round-trip time to the internal vector of times.
  36. ///
  37. /// \param RTT to record.
  38. void addRtt(uint32_t rtt) {
  39. rtt_.push_back(rtt);
  40. }
  41. /// \brief Return RTT Vector
  42. std::vector<uint32_t> getRtt() const {
  43. return rtt_;
  44. }
  45. private:
  46. std::vector<uint32_t> rtt_; ///< Stored round-trip times
  47. };
  48. /// \brief Recursive Query
  49. ///
  50. /// The \c RecursiveQuery class provides a layer of abstraction around
  51. /// the ASIO code that carries out an upstream query.
  52. class RecursiveQuery {
  53. ///
  54. /// \name Constructors
  55. ///
  56. //@{
  57. public:
  58. /// \brief Constructor
  59. ///
  60. /// This is currently the only way to construct \c RecursiveQuery
  61. /// object. If the addresses of the forward nameservers is specified,
  62. /// and every upstream query will be sent to one random address, and
  63. /// the result sent back directly. If not, it will do full resolving.
  64. ///
  65. /// \param dns_service The DNS Service to perform the recursive
  66. /// query on.
  67. /// \param upstream Addresses and ports of the upstream servers
  68. /// to forward queries to.
  69. /// \param upstream_root Addresses and ports of the root servers
  70. /// to use when resolving.
  71. /// \param query_timeout Timeout value for queries we sent, in ms
  72. /// \param client_timeout Timeout value for when we send back an
  73. /// error, in ms
  74. /// \param lookup_timeout Timeout value for when we give up, in ms
  75. /// \param retries how many times we try again (0 means just send and
  76. /// and return if it returs).
  77. RecursiveQuery(DNSService& dns_service,
  78. isc::nsas::NameserverAddressStore& nsas,
  79. isc::cache::ResolverCache& cache,
  80. const std::vector<std::pair<std::string, uint16_t> >&
  81. upstream,
  82. const std::vector<std::pair<std::string, uint16_t> >&
  83. upstream_root,
  84. int query_timeout = 2000,
  85. int client_timeout = 4000,
  86. int lookup_timeout = 30000,
  87. unsigned retries = 3);
  88. //@}
  89. /// \brief Set Round-Trip Time Recorder
  90. ///
  91. /// Sets the RTT recorder object. This is not accessed directly, instead
  92. /// it is passed to created RunningQuery objects.
  93. ///
  94. /// \param recorder Pointer to the RTT recorder object used to hold RTTs.
  95. void setRttRecorder(boost::shared_ptr<RttRecorder>& recorder);
  96. /// \brief Initiate resolving
  97. ///
  98. /// When sendQuery() is called, a (set of) message(s) is sent
  99. /// asynchronously. If upstream servers are set, one is chosen
  100. /// and the response (if any) from that server will be returned.
  101. ///
  102. /// If not upstream is set, a root server is chosen from the
  103. /// root_servers, and the RunningQuery shall do a full resolve
  104. /// (i.e. if the answer is a delegation, it will be followed, etc.)
  105. /// until there is an answer or an error.
  106. ///
  107. /// When there is a response or an error and we give up, the given
  108. /// CallbackPtr object shall be called (with either success() or
  109. /// failure(). See ResolverInterface::Callback for more information.
  110. ///
  111. /// \param question The question being answered <qname/qclass/qtype>
  112. /// \param callback Callback object. See
  113. /// \c ResolverInterface::Callback for more information
  114. void resolve(const isc::dns::QuestionPtr& question,
  115. const isc::resolve::ResolverInterface::CallbackPtr callback);
  116. /// \brief Initiates resolving for the given question.
  117. ///
  118. /// This actually calls the previous sendQuery() with a default
  119. /// callback object, which calls resume() on the given DNSServer
  120. /// object.
  121. ///
  122. /// \param question The question being answered <qname/qclass/qtype>
  123. /// \param answer_message An output Message into which the final response will be copied
  124. /// \param buffer An output buffer into which the intermediate responses will be copied
  125. /// \param server A pointer to the \c DNSServer object handling the client
  126. void resolve(const isc::dns::Question& question,
  127. isc::dns::MessagePtr answer_message,
  128. isc::dns::OutputBufferPtr buffer,
  129. DNSServer* server);
  130. /// \brief Set Test Server
  131. ///
  132. /// This method is *only* for unit testing the class. If set, it enables
  133. /// recursive behaviour but, regardless of responses received, sends every
  134. /// query to the test server.
  135. ///
  136. /// The test server is enabled by setting a non-zero port number.
  137. ///
  138. /// \param address IP address of the test server.
  139. /// \param port Port number of the test server
  140. void setTestServer(const std::string& address, uint16_t port);
  141. private:
  142. DNSService& dns_service_;
  143. isc::nsas::NameserverAddressStore& nsas_;
  144. isc::cache::ResolverCache& cache_;
  145. boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
  146. upstream_;
  147. boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
  148. upstream_root_;
  149. std::pair<std::string, uint16_t> test_server_;
  150. int query_timeout_;
  151. int client_timeout_;
  152. int lookup_timeout_;
  153. unsigned retries_;
  154. boost::shared_ptr<RttRecorder> rtt_recorder_; ///< Round-trip time recorder
  155. };
  156. } // namespace asiodns
  157. } // namespace isc
  158. #endif // __RECURSIVE_QUERY_H