mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
resolver: Clean up and simplify gethostbyname/gethostbyaddr/getnameinfo
This commit is contained in:
parent
af4a025e9b
commit
f062c6ecab
@ -77,7 +77,7 @@ Result resolverRemoveIpAddressFromCache(u32 ip) {
|
|||||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); // not implemented
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); // not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hostent *_resolverDeserializeHostent(int *err, const void *out_he_serialized) {
|
static struct hostent *_resolverDeserializeHostent(const void *out_he_serialized) {
|
||||||
const char *buf = (const char *)out_he_serialized;
|
const char *buf = (const char *)out_he_serialized;
|
||||||
const char *pos, *pos_aliases, *pos_addresses;
|
const char *pos, *pos_aliases, *pos_addresses;
|
||||||
size_t name_size, total_aliases_size = 0;
|
size_t name_size, total_aliases_size = 0;
|
||||||
@ -114,7 +114,8 @@ static struct hostent *_resolverDeserializeHostent(int *err, const void *out_he_
|
|||||||
|
|
||||||
// sfdnsres will only return IPv4 addresses for the "host" commands
|
// sfdnsres will only return IPv4 addresses for the "host" commands
|
||||||
if (addrtype != AF_INET || addrlen != sizeof(struct in_addr)) {
|
if (addrtype != AF_INET || addrlen != sizeof(struct in_addr)) {
|
||||||
*err = NO_ADDRESS;
|
h_errno = NO_ADDRESS;
|
||||||
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +135,8 @@ static struct hostent *_resolverDeserializeHostent(int *err, const void *out_he_
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!he) {
|
if (!he) {
|
||||||
*err = NO_RECOVERY;
|
h_errno = NETDB_INTERNAL;
|
||||||
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,111 +359,107 @@ void freeaddrinfo(struct addrinfo *ai) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct hostent *gethostbyname(const char *name) {
|
struct hostent *gethostbyname(const char *name) {
|
||||||
Result rc = 0;
|
if (!name) {
|
||||||
void *out_he_serialized = malloc(g_resolverHostByNameBufferSize);
|
h_errno = HOST_NOT_FOUND;
|
||||||
struct hostent *he = NULL;
|
errno = EINVAL;
|
||||||
u32 ret = 0;
|
return NULL;
|
||||||
u32 errno_ = 0;
|
|
||||||
|
|
||||||
if(out_he_serialized == NULL) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = ENOMEM; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
rc = sfdnsresGetHostByNameRequest(
|
|
||||||
|
if (!g_resolverHostByNameBufferSize) {
|
||||||
|
h_errno = NETDB_INTERNAL;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *out_serialized = malloc(g_resolverHostByNameBufferSize);
|
||||||
|
if (!out_serialized) {
|
||||||
|
h_errno = NETDB_INTERNAL;
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc = sfdnsresGetHostByNameRequest(
|
||||||
g_resolverCancelHandle,
|
g_resolverCancelHandle,
|
||||||
!g_resolverDisableServiceDiscovery,
|
!g_resolverDisableServiceDiscovery,
|
||||||
name,
|
name,
|
||||||
&ret,
|
(u32*)&h_errno,
|
||||||
&errno_,
|
(u32*)&errno,
|
||||||
out_he_serialized, g_resolverHostByNameBufferSize,
|
out_serialized, g_resolverHostByNameBufferSize,
|
||||||
NULL);
|
NULL);
|
||||||
g_resolverCancelHandle = 0;
|
g_resolverCancelHandle = 0;
|
||||||
|
|
||||||
if(rc == 0xD401) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = EFAULT; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel
|
|
||||||
h_errno = TRY_AGAIN;
|
|
||||||
errno = EAGAIN; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else if(R_FAILED(rc)) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = EINVAL; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if(ret != NETDB_SUCCESS) {
|
|
||||||
h_errno = ret;
|
|
||||||
errno = errno_; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
he = _resolverDeserializeHostent(&h_errno, out_he_serialized);
|
|
||||||
if(he == NULL) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = ENOMEM; // POSIX leaves this unspecified
|
|
||||||
}
|
|
||||||
cleanup:
|
|
||||||
g_resolverResult = rc;
|
g_resolverResult = rc;
|
||||||
free(out_he_serialized);
|
|
||||||
return he;
|
if (R_FAILED(rc)) {
|
||||||
|
if (R_MODULE(rc) == 21) // SM
|
||||||
|
errno = EAGAIN;
|
||||||
|
else if (R_MODULE(rc) == 1) // Kernel
|
||||||
|
errno = EFAULT;
|
||||||
|
else
|
||||||
|
errno = EPIPE;
|
||||||
|
h_errno = NETDB_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hostent *ret = NULL;
|
||||||
|
if (h_errno == NETDB_SUCCESS)
|
||||||
|
ret = _resolverDeserializeHostent(out_serialized);
|
||||||
|
|
||||||
|
free(out_serialized);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
|
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
|
||||||
Result rc = 0;
|
if (!addr || !len) {
|
||||||
void *out_he_serialized = malloc(g_resolverHostByAddrBufferSize);
|
h_errno = HOST_NOT_FOUND;
|
||||||
struct hostent *he = NULL;
|
errno = EINVAL;
|
||||||
u32 ret = 0;
|
return NULL;
|
||||||
u32 errno_ = 0;
|
|
||||||
|
|
||||||
if(out_he_serialized == NULL) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = ENOMEM; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
rc = sfdnsresGetHostByAddrRequest(
|
|
||||||
|
if (type != AF_INET) {
|
||||||
|
h_errno = HOST_NOT_FOUND;
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_resolverHostByAddrBufferSize) {
|
||||||
|
h_errno = NETDB_INTERNAL;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *out_serialized = malloc(g_resolverHostByAddrBufferSize);
|
||||||
|
if (!out_serialized) {
|
||||||
|
h_errno = NETDB_INTERNAL;
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc = sfdnsresGetHostByAddrRequest(
|
||||||
addr, len,
|
addr, len,
|
||||||
type,
|
type,
|
||||||
g_resolverCancelHandle,
|
g_resolverCancelHandle,
|
||||||
&ret,
|
(void*)&h_errno,
|
||||||
&errno_,
|
(void*)&errno,
|
||||||
out_he_serialized, g_resolverHostByAddrBufferSize,
|
out_serialized, g_resolverHostByAddrBufferSize,
|
||||||
NULL);
|
NULL);
|
||||||
g_resolverCancelHandle = 0;
|
g_resolverCancelHandle = 0;
|
||||||
|
|
||||||
if(rc == 0xD401) {
|
|
||||||
h_errno = NO_RECOVERY; // POSIX leaves this unspecified
|
|
||||||
errno = EFAULT;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel
|
|
||||||
h_errno = TRY_AGAIN;
|
|
||||||
errno = EAGAIN; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else if(R_FAILED(rc)) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = EINVAL; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if(ret != NETDB_SUCCESS) {
|
|
||||||
h_errno = ret;
|
|
||||||
errno = errno_; // POSIX leaves this unspecified
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
he = _resolverDeserializeHostent(&h_errno, out_he_serialized);
|
|
||||||
if(he == NULL) {
|
|
||||||
h_errno = NO_RECOVERY;
|
|
||||||
errno = ENOMEM; // POSIX leaves this unspecified
|
|
||||||
}
|
|
||||||
cleanup:
|
|
||||||
g_resolverResult = rc;
|
g_resolverResult = rc;
|
||||||
free(out_he_serialized);
|
|
||||||
return he;
|
if (R_FAILED(rc)) {
|
||||||
|
if (R_MODULE(rc) == 21) // SM
|
||||||
|
errno = EAGAIN;
|
||||||
|
else if (R_MODULE(rc) == 1) // Kernel
|
||||||
|
errno = EFAULT;
|
||||||
|
else
|
||||||
|
errno = EPIPE;
|
||||||
|
h_errno = NETDB_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hostent *ret = NULL;
|
||||||
|
if (h_errno == NETDB_SUCCESS)
|
||||||
|
ret = _resolverDeserializeHostent(out_serialized);
|
||||||
|
|
||||||
|
free(out_serialized);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *hstrerror(int err) {
|
const char *hstrerror(int err) {
|
||||||
@ -517,7 +515,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi
|
|||||||
return EAI_FAIL;
|
return EAI_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 gaie = 0;
|
s32 ret = 0;
|
||||||
Result rc = sfdnsresGetAddrInfoRequest(
|
Result rc = sfdnsresGetAddrInfoRequest(
|
||||||
g_resolverCancelHandle,
|
g_resolverCancelHandle,
|
||||||
!g_resolverDisableServiceDiscovery,
|
!g_resolverDisableServiceDiscovery,
|
||||||
@ -526,7 +524,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi
|
|||||||
hints_serialized, hints_sz,
|
hints_serialized, hints_sz,
|
||||||
out_serialized, g_resolverAddrInfoBufferSize,
|
out_serialized, g_resolverAddrInfoBufferSize,
|
||||||
(u32*)&errno,
|
(u32*)&errno,
|
||||||
&gaie,
|
&ret,
|
||||||
NULL);
|
NULL);
|
||||||
g_resolverResult = rc;
|
g_resolverResult = rc;
|
||||||
g_resolverCancelHandle = 0;
|
g_resolverCancelHandle = 0;
|
||||||
@ -539,61 +537,48 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi
|
|||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
else
|
else
|
||||||
errno = EPIPE;
|
errno = EPIPE;
|
||||||
gaie = EAI_SYSTEM;
|
ret = EAI_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gaie == 0) {
|
if (ret == 0) {
|
||||||
*res = _resolverDeserializeAddrInfoList(out_serialized);
|
*res = _resolverDeserializeAddrInfoList(out_serialized);
|
||||||
if (!*res) {
|
if (!*res) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
gaie = EAI_MEMORY;
|
ret = EAI_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(out_serialized);
|
free(out_serialized);
|
||||||
return gaie;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||||
char *host, socklen_t hostlen,
|
char *host, socklen_t hostlen,
|
||||||
char *serv, socklen_t servlen,
|
char *serv, socklen_t servlen,
|
||||||
int flags) {
|
int flags) {
|
||||||
Result rc = 0;
|
s32 ret = 0;
|
||||||
u32 errno_ = 0;
|
Result rc = sfdnsresGetNameInfoRequest(
|
||||||
s32 gaie = 0;
|
|
||||||
|
|
||||||
rc = sfdnsresGetNameInfoRequest(
|
|
||||||
flags,
|
flags,
|
||||||
sa, salen,
|
sa, salen,
|
||||||
host, hostlen,
|
host, hostlen,
|
||||||
serv, servlen,
|
serv, servlen,
|
||||||
g_resolverCancelHandle,
|
g_resolverCancelHandle,
|
||||||
&errno_,
|
(u32*)&errno,
|
||||||
&gaie);
|
&ret);
|
||||||
|
g_resolverResult = rc;
|
||||||
g_resolverCancelHandle = 0;
|
g_resolverCancelHandle = 0;
|
||||||
|
|
||||||
if(rc == 0xD401) {
|
if (R_FAILED(rc)) {
|
||||||
gaie = EAI_SYSTEM;
|
if (R_MODULE(rc) == 21) // SM
|
||||||
|
errno = EAGAIN;
|
||||||
|
else if (R_MODULE(rc) == 1) // Kernel
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
goto cleanup;
|
else
|
||||||
}
|
errno = EPIPE;
|
||||||
else if(R_FAILED(rc) && R_MODULE(rc) == 1) { // Kernel
|
ret = EAI_SYSTEM;
|
||||||
gaie = EAI_AGAIN;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else if(R_FAILED(rc)) {
|
|
||||||
gaie = EAI_FAIL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gaie != 0) {
|
return ret;
|
||||||
if(gaie == EAI_SYSTEM)
|
|
||||||
errno = errno_;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
g_resolverResult = rc;
|
|
||||||
return gaie;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long gethostid(void) {
|
long gethostid(void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user