io_fetch.h 6.07 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
#include <util/buffer.h>
29 30 31 32
#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
        const isc::dns::Question& question, const IOAddress& address,
137
        uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb,
Stephen Morris's avatar
Stephen Morris committed
138
        int wait = -1);
139

140 141 142 143 144
    /// \brief Return Current Protocol
    ///
    /// \return Protocol associated with this IOFetch object.
    Protocol getProtocol() const;

145 146 147 148 149 150 151
    /// \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
152
    void operator()(asio::error_code ec = asio::error_code(), size_t length = 0);
153 154 155 156 157 158 159 160 161 162

    /// \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:
163 164 165 166 167
    /// \brief Log I/O Failure
    ///
    /// Records an I/O failure to the log file
    ///
    /// \param ec ASIO error code
168
    void logIOFailure(asio::error_code ec);
169

170 171 172
    // 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
173
    boost::shared_ptr<IOFetchData>  data_;   ///< Private data
174

Stephen Morris's avatar
Stephen Morris committed
175
};
176

Stephen Morris's avatar
Stephen Morris committed
177
} // namespace asiolink
178

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