io_fetch.h 8.86 KB
Newer Older
1
// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC")
2
//
3 4 5
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6

7 8
#ifndef IO_FETCH_H
#define IO_FETCH_H 1
9 10 11

#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
Stephen Morris's avatar
Stephen Morris committed
12
#include <boost/date_time/posix_time/posix_time_types.hpp>
13

Stephen Morris's avatar
Stephen Morris committed
14 15
#include <coroutine.h>

Francis Dupont's avatar
Francis Dupont committed
16
#include <boost/system/error_code.hpp>
17
#include <asiolink/io_address.h>
18
#include <asiolink/io_service.h>
19

20
#include <util/buffer.h>
21
#include <dns/question.h>
22
#include <dns/message.h>
23

24 25
namespace isc {
namespace asiodns {
26

27
// Forward declarations
28
struct IOFetchData;
Stephen Morris's avatar
Stephen Morris committed
29

30 31 32
/// \brief Upstream Fetch Processing
///
/// IOFetch is the class used to send upstream fetches and to handle responses.
Stephen Morris's avatar
Stephen Morris committed
33 34 35 36
///
/// \param E Endpoint type to use.

class IOFetch : public coroutine {
37
public:
38 39 40 41 42 43
    /// \brief Protocol to use on the fetch
    enum Protocol {
        UDP = 0,
        TCP = 1
    };

44 45 46 47 48 49 50 51 52 53 54
    /// \brief Origin of Asynchronous I/O Call
    ///
    /// Indicates what initiated an asynchronous I/O call and used in deciding
    /// what error message to output if the I/O fails.
    enum Origin {
        NONE = 0,           ///< No asynchronous call outstanding
        OPEN = 1,
        SEND = 2,
        RECEIVE = 3,
        CLOSE = 4
    };
55 56 57 58 59 60 61 62

    /// \brief Result of Upstream Fetch
    ///
    /// Note that this applies to the status of I/Os in the fetch - a fetch
    /// that resulted in a packet being received from the server is a SUCCESS,
    /// even if the contents of the packet indicate that some error occurred.
    enum Result {
        SUCCESS = 0,        ///< Success, fetch completed
63 64 65
        TIME_OUT = 1,       ///< Failure, fetch timed out
        STOPPED = 2,        ///< Control code, fetch has been stopped
        NOTSET = 3          ///< For testing, indicates value not set
66
    };
Stephen Morris's avatar
Stephen Morris committed
67

68 69 70 71 72
    // The next enum is a "trick" to allow constants to be defined in a class
    // declaration.

    /// \brief Integer Constants
    enum {
73
        STAGING_LENGTH = 8192   ///< Size of staging buffer
74
    };
Stephen Morris's avatar
Stephen Morris committed
75

76 77
    /// \brief I/O Fetch Callback
    ///
78 79 80 81 82 83 84 85 86
    /// Class of callback object for when the fetch itself has completed - an
    /// object of this class is passed to the IOFetch constructor and its
    /// operator() method called when the fetch completes.
    ///
    /// Note the difference between the two operator() methods:
    /// - IOFetch::operator() callback is called when an asynchronous I/O has
    ///   completed.
    /// - IOFetch::Callback::operator() is called when an upstream fetch - which
    ///   may have involved several asynchronous I/O operations - has completed.
87 88 89 90 91 92 93 94 95 96 97 98
    ///
    /// This is an abstract class.
    class Callback {
    public:
        /// \brief Default Constructor
        Callback()
        {}

        /// \brief Virtual Destructor
        virtual ~Callback()
        {}

99
        /// \brief Callback method
100
        ///
Stephen Morris's avatar
Stephen Morris committed
101
        /// This is the method called when the fetch completes.
102
        ///
103 104
        /// \param result Result of the fetch
        virtual void operator()(Result result) = 0;
105 106 107 108 109 110
    };

    /// \brief Constructor.
    ///
    /// Creates the object that will handle the upstream fetch.
    ///
111
    /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
Stephen Morris's avatar
Stephen Morris committed
112
    /// \param service I/O Service object to handle the asynchronous
113
    ///        operations.
114
    /// \param question DNS question to send to the upstream server.
Stephen Morris's avatar
Stephen Morris committed
115 116
    /// \param address IP address of upstream server
    /// \param port Port to which to connect on the upstream server
117 118 119 120 121
    /// \param buff Output buffer into which the response (in wire format)
    ///        is written (if a response is received).
    /// \param cb Callback object containing the callback to be called when we
    ///        terminate.  The caller is responsible for managing this object
    ///        and deleting it if necessary.
Stephen Morris's avatar
Stephen Morris committed
122
    /// \param wait Timeout for the fetch (in ms).  The default value of
Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
123
    ///        -1 indicates no timeout.
Dima Volodin's avatar
Dima Volodin committed
124 125
    /// \param edns true if the request should be EDNS. The default value is
    ///        true.
126 127 128
    IOFetch(Protocol protocol, isc::asiolink::IOService& service,
        const isc::dns::Question& question,
        const isc::asiolink::IOAddress& address,
129
        uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
Dima Volodin's avatar
Dima Volodin committed
130 131
        int wait = -1,
        bool edns = true);
132

133 134 135
    /// \brief Constructor
    ///  This constructor has one parameter "query_message", which
    ///  is the shared_ptr to a full query message. It's different
136
    ///  with above constructor which has only question section. All
137 138
    ///  other parameters are same.
    ///
139 140 141
    /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
    /// \param service I/O Service object to handle the asynchronous
    ///        operations.
142 143
    /// \param query_message the shared_ptr to a full query message
    ///        got from a query client.
144 145 146 147 148 149 150 151 152
    /// \param address IP address of upstream server
    /// \param port Port to which to connect on the upstream server
    /// \param buff Output buffer into which the response (in wire format)
    ///        is written (if a response is received).
    /// \param cb Callback object containing the callback to be called when we
    ///        terminate.  The caller is responsible for managing this object
    ///        and deleting it if necessary.
    /// \param wait Timeout for the fetch (in ms).  The default value of
    ///        -1 indicates no timeout.
153 154 155 156 157 158
    IOFetch(Protocol protocol, isc::asiolink::IOService& service,
        isc::dns::ConstMessagePtr query_message,
        const isc::asiolink::IOAddress& address,
        uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
        int wait = -1);

Stephen Morris's avatar
Stephen Morris committed
159 160 161
    /// \brief Constructor.
    ///
    /// Creates the object that will handle the upstream fetch.
Stephen Morris's avatar
Stephen Morris committed
162
    ///
163
    /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
Stephen Morris's avatar
Stephen Morris committed
164
    /// \param service I/O Service object to handle the asynchronous
165
    ///     operations.
Stephen Morris's avatar
Stephen Morris committed
166 167
    /// \param outpkt Packet to send to upstream server.  Note that the
    ///     QID (first two bytes of the packet) may be altered in the sending.
Stephen Morris's avatar
Stephen Morris committed
168
    /// \param buff Output buffer into which the response (in wire format)
169
    ///     is written (if a response is received).
Stephen Morris's avatar
Stephen Morris committed
170
    /// \param cb Callback object containing the callback to be called
171 172
    ///     when we terminate.  The caller is responsible for managing this
    ///     object and deleting it if necessary.
Stephen Morris's avatar
Stephen Morris committed
173 174 175 176
    /// \param address IP address of upstream server
    /// \param port Port to which to connect on the upstream server
    /// (default = 53)
    /// \param wait Timeout for the fetch (in ms).  The default value of
177
    ///     -1 indicates no timeout.
178
    IOFetch(Protocol protocol, isc::asiolink::IOService& service,
179
        isc::util::OutputBufferPtr& outpkt,
180
        const isc::asiolink::IOAddress& address,
181
        uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
Stephen Morris's avatar
Stephen Morris committed
182
        int wait = -1);
183

184 185 186 187 188
    /// \brief Return Current Protocol
    ///
    /// \return Protocol associated with this IOFetch object.
    Protocol getProtocol() const;

189 190 191 192 193 194 195
    /// \brief Coroutine entry point
    ///
    /// The operator() method is the method in which the coroutine code enters
    /// this object when an operation has been completed.
    ///
    /// \param ec Error code, the result of the last asynchronous I/O operation.
    /// \param length Amount of data received on the last asynchronous read
196
    void operator()(boost::system::error_code ec = boost::system::error_code(), size_t length = 0);
197 198 199 200 201 202 203 204 205 206

    /// \brief Terminate query
    ///
    /// This method can be called at any point.  It terminates the current
    /// query with the specified reason.
    ///
    /// \param reason Reason for terminating the query
    void stop(Result reason = STOPPED);

private:
207 208 209 210 211 212 213
    /// \brief IOFetch Initialization Function.
    /// All the parameters are same with the constructor, except
    /// parameter "query_message"
    /// \param query_message the message to be sent out.
    void initIOFetch(isc::dns::MessagePtr& query_message, Protocol protocol,
            isc::asiolink::IOService& service, const isc::dns::Question& question,
            const isc::asiolink::IOAddress& address, uint16_t port,
Dima Volodin's avatar
Dima Volodin committed
214
            isc::util::OutputBufferPtr& buff, Callback* cb, int wait,
215
            bool edns = true);
216

217 218 219 220 221
    /// \brief Log I/O Failure
    ///
    /// Records an I/O failure to the log file
    ///
    /// \param ec ASIO error code
222
    void logIOFailure(boost::system::error_code ec);
223

224 225 226
    // Member variables.  All data is in a structure pointed to by a shared
    // pointer.  The IOFetch object is copied a number of times during its
    // life, and only requiring a pointer to be copied reduces overhead.
Stephen Morris's avatar
Stephen Morris committed
227
    boost::shared_ptr<IOFetchData>  data_;   ///< Private data
228

Stephen Morris's avatar
Stephen Morris committed
229
};
230

231 232
} // namespace asiodns
} // namespace isc
233

234
#endif // IO_FETCH_H