dns_server.h 6.1 KB

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