12#include <sys/socket.h>
14#include <fmt/format.h>
16USERVER_NAMESPACE_BEGIN
24template <std::size_t N>
25class AddressBase
final {
26 static_assert(N == 4 || N == 16,
"Address can only be 4 or 16 bytes size");
29 static constexpr std::size_t AddressSize = N;
30 using BytesType = std::array<
unsigned char, N>;
32 AddressBase()
noexcept : address_({0}) {}
33 explicit AddressBase(
const BytesType& address) : address_(address) {}
36 const BytesType&
GetBytes()
const noexcept {
return address_; }
38 friend bool operator==(
const AddressBase<N>& a1,
39 const AddressBase<N>& a2)
noexcept {
40 return a1.address_ == a2.address_;
43 friend bool operator!=(
const AddressBase<N>& a1,
44 const AddressBase<N>& a2)
noexcept {
45 return a1.address_ != a2.address_;
55using AddressV4 = AddressBase<4>;
60using AddressV6 = AddressBase<16>;
63inline constexpr bool kIsAddressType =
64 std::is_same_v<T, AddressV4> || std::is_same_v<T, AddressV6>;
84template <
typename Address,
85 typename = std::enable_if_t<kIsAddressType<Address>>>
86class NetworkBase
final {
88 using AddressType = Address;
89 static constexpr unsigned char kMaximumPrefixLength =
90 std::is_same_v<Address, AddressV4> ? 32 : 128;
92 NetworkBase()
noexcept =
default;
94 NetworkBase(
const AddressType& address,
unsigned short prefix_length)
95 : address_(address), prefix_length_(prefix_length) {
96 if (prefix_length > kMaximumPrefixLength) {
97 throw std::out_of_range(fmt::format(
98 "{} prefix length is too large",
99 std::is_same_v<Address, AddressV4> ?
"NetworkV4" :
"NetworkV6"));
109 friend bool operator==(
const NetworkBase<Address>& a,
110 const NetworkBase<Address>& b)
noexcept {
111 return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_;
114 friend bool operator!=(
const NetworkBase<Address>& a,
115 const NetworkBase<Address>& b)
noexcept {
120 AddressType address_;
121 unsigned char prefix_length_ = 0;
127using NetworkV4 = NetworkBase<AddressV4>;
132using NetworkV6 = NetworkBase<AddressV6>;
161class InetNetwork
final {
163 enum class AddressFamily :
unsigned char { IPv4 = AF_INET, IPv6 = AF_INET6 };
167 InetNetwork(std::vector<
unsigned char>&& bytes,
unsigned char prefix_length,
168 AddressFamily address_family);
179 friend bool operator==(
const InetNetwork& lhs,
const InetNetwork& rhs) {
180 return lhs.address_family_ == rhs.address_family_ &&
181 lhs.prefix_length_ == rhs.prefix_length_ && lhs.bytes_ == rhs.bytes_;
184 friend bool operator!=(
const InetNetwork& lhs,
const InetNetwork& rhs) {
185 return !operator==(lhs, rhs);
189 std::vector<
unsigned char> bytes_;
190 unsigned char prefix_length_;
191 AddressFamily address_family_;
207class AddressSystemError
final :
public std::exception {
209 AddressSystemError(std::error_code code, std::string_view msg)
210 : msg_(msg), code_(code) {}
213 const std::error_code&
Code()
const {
return code_; }
215 const char* what()
const noexcept final {
return msg_.c_str(); }
219 std::error_code code_;