[+] 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");
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
struct robust_list_head;
|
struct robust_list_head;
|
||||||
|
struct glibc_aicb;
|
||||||
|
|
||||||
namespace Aurora
|
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 void (AU_NORETURN *p__cxa_throw)(void *pException, std::type_info *typeInfo, void (*fDtor)(void *pThis));
|
||||||
|
|
||||||
inline AuUInt32 (*p_Unwind_RaiseException)(void *pException);
|
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 };
|
int iInfoEx { 0 };
|
||||||
|
|
||||||
|
AuMemset(&this->infoEx, 0, sizeof(infoEx));
|
||||||
|
|
||||||
if (this->bA && this->bAAAA)
|
if (this->bA && this->bAAAA)
|
||||||
{
|
{
|
||||||
infoEx.ai_family = AF_UNSPEC;
|
infoEx.ai_family = AF_UNSPEC;
|
||||||
@ -136,6 +138,14 @@ namespace Aurora::IO::Net
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||||
|
|
||||||
|
if (!pgetaddrinfo_a)
|
||||||
|
{
|
||||||
|
return this->StartStandard();
|
||||||
|
}
|
||||||
|
|
||||||
sigevent event {0};
|
sigevent event {0};
|
||||||
event.sigev_notify = SIGEV_SIGNAL;
|
event.sigev_notify = SIGEV_SIGNAL;
|
||||||
event.sigev_signo = GetGAIAsyncIOSignal();
|
event.sigev_signo = GetGAIAsyncIOSignal();
|
||||||
@ -160,28 +170,38 @@ namespace Aurora::IO::Net
|
|||||||
pBase->ar_request = (addrinfo *)&infoEx;
|
pBase->ar_request = (addrinfo *)&infoEx;
|
||||||
pBase->ar_name = hostname.c_str();
|
pBase->ar_name = hostname.c_str();
|
||||||
|
|
||||||
AuTryInsert(tlsResolvers, AuSharedFromThis());
|
if (!AuTryInsert(tlsResolvers, AuSharedFromThis()))
|
||||||
|
{
|
||||||
|
SysPushErrorMemory();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int iStatus = ::getaddrinfo_a(GAI_NOWAIT,
|
int iStatus = pgetaddrinfo_a(GAI_NOWAIT,
|
||||||
&pBase,
|
&pBase,
|
||||||
1,
|
1,
|
||||||
&event);
|
&event);
|
||||||
|
|
||||||
switch (iStatus)
|
switch (iStatus)
|
||||||
{
|
{
|
||||||
case EAI_AGAIN:
|
case EAI_AGAIN:
|
||||||
{
|
{
|
||||||
SysPushErrorNet("Low Resources | Failed to resolve");
|
SysPushErrorNet("Low Resources | Failed to resolve");
|
||||||
|
this->uOsError = iStatus;
|
||||||
|
this->error_ = this->ToError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case EAI_MEMORY:
|
case EAI_MEMORY:
|
||||||
{
|
{
|
||||||
SysPushErrorNet("Out of Memory | Failed to resolve");
|
SysPushErrorNet("Out of Memory | Failed to resolve");
|
||||||
|
this->uOsError = iStatus;
|
||||||
|
this->error_ = this->ToError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case EAI_SYSTEM:
|
case EAI_SYSTEM:
|
||||||
{
|
{
|
||||||
SysPushErrorNet("Invalid | Failed to resolve");
|
SysPushErrorNet("Invalid | Failed to resolve: {}", errno);
|
||||||
|
this->uOsError = errno;
|
||||||
|
this->error_ = this->ToError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,12 +209,87 @@ namespace Aurora::IO::Net
|
|||||||
if (iStatus != 0)
|
if (iStatus != 0)
|
||||||
{
|
{
|
||||||
SysPushErrorNet("{}", iStatus);
|
SysPushErrorNet("{}", iStatus);
|
||||||
|
this->uOsError = iStatus;
|
||||||
|
this->error_ = this->ToError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->BeginOperation(AuSharedFromThis(),
|
return this->BeginOperation(AuSharedFromThis(),
|
||||||
this->pWorker_);
|
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)
|
void NetResolver::SetCompletion(const AuSPtr<AuAsync::PromiseCallback<AuList<IPAddress>, NetError>> &callback)
|
||||||
@ -282,28 +377,58 @@ namespace Aurora::IO::Net
|
|||||||
|
|
||||||
bool NetResolver::CheckAsync()
|
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) ||
|
return ((iStatus == 0) ||
|
||||||
(iStatus == EAI_CANCELED));
|
(iStatus == EAI_CANCELED));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return !this->bForceError_;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetResolver::Cancel()
|
void NetResolver::Cancel()
|
||||||
{
|
{
|
||||||
while (!this->HasComplete())
|
while (!this->HasComplete())
|
||||||
{
|
{
|
||||||
int iStatus = ::gai_cancel(&this->gnuAsyncOperation);
|
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||||
switch (iStatus)
|
|
||||||
|
if (pgai_cancel)
|
||||||
{
|
{
|
||||||
case EAI_CANCELED:
|
int iStatus = pgai_cancel(&this->gnuAsyncOperation);
|
||||||
case EAI_ALLDONE:
|
switch (iStatus)
|
||||||
break;
|
|
||||||
case EAI_NOTCANCELED:
|
|
||||||
{
|
{
|
||||||
IOYield();
|
case EAI_CANCELED:
|
||||||
AuThreading::ContextYield();
|
case EAI_ALLDONE:
|
||||||
continue;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(pItr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||||
|
|
||||||
static void Annoying(int)
|
static void Annoying(int)
|
||||||
{
|
{
|
||||||
for (const auto &gawad : tlsResolvers)
|
for (const auto &gawad : tlsResolvers)
|
||||||
@ -350,15 +479,21 @@ namespace Aurora::IO::Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void InitFreetardedResolver()
|
void InitFreetardedResolver()
|
||||||
{
|
{
|
||||||
|
#if defined(AURORA_HAS_GLIBC_RESOLVER_PROXY_STUBS)
|
||||||
|
|
||||||
struct sigaction action =
|
struct sigaction action =
|
||||||
{
|
{
|
||||||
.sa_handler = Annoying,
|
.sa_handler = Annoying,
|
||||||
.sa_flags = SA_ONSTACK
|
.sa_flags = SA_ONSTACK | SA_RESTART
|
||||||
};
|
};
|
||||||
|
|
||||||
::sigemptyset(&action.sa_mask);
|
::sigemptyset(&action.sa_mask);
|
||||||
::sigaction(GetGAIAsyncIOSignal(), &action, nullptr);
|
::sigaction(GetGAIAsyncIOSignal(), &action, nullptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,27 @@
|
|||||||
#include "AuNetSocketOverlappedOperation.hpp"
|
#include "AuNetSocketOverlappedOperation.hpp"
|
||||||
#include "AuNetSocket.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
|
namespace Aurora::IO::Net
|
||||||
{
|
{
|
||||||
struct Socket;
|
struct Socket;
|
||||||
@ -30,6 +51,7 @@ namespace Aurora::IO::Net
|
|||||||
AuString hostname;
|
AuString hostname;
|
||||||
|
|
||||||
bool Start();
|
bool Start();
|
||||||
|
bool StartStandard();
|
||||||
|
|
||||||
void SetCompletion(const AuSPtr<AuAsync::PromiseCallback<AuList<IPAddress>, NetError>> &callback);
|
void SetCompletion(const AuSPtr<AuAsync::PromiseCallback<AuList<IPAddress>, NetError>> &callback);
|
||||||
|
|
||||||
@ -52,10 +74,9 @@ namespace Aurora::IO::Net
|
|||||||
bool bHasCompleted_ {};
|
bool bHasCompleted_ {};
|
||||||
bool bHasUnpackedEarly {};
|
bool bHasUnpackedEarly {};
|
||||||
NetError error_;
|
NetError error_;
|
||||||
|
addrinfo infoEx { };
|
||||||
addrinfo infoEx { 0 };
|
bool bForceError_ {};
|
||||||
|
glibc_aicb gnuAsyncOperation {}; // freetarded
|
||||||
gaicb gnuAsyncOperation {}; // freetarded
|
|
||||||
bool CheckAsync();
|
bool CheckAsync();
|
||||||
friend struct ThreadLocalCaughtCompletion;
|
friend struct ThreadLocalCaughtCompletion;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user