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