0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd::net: Reverse DNS resolution; various cleanup/related.

This commit is contained in:
Jason Volk 2017-12-29 22:38:00 -07:00
parent 8ec7c988a3
commit 35038f3d63
4 changed files with 138 additions and 50 deletions

View file

@ -385,6 +385,21 @@ try
std::cout << future.get() << std::endl; std::cout << future.get() << std::endl;
break; break;
} }
case hash("ptr"):
{
net::ipport in[1]
{
net::hostport { host, port },
};
std::string out[1];
net::resolve{in, out};
for(const auto &ptr : out)
std::cout << ptr << std::endl;
break;
}
} }
break; break;

View file

@ -44,6 +44,9 @@ namespace ircd::net
std::string host(const ip::tcp::endpoint &); std::string host(const ip::tcp::endpoint &);
std::string string(const ip::address &); std::string string(const ip::address &);
std::string string(const ip::tcp::endpoint &); std::string string(const ip::tcp::endpoint &);
ipport make_ipport(const boost::asio::ip::tcp::endpoint &);
ip::tcp::endpoint make_endpoint(const ipport &);
} }
namespace ircd namespace ircd

View file

@ -105,12 +105,17 @@ struct ircd::net::resolve
{ {
using callback_one = std::function<void (std::exception_ptr, const ipport &)>; using callback_one = std::function<void (std::exception_ptr, const ipport &)>;
using callback_many = std::function<void (std::exception_ptr, vector_view<ipport>)>; using callback_many = std::function<void (std::exception_ptr, vector_view<ipport>)>;
using callback_reverse = std::function<void (std::exception_ptr, std::string)>;
resolve(const hostport &, callback_one); resolve(const hostport &, callback_one);
resolve(const hostport &, callback_many); resolve(const hostport &, callback_many);
resolve(const ipport &, callback_reverse);
resolve(const hostport &, ctx::future<ipport> &); resolve(const hostport &, ctx::future<ipport> &);
resolve(const hostport &, ctx::future<std::vector<ipport>> &); resolve(const hostport &, ctx::future<std::vector<ipport>> &);
resolve(const vector_view<hostport> &in, const vector_view<ipport> &out); resolve(const vector_view<hostport> &in, const vector_view<ipport> &out);
resolve(const vector_view<ipport> &in, const vector_view<std::string> &out);
}; };
/// This lightweight structure holds an IP address and port in native byte /// This lightweight structure holds an IP address and port in native byte
@ -134,10 +139,7 @@ struct ircd::net::ipport
operator bool() const; operator bool() const;
bool operator!() const { return !static_cast<bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
// DNS lookup! May yield ircd::ctx! ipport(const hostport &); // DNS lookup! May yield ircd::ctx!
ipport(const hostport &);
// Trivial constructors
ipport(const uint32_t &ip, const uint16_t &port); ipport(const uint32_t &ip, const uint16_t &port);
ipport(const uint128_t &ip, const uint16_t &port); ipport(const uint128_t &ip, const uint16_t &port);
ipport(const boost::asio::ip::address &, const uint16_t &port); ipport(const boost::asio::ip::address &, const uint16_t &port);

View file

@ -29,8 +29,6 @@
namespace ircd::net namespace ircd::net
{ {
ip::tcp::resolver *resolver; ip::tcp::resolver *resolver;
ipport make_ipport(const boost::asio::ip::tcp::endpoint &);
} }
struct ircd::log::log struct ircd::log::log
@ -72,18 +70,7 @@ std::shared_ptr<ircd::net::socket>
ircd::net::connect(const net::remote &remote, ircd::net::connect(const net::remote &remote,
const milliseconds &timeout) const milliseconds &timeout)
{ {
const asio::ip::tcp::endpoint ep const auto ep{make_endpoint(remote)};
{
is_v6(remote)? asio::ip::tcp::endpoint
{
asio::ip::address_v6 { std::get<remote.IP>(remote) }, port(remote)
}
: asio::ip::tcp::endpoint
{
asio::ip::address_v4 { host4(remote) }, port(remote)
},
};
return connect(ep, timeout); return connect(ep, timeout);
} }
@ -1605,6 +1592,22 @@ ircd::net::make_ipport(const boost::asio::ip::tcp::endpoint &ep)
}; };
} }
boost::asio::ip::tcp::endpoint
ircd::net::make_endpoint(const ipport &ipport)
{
return
{
is_v6(ipport)? ip::tcp::endpoint
{
asio::ip::address_v6 { std::get<ipport.IP>(ipport) }, port(ipport)
}
: ip::tcp::endpoint
{
asio::ip::address_v4 { host4(ipport) }, port(ipport)
},
};
}
ircd::net::ipport::ipport(const hostport &hp) ircd::net::ipport::ipport(const hostport &hp)
{ {
ctx::future<ipport> future; ctx::future<ipport> future;
@ -1635,7 +1638,54 @@ namespace ircd::net
{ {
// Internal resolve base (requires boost syms) // Internal resolve base (requires boost syms)
using resolve_callback = std::function<void (std::exception_ptr, ip::tcp::resolver::results_type)>; using resolve_callback = std::function<void (std::exception_ptr, ip::tcp::resolver::results_type)>;
void async_resolve(const hostport &, ip::tcp::resolver::flags, resolve_callback); void _resolve(const hostport &, ip::tcp::resolver::flags, resolve_callback);
void _resolve(const ipport &, resolve_callback);
}
ircd::net::resolve::resolve(const vector_view<ipport> &in,
const vector_view<std::string> &out)
{
assert(in.size() == out.size());
size_t a{0}, b{0};
ctx::ctx &c{ctx::cur()};
const size_t count{std::min(in.size(), out.size())};
for(; a < count; ++a) resolve
{
in[a], [&b, &c, &count, &ret(out[a])]
(std::exception_ptr eptr, std::string hostname) noexcept
{
ret = std::move(hostname);
if(++b >= count)
notify(c);
}
};
while(b < count)
ctx::wait();
}
ircd::net::resolve::resolve(const vector_view<hostport> &in,
const vector_view<ipport> &out)
{
assert(in.size() == out.size());
size_t a{0}, b{0};
ctx::ctx &c{ctx::cur()};
const size_t count{std::min(in.size(), out.size())};
for(; a < count; ++a) resolve
{
in[a], [&b, &c, &count, &ret(out[a])]
(std::exception_ptr eptr, const ipport &ip) noexcept
{
ret = ip;
if(++b >= count)
notify(c);
}
};
while(b < count)
ctx::wait();
} }
ircd::net::resolve::resolve(const hostport &hostport, ircd::net::resolve::resolve(const hostport &hostport,
@ -1670,6 +1720,24 @@ ircd::net::resolve::resolve(const hostport &hostport,
}); });
} }
ircd::net::resolve::resolve(const ipport &ipport,
callback_reverse callback)
{
_resolve(ipport, [callback(std::move(callback))]
(std::exception_ptr eptr, ip::tcp::resolver::results_type results)
{
if(eptr)
return callback(std::move(eptr), {});
if(results.empty())
return callback({}, {});
assert(results.size() <= 1);
const auto &result(*begin(results));
callback({}, result.host_name());
});
}
ircd::net::resolve::resolve(const hostport &hostport, ircd::net::resolve::resolve(const hostport &hostport,
callback_one callback) callback_one callback)
{ {
@ -1686,37 +1754,11 @@ ircd::net::resolve::resolve(const hostport &hostport,
}); });
} }
ircd::net::resolve::resolve(const vector_view<hostport> &in,
const vector_view<ipport> &out)
{
assert(in.size() == out.size());
const size_t count
{
std::min(in.size(), out.size())
};
size_t a{0}, b{0};
ctx::ctx &c{ctx::cur()};
for(; a < count; ++a) resolve
{
in[a], [&b, &c, &count, &ret(out[a])]
(std::exception_ptr eptr, const ipport &ip) noexcept
{
ret = ip;
if(++b >= count)
notify(c);
}
};
while(b < count)
ctx::wait();
}
ircd::net::resolve::resolve(const hostport &hostport, ircd::net::resolve::resolve(const hostport &hostport,
callback_many callback) callback_many callback)
{ {
static const ip::tcp::resolver::flags flags{}; static const ip::tcp::resolver::flags flags{};
async_resolve(hostport, flags, [callback(std::move(callback))] _resolve(hostport, flags, [callback(std::move(callback))]
(std::exception_ptr eptr, ip::tcp::resolver::results_type results) (std::exception_ptr eptr, ip::tcp::resolver::results_type results)
{ {
if(eptr) if(eptr)
@ -1738,10 +1780,11 @@ ircd::net::resolve::resolve(const hostport &hostport,
}); });
} }
/// Internal A/AAAA record resolver function
void void
ircd::net::async_resolve(const hostport &hostport, ircd::net::_resolve(const hostport &hostport,
ip::tcp::resolver::flags flags, ip::tcp::resolver::flags flags,
resolve_callback callback) resolve_callback callback)
{ {
// Trivial host string // Trivial host string
const string_view &host const string_view &host
@ -1770,7 +1813,32 @@ ircd::net::async_resolve(const hostport &hostport,
{ {
if(ec) if(ec)
{ {
callback(std::make_exception_ptr(boost::system::system_error{ec}), {}); callback(std::make_exception_ptr(boost::system::system_error{ec}), std::move(results));
}
else try
{
callback({}, std::move(results));
}
catch(...)
{
callback(std::make_exception_ptr(std::current_exception()), {});
}
});
}
/// Internal PTR record resolver function
void
ircd::net::_resolve(const ipport &ipport,
resolve_callback callback)
{
assert(bool(ircd::net::resolver));
resolver->async_resolve(make_endpoint(ipport), [callback(std::move(callback))]
(const error_code &ec, ip::tcp::resolver::results_type results)
noexcept
{
if(ec)
{
callback(std::make_exception_ptr(boost::system::system_error{ec}), std::move(results));
} }
else try else try
{ {