0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 08:12:37 +01:00

ircd::net: Fix/improve the v6/v4 check.

ircd::net: Add an is_null(ipport/ipaddr).

ircd::net: Improve the v6/v4 check efficiency.

ircd::net: Swap defaulting from v6 to v4 for better null address output.
This commit is contained in:
Jason Volk 2019-08-04 16:41:08 -07:00
parent d5bb55fbc3
commit c64bb6850c
3 changed files with 61 additions and 25 deletions

View file

@ -28,6 +28,7 @@ namespace ircd::net
uint128_t &host6(ipaddr &); uint128_t &host6(ipaddr &);
uint32_t &host4(ipaddr &); uint32_t &host4(ipaddr &);
bool is_null(const ipaddr &);
bool is_loop(const ipaddr &); bool is_loop(const ipaddr &);
bool is_v6(const ipaddr &); bool is_v6(const ipaddr &);
bool is_v4(const ipaddr &); bool is_v4(const ipaddr &);
@ -51,6 +52,8 @@ union ircd::net::ipaddr
{ {
struct cmp; struct cmp;
static const uint128_t v4_min, v4_max;
uint32_t v4; uint32_t v4;
uint128_t v6 {0}; uint128_t v6 {0};
std::array<uint8_t, 16> byte; std::array<uint8_t, 16> byte;
@ -94,7 +97,25 @@ ircd::net::operator<(const ipaddr &a, const ipaddr &b)
inline bool inline bool
ircd::net::operator!(const ipaddr &a) ircd::net::operator!(const ipaddr &a)
{ {
return !a.v6; return is_null(a);
}
inline bool
ircd::net::is_v4(const ipaddr &ipaddr)
{
return !ipaddr.v6 || !is_v6(ipaddr);
}
inline bool
ircd::net::is_v6(const ipaddr &ipaddr)
{
return ipaddr.v6 > ipaddr::v4_max || ipaddr.v6 < ipaddr::v4_min;
}
inline bool
ircd::net::is_null(const ipaddr &ipaddr)
{
return is_v4(ipaddr)? ipaddr.v4 == 0 : ipaddr.v6 == 0;
} }
inline uint32_t & inline uint32_t &

View file

@ -23,6 +23,7 @@ namespace ircd::net
const uint16_t &port(const ipport &); const uint16_t &port(const ipport &);
uint16_t &port(ipport &); uint16_t &port(ipport &);
bool is_null(const ipport &);
bool is_loop(const ipport &); bool is_loop(const ipport &);
bool is_v6(const ipport &); bool is_v6(const ipport &);
bool is_v4(const ipport &); bool is_v4(const ipport &);
@ -187,3 +188,9 @@ ircd::net::is_loop(const ipport &ipp)
{ {
return is_loop(std::get<ipport::IP>(ipp)); return is_loop(std::get<ipport::IP>(ipp));
} }
inline bool
ircd::net::is_null(const ipport &ipp)
{
return is_null(std::get<ipport::IP>(ipp));
}

View file

@ -4480,7 +4480,10 @@ ircd::net::string(const mutable_buffer &buf,
{ {
mutable_buffer out{buf}; mutable_buffer out{buf};
const bool has_port(port(ipp)); const bool has_port(port(ipp));
const bool need_bracket(has_port && is_v6(ipp)); const bool need_bracket
{
has_port && is_v6(ipp) && !is_null(ipp)
};
if(need_bracket) if(need_bracket)
consume(out, copy(out, "["_sv)); consume(out, copy(out, "["_sv));
@ -4565,9 +4568,9 @@ const
boost::asio::ip::address boost::asio::ip::address
ircd::net::make_address(const ipaddr &ipaddr) ircd::net::make_address(const ipaddr &ipaddr)
{ {
return is_v6(ipaddr)? return is_v4(ipaddr)?
ip::address(make_address(ipaddr.v6)): ip::address(make_address(ipaddr.v4)):
ip::address(make_address(ipaddr.v4)); ip::address(make_address(ipaddr.v6));
} }
boost::asio::ip::address boost::asio::ip::address
@ -4622,9 +4625,9 @@ ircd::string_view
ircd::net::string(const mutable_buffer &buf, ircd::net::string(const mutable_buffer &buf,
const ipaddr &ipaddr) const ipaddr &ipaddr)
{ {
return is_v6(ipaddr)? return is_v4(ipaddr)?
string_ip6(buf, ipaddr.v6): string_ip4(buf, ipaddr.v4):
string_ip4(buf, ipaddr.v4); string_ip6(buf, ipaddr.v6);
} }
ircd::string_view ircd::string_view
@ -4644,29 +4647,34 @@ ircd::net::string_ip6(const mutable_buffer &buf,
bool bool
ircd::net::is_loop(const ipaddr &ipaddr) ircd::net::is_loop(const ipaddr &ipaddr)
{ {
return is_v6(ipaddr)? return is_v4(ipaddr)?
make_address(ipaddr.v6).is_loopback(): make_address(ipaddr.v4).is_loopback():
make_address(ipaddr.v4).is_loopback(); make_address(ipaddr.v6).is_loopback();
}
bool
ircd::net::is_v4(const ipaddr &ipaddr)
{
return ipaddr.v6 == 0 ||
(ipaddr.byte[4] == 0xff && ipaddr.byte[5] == 0xff);
}
bool
ircd::net::is_v6(const ipaddr &ipaddr)
{
return ipaddr.v6 == 0 ||
!(ipaddr.byte[4] == 0xff && ipaddr.byte[5] == 0xff);
} }
// //
// ipaddr::ipaddr // ipaddr::ipaddr
// //
static_assert
(
SIZEOF_LONG_LONG >= 8,
"8 byte integer literals are required."
);
decltype(ircd::net::ipaddr::v4_max)
ircd::net::ipaddr::v4_min
{
0x0000ffff00000000ULL
};
decltype(ircd::net::ipaddr::v4_max)
ircd::net::ipaddr::v4_max
{
v4_min +
0x00000000ffffffffULL
};
ircd::net::ipaddr::ipaddr(const string_view &ip) ircd::net::ipaddr::ipaddr(const string_view &ip)
:ipaddr :ipaddr
{ {