%PDF- %PDF-
Direktori : /backups/router/usr/local/include/kea/asiodns/ |
Current File : //backups/router/usr/local/include/kea/asiodns/io_fetch.h |
// Copyright (C) 2010-2024 Internet Systems Consortium, Inc. ("ISC") // // 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/. #ifndef IO_FETCH_H #define IO_FETCH_H #include <config.h> // We want to use coroutine.hpp from the system's boost headers if possible. // However, very old Boost versions (provided by RHEL 7 or CentOS 7) didn't have // this header. So we can resort to our bundled version, but only if necessary. #ifdef HAVE_BOOST_ASIO_COROUTINE_HPP #include <boost/asio/coroutine.hpp> #else #include <ext/coroutine/coroutine.hpp> #endif #include <asiolink/io_address.h> #include <asiolink/io_service.h> #include <dns/message.h> #include <dns/question.h> #include <util/buffer.h> #include <boost/shared_array.hpp> #include <boost/shared_ptr.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/system/error_code.hpp> namespace isc { namespace asiodns { // Forward declarations struct IOFetchData; /// @brief Upstream Fetch Processing. /// /// IOFetch is the class used to send upstream fetches and to handle responses. class IOFetch : public boost::asio::coroutine { public: /// @brief Protocol to use on the fetch enum Protocol { UDP = 0, TCP = 1 }; /// @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 }; /// @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 TIME_OUT = 1, // Failure, fetch timed out STOPPED = 2, // Control code, fetch has been stopped NOTSET = 3 // For testing, indicates value not set }; /// @note The next enum is a "trick" to allow constants to be defined in a class /// declaration. /// @brief Integer Constants. enum { STAGING_LENGTH = 8192 // Size of staging buffer }; /// @brief I/O Fetch Callback. /// /// 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. /// /// This is an abstract class. class Callback { public: /// @brief Constructor. Callback() = default; /// @brief Destructor. virtual ~Callback() = default; /// @brief Callback method. /// /// This method is called when the fetch completes. /// /// @param result Result of the fetch. virtual void operator()(Result result) = 0; }; /// @brief Constructor. /// /// Creates the object that will handle the upstream fetch. /// /// @param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP. /// @param service I/O Service object to handle the asynchronous /// operations. /// @param question DNS question to send to the upstream server. /// @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. /// @param edns true if the request should be EDNS. The default value is /// true. IOFetch(Protocol protocol, const isc::asiolink::IOServicePtr& service, const isc::dns::Question& question, const isc::asiolink::IOAddress& address, uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb, int wait = -1, bool edns = true); /// @brief Constructor /// /// This constructor has one parameter "query_message", which is the shared_ptr /// to a full query message. It's different with above constructor which has only /// question section. All other parameters are the same. /// /// @param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP. /// @param service I/O Service object to handle the asynchronous /// operations. /// @param query_message the shared_ptr to a full query message got from a /// query client. /// @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. IOFetch(Protocol protocol, const isc::asiolink::IOServicePtr& service, isc::dns::ConstMessagePtr query_message, const isc::asiolink::IOAddress& address, uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb, int wait = -1); /// @brief Constructor. /// /// Creates the object that will handle the upstream fetch. /// /// @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, const isc::asiolink::IOServicePtr& service, isc::util::OutputBufferPtr& outpkt, const isc::asiolink::IOAddress& address, uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb, int wait = -1); /// @brief Return Current Protocol. /// /// @return Protocol associated with this IOFetch object. Protocol getProtocol() const; /// @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. void operator()(boost::system::error_code ec = boost::system::error_code(), size_t length = 0); /// @brief Terminate query. /// /// This method can be called at any point. It terminates the current /// query with the specified reason. /// This function stops the coroutine sequence. It is called either when the /// query finishes or when the timer times out. Either way, it sets the /// "stopped_" flag and cancels anything that is in progress. /// /// As the function may be entered multiple times as things wind down, it checks /// if the stopped_ flag is already set. If it is, the call is a no-op. /// /// @param reason Reason for terminating the query. void stop(Result reason = STOPPED); private: /// @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, const isc::asiolink::IOServicePtr& service, const isc::dns::Question& question, const isc::asiolink::IOAddress& address, uint16_t port, isc::util::OutputBufferPtr& buff, Callback* cb, int wait, bool edns = true); /// @brief Log I/O Failure. /// /// Records an I/O failure to the log file. /// /// @param ec ASIO error code. void logIOFailure(boost::system::error_code ec); /// @brief data which is 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. boost::shared_ptr<IOFetchData> data_; ///< Private data }; /// @brief Defines a pointer to an IOFetch. typedef boost::shared_ptr<IOFetch> IOFetchPtr; } // namespace asiodns } // namespace isc #endif // IO_FETCH_H