25 #include <boost/bind.hpp> 26 #include <boost/scoped_ptr.hpp> 27 #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()),
136 origin(ASIODNS_UNKNOWN_ORIGIN),
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(
269 data_->origin = ASIODNS_OPEN_SOCKET;
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);
279 data_->origin = ASIODNS_SEND_DATA;
280 BOOST_ASIO_CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
281 data_->msgbuf->getLength(), data_->remote_snd.get(), *
this);
302 data_->origin = ASIODNS_READ_DATA;
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());
318 data_->origin = ASIODNS_UNKNOWN_ORIGIN;
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) {
397 assert((data_->origin == ASIODNS_OPEN_SOCKET) ||
398 (data_->origin == ASIODNS_SEND_DATA) ||
399 (data_->origin == ASIODNS_READ_DATA) ||
400 (data_->origin == ASIODNS_UNKNOWN_ORIGIN));
403 arg((data_->remote_snd->getProtocol() == IPPROTO_TCP) ?
405 arg(data_->remote_snd->getAddress().toText()).
406 arg(data_->remote_snd->getPort());
void setBuffer(isc::util::OutputBuffer *buffer)
Set or reset a temporary output buffer.
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,...
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.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Protocol getProtocol() const
Return Current Protocol.
Failure, fetch timed out.
isc::dns::qid_t qid
The QID set in the query.
The Message class encapsulates a standard DNS message.
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.
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.
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.
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.
The IOAddress class represents an IP addresses (version agnostic)
Success, fetch completed.
This class generates Qids for outgoing queries.
bool packet
true if packet was supplied
boost::shared_ptr< const Message > ConstMessagePtr
The IOEndpoint class is an abstract base class to represent a communication endpoint.