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());