mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 02:02:38 +01:00
ircd::net: Add resolve interface; Update remote interface.
This commit is contained in:
parent
baa35a368a
commit
0eb16673ee
5 changed files with 306 additions and 354 deletions
|
@ -353,6 +353,43 @@ try
|
|||
break;
|
||||
}
|
||||
|
||||
case hash("resolve"):
|
||||
{
|
||||
const auto args(tokens_after(line, " ", 0));
|
||||
const params token{args, " ", {"what", "host", "port"}};
|
||||
const auto &what(token.at(0));
|
||||
const auto &host{token.at(1)};
|
||||
const auto &port{token.at(2)};
|
||||
const net::hostport hostport
|
||||
{
|
||||
host, port
|
||||
};
|
||||
|
||||
switch(hash(what))
|
||||
{
|
||||
case hash("ips"):
|
||||
{
|
||||
ctx::future<std::vector<net::ipport>> future;
|
||||
net::resolve{hostport, future};
|
||||
const auto ips{future.get()};
|
||||
for(const auto &ip : ips)
|
||||
std::cout << ip << std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case hash("ip"):
|
||||
{
|
||||
ctx::future<net::ipport> future;
|
||||
net::resolve{hostport, future};
|
||||
std::cout << future.get() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case hash("reconnect"):
|
||||
{
|
||||
handle_line("disconnect");
|
||||
|
|
|
@ -68,8 +68,6 @@ namespace ircd::net
|
|||
size_t available(const socket &) noexcept;
|
||||
ipport local_ipport(const socket &) noexcept;
|
||||
ipport remote_ipport(const socket &) noexcept;
|
||||
hostport local_hostport(const socket &) noexcept;
|
||||
hostport remote_hostport(const socket &) noexcept;
|
||||
|
||||
size_t write(socket &, const ilist<const_buffer> &); // write_all
|
||||
size_t write(socket &, const iov<const_buffer> &); // write_all
|
||||
|
@ -87,17 +85,13 @@ namespace ircd::net
|
|||
const_raw_buffer peer_cert_der(const mutable_raw_buffer &, const socket &);
|
||||
}
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
using net::socket;
|
||||
using net::hostport;
|
||||
using net::host;
|
||||
using net::port;
|
||||
using net::string;
|
||||
}
|
||||
|
||||
struct ircd::net::init
|
||||
{
|
||||
init();
|
||||
~init() noexcept;
|
||||
};
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
using net::socket;
|
||||
}
|
||||
|
|
|
@ -22,15 +22,20 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_NET_REMOTE_H
|
||||
|
||||
// Forward declarations for boost because it is not included here.
|
||||
namespace boost::asio::ip
|
||||
{
|
||||
struct address;
|
||||
};
|
||||
|
||||
namespace ircd::net
|
||||
{
|
||||
struct remote;
|
||||
struct ipport;
|
||||
struct hostport;
|
||||
struct resolve;
|
||||
struct ipport;
|
||||
struct remote;
|
||||
|
||||
const uint16_t &port(const hostport &);
|
||||
const uint16_t &port(const ipport &);
|
||||
uint16_t &port(hostport &);
|
||||
uint16_t &port(ipport &);
|
||||
|
||||
bool is_v6(const ipport &);
|
||||
|
@ -43,17 +48,20 @@ namespace ircd::net
|
|||
uint32_t &host4(ipport &);
|
||||
auto &host(hostport &);
|
||||
|
||||
string_view string(const uint32_t &, const mutable_buffer &buf);
|
||||
string_view string(const uint128_t &, const mutable_buffer &buf);
|
||||
string_view string(const hostport &, const mutable_buffer &buf);
|
||||
string_view string(const ipport &, const mutable_buffer &buf);
|
||||
string_view string(const remote &, const mutable_buffer &buf);
|
||||
string_view string(const mutable_buffer &out, const uint32_t &);
|
||||
string_view string(const mutable_buffer &out, const uint128_t &);
|
||||
string_view string(const mutable_buffer &out, const hostport &);
|
||||
string_view string(const mutable_buffer &out, const ipport &);
|
||||
string_view string(const mutable_buffer &out, const remote &);
|
||||
}
|
||||
|
||||
std::string string(const uint32_t &);
|
||||
std::string string(const uint128_t &);
|
||||
std::string string(const hostport &);
|
||||
std::string string(const ipport &);
|
||||
std::string string(const remote &);
|
||||
namespace ircd
|
||||
{
|
||||
using net::hostport;
|
||||
using net::ipport;
|
||||
using net::remote;
|
||||
using net::host;
|
||||
using net::port;
|
||||
}
|
||||
|
||||
/// This structure holds a hostname and port usually fresh from user input
|
||||
|
@ -64,15 +72,45 @@ namespace ircd::net
|
|||
/// then 8448 is assumed.
|
||||
///
|
||||
struct ircd::net::hostport
|
||||
:std::pair<std::string, uint16_t>
|
||||
{
|
||||
static const hostport null;
|
||||
string_view host {"0.0.0.0"};
|
||||
string_view port {"8448"};
|
||||
uint16_t portnum {0};
|
||||
|
||||
hostport(std::string s, const uint16_t &port = 8448);
|
||||
hostport(const string_view &host, const string_view &port)
|
||||
:host{host}
|
||||
,port{port}
|
||||
{}
|
||||
|
||||
hostport(const string_view &host, const uint16_t &portnum)
|
||||
:host{host}
|
||||
,port{}
|
||||
,portnum{portnum}
|
||||
{}
|
||||
|
||||
hostport(const string_view &amalgam)
|
||||
:host{rsplit(amalgam, ':').first}
|
||||
,port{rsplit(amalgam, ':').second}
|
||||
{}
|
||||
|
||||
hostport() = default;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const hostport &);
|
||||
};
|
||||
|
||||
/// DNS resolution section
|
||||
///
|
||||
struct ircd::net::resolve
|
||||
{
|
||||
using callback_one = std::function<void (std::exception_ptr, const ipport &)>;
|
||||
using callback_many = std::function<void (std::exception_ptr, vector_view<ipport>)>;
|
||||
|
||||
resolve(const hostport &, callback_one);
|
||||
resolve(const hostport &, callback_many);
|
||||
resolve(const hostport &, ctx::future<ipport> &);
|
||||
resolve(const hostport &, ctx::future<std::vector<ipport>> &);
|
||||
};
|
||||
|
||||
/// This lightweight structure holds an IP address and port in native byte
|
||||
/// form. It is usually returned from the result of a resolution but may also
|
||||
/// serve as input to a reverse resolution. Either way, this allocation-free
|
||||
|
@ -94,16 +132,13 @@ struct ircd::net::ipport
|
|||
operator bool() const;
|
||||
bool operator!() const { return !static_cast<bool>(*this); }
|
||||
|
||||
// DNS lookup! May yield ircd::ctx!
|
||||
ipport(const hostport &);
|
||||
|
||||
// Trivial constructors
|
||||
ipport(const uint32_t &ip, const uint16_t &port);
|
||||
ipport(const uint128_t &ip, const uint16_t &port);
|
||||
|
||||
// DNS lookup! May yield ircd::ctx!
|
||||
ipport(const std::string &hostname, const std::string &port);
|
||||
ipport(const std::string &hostname, const uint16_t &port);
|
||||
ipport(const string_view &hostname, const string_view &port = "8448");
|
||||
ipport(const string_view &hostname, const uint16_t &port);
|
||||
ipport(const hostport &);
|
||||
ipport(const boost::asio::ip::address &, const uint16_t &port);
|
||||
ipport();
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const ipport &);
|
||||
|
@ -117,22 +152,21 @@ struct ircd::net::ipport
|
|||
struct ircd::net::remote
|
||||
:ircd::net::ipport
|
||||
{
|
||||
static const remote null;
|
||||
|
||||
std::string hostname;
|
||||
|
||||
operator bool() const;
|
||||
bool operator!() const { return !static_cast<bool>(*this); }
|
||||
bool resolved() const;
|
||||
|
||||
remote(std::string hostname, const std::string &port);
|
||||
remote(std::string hostname, const uint16_t &port);
|
||||
remote(std::string hostname);
|
||||
explicit remote(const string_view &hostname, const string_view &port);
|
||||
explicit remote(const string_view &hostname, const uint16_t &port);
|
||||
remote(const string_view &hostname);
|
||||
explicit remote(const ipport &);
|
||||
remote(hostport);
|
||||
explicit remote(const ipport &ipp)
|
||||
:ipport{ipp}
|
||||
{}
|
||||
|
||||
remote(const hostport &hp)
|
||||
:ipport{hp}
|
||||
,hostname{std::string{hp.host}}
|
||||
{}
|
||||
|
||||
remote() = default;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const remote &);
|
||||
|
@ -157,8 +191,8 @@ ircd::net::ipport::ipport()
|
|||
{
|
||||
std::get<PORT>(*this) = 0;
|
||||
std::get<TYPE>(*this) = 0;
|
||||
//auto &ip(std::get<IP>(*this));
|
||||
//std::fill(begin(ip), end(ip), 0x00);
|
||||
auto &ip(std::get<IP>(*this));
|
||||
std::fill(begin(ip), end(ip), 0x0);
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -229,13 +263,13 @@ ircd::net::is_v4(const ipport &ipp)
|
|||
inline auto &
|
||||
ircd::net::host(hostport &hp)
|
||||
{
|
||||
return hp.first;
|
||||
return hp.host;
|
||||
}
|
||||
|
||||
inline const auto &
|
||||
ircd::net::host(const hostport &hp)
|
||||
{
|
||||
return hp.first;
|
||||
return hp.host;
|
||||
}
|
||||
|
||||
inline uint16_t &
|
||||
|
@ -249,15 +283,3 @@ ircd::net::port(const ipport &ipp)
|
|||
{
|
||||
return std::get<ipp.PORT>(ipp);
|
||||
}
|
||||
|
||||
inline uint16_t &
|
||||
ircd::net::port(hostport &hp)
|
||||
{
|
||||
return hp.second;
|
||||
}
|
||||
|
||||
inline const uint16_t &
|
||||
ircd::net::port(const hostport &hp)
|
||||
{
|
||||
return hp.second;
|
||||
}
|
||||
|
|
|
@ -105,22 +105,22 @@ noexcept
|
|||
}
|
||||
}
|
||||
|
||||
ircd::hostport
|
||||
ircd::ipport
|
||||
ircd::local(const client &client)
|
||||
{
|
||||
if(!client.sock)
|
||||
return hostport::null;
|
||||
return {};
|
||||
|
||||
return net::local_hostport(*client.sock);
|
||||
return net::local_ipport(*client.sock);
|
||||
}
|
||||
|
||||
ircd::hostport
|
||||
ircd::ipport
|
||||
ircd::remote(const client &client)
|
||||
{
|
||||
if(!client.sock)
|
||||
return hostport::null;
|
||||
return {};
|
||||
|
||||
return net::remote_hostport(*client.sock);
|
||||
return net::remote_ipport(*client.sock);
|
||||
}
|
||||
|
||||
ircd::http::response::write_closure
|
||||
|
|
473
ircd/net.cc
473
ircd/net.cc
|
@ -29,6 +29,8 @@
|
|||
namespace ircd::net
|
||||
{
|
||||
ip::tcp::resolver *resolver;
|
||||
|
||||
ipport make_ipport(const boost::asio::ip::tcp::endpoint &);
|
||||
}
|
||||
|
||||
struct ircd::log::log
|
||||
|
@ -682,46 +684,12 @@ ircd::net::sslv23_client
|
|||
boost::asio::ssl::context::method::sslv23_client
|
||||
};
|
||||
|
||||
ircd::net::hostport
|
||||
ircd::net::local_hostport(const socket &socket)
|
||||
noexcept try
|
||||
{
|
||||
const auto &ep(socket.local());
|
||||
return { host(ep), port(ep) };
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return { std::string{}, 0 };
|
||||
}
|
||||
|
||||
ircd::net::hostport
|
||||
ircd::net::remote_hostport(const socket &socket)
|
||||
noexcept try
|
||||
{
|
||||
const auto &ep(socket.remote());
|
||||
return { host(ep), port(ep) };
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return { std::string{}, 0 };
|
||||
}
|
||||
|
||||
ircd::net::ipport
|
||||
ircd::net::local_ipport(const socket &socket)
|
||||
noexcept try
|
||||
{
|
||||
const auto &ep(socket.local());
|
||||
const auto &a(addr(ep));
|
||||
|
||||
ipport ret;
|
||||
if(a.is_v6())
|
||||
{
|
||||
std::get<ret.IP>(ret) = a.to_v6().to_bytes();
|
||||
std::reverse(std::get<ret.IP>(ret).begin(), std::get<ret.IP>(ret).end());
|
||||
}
|
||||
else host4(ret) = a.to_v4().to_ulong();
|
||||
|
||||
return ret;
|
||||
return make_ipport(ep);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -733,18 +701,7 @@ ircd::net::remote_ipport(const socket &socket)
|
|||
noexcept try
|
||||
{
|
||||
const auto &ep(socket.remote());
|
||||
const auto &a(addr(ep));
|
||||
|
||||
ipport ret;
|
||||
if(a.is_v6())
|
||||
{
|
||||
std::get<ret.IP>(ret) = a.to_v6().to_bytes();
|
||||
std::reverse(std::get<ret.IP>(ret).begin(), std::get<ret.IP>(ret).end());
|
||||
}
|
||||
else host4(ret) = a.to_v4().to_ulong();
|
||||
|
||||
port(ret) = port(ep);
|
||||
return ret;
|
||||
return make_ipport(ep);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -1031,7 +988,7 @@ try
|
|||
if(sd.is_open())
|
||||
log.debug("socket(%p): disconnect: %s type:%d user: in:%zu out:%zu",
|
||||
(const void *)this,
|
||||
string(remote_ipport(*this)),
|
||||
ircd::string(remote_ipport(*this)),
|
||||
uint(type),
|
||||
in.bytes,
|
||||
out.bytes);
|
||||
|
@ -1520,89 +1477,21 @@ ircd::net::string(const mutable_buffer &buf,
|
|||
// host / port utils
|
||||
//
|
||||
|
||||
std::ostream &
|
||||
ircd::net::operator<<(std::ostream &s, const hostport &t)
|
||||
{
|
||||
char buf[256];
|
||||
s << string(t, buf);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
ircd::net::operator<<(std::ostream &s, const ipport &t)
|
||||
{
|
||||
char buf[256];
|
||||
s << string(t, buf);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
ircd::net::operator<<(std::ostream &s, const remote &t)
|
||||
{
|
||||
char buf[256];
|
||||
s << string(t, buf);
|
||||
return s;
|
||||
}
|
||||
|
||||
namespace ircd::net
|
||||
{
|
||||
template<class T> std::string _string(const T &t);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::string
|
||||
ircd::net::_string(const T &t)
|
||||
{
|
||||
std::string ret(256, char{});
|
||||
ret.resize(net::string(t, mutable_buffer{ret}).size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string
|
||||
ircd::net::string(const uint32_t &t)
|
||||
{
|
||||
return _string(t);
|
||||
}
|
||||
|
||||
std::string
|
||||
ircd::net::string(const uint128_t &t)
|
||||
{
|
||||
return _string(t);
|
||||
}
|
||||
|
||||
std::string
|
||||
ircd::net::string(const hostport &t)
|
||||
{
|
||||
return _string(t);
|
||||
}
|
||||
|
||||
std::string
|
||||
ircd::net::string(const ipport &t)
|
||||
{
|
||||
return _string(t);
|
||||
}
|
||||
|
||||
std::string
|
||||
ircd::net::string(const remote &t)
|
||||
{
|
||||
return _string(t);
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::net::string(const uint32_t &ip,
|
||||
const mutable_buffer &buf)
|
||||
ircd::net::string(const mutable_buffer &buf,
|
||||
const uint32_t &ip)
|
||||
{
|
||||
const auto len
|
||||
{
|
||||
fmt::sprintf(buf, "%s", ip::address_v4{ip}.to_string())
|
||||
ip::address_v4{ip}.to_string().copy(data(buf), size(buf))
|
||||
};
|
||||
|
||||
return { data(buf), size_t(len) };
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::net::string(const uint128_t &ip,
|
||||
const mutable_buffer &buf)
|
||||
ircd::net::string(const mutable_buffer &buf,
|
||||
const uint128_t &ip)
|
||||
{
|
||||
const auto &pun
|
||||
{
|
||||
|
@ -1616,27 +1505,32 @@ ircd::net::string(const uint128_t &ip,
|
|||
|
||||
const auto len
|
||||
{
|
||||
fmt::sprintf(buf, "%s", ip::address_v6{punpun}.to_string())
|
||||
ip::address_v6{punpun}.to_string().copy(data(buf), size(buf))
|
||||
};
|
||||
|
||||
return { data(buf), size_t(len) };
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::net::string(const hostport &pair,
|
||||
const mutable_buffer &buf)
|
||||
ircd::net::string(const mutable_buffer &buf,
|
||||
const hostport &hp)
|
||||
{
|
||||
const auto len
|
||||
{
|
||||
fmt::sprintf(buf, "%s:%u", pair.first, pair.second)
|
||||
fmt::sprintf
|
||||
{
|
||||
buf, "%s:%s",
|
||||
hp.host,
|
||||
hp.portnum? lex_cast(hp.portnum) : hp.port
|
||||
}
|
||||
};
|
||||
|
||||
return { data(buf), size_t(len) };
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::net::string(const ipport &ipp,
|
||||
const mutable_buffer &buf)
|
||||
ircd::net::string(const mutable_buffer &buf,
|
||||
const ipport &ipp)
|
||||
{
|
||||
const auto len
|
||||
{
|
||||
|
@ -1657,8 +1551,8 @@ ircd::net::string(const ipport &ipp,
|
|||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::net::string(const remote &remote,
|
||||
const mutable_buffer &buf)
|
||||
ircd::net::string(const mutable_buffer &buf,
|
||||
const remote &remote)
|
||||
{
|
||||
const auto &ipp
|
||||
{
|
||||
|
@ -1675,147 +1569,52 @@ ircd::net::string(const remote &remote,
|
|||
const auto len{strlcpy(data(buf), remote.hostname, size(buf))};
|
||||
return { data(buf), size_t(len) };
|
||||
}
|
||||
else return string(ipp, buf);
|
||||
else return string(buf, ipp);
|
||||
}
|
||||
|
||||
//
|
||||
// remote
|
||||
//
|
||||
|
||||
const ircd::net::remote
|
||||
ircd::net::remote::null
|
||||
{};
|
||||
|
||||
ircd::net::remote::remote(hostport hp)
|
||||
:remote{std::move(hp.first), hp.second}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(const string_view &host)
|
||||
:remote
|
||||
{
|
||||
std::string(host), "8448"s
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(const string_view &host,
|
||||
const uint16_t &port)
|
||||
:remote
|
||||
{
|
||||
std::string(host), std::string(lex_cast(port))
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(const string_view &host,
|
||||
const string_view &port)
|
||||
:remote
|
||||
{
|
||||
std::string(host), std::string(port)
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(std::string host)
|
||||
:remote
|
||||
{
|
||||
std::move(host), "8448"s
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(std::string host,
|
||||
const uint16_t &port)
|
||||
:ipport{host, port}
|
||||
,hostname{std::move(host)}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(std::string host,
|
||||
const std::string &port)
|
||||
:ipport{host, port}
|
||||
,hostname{std::move(host)}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::remote::remote(const ipport &ipp)
|
||||
:ipport{ipp}
|
||||
std::ostream &
|
||||
ircd::net::operator<<(std::ostream &s, const remote &t)
|
||||
{
|
||||
char buf[256];
|
||||
s << string(buf, t);
|
||||
return s;
|
||||
}
|
||||
|
||||
//
|
||||
// ipport
|
||||
//
|
||||
|
||||
std::ostream &
|
||||
ircd::net::operator<<(std::ostream &s, const ipport &t)
|
||||
{
|
||||
char buf[256];
|
||||
s << string(buf, t);
|
||||
return s;
|
||||
}
|
||||
|
||||
ircd::net::ipport
|
||||
ircd::net::make_ipport(const boost::asio::ip::tcp::endpoint &ep)
|
||||
{
|
||||
return ipport
|
||||
{
|
||||
ep.address(), ep.port()
|
||||
};
|
||||
}
|
||||
|
||||
ircd::net::ipport::ipport(const hostport &hp)
|
||||
:ipport
|
||||
{
|
||||
hp.first, std::string(lex_cast(port(hp)))
|
||||
}
|
||||
{
|
||||
ctx::future<ipport> future;
|
||||
resolve{hp, future};
|
||||
*this = future.get();
|
||||
}
|
||||
|
||||
ircd::net::ipport::ipport(const string_view &host,
|
||||
ircd::net::ipport::ipport(const boost::asio::ip::address &address,
|
||||
const uint16_t &port)
|
||||
:ipport
|
||||
{
|
||||
std::string(host), std::string(lex_cast(port))
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::ipport::ipport(const string_view &host,
|
||||
const string_view &port)
|
||||
:ipport
|
||||
{
|
||||
std::string(host), std::string(port)
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::ipport::ipport(const std::string &host,
|
||||
const uint16_t &port)
|
||||
:ipport
|
||||
{
|
||||
host, std::string{lex_cast(port)}
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::net::ipport::ipport(const std::string &host,
|
||||
const std::string &port)
|
||||
:ipport
|
||||
{
|
||||
uint32_t{0},
|
||||
lex_cast<uint16_t>(port)
|
||||
}
|
||||
{
|
||||
assert(resolver);
|
||||
const ip::tcp::resolver::query query
|
||||
{
|
||||
host, port
|
||||
};
|
||||
|
||||
auto epit
|
||||
{
|
||||
resolver->async_resolve(query, yield_context{to_asio{}})
|
||||
};
|
||||
|
||||
static const ip::tcp::resolver::iterator end;
|
||||
if(epit == end)
|
||||
throw nxdomain("host '%s' not found", host);
|
||||
|
||||
const ip::tcp::endpoint &ep
|
||||
{
|
||||
*epit
|
||||
};
|
||||
|
||||
const asio::ip::address &address
|
||||
{
|
||||
ep.address()
|
||||
};
|
||||
|
||||
std::get<TYPE>(*this) = address.is_v6();
|
||||
|
||||
if(is_v6(*this))
|
||||
|
@ -1825,49 +1624,149 @@ ircd::net::ipport::ipport(const std::string &host,
|
|||
}
|
||||
else host4(*this) = address.to_v4().to_ulong();
|
||||
|
||||
log.debug("resolved remote %s:%u => %s %s",
|
||||
host,
|
||||
net::port(*this),
|
||||
is_v6(*this)? "IP6" : "IP4",
|
||||
string(*this));
|
||||
net::port(*this) = port;
|
||||
}
|
||||
|
||||
//
|
||||
// resolve
|
||||
//
|
||||
|
||||
namespace ircd::net
|
||||
{
|
||||
// Internal resolve base (requires boost syms)
|
||||
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);
|
||||
}
|
||||
|
||||
ircd::net::resolve::resolve(const hostport &hostport,
|
||||
ctx::future<ipport> &future)
|
||||
{
|
||||
ctx::promise<ipport> p;
|
||||
future = ctx::future<ipport>{p};
|
||||
resolve(hostport, [p(std::move(p))]
|
||||
(std::exception_ptr eptr, const ipport &ip)
|
||||
mutable
|
||||
{
|
||||
if(eptr)
|
||||
p.set_exception(std::move(eptr));
|
||||
else
|
||||
p.set_value(ip);
|
||||
});
|
||||
}
|
||||
|
||||
ircd::net::resolve::resolve(const hostport &hostport,
|
||||
ctx::future<std::vector<ipport>> &future)
|
||||
{
|
||||
ctx::promise<std::vector<ipport>> p;
|
||||
future = ctx::future<std::vector<ipport>>{p};
|
||||
resolve(hostport, [p(std::move(p))]
|
||||
(std::exception_ptr eptr, const vector_view<ipport> &ips)
|
||||
mutable
|
||||
{
|
||||
if(eptr)
|
||||
p.set_exception(std::move(eptr));
|
||||
else
|
||||
p.set_value(std::vector<ipport>(begin(ips), end(ips)));
|
||||
});
|
||||
}
|
||||
|
||||
ircd::net::resolve::resolve(const hostport &hostport,
|
||||
callback_one callback)
|
||||
{
|
||||
resolve(hostport, [callback(std::move(callback))]
|
||||
(std::exception_ptr eptr, const vector_view<ipport> &ips)
|
||||
{
|
||||
if(eptr)
|
||||
return callback(std::move(eptr), {});
|
||||
|
||||
if(ips.empty())
|
||||
return callback(std::make_exception_ptr(nxdomain{}), {});
|
||||
|
||||
callback(std::move(eptr), ips.at(0));
|
||||
});
|
||||
}
|
||||
|
||||
ircd::net::resolve::resolve(const hostport &hostport,
|
||||
callback_many callback)
|
||||
{
|
||||
static const ip::tcp::resolver::flags flags{};
|
||||
async_resolve(hostport, flags, [callback(std::move(callback))]
|
||||
(std::exception_ptr eptr, ip::tcp::resolver::results_type results)
|
||||
{
|
||||
if(eptr)
|
||||
return callback(std::move(eptr), {});
|
||||
|
||||
static const size_t max{64};
|
||||
const size_t result_count{results.size()};
|
||||
const size_t count{std::min(max, result_count)};
|
||||
|
||||
ipport vector[count];
|
||||
std::transform(begin(results), end(results), vector, []
|
||||
(const auto &entry)
|
||||
{
|
||||
return make_ipport(entry.endpoint());
|
||||
});
|
||||
|
||||
assert(!eptr);
|
||||
callback(std::move(eptr), vector_view<ipport>(vector, count));
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ircd::net::async_resolve(const hostport &hostport,
|
||||
ip::tcp::resolver::flags flags,
|
||||
resolve_callback callback)
|
||||
{
|
||||
// Trivial host string
|
||||
const string_view &host
|
||||
{
|
||||
hostport.host
|
||||
};
|
||||
|
||||
// Determine if the port is a string or requires a lex_cast to one.
|
||||
char portbuf[8];
|
||||
const string_view &port
|
||||
{
|
||||
hostport.portnum? lex_cast(hostport.portnum, portbuf) : hostport.port
|
||||
};
|
||||
|
||||
// Determine if the port is numeric and hint to avoid name lookup if so.
|
||||
if(hostport.portnum || ctype<std::isdigit>(hostport.port) == -1)
|
||||
flags |= ip::tcp::resolver::numeric_service;
|
||||
|
||||
// This base handler will provide exception guarantees for the entire stack.
|
||||
// It may invoke callback twice in the case when callback throws unhandled,
|
||||
// but the latter invocation will always have an the eptr set.
|
||||
assert(bool(ircd::net::resolver));
|
||||
resolver->async_resolve(host, port, flags, [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}), {});
|
||||
}
|
||||
else try
|
||||
{
|
||||
callback({}, std::move(results));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
callback(std::make_exception_ptr(std::current_exception()), {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// hostport
|
||||
//
|
||||
|
||||
const ircd::net::hostport
|
||||
ircd::net::hostport::null
|
||||
std::ostream &
|
||||
ircd::net::operator<<(std::ostream &s, const hostport &t)
|
||||
{
|
||||
"0.0.0.0"s, 0
|
||||
};
|
||||
|
||||
ircd::net::hostport::hostport(std::string s,
|
||||
const uint16_t &port)
|
||||
try
|
||||
:std::pair<std::string, uint16_t>
|
||||
{
|
||||
std::move(s), port
|
||||
}
|
||||
{
|
||||
if(port != 8448)
|
||||
return;
|
||||
|
||||
//TODO: ipv6
|
||||
const auto port_suffix
|
||||
{
|
||||
rsplit(first, ':').second
|
||||
};
|
||||
|
||||
if(!port_suffix.empty() && port_suffix != "8448")
|
||||
second = lex_cast<uint16_t>(port_suffix);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
throw net::invalid_argument
|
||||
{
|
||||
"Supplied host name and/or port number: ", e.what()
|
||||
};
|
||||
char buf[256];
|
||||
s << string(buf, t);
|
||||
return s;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue