auth_srv.h 19 KB

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