[+] Added basic posix name resolution for when glibc isnt present or when being built on non-glibc toolchains
This commit is contained in:
parent
592afe00a7
commit
e7597b8463
@ -42,6 +42,10 @@ namespace Aurora
|
||||
{
|
||||
p__cxa_throw = (decltype(p__cxa_throw))dlsym(RTLD_DEFAULT, "__cxa_throw");
|
||||
}
|
||||
|
||||
pgai_error = (decltype(pgai_error))dlsym(RTLD_DEFAULT, "gai_error");
|
||||
pgai_cancel = (decltype(pgai_cancel))dlsym(RTLD_DEFAULT, "gai_cancel");
|
||||
pgetaddrinfo_a = (decltype(pgetaddrinfo_a))dlsym(RTLD_DEFAULT, "getaddrinfo_a");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct robust_list_head;
|
||||
struct glibc_aicb;
|
||||
|
||||
namespace Aurora
|
||||
{
|
||||
@ -68,4 +69,9 @@ namespace Aurora
|
||||
inline void (AU_NORETURN *p__cxa_throw)(void *pException, std::type_info *typeInfo, void (*fDtor)(void *pThis));
|
||||
|
||||
inline AuUInt32 (*p_Unwind_RaiseException)(void *pException);
|
||||
|
||||
inline int (* pgai_error) (struct glibc_aicb *pContext);
|
||||
inline int (* pgai_cancel) (struct glibc_aicb *pContext);
|
||||
inline int (* pgetaddrinfo_a) (int mode, struct glibc_aicb **pContext, int count, struct sigevent *sig);
|
||||
#define AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS
|
||||
}
|
@ -119,6 +119,8 @@ namespace Aurora::IO::Net
|
||||
{
|
||||
int iInfoEx { 0 };
|
||||
|
||||
AuMemset(&this->infoEx, 0, sizeof(infoEx));
|
||||
|
||||
if (this->bA && this->bAAAA)
|
||||
{
|
||||
infoEx.ai_family = AF_UNSPEC;
|
||||
@ -136,6 +138,14 @@ namespace Aurora::IO::Net
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||
|
||||
if (!pgetaddrinfo_a)
|
||||
{
|
||||
return this->StartStandard();
|
||||
}
|
||||
|
||||
sigevent event {0};
|
||||
event.sigev_notify = SIGEV_SIGNAL;
|
||||
event.sigev_signo = GetGAIAsyncIOSignal();
|
||||
@ -160,28 +170,38 @@ namespace Aurora::IO::Net
|
||||
pBase->ar_request = (addrinfo *)&infoEx;
|
||||
pBase->ar_name = hostname.c_str();
|
||||
|
||||
AuTryInsert(tlsResolvers, AuSharedFromThis());
|
||||
if (!AuTryInsert(tlsResolvers, AuSharedFromThis()))
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
int iStatus = ::getaddrinfo_a(GAI_NOWAIT,
|
||||
&pBase,
|
||||
1,
|
||||
&event);
|
||||
int iStatus = pgetaddrinfo_a(GAI_NOWAIT,
|
||||
&pBase,
|
||||
1,
|
||||
&event);
|
||||
|
||||
switch (iStatus)
|
||||
{
|
||||
case EAI_AGAIN:
|
||||
{
|
||||
SysPushErrorNet("Low Resources | Failed to resolve");
|
||||
this->uOsError = iStatus;
|
||||
this->error_ = this->ToError();
|
||||
return false;
|
||||
}
|
||||
case EAI_MEMORY:
|
||||
{
|
||||
SysPushErrorNet("Out of Memory | Failed to resolve");
|
||||
this->uOsError = iStatus;
|
||||
this->error_ = this->ToError();
|
||||
return false;
|
||||
}
|
||||
case EAI_SYSTEM:
|
||||
{
|
||||
SysPushErrorNet("Invalid | Failed to resolve");
|
||||
SysPushErrorNet("Invalid | Failed to resolve: {}", errno);
|
||||
this->uOsError = errno;
|
||||
this->error_ = this->ToError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -189,12 +209,87 @@ namespace Aurora::IO::Net
|
||||
if (iStatus != 0)
|
||||
{
|
||||
SysPushErrorNet("{}", iStatus);
|
||||
this->uOsError = iStatus;
|
||||
this->error_ = this->ToError();
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->BeginOperation(AuSharedFromThis(),
|
||||
this->pWorker_);
|
||||
|
||||
#else
|
||||
|
||||
return this->StartStandard();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool NetResolver::StartStandard()
|
||||
{
|
||||
auto pShared = this->SharedFromThis();
|
||||
|
||||
auto pThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
||||
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind([=]()
|
||||
{
|
||||
int iRet {};
|
||||
addrinfo infoA { 0 };
|
||||
addrinfo *pInfoRet {};
|
||||
infoA.ai_family = infoEx.ai_family;
|
||||
|
||||
iRet = getaddrinfo(pShared->hostname.c_str(),
|
||||
nullptr,
|
||||
&infoA,
|
||||
&pInfoRet);
|
||||
|
||||
if (iRet == 0)
|
||||
{
|
||||
auto pCurrent = pInfoRet;
|
||||
|
||||
while (pCurrent)
|
||||
{
|
||||
NetEndpoint endpoint;
|
||||
AuMemcpy(endpoint.hint, pCurrent->ai_addr, pCurrent->ai_addrlen);
|
||||
DeoptimizeEndpoint(endpoint);
|
||||
|
||||
if (!AuTryInsert(pShared->processedIps_, endpoint.ip))
|
||||
{
|
||||
pShared->bForceError_ = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pCurrent = pCurrent->ai_next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pShared->bForceError_ = true;
|
||||
pShared->uOsError = iRet;
|
||||
pShared->error_ = pShared->ToError();
|
||||
}
|
||||
|
||||
if (pInfoRet)
|
||||
{
|
||||
freeaddrinfo(pInfoRet);
|
||||
}
|
||||
|
||||
pShared->pEvent->Set();
|
||||
})),
|
||||
AuThreads::IThreadVectorsFunctional::OnExit_t{}),
|
||||
"Legacy Posix DNS Request"
|
||||
));
|
||||
|
||||
if (!pThread)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pThread->Run();
|
||||
pThread->Detach();
|
||||
|
||||
this->UpdateTrigger(pShared->pEvent);
|
||||
|
||||
return this->BeginOperation(AuSharedFromThis(),
|
||||
this->pWorker_);
|
||||
}
|
||||
|
||||
void NetResolver::SetCompletion(const AuSPtr<AuAsync::PromiseCallback<AuList<IPAddress>, NetError>> &callback)
|
||||
@ -282,28 +377,58 @@ namespace Aurora::IO::Net
|
||||
|
||||
bool NetResolver::CheckAsync()
|
||||
{
|
||||
int iStatus = ::gai_error(&this->gnuAsyncOperation);
|
||||
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||
|
||||
if (!pgai_error)
|
||||
{
|
||||
return !this->bForceError_;
|
||||
}
|
||||
|
||||
int iStatus = pgai_error(&this->gnuAsyncOperation);
|
||||
return ((iStatus == 0) ||
|
||||
(iStatus == EAI_CANCELED));
|
||||
|
||||
#else
|
||||
|
||||
return !this->bForceError_;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void NetResolver::Cancel()
|
||||
{
|
||||
while (!this->HasComplete())
|
||||
{
|
||||
int iStatus = ::gai_cancel(&this->gnuAsyncOperation);
|
||||
switch (iStatus)
|
||||
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||
|
||||
if (pgai_cancel)
|
||||
{
|
||||
case EAI_CANCELED:
|
||||
case EAI_ALLDONE:
|
||||
break;
|
||||
case EAI_NOTCANCELED:
|
||||
int iStatus = pgai_cancel(&this->gnuAsyncOperation);
|
||||
switch (iStatus)
|
||||
{
|
||||
IOYield();
|
||||
AuThreading::ContextYield();
|
||||
continue;
|
||||
case EAI_CANCELED:
|
||||
case EAI_ALLDONE:
|
||||
break;
|
||||
case EAI_NOTCANCELED:
|
||||
{
|
||||
IOYield();
|
||||
AuThreading::ContextYield();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IOYield();
|
||||
AuThreading::ContextYield();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
IOYield();
|
||||
AuThreading::ContextYield();
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,11 +459,15 @@ namespace Aurora::IO::Net
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
freeaddrinfo(pItr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||
|
||||
static void Annoying(int)
|
||||
{
|
||||
for (const auto &gawad : tlsResolvers)
|
||||
@ -350,15 +479,21 @@ namespace Aurora::IO::Net
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void InitFreetardedResolver()
|
||||
{
|
||||
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||
|
||||
struct sigaction action =
|
||||
{
|
||||
.sa_handler = Annoying,
|
||||
.sa_flags = SA_ONSTACK
|
||||
.sa_flags = SA_ONSTACK | SA_RESTART
|
||||
};
|
||||
|
||||
::sigemptyset(&action.sa_mask);
|
||||
::sigaction(GetGAIAsyncIOSignal(), &action, nullptr);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
@ -10,6 +10,27 @@
|
||||
#include "AuNetSocketOverlappedOperation.hpp"
|
||||
#include "AuNetSocket.hpp"
|
||||
|
||||
#if !defined(EAI_AGAIN)
|
||||
#define EAI_AGAIN -3
|
||||
#endif
|
||||
|
||||
#if !defined(EAI_MEMORY)
|
||||
#define EAI_MEMORY -10
|
||||
#endif
|
||||
|
||||
#if !defined(EAI_SYSTEM)
|
||||
#define EAI_SYSTEM -11
|
||||
#endif
|
||||
|
||||
struct glibc_aicb
|
||||
{
|
||||
const char * ar_name { };
|
||||
const char * ar_service { };
|
||||
const struct addrinfo *ar_request { };
|
||||
struct addrinfo * ar_result { };
|
||||
int reserved[10] { };
|
||||
};
|
||||
|
||||
namespace Aurora::IO::Net
|
||||
{
|
||||
struct Socket;
|
||||
@ -30,6 +51,7 @@ namespace Aurora::IO::Net
|
||||
AuString hostname;
|
||||
|
||||
bool Start();
|
||||
bool StartStandard();
|
||||
|
||||
void SetCompletion(const AuSPtr<AuAsync::PromiseCallback<AuList<IPAddress>, NetError>> &callback);
|
||||
|
||||
@ -52,10 +74,9 @@ namespace Aurora::IO::Net
|
||||
bool bHasCompleted_ {};
|
||||
bool bHasUnpackedEarly {};
|
||||
NetError error_;
|
||||
|
||||
addrinfo infoEx { 0 };
|
||||
|
||||
gaicb gnuAsyncOperation {}; // freetarded
|
||||
addrinfo infoEx { };
|
||||
bool bForceError_ {};
|
||||
glibc_aicb gnuAsyncOperation {}; // freetarded
|
||||
bool CheckAsync();
|
||||
friend struct ThreadLocalCaughtCompletion;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user