Branch data Line data Source code
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 : :
15 : : #ifndef __AUTH_SRV_H
16 : : #define __AUTH_SRV_H 1
17 : :
18 : : #include <string>
19 : :
20 : : // For InMemoryClientPtr below. This should be a temporary definition until
21 : : // we reorganize the data source framework.
22 : : #include <boost/shared_ptr.hpp>
23 : :
24 : : #include <cc/data.h>
25 : : #include <config/ccsession.h>
26 : : #include <dns/message.h>
27 : : #include <dns/opcode.h>
28 : : #include <util/buffer.h>
29 : :
30 : : #include <asiodns/dns_server.h>
31 : : #include <asiodns/dns_service.h>
32 : : #include <asiodns/dns_lookup.h>
33 : : #include <asiodns/dns_answer.h>
34 : : #include <asiolink/io_message.h>
35 : : #include <asiolink/io_service.h>
36 : : #include <asiolink/simple_callback.h>
37 : :
38 : : #include <asiolink/asiolink.h>
39 : : #include <server_common/portconfig.h>
40 : : #include <auth/statistics.h>
41 : :
42 : : namespace isc {
43 : : namespace datasrc {
44 : : class InMemoryClient;
45 : : }
46 : : namespace xfr {
47 : : class AbstractXfroutClient;
48 : : }
49 : : namespace dns {
50 : : class TSIGKeyRing;
51 : : }
52 : : }
53 : :
54 : :
55 : : /// \brief The implementation class for the \c AuthSrv class using the pimpl
56 : : /// idiom.
57 : : class AuthSrvImpl;
58 : :
59 : : /// \brief The authoritative nameserver class.
60 : : ///
61 : : /// \c AuthSrv is a concrete class that implements authoritative DNS server
62 : : /// protocol processing.
63 : : /// An \c AuthSrv object is primarily responsible for handling incoming DNS
64 : : /// requests: It parses the request and dispatches subsequent processing to
65 : : /// the corresponding module (which may be an internal library or a separate
66 : : /// process) depending on the request type. For normal queries, the
67 : : /// \c AuthSrv object searches configured data sources for the answer to the
68 : : /// query, and builds a response containing the answer.
69 : : ///
70 : : /// This class uses the "pimpl" idiom, and hides detailed implementation
71 : : /// through the \c impl_ pointer (which points to an instance of the
72 : : /// \c AuthSrvImpl class). An \c AuthSrv object is supposed to exist for quite
73 : : /// a long period, and only a few \c AuthSrv objects will be created (in fact,
74 : : /// in this current implementation there will only be one object), so the
75 : : /// construction overhead of this approach should be acceptable.
76 : : ///
77 : : /// The design of this class is still in flux. It's quite likely to change
78 : : /// in future versions.
79 : : ///
80 : : class AuthSrv {
81 : : ///
82 : : /// \name Constructors, Assignment Operator and Destructor.
83 : : ///
84 : : /// Note: The copy constructor and the assignment operator are
85 : : /// intentionally defined as private.
86 : : //@{
87 : : private:
88 : : AuthSrv(const AuthSrv& source);
89 : : AuthSrv& operator=(const AuthSrv& source);
90 : : public:
91 : : /// The constructor.
92 : : ///
93 : : /// \param use_cache Whether to enable hot spot cache for lookup results.
94 : : /// \param xfrout_client Communication interface with a separate xfrout
95 : : /// process. It's normally a reference to an xfr::XfroutClient object,
96 : : /// but can refer to a local mock object for testing (or other
97 : : /// experimental) purposes.
98 : : AuthSrv(const bool use_cache,
99 : : isc::xfr::AbstractXfroutClient& xfrout_client);
100 : : ~AuthSrv();
101 : : //@}
102 : :
103 : : /// Stop the server.
104 : : ///
105 : : /// It stops the internal event loop of the server and subsequently
106 : : /// returns the control to the top level context.
107 : : ///
108 : : /// This method should never throw an exception.
109 : : void stop();
110 : :
111 : : /// \brief Process an incoming DNS message, then signal 'server' to resume
112 : : ///
113 : : /// A DNS query (or other message) has been received by a \c DNSServer
114 : : /// object. Find an answer, then post the \c DNSServer object on the
115 : : /// I/O service queue and return. When the server resumes, it can
116 : : /// send the reply.
117 : : ///
118 : : /// \param io_message The raw message received
119 : : /// \param message the \c Message object
120 : : /// \param buffer an \c OutputBuffer for the resposne
121 : : /// \param server Pointer to the \c DNSServer
122 : : ///
123 : : /// \throw isc::Unexpected Protocol type of \a message is unexpected
124 : : void processMessage(const isc::asiolink::IOMessage& io_message,
125 : : isc::dns::Message& message,
126 : : isc::util::OutputBuffer& buffer,
127 : : isc::asiodns::DNSServer* server);
128 : :
129 : : /// \brief Updates the data source for the \c AuthSrv object.
130 : : ///
131 : : /// This method installs or replaces the data source that the \c AuthSrv
132 : : /// object refers to for query processing.
133 : : /// Although the method name is generic, the only thing it does is to
134 : : /// update the data source information.
135 : : /// If there is a data source installed, it will be replaced with the
136 : : /// new one.
137 : : ///
138 : : /// In the current implementation, the SQLite data source and InMemoryClient
139 : : /// are assumed.
140 : : /// We can enable memory data source and get the path of SQLite database by
141 : : /// the \c config parameter. If we disabled memory data source, the SQLite
142 : : /// data source will be used.
143 : : ///
144 : : /// On success this method returns a data \c Element (in the form of a
145 : : /// pointer like object) indicating the successful result,
146 : : /// i.e., {"result": [0]}.
147 : : /// Otherwise, it returns a data \c Element explaining the error:
148 : : /// {"result": [1, <error-description>]}.
149 : : ///
150 : : /// This method is mostly exception free (error conditions are represented
151 : : /// via the return value). But it may still throw a standard exception
152 : : /// if memory allocation fails inside the method.
153 : : /// When a standard exception is thrown or an implementation specific
154 : : /// exception is triggered and caught internally, this function provides
155 : : /// the strong exception guarantee: Unless everything succeeds, currently
156 : : /// installed data source (if any) won't be replaced.
157 : : ///
158 : : /// \param config An immutable pointer-like object to a data \c Element,
159 : : /// possibly containing the data source information to be used.
160 : : /// \return An immutable pointer-like object to a data \c Element
161 : : /// containing the result of the update operation.
162 : : isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
163 : :
164 : : /// \brief Returns the command and configuration session for the
165 : : /// \c AuthSrv.
166 : : ///
167 : : /// This method never throws an exception.
168 : : ///
169 : : /// \return A pointer to \c ModuleCCSession object stored in the
170 : : /// \c AuthSrv object. In this implementation it could be NULL.
171 : : isc::config::ModuleCCSession* getConfigSession() const;
172 : :
173 : : /// \brief Set the command and configuration session for the \c AuthSrv.
174 : : ///
175 : : /// Note: this interface is tentative. We'll revisit the ASIO and session
176 : : /// frameworks, at which point the session will probably be passed on
177 : : /// construction of the server.
178 : : /// In the current implementation, this method is expected to be called
179 : : /// exactly once as part of initialization. If this method is called
180 : : /// multiple times, previously specified session is silently overridden.
181 : : ///
182 : : /// This method never throws an exception.
183 : : ///
184 : : /// \param config_session A pointer to \c ModuleCCSession object to receive
185 : : /// control commands and configuration updates.
186 : : void setConfigSession(isc::config::ModuleCCSession* config_session);
187 : :
188 : : /// \brief Return this object's ASIO IO Service queue
189 : : isc::asiolink::IOService& getIOService();
190 : :
191 : : /// \brief Return pointer to the DNS Lookup callback function
192 : 0 : isc::asiodns::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
193 : :
194 : : /// \brief Return pointer to the DNS Answer callback function
195 : 0 : isc::asiodns::DNSAnswer* getDNSAnswerProvider() const { return (dns_answer_); }
196 : :
197 : : /// \brief Return pointer to the Checkin callback function
198 : : isc::asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
199 : :
200 : : /// \brief Set or update the size (number of slots) of hot spot cache.
201 : : ///
202 : : /// If the specified size is 0, it means the size will be unlimited.
203 : : /// The specified size is recorded even if the cache is disabled; the
204 : : /// new size will be effective when the cache is enabled.
205 : : ///
206 : : /// This method never throws an exception.
207 : : ///
208 : : /// \param slots The number of cache slots.
209 : : void setCacheSlots(const size_t slots);
210 : :
211 : : /// \brief Get the current size (number of slots) of hot spot cache.
212 : : ///
213 : : /// It always returns the recorded size regardless of the cache is enabled.
214 : : ///
215 : : /// This method never throws an exception.
216 : : ///
217 : : /// \return The current number of cache slots.
218 : : size_t getCacheSlots() const;
219 : :
220 : : /// \brief Set the communication session with a separate process for
221 : : /// outgoing zone transfers.
222 : : ///
223 : : /// Note: this interface is tentative. We'll revisit the ASIO and session
224 : : /// frameworks, at which point the session will probably be passed on
225 : : /// construction of the server.
226 : : ///
227 : : /// \param xfrin_session A Session object over which NOTIFY message
228 : : /// information is exchanged with a XFRIN handler.
229 : : /// The session must be established before setting in the server
230 : : /// object.
231 : : /// Ownership isn't transferred: the caller is responsible for keeping
232 : : /// this object to be valid while the server object is working and for
233 : : /// disconnecting the session and destroying the object when the server
234 : : /// is shutdown.
235 : : ///
236 : : void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
237 : :
238 : : /// A shared pointer type for \c InMemoryClient.
239 : : ///
240 : : /// This is defined inside the \c AuthSrv class as it's supposed to be
241 : : /// a short term interface until we integrate the in-memory and other
242 : : /// data source frameworks.
243 : : typedef boost::shared_ptr<isc::datasrc::InMemoryClient> InMemoryClientPtr;
244 : :
245 : : /// An immutable shared pointer type for \c InMemoryClient.
246 : : typedef boost::shared_ptr<const isc::datasrc::InMemoryClient>
247 : : ConstInMemoryClientPtr;
248 : :
249 : : /// Returns the in-memory data source configured for the \c AuthSrv,
250 : : /// if any.
251 : : ///
252 : : /// The in-memory data source is configured per RR class. However,
253 : : /// the data source may not be available for all RR classes.
254 : : /// If it is not available for the specified RR class, an exception of
255 : : /// class \c InvalidParameter will be thrown.
256 : : /// This method never throws an exception otherwise.
257 : : ///
258 : : /// Even for supported RR classes, the in-memory data source is not
259 : : /// configured by default. In that case a NULL (shared) pointer will
260 : : /// be returned.
261 : : ///
262 : : /// \param rrclass The RR class of the requested in-memory data source.
263 : : /// \return A pointer to the in-memory data source, if configured;
264 : : /// otherwise NULL.
265 : : InMemoryClientPtr getInMemoryClient(const isc::dns::RRClass& rrclass);
266 : :
267 : : /// Sets or replaces the in-memory data source of the specified RR class.
268 : : ///
269 : : /// As noted in \c getInMemoryClient(), some RR classes may not be
270 : : /// supported, in which case an exception of class \c InvalidParameter
271 : : /// will be thrown.
272 : : /// This method never throws an exception otherwise.
273 : : ///
274 : : /// If there is already an in memory data source configured, it will be
275 : : /// replaced with the newly specified one.
276 : : /// \c memory_datasrc can be NULL, in which case it will (re)disable the
277 : : /// in-memory data source.
278 : : ///
279 : : /// \param rrclass The RR class of the in-memory data source to be set.
280 : : /// \param memory_client A (shared) pointer to \c InMemoryClient to be set.
281 : : void setInMemoryClient(const isc::dns::RRClass& rrclass,
282 : : InMemoryClientPtr memory_client);
283 : :
284 : : /// \brief Set the communication session with Statistics.
285 : : ///
286 : : /// This function never throws an exception as far as
287 : : /// AuthCounters::setStatisticsSession() doesn't throw.
288 : : ///
289 : : /// Note: this interface is tentative. We'll revisit the ASIO and
290 : : /// session frameworks, at which point the session will probably
291 : : /// be passed on construction of the server.
292 : : ///
293 : : /// \param statistics_session A Session object over which statistics
294 : : /// information is exchanged with statistics module.
295 : : /// The session must be established before setting in the server
296 : : /// object.
297 : : /// Ownership isn't transferred: the caller is responsible for keeping
298 : : /// this object to be valid while the server object is working and for
299 : : /// disconnecting the session and destroying the object when the server
300 : : /// is shutdown.
301 : : void setStatisticsSession(isc::cc::AbstractSession* statistics_session);
302 : :
303 : : /// Return the interval of periodic submission of statistics in seconds.
304 : : ///
305 : : /// If the statistics submission is disabled, it returns 0.
306 : : ///
307 : : /// This method never throws an exception.
308 : : uint32_t getStatisticsTimerInterval() const;
309 : :
310 : : /// Set the interval of periodic submission of statistics.
311 : : ///
312 : : /// If the specified value is non 0, the \c AuthSrv object will submit
313 : : /// its statistics to the statistics module every \c interval seconds.
314 : : /// If it's 0, and \c AuthSrv currently submits statistics, the submission
315 : : /// will be disabled. \c interval must be equal to or shorter than 86400
316 : : /// seconds (1 day).
317 : : ///
318 : : /// This method should normally not throw an exception; however, its
319 : : /// underlying library routines may involve resource allocation, and
320 : : /// when it fails it would result in a corresponding standard exception.
321 : : ///
322 : : /// \param interval The submission interval in seconds if non 0;
323 : : /// or a value of 0 to disable the submission.
324 : : void setStatisticsTimerInterval(uint32_t interval);
325 : :
326 : : /// \brief Submit statistics counters to statistics module.
327 : : ///
328 : : /// This function can throw an exception from
329 : : /// AuthCounters::submitStatistics().
330 : : ///
331 : : /// \return true on success, false on failure (e.g. session timeout,
332 : : /// session error).
333 : : bool submitStatistics() const;
334 : :
335 : : /// \brief Get the value of counter in the AuthCounters.
336 : : ///
337 : : /// This function calls AuthCounters::getCounter() and
338 : : /// returns its return value.
339 : : ///
340 : : /// This function never throws an exception as far as
341 : : /// AuthCounters::getCounter() doesn't throw.
342 : : ///
343 : : /// Note: Currently this function is for testing purpose only.
344 : : ///
345 : : /// \param type Type of a counter to get the value of
346 : : ///
347 : : /// \return the value of the counter.
348 : :
349 : : uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
350 : :
351 : : /// \brief Get the value of per Opcode counter in the Auth Counters.
352 : : ///
353 : : /// This function calls AuthCounters::getCounter(isc::dns::Opcode) and
354 : : /// returns its return value.
355 : : ///
356 : : /// \note This is a tentative interface as an attempt of experimentally
357 : : /// supporting more statistics counters. This should eventually be more
358 : : /// generalized. In any case, this method is mainly for testing.
359 : : ///
360 : : /// \throw None
361 : : /// \param opcode The opcode of the counter to get the value of
362 : : /// \return the value of the counter.
363 : : uint64_t getCounter(const isc::dns::Opcode opcode) const;
364 : :
365 : : /// \brief Get the value of per Rcode counter in the Auth Counters.
366 : : ///
367 : : /// This function calls AuthCounters::getCounter(isc::dns::Rcode) and
368 : : /// returns its return value.
369 : : ///
370 : : /// \note This is a tentative interface as an attempt of experimentally
371 : : /// supporting more statistics counters. This should eventually be more
372 : : /// generalized. In any case, this method is mainly for testing.
373 : : ///
374 : : /// \throw None
375 : : /// \param rcode The rcode of the counter to get the value of
376 : : /// \return the value of the counter.
377 : : uint64_t getCounter(const isc::dns::Rcode rcode) const;
378 : :
379 : : /**
380 : : * \brief Set and get the addresses we listen on.
381 : : */
382 : : void setListenAddresses(const isc::server_common::portconfig::AddressList&
383 : : addreses);
384 : : const isc::server_common::portconfig::AddressList& getListenAddresses()
385 : : const;
386 : :
387 : : /// \brief Assign an ASIO DNS Service queue to this Auth object
388 : : void setDNSService(isc::asiodns::DNSServiceBase& dnss);
389 : :
390 : : /// \brief Sets the keyring used for verifying and signing
391 : : ///
392 : : /// The parameter is pointer to shared pointer, because the automatic
393 : : /// reloading routines of tsig keys replace the actual keyring object.
394 : : /// It is expected the pointer will point to some statically-allocated
395 : : /// object, it doesn't take ownership of it.
396 : : void setTSIGKeyRing(const boost::shared_ptr<isc::dns::TSIGKeyRing>*
397 : : keyring);
398 : :
399 : : private:
400 : : AuthSrvImpl* impl_;
401 : : isc::asiolink::SimpleCallback* checkin_;
402 : : isc::asiodns::DNSLookup* dns_lookup_;
403 : : isc::asiodns::DNSAnswer* dns_answer_;
404 : : isc::asiodns::DNSServiceBase* dnss_;
405 : : };
406 : :
407 : : #endif // __AUTH_SRV_H
408 : :
409 : : // Local Variables:
410 : : // mode: c++
411 : : // End:
|