dns_server.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. #ifndef __ASIOLINK_DNS_SERVER_H
  15. #define __ASIOLINK_DNS_SERVER_H 1
  16. #include <asiolink/io_message.h>
  17. namespace isc {
  18. namespace asiodns {
  19. /// \brief The \c DNSServer class is a wrapper (and base class) for
  20. /// classes which provide DNS server functionality.
  21. ///
  22. /// The classes derived from this one, \c TCPServer and \c UDPServer,
  23. /// act as the interface layer between clients sending queries, and
  24. /// functions defined elsewhere that provide answers to those queries.
  25. /// Those functions are described in more detail below under
  26. /// \c SimpleCallback, \c DNSLookup, and \c DNSAnswer.
  27. ///
  28. /// Notes to developers:
  29. /// When constructed, this class (and its derived classes) will have its
  30. /// "self_" member set to point to "this". Objects of this class (as
  31. /// instantiated through a base class) are sometimes passed by
  32. /// reference (as this superclass); calls to methods in the base
  33. /// class are then rerouted via this pointer to methods in the derived
  34. /// class. This allows code from outside asiodns, with no specific
  35. /// knowledge of \c TCPServer or \c UDPServer, to access their methods.
  36. ///
  37. /// This class is both assignable and copy-constructable. Its subclasses
  38. /// use the "stackless coroutine" pattern, meaning that it will copy itself
  39. /// when "forking", and that instances will be posted as ASIO handler
  40. /// objects, which are always copied.
  41. ///
  42. /// Because these objects are frequently copied, it is recommended
  43. /// that derived classes be kept small to reduce copy overhead.
  44. class DNSServer {
  45. protected:
  46. ///
  47. /// \name Constructors and destructors
  48. ///
  49. /// This is intentionally defined as \c protected, as this base class
  50. /// should never be instantiated except as part of a derived class.
  51. //@{
  52. DNSServer() {
  53. self_ = this;
  54. }
  55. public:
  56. /// \brief The destructor
  57. virtual ~DNSServer() {}
  58. //@}
  59. ///
  60. /// \name Class methods
  61. ///
  62. /// These methods all make their calls indirectly via the "self_"
  63. /// pointer, ensuring that the functions ultimately invoked will be
  64. /// the ones in the derived class. This makes it possible to pass
  65. /// instances of derived classes as references to this base class
  66. /// without losing access to derived class data.
  67. ///
  68. //@{
  69. /// \brief The funtion operator
  70. virtual void operator()(asio::error_code ec = asio::error_code(),
  71. size_t length = 0)
  72. {
  73. (*self_)(ec, length);
  74. }
  75. /// \brief Stop current running server
  76. virtual void stop() { self_->stop();}
  77. /// \brief Resume processing of the server coroutine after an
  78. /// asynchronous call (e.g., to the DNS Lookup provider) has completed.
  79. ///
  80. /// \param done If true, this signals the system there is an answer
  81. /// to return.
  82. virtual void resume(const bool done) { self_->resume(done); }
  83. /// \brief Returns a pointer to a clone of this DNSServer object.
  84. ///
  85. /// When a \c DNSServer object is copied or assigned, the result will
  86. /// normally be another \c DNSServer object containing a copy
  87. /// of the original "self_" pointer. Calling clone() guarantees
  88. /// that the underlying object is also correctly copied.
  89. ///
  90. /// \return A deep copy of this DNSServer object
  91. virtual DNSServer* clone() { return (self_->clone()); }
  92. //@}
  93. protected:
  94. /// \brief Lookup handler object.
  95. ///
  96. /// This is a protected class; it can only be instantiated
  97. /// from within a derived class of \c DNSServer.
  98. ///
  99. /// A server object that has received a query creates an instance
  100. /// of this class and scheudles it on the ASIO service queue
  101. /// using asio::io_service::post(). When the handler executes, it
  102. /// calls the asyncLookup() method in the server object to start a
  103. /// DNS lookup. When the lookup is complete, the server object is
  104. /// scheduled to resume, again using io_service::post().
  105. ///
  106. /// Note that the calling object is copied into the handler object,
  107. /// not referenced. This is because, once the calling object yields
  108. /// control to the handler, it falls out of scope and may disappear
  109. template <typename T>
  110. class AsyncLookup {
  111. public:
  112. AsyncLookup(T& caller) : caller_(caller) {}
  113. void operator()() { caller_.asyncLookup(); }
  114. private:
  115. T caller_;
  116. };
  117. /// \brief Carries out a DNS lookup.
  118. ///
  119. /// This function calls the \c DNSLookup object specified by the
  120. /// DNS server when the \c IOService was created, passing along
  121. /// the details of the query and a pointer back to the current
  122. /// server object. It is called asynchronously via the AsyncLookup
  123. /// handler class.
  124. virtual void asyncLookup() { self_->asyncLookup(); }
  125. private:
  126. DNSServer* self_;
  127. };
  128. } // namespace asiodns
  129. } // namespace isc
  130. #endif // __ASIOLINK_DNS_SERVER_H