summaryrefslogtreecommitdiffstats
path: root/src/lib/asiodns/io_fetch.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/asiodns/io_fetch.cc')
-rw-r--r--src/lib/asiodns/io_fetch.cc195
1 files changed, 79 insertions, 116 deletions
diff --git a/src/lib/asiodns/io_fetch.cc b/src/lib/asiodns/io_fetch.cc
index 1041e24999..742abc66e9 100644
--- a/src/lib/asiodns/io_fetch.cc
+++ b/src/lib/asiodns/io_fetch.cc
@@ -20,7 +20,6 @@
#include <dns/opcode.h>
#include <cryptolink/crypto_rng.h>
#include <dns/rcode.h>
-#include <util/buffer.h>
#include <util/io.h>
#include <boost/scoped_ptr.hpp>
@@ -32,23 +31,24 @@
#include <stdint.h>
#include <sys/socket.h>
-using namespace boost::asio;
using namespace isc::asiolink;
using namespace isc::dns;
-using namespace isc::util;
using namespace isc::log;
+using namespace isc::util;
+
+using namespace boost::asio;
using namespace std;
namespace isc {
namespace asiodns {
-// Log debug verbosity
+// Log debug verbosity.
const int DBG_IMPORTANT = DBGLVL_TRACE_BASIC;
const int DBG_COMMON = DBGLVL_TRACE_DETAIL;
const int DBG_ALL = DBGLVL_TRACE_DETAIL + 20;
-/// \brief IOFetch Data
+/// @brief IOFetch Data
///
/// The data for IOFetch is held in a separate struct pointed to by a shared_ptr
/// object. This is because the IOFetch object will be copied often (it is used
@@ -56,111 +56,94 @@ const int DBG_ALL = DBGLVL_TRACE_DETAIL + 20;
/// want keep the same data). Organising the data in this way keeps copying to
/// a minimum.
struct IOFetchData : boost::noncopyable {
- IOServicePtr io_service_; ///< The IO service
+ IOServicePtr io_service_; // The IO service
// The first two members are shared pointers to a base class because what is
// actually instantiated depends on whether the fetch is over UDP or TCP,
// which is not known until construction of the IOFetch. Use of a shared
// pointer here is merely to ensure deletion when the data object is deleted.
- boost::scoped_ptr<IOAsioSocket<IOFetch>> socket; ///< Socket to use for I/O
- boost::scoped_ptr<IOEndpoint> remote_snd; ///< Where the fetch is sent
- boost::scoped_ptr<IOEndpoint> remote_rcv; ///< Where the response came from
- OutputBufferPtr msgbuf; ///< Wire buffer for question
- OutputBufferPtr received; ///< Received data put here
- IOFetch::Callback* callback; ///< Called on I/O Completion
- boost::asio::deadline_timer timer; ///< Timer to measure timeouts
- IOFetch::Protocol protocol; ///< Protocol being used
- size_t cumulative; ///< Cumulative received amount
- size_t expected; ///< Expected amount of data
- size_t offset; ///< Offset to receive data
- bool stopped; ///< Have we stopped running?
- int timeout; ///< Timeout in ms
- bool packet; ///< true if packet was supplied
+ boost::scoped_ptr<IOAsioSocket<IOFetch>> socket; // Socket to use for I/O
+ boost::scoped_ptr<IOEndpoint> remote_snd; // Where the fetch is sent
+ boost::scoped_ptr<IOEndpoint> remote_rcv; // Where the response came from
+ OutputBufferPtr msgbuf; // Wire buffer for question
+ OutputBufferPtr received; // Received data put here
+ IOFetch::Callback* callback; // Called on I/O Completion
+ boost::asio::deadline_timer timer; // Timer to measure timeouts
+ IOFetch::Protocol protocol; // Protocol being used
+ size_t cumulative; // Cumulative received amount
+ size_t expected; // Expected amount of data
+ size_t offset; // Offset to receive data
+ bool stopped; // Have we stopped running?
+ int timeout; // Timeout in ms
+ bool packet; // true if packet was supplied
// In case we need to log an error, the origin of the last asynchronous
// I/O is recorded. To save time and simplify the code, this is recorded
// as the ID of the error message that would be generated if the I/O failed.
// This means that we must make sure that all possible "origins" take the
// same arguments in their message in the same order.
- isc::log::MessageID origin; ///< Origin of last asynchronous I/O
+ isc::log::MessageID origin; // Origin of last asynchronous I/O
uint8_t staging[IOFetch::STAGING_LENGTH];
- ///< Temporary array for received data
- isc::dns::qid_t qid; ///< The QID set in the query
+ // Temporary array for received data
+ isc::dns::qid_t qid; // The QID set in the query
- /// \brief Constructor
+ /// @brief Constructor.
///
- /// Just fills in the data members of the IOFetchData structure
+ /// Just fills in the data members of the IOFetchData structure.
///
- /// \param proto Either IOFetch::TCP or IOFetch::UDP.
- /// \param service I/O Service object to handle the asynchronous
+ /// @param proto Either IOFetch::TCP or IOFetch::UDP.
+ /// @param service I/O Service object to handle the asynchronous
/// operations.
- /// \param address IP address of upstream server
- /// \param port Port to use for the query
- /// \param buff Output buffer into which the response (in wire format)
+ /// @param address IP address of upstream server.
+ /// @param port Port to use for the query.
+ /// @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
+ /// @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).
+ /// @param wait Timeout for the fetch (in ms).
///
- /// TODO: May need to alter constructor (see comment 4 in Trac ticket #554)
+ /// TODO: May need to alter constructor (see comment 4 in Trac ticket #554).
IOFetchData(IOFetch::Protocol proto, const IOServicePtr& service,
- const IOAddress& address, uint16_t port, OutputBufferPtr& buff,
- IOFetch::Callback* cb, int wait) : io_service_(service),
- socket((proto == IOFetch::UDP) ?
- static_cast<IOAsioSocket<IOFetch>*>(
- new UDPSocket<IOFetch>(io_service_)) :
- static_cast<IOAsioSocket<IOFetch>*>(
- new TCPSocket<IOFetch>(io_service_))
- ),
+ const IOAddress& address, uint16_t port, OutputBufferPtr& buff,
+ IOFetch::Callback* cb, int wait) :
+ io_service_(service), socket((proto == IOFetch::UDP) ?
+ static_cast<IOAsioSocket<IOFetch>*>(new UDPSocket<IOFetch>(io_service_)) :
+ static_cast<IOAsioSocket<IOFetch>*>(new TCPSocket<IOFetch>(io_service_))),
remote_snd((proto == IOFetch::UDP) ?
static_cast<IOEndpoint*>(new UDPEndpoint(address, port)) :
- static_cast<IOEndpoint*>(new TCPEndpoint(address, port))
- ),
+ static_cast<IOEndpoint*>(new TCPEndpoint(address, port))),
remote_rcv((proto == IOFetch::UDP) ?
static_cast<IOEndpoint*>(new UDPEndpoint(address, port)) :
- static_cast<IOEndpoint*>(new TCPEndpoint(address, port))
- ),
- msgbuf(new OutputBuffer(512)),
- received(buff),
- callback(cb),
- timer(io_service_->getInternalIOService()),
- protocol(proto),
- cumulative(0),
- expected(0),
- offset(0),
- stopped(false),
- timeout(wait),
- packet(false),
- origin(ASIODNS_UNKNOWN_ORIGIN),
- staging(),
- qid(cryptolink::generateQid()) {
+ static_cast<IOEndpoint*>(new TCPEndpoint(address, port))),
+ msgbuf(new OutputBuffer(512)), received(buff), callback(cb),
+ timer(io_service_->getInternalIOService()), protocol(proto), cumulative(0),
+ expected(0), offset(0), stopped(false), timeout(wait), packet(false),
+ origin(ASIODNS_UNKNOWN_ORIGIN), staging(), qid(cryptolink::generateQid()) {
}
- /// \brief Destructor
+ /// @brief Destructor
~IOFetchData() {
timer.cancel();
}
- // Checks if the response we received was ok;
- // - data contains the buffer we read, as well as the address
- // we sent to and the address we received from.
- // length is provided by the operator() in IOFetch.
- // Addresses must match, number of octets read must be at least
- // 2, and the first two octets must match the qid of the message
- // we sent.
+ /// @brief Checks if the response we received was ok.
+ ///
+ /// The data member contains the buffer we read, as well as the address we
+ /// sent to and the address we received from, length is provided by the
+ /// operator() in IOFetch.
+ /// The addresses must match, number of octets read must be at least two,
+ /// and they must match the qid of the message we sent.
bool responseOK() {
return (*remote_snd == *remote_rcv && cumulative >= 2 &&
readUint16(received->getData(), received->getLength()) == qid);
}
};
-/// IOFetch Constructor - just initialize the private data
-
IOFetch::IOFetch(Protocol protocol, const IOServicePtr& service,
const isc::dns::Question& question, const IOAddress& address,
uint16_t port, OutputBufferPtr& buff, Callback* cb, int wait, bool edns) {
- MessagePtr query_msg(new Message(Message::RENDER));
- initIOFetch(query_msg, protocol, service, question, address, port, buff,
+ MessagePtr query(new Message(Message::RENDER));
+ initIOFetch(query, protocol, service, question, address, port, buff,
cb, wait, edns);
}
@@ -174,57 +157,46 @@ IOFetch::IOFetch(Protocol protocol, const IOServicePtr& service,
}
IOFetch::IOFetch(Protocol protocol, const IOServicePtr& service,
- ConstMessagePtr query_message, const IOAddress& address, uint16_t port,
- OutputBufferPtr& buff, Callback* cb, int wait) {
- MessagePtr msg(new Message(Message::RENDER));
-
- msg->setHeaderFlag(Message::HEADERFLAG_RD,
- query_message->getHeaderFlag(Message::HEADERFLAG_RD));
- msg->setHeaderFlag(Message::HEADERFLAG_CD,
- query_message->getHeaderFlag(Message::HEADERFLAG_CD));
-
- initIOFetch(msg, protocol, service,
- **(query_message->beginQuestion()),
- address, port, buff, cb, wait);
+ ConstMessagePtr query_message, const IOAddress& address,
+ uint16_t port, OutputBufferPtr& buff, Callback* cb, int wait) {
+ MessagePtr question(new Message(Message::RENDER));
+ question->setHeaderFlag(Message::HEADERFLAG_RD,
+ query_message->getHeaderFlag(Message::HEADERFLAG_RD));
+ question->setHeaderFlag(Message::HEADERFLAG_CD,
+ query_message->getHeaderFlag(Message::HEADERFLAG_CD));
+
+ initIOFetch(question, protocol, service, **(query_message->beginQuestion()), address,
+ port, buff, cb, wait);
}
void
-IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol,
- const IOServicePtr& service,
- const isc::dns::Question& question,
- const IOAddress& address, uint16_t port,
+IOFetch::initIOFetch(MessagePtr& query, Protocol protocol, const IOServicePtr& service,
+ const isc::dns::Question& question, const IOAddress& address, uint16_t port,
OutputBufferPtr& buff, Callback* cb, int wait, bool edns) {
- data_ = boost::shared_ptr<IOFetchData>(new IOFetchData(
- protocol, service, address, port, buff, cb, wait));
-
- query_msg->setQid(data_->qid);
- query_msg->setOpcode(Opcode::QUERY());
- query_msg->setRcode(Rcode::NOERROR());
- query_msg->setHeaderFlag(Message::HEADERFLAG_RD);
- query_msg->addQuestion(question);
+ data_ = boost::shared_ptr<IOFetchData>(new IOFetchData(protocol, service, address, port, buff, cb, wait));
+ query->setQid(data_->qid);
+ query->setOpcode(Opcode::QUERY());
+ query->setRcode(Rcode::NOERROR());
+ query->setHeaderFlag(Message::HEADERFLAG_RD);
+ query->addQuestion(question);
if (edns) {
EDNSPtr edns_query(new EDNS());
edns_query->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
- query_msg->setEDNS(edns_query);
+ query->setEDNS(edns_query);
}
- MessageRenderer renderer;
- renderer.setBuffer(data_->msgbuf.get());
- query_msg->toWire(renderer);
- renderer.setBuffer(NULL);
+ MessageRenderer r;
+ r.setBuffer(data_->msgbuf.get());
+ query->toWire(r);
+ r.setBuffer(NULL);
}
-// Return protocol in use.
-
IOFetch::Protocol
IOFetch::getProtocol() const {
return (data_->protocol);
}
-/// The function operator is implemented with the "stackless coroutine"
-/// pattern; see boost/asio/coroutine.hpp for details.
-
void
IOFetch::operator()(boost::system::error_code ec, size_t length) {
if (data_->stopped) {
@@ -320,13 +292,6 @@ IOFetch::operator()(boost::system::error_code ec, size_t length) {
}
}
-// Function that 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.
-
void
IOFetch::stop(Result result) {
if (!data_->stopped) {
@@ -385,8 +350,6 @@ IOFetch::stop(Result result) {
}
}
-// Log an error - called on I/O failure
-
void IOFetch::logIOFailure(boost::system::error_code ec) {
// Should only get here with a known error code.
if ((data_->origin != ASIODNS_OPEN_SOCKET) &&
@@ -403,5 +366,5 @@ void IOFetch::logIOFailure(boost::system::error_code ec) {
arg(data_->remote_snd->getPort());
}
-} // namespace asiodns
-} // namespace isc {
+} // namespace asiodns
+} // namespace isc