123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
- //
- // Permission to use, copy, modify, and/or distribute this software for any
- // purpose with or without fee is hereby granted, provided that the above
- // copyright notice and this permission notice appear in all copies.
- //
- // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- #ifndef __RECURSIVE_QUERY_H
- #define __RECURSIVE_QUERY_H 1
- #include <asiodns/dns_service.h>
- #include <asiodns/dns_server.h>
- #include <dns/buffer.h>
- #include <nsas/nameserver_address_store.h>
- #include <cache/resolver_cache.h>
- namespace isc {
- namespace asiodns {
- /// \brief RTT Recorder
- ///
- /// Used for testing, this class will hold the set of round-trip times to
- /// nameservers for the current recursive query.
- ///
- /// A pointer to an object of this class is passed to RecursiveQuery which in
- /// turn passes it to the created RunningQuery class. When a running query
- /// completes, its RTT is passed to the RTT Recorder object.
- class RttRecorder {
- public:
- /// \brief Record Time
- ///
- /// Adds a round-trip time to the internal vector of times.
- ///
- /// \param RTT to record.
- void addRtt(uint32_t rtt) {
- rtt_.push_back(rtt);
- }
- /// \brief Return RTT Vector
- std::vector<uint32_t> getRtt() const {
- return rtt_;
- }
- private:
- std::vector<uint32_t> rtt_; ///< Stored round-trip times
- };
- /// \brief Recursive Query
- ///
- /// The \c RecursiveQuery class provides a layer of abstraction around
- /// the ASIO code that carries out an upstream query.
- class RecursiveQuery {
- ///
- /// \name Constructors
- ///
- //@{
- public:
- /// \brief Constructor
- ///
- /// This is currently the only way to construct \c RecursiveQuery
- /// object. If the addresses of the forward nameservers is specified,
- /// and every upstream query will be sent to one random address, and
- /// the result sent back directly. If not, it will do full resolving.
- ///
- /// \param dns_service The DNS Service to perform the recursive
- /// query on.
- /// \param upstream Addresses and ports of the upstream servers
- /// to forward queries to.
- /// \param upstream_root Addresses and ports of the root servers
- /// to use when resolving.
- /// \param query_timeout Timeout value for queries we sent, in ms
- /// \param client_timeout Timeout value for when we send back an
- /// error, in ms
- /// \param lookup_timeout Timeout value for when we give up, in ms
- /// \param retries how many times we try again (0 means just send and
- /// and return if it returs).
- RecursiveQuery(DNSService& dns_service,
- isc::nsas::NameserverAddressStore& nsas,
- isc::cache::ResolverCache& cache,
- const std::vector<std::pair<std::string, uint16_t> >&
- upstream,
- const std::vector<std::pair<std::string, uint16_t> >&
- upstream_root,
- int query_timeout = 2000,
- int client_timeout = 4000,
- int lookup_timeout = 30000,
- unsigned retries = 3);
- //@}
- /// \brief Set Round-Trip Time Recorder
- ///
- /// Sets the RTT recorder object. This is not accessed directly, instead
- /// it is passed to created RunningQuery objects.
- ///
- /// \param recorder Pointer to the RTT recorder object used to hold RTTs.
- void setRttRecorder(boost::shared_ptr<RttRecorder>& recorder);
- /// \brief Initiate resolving
- ///
- /// When sendQuery() is called, a (set of) message(s) is sent
- /// asynchronously. If upstream servers are set, one is chosen
- /// and the response (if any) from that server will be returned.
- ///
- /// If not upstream is set, a root server is chosen from the
- /// root_servers, and the RunningQuery shall do a full resolve
- /// (i.e. if the answer is a delegation, it will be followed, etc.)
- /// until there is an answer or an error.
- ///
- /// When there is a response or an error and we give up, the given
- /// CallbackPtr object shall be called (with either success() or
- /// failure(). See ResolverInterface::Callback for more information.
- ///
- /// \param question The question being answered <qname/qclass/qtype>
- /// \param callback Callback object. See
- /// \c ResolverInterface::Callback for more information
- void resolve(const isc::dns::QuestionPtr& question,
- const isc::resolve::ResolverInterface::CallbackPtr callback);
- /// \brief Initiates resolving for the given question.
- ///
- /// This actually calls the previous sendQuery() with a default
- /// callback object, which calls resume() on the given DNSServer
- /// object.
- ///
- /// \param question The question being answered <qname/qclass/qtype>
- /// \param answer_message An output Message into which the final response will be copied
- /// \param buffer An output buffer into which the intermediate responses will be copied
- /// \param server A pointer to the \c DNSServer object handling the client
- void resolve(const isc::dns::Question& question,
- isc::dns::MessagePtr answer_message,
- isc::dns::OutputBufferPtr buffer,
- DNSServer* server);
- /// \brief Set Test Server
- ///
- /// This method is *only* for unit testing the class. If set, it enables
- /// recursive behaviour but, regardless of responses received, sends every
- /// query to the test server.
- ///
- /// The test server is enabled by setting a non-zero port number.
- ///
- /// \param address IP address of the test server.
- /// \param port Port number of the test server
- void setTestServer(const std::string& address, uint16_t port);
- private:
- DNSService& dns_service_;
- isc::nsas::NameserverAddressStore& nsas_;
- isc::cache::ResolverCache& cache_;
- boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
- upstream_;
- boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
- upstream_root_;
- std::pair<std::string, uint16_t> test_server_;
- int query_timeout_;
- int client_timeout_;
- int lookup_timeout_;
- unsigned retries_;
- boost::shared_ptr<RttRecorder> rtt_recorder_; ///< Round-trip time recorder
- };
- } // namespace asiodns
- } // namespace isc
- #endif // __RECURSIVE_QUERY_H
|