25 #include <boost/asio/io_service.hpp>
26 #include <boost/asio/ip/udp.hpp>
27 #if BOOST_VERSION >= 106600
28 #include <boost/asio/post.hpp>
34 class Resolver : noncopyable
37 using protocol = boost::asio::ip::udp;
38 using iterator = protocol::resolver::iterator;
39 using query = protocol::resolver::query;
42 Resolver(boost::asio::io_service& ioService,
44 : m_resolver(ioService)
45 , m_addressSelector(addressSelector)
46 , m_scheduler(ioService)
48 BOOST_ASSERT(m_addressSelector !=
nullptr);
56 const shared_ptr<Resolver>&
self)
58 m_onSuccess = onSuccess;
61 m_resolver.async_resolve(q, [=] (
auto&&... args) {
62 onResolveResult(std::forward<decltype(args)>(args)...,
self);
65 m_resolveTimeout = m_scheduler.schedule(timeout, [=] { onResolveTimeout(
self); });
71 return selectAddress(m_resolver.resolve(q));
76 onResolveResult(
const boost::system::error_code& error,
77 iterator it,
const shared_ptr<Resolver>&
self)
79 m_resolveTimeout.cancel();
82 #if BOOST_VERSION >= 106600
83 boost::asio::post(m_resolver.get_executor(), [
self] {});
85 m_resolver.get_io_service().post([
self] {});
89 if (error == boost::asio::error::operation_aborted)
93 m_onError(
"Hostname cannot be resolved: " + error.message());
98 it = selectAddress(it);
100 if (it != iterator() && m_onSuccess) {
101 m_onSuccess(it->endpoint().address());
103 else if (m_onError) {
104 m_onError(
"No endpoints match the specified address selector");
109 onResolveTimeout(
const shared_ptr<Resolver>&
self)
114 #if BOOST_VERSION >= 106600
115 boost::asio::post(m_resolver.get_executor(), [
self] {});
117 m_resolver.get_io_service().post([
self] {});
121 m_onError(
"Hostname resolution timed out");
125 selectAddress(iterator it)
const
127 while (it != iterator() && !m_addressSelector(it->endpoint().address())) {
134 protocol::resolver m_resolver;
148 boost::asio::io_service& ioService,
152 auto resolver = make_shared<Resolver>(ioService, addressSelector);
153 resolver->asyncResolve(Resolver::query(host,
""), onSuccess, onError, timeout, resolver);
159 boost::asio::io_service& ioService,
162 Resolver resolver(ioService, addressSelector);
163 auto it = resolver.syncResolve(Resolver::query(host,
""));
165 if (it == Resolver::iterator()) {
166 NDN_THROW(
Error(
"No endpoints match the specified address selector"));
169 return it->endpoint().address();
A handle for a scheduled event.
Generic time-based scheduler.
boost::asio::ip::address IpAddress
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.
function< void(const IpAddress &address)> SuccessCallback
function< bool(const IpAddress &address)> AddressSelector
function< void(const std::string &reason)> ErrorCallback
IpAddress syncResolve(const std::string &host, boost::asio::io_service &ioService, const AddressSelector &addressSelector)
Synchronously resolve host.
boost::chrono::nanoseconds nanoseconds