asiolink.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. // Copyright (C) 2010 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 __ASIOLINK_H
  15. #define __ASIOLINK_H 1
  16. // IMPORTANT NOTE: only very few ASIO headers files can be included in
  17. // this file. In particular, asio.hpp should never be included here.
  18. // See the description of the namespace below.
  19. #include <unistd.h> // for some network system calls
  20. #include <asio/ip/address.hpp>
  21. #include <boost/shared_ptr.hpp>
  22. #include <boost/function.hpp>
  23. #include <functional>
  24. #include <string>
  25. #include <vector>
  26. #include <utility>
  27. #include <dns/buffer.h>
  28. #include <dns/message.h>
  29. #include <dns/question.h>
  30. #include <dns/rcode.h>
  31. #include <exceptions/exceptions.h>
  32. #include <asiolink/ioaddress.h>
  33. #include <asiolink/ioendpoint.h>
  34. #include <asiolink/iomessage.h>
  35. #include <asiolink/iosocket.h>
  36. #include <resolve/resolver_interface.h>
  37. namespace asio {
  38. // forward declaration for IOService::get_io_service() below
  39. class io_service;
  40. }
  41. /// \namespace asiolink
  42. /// \brief A wrapper interface for the ASIO library.
  43. ///
  44. /// The \c asiolink namespace is used to define a set of wrapper interfaces
  45. /// for the ASIO library.
  46. ///
  47. /// BIND 10 uses the non-Boost version of ASIO because it's header-only,
  48. /// i.e., does not require a separate library object to be linked, and thus
  49. /// lowers the bar for introduction.
  50. ///
  51. /// But the advantage comes with its own costs: since the header-only version
  52. /// includes more definitions in public header files, it tends to trigger
  53. /// more compiler warnings for our own sources, and, depending on the
  54. /// compiler options, may make the build fail.
  55. ///
  56. /// We also found it may be tricky to use ASIO and standard C++ libraries
  57. /// in a single translation unit, i.e., a .cc file: depending on the order
  58. /// of including header files, ASIO may or may not work on some platforms.
  59. ///
  60. /// This wrapper interface is intended to centralize these
  61. /// problematic issues in a single sub module. Other BIND 10 modules should
  62. /// simply include \c asiolink.h and use the wrapper API instead of
  63. /// including ASIO header files and using ASIO-specific classes directly.
  64. ///
  65. /// This wrapper may be used for other IO libraries if and when we want to
  66. /// switch, but generality for that purpose is not the primary goal of
  67. /// this module. The resulting interfaces are thus straightforward mapping
  68. /// to the ASIO counterparts.
  69. ///
  70. /// Notes to developers:
  71. /// Currently the wrapper interface is fairly specific to use by a
  72. /// DNS server, i.e., b10-auth or b10-resolver. But the plan is to
  73. /// generalize it and have other modules use it as well.
  74. ///
  75. /// One obvious drawback of this approach is performance overhead
  76. /// due to the additional layer. We should eventually evaluate the cost
  77. /// of the wrapper abstraction in benchmark tests. Another drawback is
  78. /// that the wrapper interfaces don't provide all features of ASIO
  79. /// (at least for the moment). We should also re-evaluate the
  80. /// maintenance overhead of providing necessary wrappers as we develop
  81. /// more.
  82. ///
  83. /// On the other hand, we may be able to exploit the wrapper approach to
  84. /// simplify the interfaces (by limiting the usage) and unify performance
  85. /// optimization points.
  86. ///
  87. /// As for optimization, we may want to provide a custom allocator for
  88. /// the placeholder of callback handlers:
  89. /// http://think-async.com/Asio/asio-1.3.1/doc/asio/reference/asio_handler_allocate.html
  90. namespace asiolink {
  91. class DNSServiceImpl;
  92. struct IOServiceImpl;
  93. struct IntervalTimerImpl;
  94. /// \brief An exception that is thrown if an error occurs within the IO
  95. /// module. This is mainly intended to be a wrapper exception class for
  96. /// ASIO specific exceptions.
  97. class IOError : public isc::Exception {
  98. public:
  99. IOError(const char* file, size_t line, const char* what) :
  100. isc::Exception(file, line, what) {}
  101. };
  102. /// \brief Forward declarations for classes used below
  103. class SimpleCallback;
  104. class DNSLookup;
  105. class DNSAnswer;
  106. /// \brief The \c IOService class is a wrapper for the ASIO \c io_service
  107. /// class.
  108. ///
  109. class IOService {
  110. ///
  111. /// \name Constructors and Destructor
  112. ///
  113. /// Note: The copy constructor and the assignment operator are
  114. /// intentionally defined as private, making this class non-copyable.
  115. //@{
  116. private:
  117. IOService(const IOService& source);
  118. IOService& operator=(const IOService& source);
  119. public:
  120. /// \brief The constructor
  121. IOService();
  122. /// \brief The destructor.
  123. ~IOService();
  124. //@}
  125. /// \brief Start the underlying event loop.
  126. ///
  127. /// This method does not return control to the caller until
  128. /// the \c stop() method is called via some handler.
  129. void run();
  130. /// \brief Run the underlying event loop for a single event.
  131. ///
  132. /// This method return control to the caller as soon as the
  133. /// first handler has completed. (If no handlers are ready when
  134. /// it is run, it will block until one is.)
  135. void run_one();
  136. /// \brief Stop the underlying event loop.
  137. ///
  138. /// This will return the control to the caller of the \c run() method.
  139. void stop();
  140. /// \brief Return the native \c io_service object used in this wrapper.
  141. ///
  142. /// This is a short term work around to support other BIND 10 modules
  143. /// that share the same \c io_service with the authoritative server.
  144. /// It will eventually be removed once the wrapper interface is
  145. /// generalized.
  146. asio::io_service& get_io_service();
  147. private:
  148. IOServiceImpl* io_impl_;
  149. };
  150. ///
  151. /// DNSService is the service that handles DNS queries and answers with
  152. /// a given IOService. This class is mainly intended to hold all the
  153. /// logic that is shared between the authoritative and the recursive
  154. /// server implementations. As such, it handles asio, including config
  155. /// updates (through the 'Checkinprovider'), and listening sockets.
  156. ///
  157. class DNSService {
  158. ///
  159. /// \name Constructors and Destructor
  160. ///
  161. /// Note: The copy constructor and the assignment operator are
  162. /// intentionally defined as private, making this class non-copyable.
  163. //@{
  164. private:
  165. DNSService(const DNSService& source);
  166. DNSService& operator=(const DNSService& source);
  167. public:
  168. /// \brief The constructor with a specific IP address and port on which
  169. /// the services listen on.
  170. ///
  171. /// \param io_service The IOService to work with
  172. /// \param port the port to listen on
  173. /// \param address the IP address to listen on
  174. /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
  175. /// \param lookup The lookup provider (see \c DNSLookup)
  176. /// \param answer The answer provider (see \c DNSAnswer)
  177. DNSService(IOService& io_service, const char& port,
  178. const char& address, SimpleCallback* checkin,
  179. DNSLookup* lookup, DNSAnswer* answer);
  180. /// \brief The constructor with a specific port on which the services
  181. /// listen on.
  182. ///
  183. /// It effectively listens on "any" IPv4 and/or IPv6 addresses.
  184. /// IPv4/IPv6 services will be available if and only if \c use_ipv4
  185. /// or \c use_ipv6 is \c true, respectively.
  186. ///
  187. /// \param io_service The IOService to work with
  188. /// \param port the port to listen on
  189. /// \param ipv4 If true, listen on ipv4 'any'
  190. /// \param ipv6 If true, listen on ipv6 'any'
  191. /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
  192. /// \param lookup The lookup provider (see \c DNSLookup)
  193. /// \param answer The answer provider (see \c DNSAnswer)
  194. DNSService(IOService& io_service, const char& port,
  195. const bool use_ipv4, const bool use_ipv6,
  196. SimpleCallback* checkin, DNSLookup* lookup,
  197. DNSAnswer* answer);
  198. /// \brief The constructor without any servers.
  199. ///
  200. /// Use addServer() to add some servers.
  201. DNSService(IOService& io_service, SimpleCallback* checkin,
  202. DNSLookup* lookup, DNSAnswer* answer);
  203. /// \brief The destructor.
  204. ~DNSService();
  205. //@}
  206. /// \brief Add another server to the service
  207. void addServer(uint16_t port, const std::string &address);
  208. void addServer(const char &port, const std::string &address);
  209. /// \brief Remove all servers from the service
  210. void clearServers();
  211. /// \brief Return the native \c io_service object used in this wrapper.
  212. ///
  213. /// This is a short term work around to support other BIND 10 modules
  214. /// that share the same \c io_service with the authoritative server.
  215. /// It will eventually be removed once the wrapper interface is
  216. /// generalized.
  217. asio::io_service& get_io_service() { return io_service_.get_io_service(); }
  218. private:
  219. DNSServiceImpl* impl_;
  220. IOService& io_service_;
  221. };
  222. /// \brief The \c DNSServer class is a wrapper (and base class) for
  223. /// classes which provide DNS server functionality.
  224. ///
  225. /// The classes derived from this one, \c TCPServer and \c UDPServer,
  226. /// act as the interface layer between clients sending queries, and
  227. /// functions defined elsewhere that provide answers to those queries.
  228. /// Those functions are described in more detail below under
  229. /// \c SimpleCallback, \c DNSLookup, and \c DNSAnswer.
  230. ///
  231. /// Notes to developers:
  232. /// When constructed, this class (and its derived classes) will have its
  233. /// "self_" member set to point to "this". Objects of this class (as
  234. /// instantiated through a base class) are sometimes passed by
  235. /// reference (as this superclass); calls to methods in the base
  236. /// class are then rerouted via this pointer to methods in the derived
  237. /// class. This allows code from outside asiolink, with no specific
  238. /// knowledge of \c TCPServer or \c UDPServer, to access their methods.
  239. ///
  240. /// This class is both assignable and copy-constructable. Its subclasses
  241. /// use the "stackless coroutine" pattern, meaning that it will copy itself
  242. /// when "forking", and that instances will be posted as ASIO handler
  243. /// objects, which are always copied.
  244. ///
  245. /// Because these objects are frequently copied, it is recommended
  246. /// that derived classes be kept small to reduce copy overhead.
  247. class DNSServer {
  248. protected:
  249. ///
  250. /// \name Constructors and destructors
  251. ///
  252. /// This is intentionally defined as \c protected, as this base class
  253. /// should never be instantiated except as part of a derived class.
  254. //@{
  255. DNSServer() : self_(this) {}
  256. public:
  257. /// \brief The destructor
  258. virtual ~DNSServer() {}
  259. //@}
  260. ///
  261. /// \name Class methods
  262. ///
  263. /// These methods all make their calls indirectly via the "self_"
  264. /// pointer, ensuring that the functions ultimately invoked will be
  265. /// the ones in the derived class. This makes it possible to pass
  266. /// instances of derived classes as references to this base class
  267. /// without losing access to derived class data.
  268. ///
  269. //@{
  270. /// \brief The funtion operator
  271. virtual void operator()(asio::error_code ec = asio::error_code(),
  272. size_t length = 0)
  273. {
  274. (*self_)(ec, length);
  275. }
  276. /// \brief Resume processing of the server coroutine after an
  277. /// asynchronous call (e.g., to the DNS Lookup provider) has completed.
  278. ///
  279. /// \param done If true, this signals the system there is an answer
  280. /// to return.
  281. virtual void resume(const bool done) { self_->resume(done); }
  282. /// \brief Indicate whether the server is able to send an answer
  283. /// to a query.
  284. ///
  285. /// This is presently used only for testing purposes.
  286. virtual bool hasAnswer() { return (self_->hasAnswer()); }
  287. /// \brief Returns the current value of the 'coroutine' object
  288. ///
  289. /// This is a temporary method, intended to be used for debugging
  290. /// purposes during development and removed later. It allows
  291. /// callers from outside the coroutine object to retrieve information
  292. /// about its current state.
  293. ///
  294. /// \return The value of the 'coroutine' object
  295. virtual int value() { return (self_->value()); }
  296. /// \brief Returns a pointer to a clone of this DNSServer object.
  297. ///
  298. /// When a \c DNSServer object is copied or assigned, the result will
  299. /// normally be another \c DNSServer object containing a copy
  300. /// of the original "self_" pointer. Calling clone() guarantees
  301. /// that the underlying object is also correctly copied.
  302. ///
  303. /// \return A deep copy of this DNSServer object
  304. virtual DNSServer* clone() { return (self_->clone()); }
  305. //@}
  306. protected:
  307. /// \brief Lookup handler object.
  308. ///
  309. /// This is a protected class; it can only be instantiated
  310. /// from within a derived class of \c DNSServer.
  311. ///
  312. /// A server object that has received a query creates an instance
  313. /// of this class and scheudles it on the ASIO service queue
  314. /// using asio::io_service::post(). When the handler executes, it
  315. /// calls the asyncLookup() method in the server object to start a
  316. /// DNS lookup. When the lookup is complete, the server object is
  317. /// scheduled to resume, again using io_service::post().
  318. ///
  319. /// Note that the calling object is copied into the handler object,
  320. /// not referenced. This is because, once the calling object yields
  321. /// control to the handler, it falls out of scope and may disappear
  322. template <typename T>
  323. class AsyncLookup {
  324. public:
  325. AsyncLookup(T& caller) : caller_(caller) {}
  326. void operator()() { caller_.asyncLookup(); }
  327. private:
  328. T caller_;
  329. };
  330. /// \brief Carries out a DNS lookup.
  331. ///
  332. /// This function calls the \c DNSLookup object specified by the
  333. /// DNS server when the \c IOService was created, passing along
  334. /// the details of the query and a pointer back to the current
  335. /// server object. It is called asynchronously via the AsyncLookup
  336. /// handler class.
  337. virtual void asyncLookup() { self_->asyncLookup(); }
  338. private:
  339. DNSServer* self_;
  340. };
  341. /// \brief The \c DNSLookup class is an abstract base class for a DNS
  342. /// Lookup provider function.
  343. ///
  344. /// Specific derived class implementations are hidden within the
  345. /// implementation. Instances of the derived classes can be called
  346. /// as functions via the operator() interface. Pointers to these
  347. /// instances can then be provided to the \c IOService class
  348. /// via its constructor.
  349. ///
  350. /// A DNS Lookup provider function obtains the data needed to answer
  351. /// a DNS query (e.g., from authoritative data source, cache, or upstream
  352. /// query). After it has run, the OutputBuffer object passed to it
  353. /// should contain the answer to the query, in an internal representation.
  354. class DNSLookup {
  355. ///
  356. /// \name Constructors and Destructor
  357. ///
  358. /// Note: The copy constructor and the assignment operator are
  359. /// intentionally defined as private, making this class non-copyable.
  360. //@{
  361. private:
  362. DNSLookup(const DNSLookup& source);
  363. DNSLookup& operator=(const DNSLookup& source);
  364. protected:
  365. /// \brief The default constructor.
  366. ///
  367. /// This is intentionally defined as \c protected as this base class
  368. /// should never be instantiated (except as part of a derived class).
  369. DNSLookup() : self_(this) {}
  370. public:
  371. /// \brief The destructor
  372. virtual ~DNSLookup() {}
  373. //@}
  374. /// \brief The function operator
  375. ///
  376. /// This makes its call indirectly via the "self" pointer, ensuring
  377. /// that the function ultimately invoked will be the one in the derived
  378. /// class.
  379. ///
  380. /// \param io_message The event message to handle
  381. /// \param message The DNS MessagePtr that needs handling
  382. /// \param buffer The final answer is put here
  383. /// \param DNSServer DNSServer object to use
  384. virtual void operator()(const IOMessage& io_message,
  385. isc::dns::MessagePtr message,
  386. isc::dns::MessagePtr answer_message,
  387. isc::dns::OutputBufferPtr buffer,
  388. DNSServer* server) const
  389. {
  390. (*self_)(io_message, message, answer_message, buffer, server);
  391. }
  392. private:
  393. DNSLookup* self_;
  394. };
  395. /// \brief The \c DNSAnswer class is an abstract base class for a DNS
  396. /// Answer provider function.
  397. ///
  398. /// Specific derived class implementations are hidden within the
  399. /// implementation. Instances of the derived classes can be called
  400. /// as functions via the operator() interface. Pointers to these
  401. /// instances can then be provided to the \c IOService class
  402. /// via its constructor.
  403. ///
  404. /// A DNS Answer provider function takes answer data that has been obtained
  405. /// from a DNS Lookup provider functon and readies it to be sent to the
  406. /// client. After it has run, the OutputBuffer object passed to it should
  407. /// contain the answer to the query rendered into wire format.
  408. class DNSAnswer {
  409. ///
  410. /// \name Constructors and Destructor
  411. ///
  412. /// Note: The copy constructor and the assignment operator are
  413. /// intentionally defined as private, making this class non-copyable.
  414. //@{
  415. private:
  416. DNSAnswer(const DNSAnswer& source);
  417. DNSAnswer& operator=(const DNSAnswer& source);
  418. protected:
  419. /// \brief The default constructor.
  420. ///
  421. /// This is intentionally defined as \c protected as this base class
  422. /// should never be instantiated (except as part of a derived class).
  423. DNSAnswer() {}
  424. public:
  425. /// \brief The destructor
  426. virtual ~DNSAnswer() {}
  427. //@}
  428. /// \brief The function operator
  429. ///
  430. /// This makes its call indirectly via the "self" pointer, ensuring
  431. /// that the function ultimately invoked will be the one in the derived
  432. /// class.
  433. ///
  434. /// \param io_message The event message to handle
  435. /// \param message The DNS MessagePtr that needs handling
  436. /// \param buffer The result is put here
  437. virtual void operator()(const IOMessage& io_message,
  438. isc::dns::MessagePtr message,
  439. isc::dns::MessagePtr answer_message,
  440. isc::dns::OutputBufferPtr buffer) const = 0;
  441. };
  442. /// \brief The \c SimpleCallback class is an abstract base class for a
  443. /// simple callback function with the signature:
  444. ///
  445. /// void simpleCallback(const IOMessage& io_message) const;
  446. ///
  447. /// Specific derived class implementations are hidden within the
  448. /// implementation. Instances of the derived classes can be called
  449. /// as functions via the operator() interface. Pointers to these
  450. /// instances can then be provided to the \c IOService class
  451. /// via its constructor.
  452. ///
  453. /// The \c SimpleCallback is expected to be used for basic, generic
  454. /// tasks such as checking for configuration changes. It may also be
  455. /// used for testing purposes.
  456. class SimpleCallback {
  457. ///
  458. /// \name Constructors and Destructor
  459. ///
  460. /// Note: The copy constructor and the assignment operator are
  461. /// intentionally defined as private, making this class non-copyable.
  462. //@{
  463. private:
  464. SimpleCallback(const SimpleCallback& source);
  465. SimpleCallback& operator=(const SimpleCallback& source);
  466. protected:
  467. /// \brief The default constructor.
  468. ///
  469. /// This is intentionally defined as \c protected as this base class
  470. /// should never be instantiated (except as part of a derived class).
  471. SimpleCallback() : self_(this) {}
  472. public:
  473. /// \brief The destructor
  474. virtual ~SimpleCallback() {}
  475. /// \brief The function operator
  476. //@}
  477. ///
  478. /// This makes its call indirectly via the "self" pointer, ensuring
  479. /// that the function ultimately invoked will be the one in the derived
  480. /// class.
  481. ///
  482. /// \param io_message The event message to handle
  483. virtual void operator()(const IOMessage& io_message) const {
  484. (*self_)(io_message);
  485. }
  486. private:
  487. SimpleCallback* self_;
  488. };
  489. /// \brief The \c RecursiveQuery class provides a layer of abstraction around
  490. /// the ASIO code that carries out an upstream query.
  491. ///
  492. /// This design is very preliminary; currently it is only capable of
  493. /// handling simple forward requests to a single resolver.
  494. class RecursiveQuery {
  495. ///
  496. /// \name Constructors
  497. ///
  498. //@{
  499. public:
  500. /// \brief Constructor
  501. ///
  502. /// This is currently the only way to construct \c RecursiveQuery
  503. /// object. If the addresses of the forward nameservers is specified,
  504. /// and every upstream query will be sent to one random address, and
  505. /// the result sent back directly. If not, it will do full resolving.
  506. ///
  507. /// \param dns_service The DNS Service to perform the recursive
  508. /// query on.
  509. /// \param upstream Addresses and ports of the upstream servers
  510. /// to forward queries to.
  511. /// \param upstream_root Addresses and ports of the root servers
  512. /// to use when resolving.
  513. /// \param timeout How long to timeout the query, in ms
  514. /// -1 means never timeout (but do not use that).
  515. /// TODO: This should be computed somehow dynamically in future
  516. /// \param retries how many times we try again (0 means just send and
  517. /// and return if it returs).
  518. RecursiveQuery(DNSService& dns_service,
  519. const std::vector<std::pair<std::string, uint16_t> >&
  520. upstream,
  521. const std::vector<std::pair<std::string, uint16_t> >&
  522. upstream_root,
  523. int query_timeout = 2000,
  524. int client_timeout = 4000,
  525. int lookup_timeout = 30000,
  526. unsigned retries = 3);
  527. //@}
  528. /// \brief Initiate resolving
  529. ///
  530. /// When sendQuery() is called, a (set of) message(s) is sent
  531. /// asynchronously. If upstream servers are set, one is chosen
  532. /// and the response (if any) from that server will be returned.
  533. ///
  534. /// If not upstream is set, a root server is chosen from the
  535. /// root_servers, and the RunningQuery shall do a full resolve
  536. /// (i.e. if the answer is a delegation, it will be followed, etc.)
  537. /// until there is an answer or an error.
  538. ///
  539. /// When there is a response or an error and we give up, the given
  540. /// CallbackPtr object shall be called (with either success() or
  541. /// failure(). See ResolverInterface::Callback for more information.
  542. ///
  543. /// \param question The question being answered <qname/qclass/qtype>
  544. /// \param callback Callback object. See
  545. /// \c ResolverInterface::Callback for more information
  546. void resolve(const isc::dns::QuestionPtr& question,
  547. const isc::resolve::ResolverInterface::CallbackPtr callback);
  548. /// \brief Initiates resolving for the given question.
  549. ///
  550. /// This actually calls the previous sendQuery() with a default
  551. /// callback object, which calls resume() on the given DNSServer
  552. /// object.
  553. ///
  554. /// \param question The question being answered <qname/qclass/qtype>
  555. /// \param answer_message An output Message into which the final response will be copied
  556. /// \param buffer An output buffer into which the intermediate responses will be copied
  557. /// \param server A pointer to the \c DNSServer object handling the client
  558. void resolve(const isc::dns::Question& question,
  559. isc::dns::MessagePtr answer_message,
  560. isc::dns::OutputBufferPtr buffer,
  561. DNSServer* server);
  562. private:
  563. DNSService& dns_service_;
  564. boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
  565. upstream_;
  566. boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
  567. upstream_root_;
  568. int query_timeout_;
  569. int client_timeout_;
  570. int lookup_timeout_;
  571. unsigned retries_;
  572. };
  573. /// \brief The \c IntervalTimer class is a wrapper for the ASIO
  574. /// \c asio::deadline_timer class.
  575. ///
  576. /// This class is implemented to use \c asio::deadline_timer as interval
  577. /// timer.
  578. ///
  579. /// \c setup() sets a timer to expire on (now + interval) and a call back
  580. /// function.
  581. ///
  582. /// \c IntervalTimerImpl::callback() is called by the timer when it expires.
  583. ///
  584. /// The function calls the call back function set by \c setup() and updates
  585. /// the timer to expire in (now + interval) milliseconds.
  586. /// The type of call back function is \c void(void).
  587. ///
  588. /// The call back function will not be called if the instance of this class is
  589. /// destroyed before the timer is expired.
  590. ///
  591. /// Note: Destruction of an instance of this class while call back is pending
  592. /// causes throwing an exception from \c IOService.
  593. ///
  594. /// Sample code:
  595. /// \code
  596. /// void function_to_call_back() {
  597. /// // this function will be called periodically
  598. /// }
  599. /// int interval_in_milliseconds = 1000;
  600. /// IOService io_service;
  601. ///
  602. /// IntervalTimer intervalTimer(io_service);
  603. /// intervalTimer.setup(function_to_call_back, interval_in_milliseconds);
  604. /// io_service.run();
  605. /// \endcode
  606. class IntervalTimer {
  607. public:
  608. /// \name The type of timer callback function
  609. typedef boost::function<void()> Callback;
  610. ///
  611. /// \name Constructors and Destructor
  612. ///
  613. /// Note: The copy constructor and the assignment operator are
  614. /// intentionally defined as private, making this class non-copyable.
  615. //@{
  616. private:
  617. IntervalTimer(const IntervalTimer& source);
  618. IntervalTimer& operator=(const IntervalTimer& source);
  619. public:
  620. /// \brief The constructor with \c IOService.
  621. ///
  622. /// This constructor may throw a standard exception if
  623. /// memory allocation fails inside the method.
  624. /// This constructor may also throw \c asio::system_error.
  625. ///
  626. /// \param io_service A reference to an instance of IOService
  627. IntervalTimer(IOService& io_service);
  628. /// \brief The destructor.
  629. ///
  630. /// This destructor never throws an exception.
  631. ///
  632. /// On the destruction of this class the timer will be canceled
  633. /// inside \c asio::deadline_timer.
  634. ~IntervalTimer();
  635. //@}
  636. /// \brief Register timer callback function and interval.
  637. ///
  638. /// This function sets callback function and interval in milliseconds.
  639. /// Timer will actually start after calling \c IOService::run().
  640. ///
  641. /// \param cbfunc A reference to a function \c void(void) to call back
  642. /// when the timer is expired (should not be an empty functor)
  643. /// \param interval Interval in milliseconds (greater than 0)
  644. ///
  645. /// Note: IntervalTimer will not pass \c asio::error_code to
  646. /// call back function. In case the timer is cancelled, the function
  647. /// will not be called.
  648. ///
  649. /// \throw isc::InvalidParameter cbfunc is empty
  650. /// \throw isc::BadValue interval is less than or equal to 0
  651. /// \throw isc::Unexpected ASIO library error
  652. void setup(const Callback& cbfunc, const long interval);
  653. /// Cancel the timer.
  654. ///
  655. /// If the timer has been set up, this method cancels any asynchronous
  656. /// events waiting on the timer and stops the timer itself.
  657. /// If the timer has already been canceled, this method effectively does
  658. /// nothing.
  659. ///
  660. /// This method never throws an exception.
  661. void cancel();
  662. /// Return the timer interval.
  663. ///
  664. /// This method returns the timer interval in milliseconds if it's running;
  665. /// if the timer has been canceled it returns 0.
  666. ///
  667. /// This method never throws an exception.
  668. long getInterval() const;
  669. private:
  670. IntervalTimerImpl* impl_;
  671. };
  672. } // asiolink
  673. #endif // __ASIOLINK_H
  674. // Local Variables:
  675. // mode: c++
  676. // End: