25 #include <boost/scoped_ptr.hpp>
26 #include <boost/date_time/posix_time/posix_time_types.hpp>
30 #include <netinet/in.h>
32 #include <sys/socket.h>
63 boost::scoped_ptr<IOAsioSocket<IOFetch> >
socket;
70 boost::asio::deadline_timer
timer;
85 uint8_t staging[IOFetch::STAGING_LENGTH];
109 socket((proto ==
IOFetch::UDP) ?
115 remote_snd((proto ==
IOFetch::UDP) ?
119 remote_rcv((proto ==
IOFetch::UDP) ?
126 timer(service.get_io_service()),
147 return (*remote_snd == *remote_rcv && cumulative >= 2 &&
148 readUint16(received->getData(), received->getLength()) == qid);
158 initIOFetch(query_msg, protocol, service, question, address, port, buff,
166 address, port, buff, cb, wait)) {
167 data_->msgbuf = outpkt;
168 data_->packet =
true;
176 msg->setHeaderFlag(Message::HEADERFLAG_RD,
177 query_message->getHeaderFlag(Message::HEADERFLAG_RD));
178 msg->setHeaderFlag(Message::HEADERFLAG_CD,
179 query_message->getHeaderFlag(Message::HEADERFLAG_CD));
181 initIOFetch(msg, protocol, service,
182 **(query_message->beginQuestion()),
183 address, port, buff, cb, wait);
187 IOFetch::initIOFetch(
MessagePtr& query_msg, Protocol protocol,
192 data_ = boost::shared_ptr<IOFetchData>(
new IOFetchData(
193 protocol, service, address, port, buff, cb, wait));
195 query_msg->setQid(data_->qid);
196 query_msg->setOpcode(Opcode::QUERY());
197 query_msg->setRcode(Rcode::NOERROR());
198 query_msg->setHeaderFlag(Message::HEADERFLAG_RD);
199 query_msg->addQuestion(question);
203 edns_query->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
204 query_msg->setEDNS(edns_query);
209 query_msg->toWire(renderer);
217 return (data_->protocol);
225 if (data_->stopped) {
231 }
else if (ec && (ec.value() != boost::asio::error::in_progress)) {
236 BOOST_ASIO_CORO_REENTER (
this) {
245 data_->msgbuf->writeUint16At(data_->qid, 0);
252 if (data_->timeout != -1) {
253 data_->timer.expires_from_now(boost::posix_time::milliseconds(
262 if (data_->socket->isOpenSynchronous()) {
263 data_->socket->open(data_->remote_snd.get(), *
this);
265 BOOST_ASIO_CORO_YIELD data_->socket->open(data_->remote_snd.get(), *
this);
272 BOOST_ASIO_CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
273 data_->msgbuf->getLength(), data_->remote_snd.get(), *
this);
295 data_->cumulative = 0;
297 data_->received->clear();
299 BOOST_ASIO_CORO_YIELD data_->socket->asyncReceive(data_->staging,
302 data_->remote_rcv.get(), *
this);
303 }
while (!data_->socket->processReceivedData(data_->staging, length,
304 data_->cumulative, data_->offset,
305 data_->expected, data_->received));
306 }
while (!data_->responseOK());
311 data_->socket->close();
327 if (!data_->stopped) {
340 data_->stopped =
true;
344 arg(data_->remote_snd->getAddress().toText()).
345 arg(data_->remote_snd->getPort());
350 arg(data_->remote_rcv->getAddress().toText()).
351 arg(data_->remote_rcv->getPort());
359 arg(data_->remote_snd->getAddress().toText()).
360 arg(data_->remote_snd->getPort());
365 arg(data_->remote_snd->getAddress().toText()).
366 arg(data_->remote_snd->getPort());
371 data_->socket->cancel();
372 data_->socket->close();
374 data_->timer.cancel();
377 if (data_->callback) {
378 (*(data_->callback))(result);
385 void IOFetch::logIOFailure(boost::system::error_code ec) {
395 arg((data_->remote_snd->getProtocol() == IPPROTO_TCP) ?
397 arg(data_->remote_snd->getAddress().toText()).
398 arg(data_->remote_snd->getPort());
A generic exception that is thrown when an unexpected error condition occurs.
Upstream Fetch Processing.
@ STAGING_LENGTH
Size of staging buffer.
void operator()(boost::system::error_code ec=boost::system::error_code(), size_t length=0)
Coroutine entry point.
Result
Result of Upstream Fetch.
@ STOPPED
Control code, fetch has been stopped.
@ TIME_OUT
Failure, fetch timed out.
@ SUCCESS
Success, fetch completed.
IOFetch(Protocol protocol, isc::asiolink::IOService &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)
Constructor.
Protocol
Protocol to use on the fetch.
void stop(Result reason=STOPPED)
Terminate query.
Protocol getProtocol() const
Return Current Protocol.
The IOAddress class represents an IP addresses (version agnostic)
I/O Socket with asynchronous operations.
The IOEndpoint class is an abstract base class to represent a communication endpoint.
The IOService class is a wrapper for the ASIO io_service class.
The TCPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a TCP ...
The TCPSocket class is a concrete derived class of IOAsioSocket that represents a TCP socket.
The UDPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a UDP ...
The UDPSocket class is a concrete derived class of IOAsioSocket that represents a UDP socket.
void setBuffer(isc::util::OutputBuffer *buffer)
Set or reset a temporary output buffer.
The EDNS class represents the EDNS OPT RR defined in RFC2671.
The MessageRenderer is a concrete derived class of AbstractMessageRenderer as a general purpose imple...
The Message class encapsulates a standard DNS message.
This class generates Qids for outgoing queries.
The Question class encapsulates the common search key of DNS lookup, consisting of owner name,...
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
isc::log::Logger logger("asiodns")
Use the ASIO logger.
const isc::log::MessageID ASIODNS_READ_TIMEOUT
const isc::log::MessageID ASIODNS_UNKNOWN_ORIGIN
const isc::log::MessageID ASIODNS_FETCH_STOPPED
const isc::log::MessageID ASIODNS_OPEN_SOCKET
const isc::log::MessageID ASIODNS_UNKNOWN_RESULT
const isc::log::MessageID ASIODNS_FETCH_COMPLETED
const isc::log::MessageID ASIODNS_READ_DATA
const isc::log::MessageID ASIODNS_SEND_DATA
boost::shared_ptr< const Message > ConstMessagePtr
boost::shared_ptr< Message > MessagePtr
Pointer-like type pointing to a Message.
boost::shared_ptr< EDNS > EDNSPtr
A pointer-like type pointing to an EDNS object.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
const int DBGLVL_TRACE_DETAIL
Trace detailed operations.
boost::shared_ptr< OutputBuffer > OutputBufferPtr
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Defines the logger used by the top-level component of kea-lfc.
IOFetch::Callback * callback
Called on I/O Completion.
boost::scoped_ptr< IOEndpoint > remote_snd
Where the fetch is sent.
isc::dns::qid_t qid
The QID set in the query.
int timeout
Timeout in ms.
bool stopped
Have we stopped running?
OutputBufferPtr msgbuf
Wire buffer for question.
IOFetch::Protocol protocol
Protocol being used.
OutputBufferPtr received
Received data put here.
size_t expected
Expected amount of data.
boost::scoped_ptr< IOAsioSocket< IOFetch > > socket
Socket to use for I/O.
size_t cumulative
Cumulative received amount.
IOFetchData(IOFetch::Protocol proto, IOService &service, const IOAddress &address, uint16_t port, OutputBufferPtr &buff, IOFetch::Callback *cb, int wait)
Constructor.
boost::asio::deadline_timer timer
Timer to measure timeouts.
boost::scoped_ptr< IOEndpoint > remote_rcv
Where the response came from.
isc::log::MessageID origin
Origin of last asynchronous I/O.
size_t offset
Offset to receive data.
bool packet
true if packet was supplied