4#include "Stroika/Foundation/StroikaPreComp.h"
8#if qStroika_Foundation_Common_Platform_POSIX
10#include <sys/socket.h>
12#elif qStroika_Foundation_Common_Platform_Windows
20#include "Stroika/Foundation/Containers/Collection.h"
21#include "Stroika/Foundation/Execution/Exceptions.h"
23#if qStroika_Foundation_Common_Platform_Windows
24#include "Stroika/Foundation/Execution/Platform/Windows/Exception.h"
25#include "Stroika/Foundation/IO/Network/Platform/Windows/WinSock.h"
27#include "Stroika/Foundation/Execution/Exceptions.h"
28#include "Stroika/Foundation/IO/Network/SocketAddress.h"
36using namespace Stroika::Foundation::Memory;
37using namespace Stroika::Foundation::IO;
40#if qStroika_Foundation_Common_Platform_Windows
43#define gai_strerror gai_strerrorA
51 class getaddrinfo_error_category_ :
public error_category {
53 virtual const char* name () const noexcept
override
57 virtual error_condition default_error_condition (
int ev)
const noexcept override
62 return std::error_condition{errc::address_family_not_supported};
66 return error_condition{errc::no_such_device};
70 return error_condition{errc::not_enough_memory};
73 return error_condition{errc::bad_message};
75 virtual string message (
int _Errval)
const override
80 const char* result = ::gai_strerror (_Errval);
81 while (isspace (*result)) {
84 const char* e = result + ::strlen (result);
85 while (result < e and isspace (*(e - 1))) {
88 return string{result, e};
91 const error_category& DNS_error_category () noexcept
93 return Common::Immortalize<getaddrinfo_error_category_> ();
104 static const DNS kDefaultDNS_;
110#if qStroika_Foundation_Common_Platform_Windows
111 IO::Network::Platform::Windows::WinSock::AssureStarted ();
117#if USE_NOISY_TRACE_IN_THIS_MODULE_
123 hints.ai_family = AF_UNSPEC;
124 hints.ai_socktype = SOCK_STREAM;
125 hints.ai_flags = AI_CANONNAME;
127 hints.ai_flags |= AI_IDN;
129#if defined(AI_CANONIDN)
130 hints.ai_flags |= AI_CANONIDN;
132 string tmp = hostNameOrAddress.
AsUTF8<
string> ();
133 if (not tmp.empty () and tmp[0] ==
'[' and tmp[tmp.size () - 1] ==
']' and isdigit (tmp[1])) {
135 tmp = tmp.substr (1, tmp.size () - 2);
137 addrinfo* res =
nullptr;
138 int errCode = ::getaddrinfo (tmp.c_str (),
nullptr, &hints, &res);
139 [[maybe_unused]]
auto&& cleanup =
Execution::Finally ([res] ()
noexcept { ::freeaddrinfo (res); });
156 if (res->ai_canonname !=
nullptr) {
161 for (addrinfo* i = res; i !=
nullptr; i = i->ai_next) {
162 if (i != res and i->ai_canonname !=
nullptr and i->ai_canonname[0] !=
'\0') {
166 if (sa.IsInternetAddress ()) {
171#if USE_NOISY_TRACE_IN_THIS_MODULE_
173 DbgTrace (L
"CANONNAME: %s", result.fCanonicalName.c_str ());
174 for (
const String& i : result.fAliases) {
175 DbgTrace (L
" ALIAS: %s", i.c_str ());
186#if USE_NOISY_TRACE_IN_THIS_MODULE_
189 char hbuf[NI_MAXHOST];
191 sockaddr_storage sadata = sa.
As<sockaddr_storage> ();
192 int flags = NI_NAMEREQD;
196 int errCode = ::getnameinfo (
reinterpret_cast<const sockaddr*
> (&sadata),
static_cast<socklen_t
> (sa.GetRequiredSize ()), hbuf,
197 sizeof (hbuf), NULL, 0, flags);
214#if USE_NOISY_TRACE_IN_THIS_MODULE_
217 char hbuf[NI_MAXHOST];
219 sockaddr_storage sadata = sa.
As<sockaddr_storage> ();
220 int flags = NI_NAMEREQD;
224 int errCode = ::getnameinfo (
reinterpret_cast<const sockaddr*
> (&sadata),
static_cast<socklen_t
> (sa.GetRequiredSize ()), hbuf,
225 sizeof (hbuf),
nullptr, 0, flags);
240#if USE_NOISY_TRACE_IN_THIS_MODULE_
242 {
"DNS::HostEntry DNS::GetHostAddresses",
"address={}"_f, address);
249#if USE_NOISY_TRACE_IN_THIS_MODULE_
253 for (
auto i = h.begin (); i != h.end (); ++i) {
254 if (i->GetAddressFamily () != family) {
263#if USE_NOISY_TRACE_IN_THIS_MODULE_
276#if USE_NOISY_TRACE_IN_THIS_MODULE_
280 for (
auto i = h.begin (); i != h.end (); ++i) {
281 if (i->GetAddressFamily () != family) {
#define Stroika_Foundation_Debug_OptionalizeTraceArgs(...)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual T AsUTF8() const
nonvirtual tuple< const wchar_t *, wstring_view > c_str(Memory::StackBuffer< wchar_t > *possibleBackingStore) const
static String FromUTF8(span< CHAR_T > from)
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual optional< String > ReverseLookup(const InternetAddress &address) const
nonvirtual optional< String > QuietReverseLookup(const InternetAddress &address) const
nonvirtual InternetAddress GetHostAddress(const String &hostNameOrAddress) const
simple wrapper on GetHostEntry.
nonvirtual HostEntry GetHostEntry(const String &hostNameOrAddress) const
nonvirtual Sequence< InternetAddress > GetHostAddresses(const String &hostNameOrAddress) const
simple wrapper on GetHostEntry - looking up the hostname/ip address and returning the list of associa...
nonvirtual InternetAddress GetInternetAddress() const
String ToString(T &&t, ARGS... args)
Return a debug-friendly, display version of the argument: not guaranteed parsable or usable except fo...
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
auto Finally(FUNCTION &&f) -> Private_::FinallySentry< FUNCTION >