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