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>
64 boost::scoped_ptr<IOAsioSocket<IOFetch> >
socket;
71 boost::asio::deadline_timer
timer;
86 uint8_t staging[IOFetch::STAGING_LENGTH];
111 socket((proto ==
IOFetch::UDP) ?
117 remote_snd((proto ==
IOFetch::UDP) ?
121 remote_rcv((proto ==
IOFetch::UDP) ?
128 timer(service.get_io_service()),
149 return (*remote_snd == *remote_rcv && cumulative >= 2 &&
150 readUint16(received->getData(), received->getLength()) == qid);
161 initIOFetch(query_msg, protocol, service, question, address, port, buff,
170 address, port, buff, cb, wait))
172 data_->msgbuf = outpkt;
173 data_->packet =
true;
182 msg->setHeaderFlag(Message::HEADERFLAG_RD,
183 query_message->getHeaderFlag(Message::HEADERFLAG_RD));
184 msg->setHeaderFlag(Message::HEADERFLAG_CD,
185 query_message->getHeaderFlag(Message::HEADERFLAG_CD));
187 initIOFetch(msg, protocol, service,
188 **(query_message->beginQuestion()),
189 address, port, buff, cb, wait);
193 IOFetch::initIOFetch(
MessagePtr& query_msg, Protocol protocol,
199 data_ = boost::shared_ptr<IOFetchData>(
new IOFetchData(
200 protocol, service, address, port, buff, cb, wait));
202 query_msg->setQid(data_->qid);
203 query_msg->setOpcode(Opcode::QUERY());
204 query_msg->setRcode(Rcode::NOERROR());
205 query_msg->setHeaderFlag(Message::HEADERFLAG_RD);
206 query_msg->addQuestion(question);
210 edns_query->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
211 query_msg->setEDNS(edns_query);
216 query_msg->toWire(renderer);
224 return (data_->protocol);
233 if (data_->stopped) {
239 }
else if (ec && (ec.value() != boost::asio::error::in_progress)) {
244 BOOST_ASIO_CORO_REENTER (
this) {
253 data_->msgbuf->writeUint16At(data_->qid, 0);
260 if (data_->timeout != -1) {
261 data_->timer.expires_from_now(boost::posix_time::milliseconds(
270 if (data_->socket->isOpenSynchronous()) {
271 data_->socket->open(data_->remote_snd.get(), *
this);
273 BOOST_ASIO_CORO_YIELD data_->socket->open(data_->remote_snd.get(), *
this);
280 BOOST_ASIO_CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
281 data_->msgbuf->getLength(), data_->remote_snd.get(), *
this);
303 data_->cumulative = 0;
305 data_->received->clear();
307 BOOST_ASIO_CORO_YIELD data_->socket->asyncReceive(data_->staging,
310 data_->remote_rcv.get(), *
this);
311 }
while (!data_->socket->processReceivedData(data_->staging, length,
312 data_->cumulative, data_->offset,
313 data_->expected, data_->received));
314 }
while (!data_->responseOK());
319 data_->socket->close();
336 if (!data_->stopped) {
349 data_->stopped =
true;
353 arg(data_->remote_snd->getAddress().toText()).
354 arg(data_->remote_snd->getPort());
359 arg(data_->remote_rcv->getAddress().toText()).
360 arg(data_->remote_rcv->getPort());
368 arg(data_->remote_snd->getAddress().toText()).
369 arg(data_->remote_snd->getPort());
374 arg(data_->remote_snd->getAddress().toText()).
375 arg(data_->remote_snd->getPort());
380 data_->socket->cancel();
381 data_->socket->close();
383 data_->timer.cancel();
386 if (data_->callback) {
387 (*(data_->callback))(result);
394 void IOFetch::logIOFailure(boost::system::error_code ec) {
405 arg((data_->remote_snd->getProtocol() == IPPROTO_TCP) ?
407 arg(data_->remote_snd->getAddress().toText()).
408 arg(data_->remote_snd->getPort());
void setBuffer(isc::util::OutputBuffer *buffer)
Set or reset a temporary output buffer.
const isc::log::MessageID ASIODNS_SEND_DATA
boost::asio::deadline_timer timer
Timer to measure timeouts.
Upstream Fetch Processing.
The TCPSocket class is a concrete derived class of IOAsioSocket that represents a TCP socket...
isc::log::MessageID origin
Origin of last asynchronous I/O.
void stop(Result reason=STOPPED)
Terminate query.
Control code, fetch has been stopped.
Protocol
Protocol to use on the fetch.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
The Question class encapsulates the common search key of DNS lookup, consisting of owner name...
const isc::log::MessageID ASIODNS_UNKNOWN_ORIGIN
const isc::log::MessageID ASIODNS_FETCH_STOPPED
size_t offset
Offset to receive data.
The UDPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a UDP ...
void operator()(boost::system::error_code ec=boost::system::error_code(), size_t length=0)
Coroutine entry point.
const isc::log::MessageID ASIODNS_FETCH_COMPLETED
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Failure, fetch timed out.
isc::dns::qid_t qid
The QID set in the query.
The Message class encapsulates a standard DNS message.
Protocol getProtocol() const
Return Current Protocol.
bool stopped
Have we stopped running?
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.
The IOService class is a wrapper for the ASIO io_service class.
boost::shared_ptr< Message > MessagePtr
Pointer-like type pointing to a Message.
OutputBufferPtr msgbuf
Wire buffer for question.
size_t cumulative
Cumulative received amount.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::scoped_ptr< IOEndpoint > remote_snd
Where the fetch is sent.
The TCPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a TCP ...
boost::shared_ptr< EDNS > EDNSPtr
A pointer-like type pointing to an EDNS object.
A generic exception that is thrown when an unexpected error condition occurs.
The UDPSocket class is a concrete derived class of IOAsioSocket that represents a UDP socket...
The EDNS class represents the EDNS OPT RR defined in RFC2671.
IOFetch::Protocol protocol
Protocol being used.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
OutputBufferPtr received
Received data put here.
Defines the logger used by the top-level component of kea-dhcp-ddns.
isc::log::Logger logger("asiodns")
Use the ASIO logger.
const isc::log::MessageID ASIODNS_READ_TIMEOUT
boost::scoped_ptr< IOAsioSocket< IOFetch > > socket
Socket to use for I/O.
The MessageRenderer is a concrete derived class of AbstractMessageRenderer as a general purpose imple...
boost::scoped_ptr< IOEndpoint > remote_rcv
Where the response came from.
size_t expected
Expected amount of data.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
I/O Socket with asynchronous operations.
Result
Result of Upstream Fetch.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
IOFetchData(IOFetch::Protocol proto, IOService &service, const IOAddress &address, uint16_t port, OutputBufferPtr &buff, IOFetch::Callback *cb, int wait)
Constructor.
int timeout
Timeout in ms.
IOFetch::Callback * callback
Called on I/O Completion.
boost::shared_ptr< OutputBuffer > OutputBufferPtr
const int DBGLVL_TRACE_DETAIL
Trace detailed operations.
const isc::log::MessageID ASIODNS_UNKNOWN_RESULT
The IOAddress class represents an IP addresses (version agnostic)
Success, fetch completed.
This class generates Qids for outgoing queries.
const isc::log::MessageID ASIODNS_READ_DATA
bool packet
true if packet was supplied
boost::shared_ptr< const Message > ConstMessagePtr
const isc::log::MessageID ASIODNS_OPEN_SOCKET
The IOEndpoint class is an abstract base class to represent a communication endpoint.