14#include <fmt/format.h>
15#include <userver/utils/fmt_compat.hpp>
17#include <userver/logging/log_helper_fwd.hpp>
19USERVER_NAMESPACE_BEGIN
26 using std::runtime_error::runtime_error;
37static_assert(AF_UNSPEC == 0,
"Your socket subsystem looks broken, please contact support chat.");
44 Sockaddr()
noexcept { ::memset(&data_, 0,
sizeof(data_)); }
50 const auto* sockaddr =
reinterpret_cast<
const struct sockaddr*>(data);
51 const auto domain =
static_cast<
AddrDomain>(sockaddr->sa_family);
52 ::memcpy(&data_, data, Sockaddr::Addrlen(domain));
74 static_assert(
sizeof(T) <=
sizeof(data_),
"Invalid socket address type");
75 return reinterpret_cast<T*>(&data_);
83 static_assert(
sizeof(T) <=
sizeof(data_),
"Invalid socket address type");
84 return reinterpret_cast<
const T*>(&data_);
88 struct sockaddr*
Data() {
return As<
struct sockaddr>(); }
91 const struct sockaddr*
Data()
const {
return As<
struct sockaddr>(); }
97 socklen_t
Capacity()
const {
return sizeof(data_); }
120 const auto res = AddrlenImpl(domain);
123 throw AddrException(fmt::format(
"Unexpected address family {}",
static_cast<
int>(domain)));
130 static constexpr socklen_t AddrlenImpl(
AddrDomain domain)
noexcept {
133 return sizeof(
struct sockaddr);
135 return sizeof(
struct sockaddr_in);
137 return sizeof(
struct sockaddr_in6);
139 return sizeof(
struct sockaddr_un);
146 struct sockaddr sa_any;
147 struct sockaddr_in sa_inet;
148 struct sockaddr_in6 sa_inet6;
149 struct sockaddr_un sa_unix;
162struct fmt::formatter<USERVER_NAMESPACE::engine::io::Sockaddr> {
163 static constexpr auto parse(format_parse_context&);
165 template <
typename FormatContext>
166 auto format(
const USERVER_NAMESPACE::engine::io::Sockaddr& sa, FormatContext& ctx)
USERVER_FMT_CONST;
169inline constexpr auto fmt::formatter<USERVER_NAMESPACE::engine::io::Sockaddr>::parse(format_parse_context& ctx) {
170 const auto* it = ctx.begin();
171 if (it != ctx.end() && *it !=
'}') {
172 throw format_error(
"invalid Sockaddr format");
177template <
typename FormatContext>
178inline auto fmt::formatter<USERVER_NAMESPACE::engine::io::Sockaddr>::format(
179 const USERVER_NAMESPACE::engine::io::Sockaddr& sa,
182 switch (sa.Domain()) {
183 case USERVER_NAMESPACE::engine::io::AddrDomain::kInet:
184 return fmt::format_to(ctx.out(),
"{}:{}", sa.PrimaryAddressString(), sa.Port());
186 case USERVER_NAMESPACE::engine::io::AddrDomain::kInet6:
187 return fmt::format_to(ctx.out(),
"[{}]:{}", sa.PrimaryAddressString(), sa.Port());
190 return fmt::format_to(ctx.out(),
"{}", sa.PrimaryAddressString());