io_fetch.h 7.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

Stephen Morris's avatar
Stephen Morris committed
15 16
#ifndef __IO_FETCH_H
#define __IO_FETCH_H 1
17 18 19 20 21

#include <config.h>

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

Stephen Morris's avatar
Stephen Morris committed
24 25
#include <coroutine.h>

26 27
#include <asio/error_code.hpp>

28 29 30 31 32
#include <dns/buffer.h>
#include <dns/question.h>

namespace asiolink {

33 34 35 36
// Forward declarations
class IOAddress;
class IOFetchData;
class IOService;
Stephen Morris's avatar
Stephen Morris committed
37

38 39 40
/// \brief Upstream Fetch Processing
///
/// IOFetch is the class used to send upstream fetches and to handle responses.
Stephen Morris's avatar
Stephen Morris committed
41 42 43 44
///
/// \param E Endpoint type to use.

class IOFetch : public coroutine {
45
public:
46 47 48 49 50 51
    /// \brief Protocol to use on the fetch
    enum Protocol {
        UDP = 0,
        TCP = 1
    };

52 53 54 55 56 57 58 59 60 61 62
    /// \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
    };
63 64 65 66 67 68 69 70

    /// \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
71 72 73
        TIME_OUT = 1,       ///< Failure, fetch timed out
        STOPPED = 2,        ///< Control code, fetch has been stopped
        NOTSET = 3          ///< For testing, indicates value not set
74
    };
Stephen Morris's avatar
Stephen Morris committed
75

76 77 78 79 80
    // The next enum is a "trick" to allow constants to be defined in a class
    // declaration.

    /// \brief Integer Constants
    enum {
81
        STAGING_LENGTH = 8192   ///< Size of staging buffer
82
    };
Stephen Morris's avatar
Stephen Morris committed
83

84 85
    /// \brief I/O Fetch Callback
    ///
86 87 88 89 90 91 92 93 94
    /// 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.
95 96 97 98 99 100 101 102 103 104 105 106
    ///
    /// This is an abstract class.
    class Callback {
    public:
        /// \brief Default Constructor
        Callback()
        {}

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

107
        /// \brief Callback method
108
        ///
Stephen Morris's avatar
Stephen Morris committed
109
        /// This is the method called when the fetch completes.
110
        ///
111 112
        /// \param result Result of the fetch
        virtual void operator()(Result result) = 0;
113 114 115 116 117 118
    };

    /// \brief Constructor.
    ///
    /// Creates the object that will handle the upstream fetch.
    ///
Stephen Morris's avatar
Stephen Morris committed
119 120
    /// TODO: Need to randomise the source port
    ///
121
    /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
Stephen Morris's avatar
Stephen Morris committed
122
    /// \param service I/O Service object to handle the asynchronous
123 124
    ///     operations.
    /// \param question DNS question to send to the upstream server.
Stephen Morris's avatar
Stephen Morris committed
125
    /// \param buff Output buffer into which the response (in wire format)
126
    ///     is written (if a response is received).
Stephen Morris's avatar
Stephen Morris committed
127
    /// \param cb Callback object containing the callback to be called
128 129
    ///     when we terminate.  The caller is responsible for managing this
    ///     object and deleting it if necessary.
Stephen Morris's avatar
Stephen Morris committed
130 131 132 133
    /// \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
134
    ///     -1 indicates no timeout.
135
    IOFetch(Protocol protocol, IOService& service,
Stephen Morris's avatar
Stephen Morris committed
136 137 138
        const isc::dns::Question& question, const IOAddress& address,
        uint16_t port, isc::dns::OutputBufferPtr& buff, Callback* cb,
        int wait = -1);
139

Stephen Morris's avatar
Stephen Morris committed
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    /// \brief Constructor.
    ///
    /// Creates the object that will handle the upstream fetch.
    ///
    /// TODO: Need to randomise the source port
    ///
    /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
    /// \param service I/O Service object to handle the asynchronous
    ///     operations.
    /// \param outpkt Packet to send to upstream server.  Note that the
    ///     QID (first two bytes of the packet) may be altered in the sending.
    /// \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 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
    ///     -1 indicates no timeout.
    IOFetch(Protocol protocol, IOService& service,
        isc::dns::OutputBufferPtr& outpkt, const IOAddress& address,
        uint16_t port, isc::dns::OutputBufferPtr& buff, Callback* cb,
        int wait = -1);

166 167 168 169 170
    /// \brief Return Current Protocol
    ///
    /// \return Protocol associated with this IOFetch object.
    Protocol getProtocol() const;

171 172 173 174 175 176 177
    /// \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
178
    void operator()(asio::error_code ec = asio::error_code(), size_t length = 0);
179 180 181 182 183 184 185 186 187 188

    /// \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:
189 190 191 192 193
    /// \brief Log I/O Failure
    ///
    /// Records an I/O failure to the log file
    ///
    /// \param ec ASIO error code
194
    void logIOFailure(asio::error_code ec);
195

196 197 198
    // 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
199
    boost::shared_ptr<IOFetchData>  data_;   ///< Private data
200

Stephen Morris's avatar
Stephen Morris committed
201
};
202

Stephen Morris's avatar
Stephen Morris committed
203
} // namespace asiolink
204

Stephen Morris's avatar
Stephen Morris committed
205
#endif // __IO_FETCH_H