io_fetch.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 __IO_FETCH_H
  15. #define __IO_FETCH_H 1
  16. #include <config.h>
  17. #include <boost/shared_array.hpp>
  18. #include <boost/shared_ptr.hpp>
  19. #include <boost/date_time/posix_time/posix_time_types.hpp>
  20. #include <coroutine.h>
  21. #include <asio/error_code.hpp>
  22. #include <asiolink/io_address.h>
  23. #include <asiolink/io_service.h>
  24. #include <util/buffer.h>
  25. #include <dns/question.h>
  26. #include <dns/message.h>
  27. namespace isc {
  28. namespace asiodns {
  29. // Forward declarations
  30. struct IOFetchData;
  31. /// \brief Upstream Fetch Processing
  32. ///
  33. /// IOFetch is the class used to send upstream fetches and to handle responses.
  34. ///
  35. /// \param E Endpoint type to use.
  36. class IOFetch : public coroutine {
  37. public:
  38. /// \brief Protocol to use on the fetch
  39. enum Protocol {
  40. UDP = 0,
  41. TCP = 1
  42. };
  43. /// \brief Origin of Asynchronous I/O Call
  44. ///
  45. /// Indicates what initiated an asynchronous I/O call and used in deciding
  46. /// what error message to output if the I/O fails.
  47. enum Origin {
  48. NONE = 0, ///< No asynchronous call outstanding
  49. OPEN = 1,
  50. SEND = 2,
  51. RECEIVE = 3,
  52. CLOSE = 4
  53. };
  54. /// \brief Result of Upstream Fetch
  55. ///
  56. /// Note that this applies to the status of I/Os in the fetch - a fetch
  57. /// that resulted in a packet being received from the server is a SUCCESS,
  58. /// even if the contents of the packet indicate that some error occurred.
  59. enum Result {
  60. SUCCESS = 0, ///< Success, fetch completed
  61. TIME_OUT = 1, ///< Failure, fetch timed out
  62. STOPPED = 2, ///< Control code, fetch has been stopped
  63. NOTSET = 3 ///< For testing, indicates value not set
  64. };
  65. // The next enum is a "trick" to allow constants to be defined in a class
  66. // declaration.
  67. /// \brief Integer Constants
  68. enum {
  69. STAGING_LENGTH = 8192 ///< Size of staging buffer
  70. };
  71. /// \brief I/O Fetch Callback
  72. ///
  73. /// Class of callback object for when the fetch itself has completed - an
  74. /// object of this class is passed to the IOFetch constructor and its
  75. /// operator() method called when the fetch completes.
  76. ///
  77. /// Note the difference between the two operator() methods:
  78. /// - IOFetch::operator() callback is called when an asynchronous I/O has
  79. /// completed.
  80. /// - IOFetch::Callback::operator() is called when an upstream fetch - which
  81. /// may have involved several asynchronous I/O operations - has completed.
  82. ///
  83. /// This is an abstract class.
  84. class Callback {
  85. public:
  86. /// \brief Default Constructor
  87. Callback()
  88. {}
  89. /// \brief Virtual Destructor
  90. virtual ~Callback()
  91. {}
  92. /// \brief Callback method
  93. ///
  94. /// This is the method called when the fetch completes.
  95. ///
  96. /// \param result Result of the fetch
  97. virtual void operator()(Result result) = 0;
  98. };
  99. /// \brief Constructor.
  100. ///
  101. /// Creates the object that will handle the upstream fetch.
  102. ///
  103. /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
  104. /// \param service I/O Service object to handle the asynchronous
  105. /// operations.
  106. /// \param question DNS question to send to the upstream server.
  107. /// \param address IP address of upstream server
  108. /// \param port Port to which to connect on the upstream server
  109. /// \param buff Output buffer into which the response (in wire format)
  110. /// is written (if a response is received).
  111. /// \param cb Callback object containing the callback to be called when we
  112. /// terminate. The caller is responsible for managing this object
  113. /// and deleting it if necessary.
  114. /// \param wait Timeout for the fetch (in ms). The default value of
  115. /// -1 indicates no timeout.
  116. IOFetch(Protocol protocol, isc::asiolink::IOService& service,
  117. const isc::dns::Question& question,
  118. const isc::asiolink::IOAddress& address,
  119. uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
  120. int wait = -1);
  121. /// \brief Constructor
  122. /// This constructor has one parameter "query_message", which
  123. /// is the shared_ptr to a full query message. It's different
  124. /// with above contructor which has only question section. All
  125. /// other parameters are same.
  126. ///
  127. /// \param query_message the shared_ptr to a full query message
  128. /// got from a query client.
  129. IOFetch(Protocol protocol, isc::asiolink::IOService& service,
  130. isc::dns::ConstMessagePtr query_message,
  131. const isc::asiolink::IOAddress& address,
  132. uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
  133. int wait = -1);
  134. /// \brief Constructor.
  135. ///
  136. /// Creates the object that will handle the upstream fetch.
  137. ///
  138. /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
  139. /// \param service I/O Service object to handle the asynchronous
  140. /// operations.
  141. /// \param outpkt Packet to send to upstream server. Note that the
  142. /// QID (first two bytes of the packet) may be altered in the sending.
  143. /// \param buff Output buffer into which the response (in wire format)
  144. /// is written (if a response is received).
  145. /// \param cb Callback object containing the callback to be called
  146. /// when we terminate. The caller is responsible for managing this
  147. /// object and deleting it if necessary.
  148. /// \param address IP address of upstream server
  149. /// \param port Port to which to connect on the upstream server
  150. /// (default = 53)
  151. /// \param wait Timeout for the fetch (in ms). The default value of
  152. /// -1 indicates no timeout.
  153. IOFetch(Protocol protocol, isc::asiolink::IOService& service,
  154. isc::util::OutputBufferPtr& outpkt,
  155. const isc::asiolink::IOAddress& address,
  156. uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
  157. int wait = -1);
  158. /// \brief Return Current Protocol
  159. ///
  160. /// \return Protocol associated with this IOFetch object.
  161. Protocol getProtocol() const;
  162. /// \brief Coroutine entry point
  163. ///
  164. /// The operator() method is the method in which the coroutine code enters
  165. /// this object when an operation has been completed.
  166. ///
  167. /// \param ec Error code, the result of the last asynchronous I/O operation.
  168. /// \param length Amount of data received on the last asynchronous read
  169. void operator()(asio::error_code ec = asio::error_code(), size_t length = 0);
  170. /// \brief Terminate query
  171. ///
  172. /// This method can be called at any point. It terminates the current
  173. /// query with the specified reason.
  174. ///
  175. /// \param reason Reason for terminating the query
  176. void stop(Result reason = STOPPED);
  177. private:
  178. /// \brief IOFetch Initialization Function.
  179. /// All the parameters are same with the constructor, except
  180. /// parameter "query_message"
  181. /// \param query_message the message to be sent out.
  182. void initIOFetch(isc::dns::MessagePtr& query_message, Protocol protocol,
  183. isc::asiolink::IOService& service, const isc::dns::Question& question,
  184. const isc::asiolink::IOAddress& address, uint16_t port,
  185. isc::util::OutputBufferPtr& buff, Callback* cb, int wait);
  186. /// \brief Log I/O Failure
  187. ///
  188. /// Records an I/O failure to the log file
  189. ///
  190. /// \param ec ASIO error code
  191. void logIOFailure(asio::error_code ec);
  192. // Member variables. All data is in a structure pointed to by a shared
  193. // pointer. The IOFetch object is copied a number of times during its
  194. // life, and only requiring a pointer to be copied reduces overhead.
  195. boost::shared_ptr<IOFetchData> data_; ///< Private data
  196. };
  197. } // namespace asiodns
  198. } // namespace isc
  199. #endif // __IO_FETCH_H