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

View file

@ -23,6 +23,7 @@ namespace ircd::net
const uint16_t &port(const ipport &);
uint16_t &port(ipport &);
bool is_null(const ipport &);
bool is_loop(const ipport &);
bool is_v6(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));
}
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};
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)
consume(out, copy(out, "["_sv));
@ -4565,9 +4568,9 @@ const
boost::asio::ip::address
ircd::net::make_address(const ipaddr &ipaddr)
{
return is_v6(ipaddr)?
ip::address(make_address(ipaddr.v6)):
ip::address(make_address(ipaddr.v4));
return is_v4(ipaddr)?
ip::address(make_address(ipaddr.v4)):
ip::address(make_address(ipaddr.v6));
}
boost::asio::ip::address
@ -4622,9 +4625,9 @@ ircd::string_view
ircd::net::string(const mutable_buffer &buf,
const ipaddr &ipaddr)
{
return is_v6(ipaddr)?
string_ip6(buf, ipaddr.v6):
string_ip4(buf, ipaddr.v4);
return is_v4(ipaddr)?
string_ip4(buf, ipaddr.v4):
string_ip6(buf, ipaddr.v6);
}
ircd::string_view
@ -4644,29 +4647,34 @@ ircd::net::string_ip6(const mutable_buffer &buf,
bool
ircd::net::is_loop(const ipaddr &ipaddr)
{
return is_v6(ipaddr)?
make_address(ipaddr.v6).is_loopback():
make_address(ipaddr.v4).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);
return is_v4(ipaddr)?
make_address(ipaddr.v4).is_loopback():
make_address(ipaddr.v6).is_loopback();
}
//
// 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)
:ipaddr
{