auth_srv.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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 <config/ccsession.h>
  17. #include <datasrc/factory.h>
  18. #include <datasrc/client_list.h>
  19. #include <datasrc/datasrc_config.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. #include <auth/datasrc_clients_mgr.h>
  34. #include <boost/shared_ptr.hpp>
  35. #include <map>
  36. #include <string>
  37. namespace isc {
  38. namespace util {
  39. namespace io {
  40. class BaseSocketSessionForwarder;
  41. }
  42. namespace thread {
  43. class Mutex;
  44. }
  45. }
  46. namespace datasrc {
  47. class ConfigurableClientList;
  48. }
  49. namespace xfr {
  50. class AbstractXfroutClient;
  51. }
  52. namespace dns {
  53. class TSIGKeyRing;
  54. }
  55. }
  56. /// \brief The implementation class for the \c AuthSrv class using the pimpl
  57. /// idiom.
  58. class AuthSrvImpl;
  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 xfrout_client Communication interface with a separate xfrout
  94. /// process. It's normally a reference to an xfr::XfroutClient object,
  95. /// but can refer to a local mock object for testing (or other
  96. /// experimental) purposes.
  97. AuthSrv(isc::xfr::AbstractXfroutClient& xfrout_client,
  98. isc::util::io::BaseSocketSessionForwarder& ddns_forwarder);
  99. ~AuthSrv();
  100. //@}
  101. /// Stop the server.
  102. ///
  103. /// It stops the internal event loop of the server and subsequently
  104. /// returns the control to the top level context.
  105. ///
  106. /// This method should never throw an exception.
  107. void stop();
  108. /// \brief Process an incoming DNS message, then signal 'server' to resume
  109. ///
  110. /// A DNS query (or other message) has been received by a \c DNSServer
  111. /// object. Find an answer, then post the \c DNSServer object on the
  112. /// I/O service queue and return. When the server resumes, it can
  113. /// send the reply.
  114. ///
  115. /// \param io_message The raw message received
  116. /// \param message the \c Message object
  117. /// \param buffer an \c OutputBuffer for the resposne
  118. /// \param server Pointer to the \c DNSServer
  119. ///
  120. /// \throw isc::Unexpected Protocol type of \a message is unexpected
  121. void processMessage(const isc::asiolink::IOMessage& io_message,
  122. isc::dns::Message& message,
  123. isc::util::OutputBuffer& buffer,
  124. isc::asiodns::DNSServer* server);
  125. /// \brief Updates the configuration for the \c AuthSrv object.
  126. ///
  127. /// On success this method returns a data \c Element (in the form of a
  128. /// pointer like object) indicating the successful result,
  129. /// i.e., {"result": [0]}.
  130. /// Otherwise, it returns a data \c Element explaining the error:
  131. /// {"result": [1, <error-description>]}.
  132. ///
  133. /// This method is mostly exception free (error conditions are represented
  134. /// via the return value). But it may still throw a standard exception
  135. /// if memory allocation fails inside the method.
  136. /// When a standard exception is thrown or an implementation specific
  137. /// exception is triggered and caught internally, this function provides
  138. /// the strong exception guarantee: Unless everything succeeds, currently
  139. /// installed data source (if any) won't be replaced.
  140. ///
  141. /// \param config An immutable pointer-like object to a data \c Element,
  142. /// possibly containing the data source information to be used.
  143. /// \return An immutable pointer-like object to a data \c Element
  144. /// containing the result of the update operation.
  145. isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
  146. /// \brief Returns the command and configuration session for the
  147. /// \c AuthSrv.
  148. ///
  149. /// This method never throws an exception.
  150. ///
  151. /// \return A pointer to \c ModuleCCSession object stored in the
  152. /// \c AuthSrv object. In this implementation it could be NULL.
  153. isc::config::ModuleCCSession* getConfigSession() const;
  154. /// \brief Set the command and configuration session for the \c AuthSrv.
  155. ///
  156. /// Note: this interface is tentative. We'll revisit the ASIO and session
  157. /// frameworks, at which point the session will probably be passed on
  158. /// construction of the server.
  159. /// In the current implementation, this method is expected to be called
  160. /// exactly once as part of initialization. If this method is called
  161. /// multiple times, previously specified session is silently overridden.
  162. ///
  163. /// This method never throws an exception.
  164. ///
  165. /// \param config_session A pointer to \c ModuleCCSession object to receive
  166. /// control commands and configuration updates.
  167. void setConfigSession(isc::config::ModuleCCSession* config_session);
  168. /// \brief Return this object's ASIO IO Service queue
  169. isc::asiolink::IOService& getIOService();
  170. /// \brief Return pointer to the DNS Lookup callback function
  171. isc::asiodns::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
  172. /// \brief Return pointer to the DNS Answer callback function
  173. isc::asiodns::DNSAnswer* getDNSAnswerProvider() const { return (dns_answer_); }
  174. /// \brief Return pointer to the Checkin callback function
  175. isc::asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
  176. /// \brief Return data source clients manager.
  177. ///
  178. /// \throw None
  179. isc::auth::DataSrcClientsMgr& getDataSrcClientsMgr();
  180. /// \brief Set the communication session with a separate process for
  181. /// outgoing zone transfers.
  182. ///
  183. /// Note: this interface is tentative. We'll revisit the ASIO and session
  184. /// frameworks, at which point the session will probably be passed on
  185. /// construction of the server.
  186. ///
  187. /// \param xfrin_session A Session object over which NOTIFY message
  188. /// information is exchanged with a XFRIN handler.
  189. /// The session must be established before setting in the server
  190. /// object.
  191. /// Ownership isn't transferred: the caller is responsible for keeping
  192. /// this object to be valid while the server object is working and for
  193. /// disconnecting the session and destroying the object when the server
  194. /// is shutdown.
  195. ///
  196. void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
  197. /// \brief Returns statistics data
  198. ///
  199. /// This function can throw an exception from
  200. /// AuthCounters::getStatistics().
  201. ///
  202. /// \return JSON format statistics data.
  203. isc::data::ConstElementPtr getStatistics() const;
  204. /// \brief Get the value of counter in the AuthCounters.
  205. ///
  206. /// This function calls AuthCounters::getStatistics() and
  207. /// returns its return value.
  208. ///
  209. /// This function never throws an exception as far as
  210. /// AuthCounters::getStatistics() doesn't throw.
  211. ///
  212. /// Note: Currently this function is for testing purpose only.
  213. ///
  214. /// \param type Type of a counter to get the value of
  215. ///
  216. /// \return the value of the counter.
  217. uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
  218. /// \brief Get the value of per Opcode counter in the Auth Counters.
  219. ///
  220. /// This function calls AuthCounters::getCounter(isc::dns::Opcode) and
  221. /// returns its return value.
  222. ///
  223. /// \note This is a tentative interface as an attempt of experimentally
  224. /// supporting more statistics counters. This should eventually be more
  225. /// generalized. In any case, this method is mainly for testing.
  226. ///
  227. /// \throw None
  228. /// \param opcode The opcode of the counter to get the value of
  229. /// \return the value of the counter.
  230. uint64_t getCounter(const isc::dns::Opcode opcode) const;
  231. /// \brief Get the value of per Rcode counter in the Auth Counters.
  232. ///
  233. /// This function calls AuthCounters::getCounter(isc::dns::Rcode) and
  234. /// returns its return value.
  235. ///
  236. /// \note This is a tentative interface as an attempt of experimentally
  237. /// supporting more statistics counters. This should eventually be more
  238. /// generalized. In any case, this method is mainly for testing.
  239. ///
  240. /// \throw None
  241. /// \param rcode The rcode of the counter to get the value of
  242. /// \return the value of the counter.
  243. uint64_t getCounter(const isc::dns::Rcode rcode) const;
  244. /**
  245. * \brief Set and get the addresses we listen on.
  246. */
  247. void setListenAddresses(const isc::server_common::portconfig::AddressList&
  248. addreses);
  249. const isc::server_common::portconfig::AddressList& getListenAddresses()
  250. const;
  251. /// \brief Assign an ASIO DNS Service queue to this Auth object
  252. void setDNSService(isc::asiodns::DNSServiceBase& dnss);
  253. /// \brief Sets the keyring used for verifying and signing
  254. ///
  255. /// The parameter is pointer to shared pointer, because the automatic
  256. /// reloading routines of tsig keys replace the actual keyring object.
  257. /// It is expected the pointer will point to some statically-allocated
  258. /// object, it doesn't take ownership of it.
  259. void setTSIGKeyRing(const boost::shared_ptr<isc::dns::TSIGKeyRing>*
  260. keyring);
  261. /// \brief Create the internal forwarder for DDNS update messages
  262. ///
  263. /// Until this method is called (it is called when the
  264. /// start_ddns_forwarder command is sent to b10-auth), b10-auth will
  265. /// respond to UPDATE messages with a NOTIMP rcode.
  266. /// If the internal forwarder was already created, it is destroyed and
  267. /// created again. This is useful for instance when b10-ddns is shut
  268. /// down and restarted.
  269. void createDDNSForwarder();
  270. /// \brief Destroy the internal forwarder for DDNS update messages
  271. ///
  272. /// After this method has been called (it is called when the
  273. /// stop_ddns_forwarder command is sent to b10-auth), DDNS Update
  274. /// messages are no longer forwarded internally, but b10-auth will
  275. /// immediately respond with a NOTIMP rcode.
  276. /// If there was no forwarder yet, this method does nothing.
  277. void destroyDDNSForwarder();
  278. /// \brief Swap the currently used set of data source client lists with
  279. /// given one.
  280. ///
  281. /// The "set" of lists is actually given in the form of map from
  282. /// RRClasses to shared pointers to isc::datasrc::ConfigurableClientList.
  283. ///
  284. /// This method returns the swapped set of lists, which was previously
  285. /// used by the server.
  286. ///
  287. /// This method is intended to be used by a separate method to update
  288. /// the data source configuration "at once". The caller must hold
  289. /// a lock for the mutex object returned by \c getDataSrcClientListMutex()
  290. /// before calling this method.
  291. ///
  292. /// The ownership of the returned pointer is transferred to the caller.
  293. /// The caller is generally expected to release the resources used in
  294. /// the old lists. Note that it could take longer time if some of the
  295. /// data source clients contain a large size of in-memory data.
  296. ///
  297. /// The caller can pass a NULL pointer. This effectively disables
  298. /// any data source for the server.
  299. ///
  300. /// \param new_lists Shared pointer to a new set of data source client
  301. /// lists.
  302. /// \return The previous set of lists. It can be NULL.
  303. isc::datasrc::DataSrcClientListsPtr
  304. swapDataSrcClientLists(isc::datasrc::DataSrcClientListsPtr new_lists);
  305. /// \brief Returns the currently used client list for the class.
  306. ///
  307. /// \param rrclass The class for which to get the list.
  308. /// \return The list, or NULL if no list is set for the class.
  309. boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  310. getDataSrcClientList(const isc::dns::RRClass& rrclass);
  311. /// \brief Return a mutex for the client lists.
  312. ///
  313. /// Background loading of data uses threads. Therefore we need to protect
  314. /// the client lists by a mutex, so they don't change (or get destroyed)
  315. /// during query processing. Get (and lock) this mutex whenever you do
  316. /// something with the lists and keep it locked until you finish. This
  317. /// is correct:
  318. /// \code
  319. /// {
  320. /// Mutex::Locker locker(auth->getDataSrcClientListMutex());
  321. /// boost::shared_ptr<isc::datasrc::ConfigurableClientList>
  322. /// list(auth->getDataSrcClientList(RRClass::IN()));
  323. /// // Do some processing here
  324. /// }
  325. /// \endcode
  326. ///
  327. /// But this is not (it releases the mutex too soon):
  328. /// \code
  329. /// boost::shared_ptr<isc::datasrc::ConfigurableClientList> list;
  330. /// {
  331. /// Mutex::Locker locker(auth->getDataSrcClientListMutex());
  332. /// list = auth->getDataSrcClientList(RRClass::IN()));
  333. /// }
  334. /// // Do some processing here
  335. /// \endcode
  336. ///
  337. /// \note This method is const even if you are allowed to modify
  338. /// (lock) the mutex. It's because locking of the mutex is not really
  339. /// a modification of the server object and it is needed to protect the
  340. /// lists even on read-only operations.
  341. isc::util::thread::Mutex& getDataSrcClientListMutex() const;
  342. /// \brief Sets the timeout for incoming TCP connections
  343. ///
  344. /// Incoming TCP connections that have not sent their data
  345. /// withing this time are dropped.
  346. ///
  347. /// \param timeout The timeout (in milliseconds). If se to
  348. /// zero, no timeouts are used, and the connection will remain
  349. /// open forever.
  350. void setTCPRecvTimeout(size_t timeout);
  351. private:
  352. AuthSrvImpl* impl_;
  353. isc::asiolink::SimpleCallback* checkin_;
  354. isc::asiodns::DNSLookup* dns_lookup_;
  355. isc::asiodns::DNSAnswer* dns_answer_;
  356. isc::asiodns::DNSServiceBase* dnss_;
  357. };
  358. #endif // __AUTH_SRV_H
  359. // Local Variables:
  360. // mode: c++
  361. // End: