diff --git a/include/ircd/net/net.h b/include/ircd/net/net.h index 6541f8652..555556cdf 100644 --- a/include/ircd/net/net.h +++ b/include/ircd/net/net.h @@ -49,6 +49,7 @@ namespace ircd::net } #include "remote.h" +#include "resolve.h" #include "listener.h" enum class ircd::net::dc diff --git a/include/ircd/net/remote.h b/include/ircd/net/remote.h index 38a123dc1..772cbde8c 100644 --- a/include/ircd/net/remote.h +++ b/include/ircd/net/remote.h @@ -31,7 +31,6 @@ namespace boost::asio::ip namespace ircd::net { struct hostport; - struct resolve; struct ipport; struct remote; @@ -98,26 +97,6 @@ struct ircd::net::hostport friend std::ostream &operator<<(std::ostream &, const hostport &); }; -/// DNS resolution suite. -/// -/// There are plenty of ways to resolve plenty of things. Still more to come. -struct ircd::net::resolve -{ - using callback_one = std::function; - using callback_many = std::function)>; - using callback_reverse = std::function; - - resolve(const hostport &, callback_one); - resolve(const hostport &, callback_many); - resolve(const ipport &, callback_reverse); - - resolve(const hostport &, ctx::future &); - resolve(const hostport &, ctx::future> &); - - resolve(const vector_view &in, const vector_view &out); - resolve(const vector_view &in, const vector_view &out); -}; - /// 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 diff --git a/include/ircd/net/resolve.h b/include/ircd/net/resolve.h new file mode 100644 index 000000000..2ccd1acff --- /dev/null +++ b/include/ircd/net/resolve.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017 Charybdis Development Team + * Copyright (C) 2017 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#define HAVE_IRCD_NET_RESOLVE_H + +namespace ircd::net +{ + struct resolve; +} + +/// DNS resolution suite. +/// +/// There are plenty of ways to resolve plenty of things. Still more to come. +struct ircd::net::resolve +{ + using callback_one = std::function; + using callback_many = std::function)>; + using callback_reverse = std::function; + + resolve(const hostport &, callback_one); + resolve(const hostport &, callback_many); + resolve(const ipport &, callback_reverse); + + resolve(const hostport &, ctx::future &); + resolve(const hostport &, ctx::future> &); + + resolve(const vector_view &in, const vector_view &out); + resolve(const vector_view &in, const vector_view &out); +}; diff --git a/ircd/net.cc b/ircd/net.cc index 16d5edee4..c879b9e47 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -1457,181 +1457,7 @@ ircd::net::string(const mutable_buffer &buf, /////////////////////////////////////////////////////////////////////////////// // -// net/remote.h -// - -// -// host / port utils -// - -ircd::string_view -ircd::net::string(const mutable_buffer &buf, - const uint32_t &ip) -{ - const auto len - { - ip::address_v4{ip}.to_string().copy(data(buf), size(buf)) - }; - - return { data(buf), size_t(len) }; -} - -ircd::string_view -ircd::net::string(const mutable_buffer &buf, - const uint128_t &ip) -{ - const auto &pun - { - reinterpret_cast(ip) - }; - - const auto &punpun - { - reinterpret_cast &>(pun) - }; - - const auto len - { - ip::address_v6{punpun}.to_string().copy(data(buf), size(buf)) - }; - - return { data(buf), size_t(len) }; -} - -ircd::string_view -ircd::net::string(const mutable_buffer &buf, - const hostport &hp) -{ - const auto len - { - 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 mutable_buffer &buf, - const ipport &ipp) -{ - const auto len - { - is_v4(ipp)? - fmt::sprintf(buf, "%s:%u", - ip::address_v4{host4(ipp)}.to_string(), - port(ipp)): - - is_v6(ipp)? - fmt::sprintf(buf, "%s:%u", - ip::address_v6{std::get(ipp)}.to_string(), - port(ipp)): - - 0 - }; - - return { data(buf), size_t(len) }; -} - -ircd::string_view -ircd::net::string(const mutable_buffer &buf, - const remote &remote) -{ - const auto &ipp - { - static_cast(remote) - }; - - if(!ipp && !remote.hostname) - { - const auto len{strlcpy(data(buf), "0.0.0.0", size(buf))}; - return { data(buf), size_t(len) }; - } - else if(!ipp) - { - const auto len{strlcpy(data(buf), remote.hostname, size(buf))}; - return { data(buf), size_t(len) }; - } - else return string(buf, ipp); -} - -// -// remote -// - -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() - }; -} - -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) }, port(ipport) - } - : ip::tcp::endpoint - { - asio::ip::address_v4 { host4(ipport) }, port(ipport) - }, - }; -} - -ircd::net::ipport::ipport(const hostport &hp) -{ - ctx::future future; - resolve{hp, future}; - *this = future.get(); -} - -ircd::net::ipport::ipport(const boost::asio::ip::address &address, - const uint16_t &port) -{ - std::get(*this) = address.is_v6(); - - if(is_v6(*this)) - { - std::get(*this) = address.to_v6().to_bytes(); - std::reverse(std::get(*this).begin(), std::get(*this).end()); - } - else host4(*this) = address.to_v4().to_ulong(); - - net::port(*this) = port; -} - -// -// resolve +// net/resolve.h // namespace ircd::net @@ -1851,6 +1677,181 @@ ircd::net::_resolve(const ipport &ipport, }); } +/////////////////////////////////////////////////////////////////////////////// +// +// net/remote.h +// + +// +// host / port utils +// + +ircd::string_view +ircd::net::string(const mutable_buffer &buf, + const uint32_t &ip) +{ + const auto len + { + ip::address_v4{ip}.to_string().copy(data(buf), size(buf)) + }; + + return { data(buf), size_t(len) }; +} + +ircd::string_view +ircd::net::string(const mutable_buffer &buf, + const uint128_t &ip) +{ + const auto &pun + { + reinterpret_cast(ip) + }; + + const auto &punpun + { + reinterpret_cast &>(pun) + }; + + const auto len + { + ip::address_v6{punpun}.to_string().copy(data(buf), size(buf)) + }; + + return { data(buf), size_t(len) }; +} + +ircd::string_view +ircd::net::string(const mutable_buffer &buf, + const hostport &hp) +{ + const auto len + { + 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 mutable_buffer &buf, + const ipport &ipp) +{ + const auto len + { + is_v4(ipp)? + fmt::sprintf(buf, "%s:%u", + ip::address_v4{host4(ipp)}.to_string(), + port(ipp)): + + is_v6(ipp)? + fmt::sprintf(buf, "%s:%u", + ip::address_v6{std::get(ipp)}.to_string(), + port(ipp)): + + 0 + }; + + return { data(buf), size_t(len) }; +} + +ircd::string_view +ircd::net::string(const mutable_buffer &buf, + const remote &remote) +{ + const auto &ipp + { + static_cast(remote) + }; + + if(!ipp && !remote.hostname) + { + const auto len{strlcpy(data(buf), "0.0.0.0", size(buf))}; + return { data(buf), size_t(len) }; + } + else if(!ipp) + { + const auto len{strlcpy(data(buf), remote.hostname, size(buf))}; + return { data(buf), size_t(len) }; + } + else return string(buf, ipp); +} + +// +// remote +// + +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() + }; +} + +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) }, port(ipport) + } + : ip::tcp::endpoint + { + asio::ip::address_v4 { host4(ipport) }, port(ipport) + }, + }; +} + +ircd::net::ipport::ipport(const hostport &hp) +{ + ctx::future future; + resolve{hp, future}; + *this = future.get(); +} + +ircd::net::ipport::ipport(const boost::asio::ip::address &address, + const uint16_t &port) +{ + std::get(*this) = address.is_v6(); + + if(is_v6(*this)) + { + std::get(*this) = address.to_v6().to_bytes(); + std::reverse(std::get(*this).begin(), std::get(*this).end()); + } + else host4(*this) = address.to_v4().to_ulong(); + + net::port(*this) = port; +} + // // hostport //