23 #include "../util/scheduler.hpp" 25 #include <boost/asio/io_service.hpp> 26 #include <boost/asio/ip/udp.hpp> 31 class Resolver : noncopyable
34 typedef boost::asio::ip::udp protocol;
35 typedef protocol::resolver::iterator iterator;
36 typedef protocol::resolver::query query;
39 Resolver(boost::asio::io_service& ioService,
41 : m_resolver(ioService)
42 , m_addressSelector(addressSelector)
43 , m_scheduler(ioService)
45 BOOST_ASSERT(m_addressSelector !=
nullptr);
52 time::nanoseconds timeout,
53 const shared_ptr<Resolver>&
self)
55 m_onSuccess = onSuccess;
58 m_resolver.async_resolve(q, bind(&Resolver::onResolveResult,
this, _1, _2,
self));
60 m_resolveTimeout = m_scheduler.scheduleEvent(timeout, bind(&Resolver::onResolveTimeout,
this,
self));
66 return selectAddress(m_resolver.resolve(q));
71 onResolveResult(
const boost::system::error_code& error,
72 iterator it,
const shared_ptr<Resolver>&
self)
74 m_scheduler.cancelEvent(m_resolveTimeout);
76 m_resolver.get_io_service().post(bind([] (
const shared_ptr<Resolver>&) {},
self));
79 if (error == boost::asio::error::operation_aborted)
83 m_onError(
"Hostname cannot be resolved: " + error.message());
88 it = selectAddress(it);
90 if (it != iterator() && m_onSuccess) {
91 m_onSuccess(it->endpoint().address());
94 m_onError(
"No endpoints match the specified address selector");
99 onResolveTimeout(
const shared_ptr<Resolver>&
self)
103 m_resolver.get_io_service().post(bind([] (
const shared_ptr<Resolver>&) {},
self));
106 m_onError(
"Hostname resolution timed out");
110 selectAddress(iterator it)
const 112 while (it != iterator() &&
113 !m_addressSelector(it->endpoint().address())) {
121 protocol::resolver m_resolver;
135 boost::asio::io_service& ioService,
137 time::nanoseconds timeout)
139 auto resolver = make_shared<Resolver>(ref(ioService), addressSelector);
140 resolver->asyncResolve(Resolver::query(host,
""), onSuccess, onError, timeout, resolver);
146 boost::asio::io_service& ioService,
149 Resolver resolver(ioService, addressSelector);
150 auto it = resolver.syncResolve(Resolver::query(host,
""));
152 if (it == Resolver::iterator()) {
153 BOOST_THROW_EXCEPTION(
Error(
"No endpoints match the specified address selector"));
156 return it->endpoint().address();
Copyright (c) 2013-2017 Regents of the University of California.
function< void(const IpAddress &address)> SuccessCallback
IpAddress syncResolve(const std::string &host, boost::asio::io_service &ioService, const AddressSelector &addressSelector)
Synchronously resolve host.
function< bool(const IpAddress &address)> AddressSelector
function< void(const std::string &reason)> ErrorCallback
void asyncResolve(const std::string &host, const SuccessCallback &onSuccess, const ErrorCallback &onError, boost::asio::io_service &ioService, const AddressSelector &addressSelector, time::nanoseconds timeout)
Asynchronously resolve host.
boost::asio::ip::address IpAddress
Identifies a scheduled event.