mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Add sfdnsres
This commit is contained in:
parent
6884a9dd19
commit
b8fb1722d0
@ -9,7 +9,6 @@
|
||||
#include "../types.h"
|
||||
#include "../kernel/tmem.h"
|
||||
|
||||
#include <sys/types.h> // for ssize_t, etc.
|
||||
#include <sys/socket.h> // for socklen_t
|
||||
#include <sys/select.h> // for fd_set
|
||||
#include <poll.h> // for struct pollfd, ndfs_t
|
||||
|
40
nx/include/switch/services/sfdnsres.h
Normal file
40
nx/include/switch/services/sfdnsres.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
|
||||
#include <sys/socket.h> // For socklen_t, etc.
|
||||
|
||||
/// Configuration structure for sfdnsres.
|
||||
typedef struct {
|
||||
size_t serialized_out_addrinfos_max_size; ///< For getaddrinfo.
|
||||
size_t serialized_out_hostent_max_size; ///< For gethostbyname/gethostbyaddr.
|
||||
bool bypass_nsd; ///< For DNS requests: bypass the Name Server Daemon.
|
||||
int timeout; ///< For DNS requests: timeout or 0.
|
||||
} SfdnsresConfig;
|
||||
|
||||
/// Result values returned by the DNS request commands.
|
||||
typedef struct {
|
||||
int ret; ///< Return value (error code).
|
||||
int errno_; ///< Errno.
|
||||
ssize_t out_serialized_size; ///< Size of the serialized output buffer or -1 (?).
|
||||
} SfdnsresRequestResults;
|
||||
|
||||
// SetDnsAddressesPrivate & GetDnsAddressPrivate are stubbed
|
||||
|
||||
Result sfdnsresGetHostByName(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const char *name);
|
||||
Result sfdnsresGetHostByAddr(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const void *addr, socklen_t len, int type);
|
||||
|
||||
Result sfdnsresGetHostStringError(char *str, size_t str_size);
|
||||
Result sfdnsresGetGaiStringError(char *str, size_t str_size);
|
||||
|
||||
Result sfdnsresGetAddrInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config, const char *node, const char *service,
|
||||
const void *hints_serialized, size_t hints_serialized_size, void *res_serialized);
|
||||
Result sfdnsresGetNameInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config,
|
||||
const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen,
|
||||
char *serv, size_t servlen, int flags);
|
||||
|
||||
Result sfdnsresRequestCancelHandle(u32 *out_handle);
|
||||
/// Bug: always sets errno ?
|
||||
Result sfdnsresCancelSocketCall(SfdnsresRequestResults *ret, u32 handle);
|
||||
/// Bug: always sets errno ?
|
||||
Result sfdnsresCancelAllSocketCalls(SfdnsresRequestResults *ret);
|
||||
Result sfdnsresClearDnsIpServerAddressArray(void);
|
@ -53,7 +53,7 @@
|
||||
*/
|
||||
|
||||
// Stripped some of them
|
||||
|
||||
#include <sys/types.h> // for ssize_t, etc.
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _SA_FAMILY_T_DECLARED
|
||||
|
282
nx/source/services/sfdnsres.c
Normal file
282
nx/source/services/sfdnsres.c
Normal file
@ -0,0 +1,282 @@
|
||||
#include "types.h"
|
||||
#include "result.h"
|
||||
#include "ipc.h"
|
||||
#include "services/sm.h"
|
||||
#include "services/sfdnsres.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static Result _sfdnsresDispatchCommand(IpcParsedCommand *r, IpcCommand *c, const void *raw, size_t raw_size) {
|
||||
Service sfdnsres;
|
||||
|
||||
Result rc = smGetService(&sfdnsres, "sfdnsres");
|
||||
if(R_FAILED(rc)) goto cleanup;
|
||||
|
||||
memcpy(ipcPrepareHeader(c, raw_size), raw, raw_size);
|
||||
|
||||
rc = serviceIpcDispatch(&sfdnsres);
|
||||
if(R_FAILED(rc)) goto cleanup;
|
||||
|
||||
ipcParse(r);
|
||||
|
||||
cleanup:
|
||||
serviceClose(&sfdnsres);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _sfdnsresDnsRequestCommand(IpcCommand *c, u64 cmd_id, SfdnsresRequestResults *ret, const SfdnsresConfig *config, bool has_serialized_data_out, int *arg) {
|
||||
Result rc;
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
int arg;
|
||||
int timeout;
|
||||
u64 pid_placeholder;
|
||||
} raw;
|
||||
|
||||
ipcSendPid(c);
|
||||
|
||||
raw.magic = SFCI_MAGIC;
|
||||
raw.cmd_id = cmd_id;
|
||||
raw.arg = arg == NULL ? (config->bypass_nsd ? 0 : 1) : *arg;
|
||||
raw.timeout = config->timeout;
|
||||
raw.pid_placeholder = 0;
|
||||
|
||||
rc = _sfdnsresDispatchCommand(&r, c, &raw, sizeof(raw));
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
int ret;
|
||||
int errno_;
|
||||
int out_serialized_size; // OOB if !has_serialized_data
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
ret->ret = resp->ret;
|
||||
ret->errno_ = resp->errno_;
|
||||
ret->out_serialized_size = has_serialized_data_out ? resp->out_serialized_size : 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _sfdnsresErrorStringGetterCommand(u64 cmd_id, char *str, size_t str_size) {
|
||||
IpcCommand c;
|
||||
Result rc;
|
||||
IpcParsedCommand r;
|
||||
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvBuffer(&c, str, str_size, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} raw;
|
||||
|
||||
raw.magic = SFCI_MAGIC;
|
||||
raw.cmd_id = cmd_id;
|
||||
|
||||
rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw));
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result sfdnsresGetHostByName(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const char *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendBuffer(&c, name, strlen(name) + 1, 0);
|
||||
|
||||
ipcAddRecvBuffer(&c, out_he_serialized, config->serialized_out_hostent_max_size, 0);
|
||||
|
||||
return _sfdnsresDnsRequestCommand(&c, 2, ret, config, true, NULL);
|
||||
}
|
||||
|
||||
Result sfdnsresGetHostByAddr(SfdnsresRequestResults *ret, const SfdnsresConfig *config, void *out_he_serialized, const void *addr, socklen_t len, int type) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvBuffer(&c, out_he_serialized, config->serialized_out_hostent_max_size, 0);
|
||||
|
||||
return _sfdnsresDnsRequestCommand(&c, 3, ret, config, true, &type);
|
||||
}
|
||||
|
||||
Result sfdnsresGetHostStringError(char *str, size_t str_size) {
|
||||
return _sfdnsresErrorStringGetterCommand(4, str, str_size);
|
||||
}
|
||||
|
||||
Result sfdnsresGetGaiStringError(char *str, size_t str_size) {
|
||||
return _sfdnsresErrorStringGetterCommand(5, str, str_size);
|
||||
}
|
||||
|
||||
Result sfdnsresGetAddrInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config, const char *node, const char *service,
|
||||
const void *hints_serialized, size_t hints_serialized_size, void *res_serialized) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
ipcAddSendBuffer(&c, node, strlen(node) + 1, 0);
|
||||
ipcAddSendBuffer(&c, node, strlen(service) + 1, 0);
|
||||
ipcAddSendBuffer(&c, hints_serialized, hints_serialized_size, 0);
|
||||
|
||||
ipcAddRecvBuffer(&c, res_serialized, config->serialized_out_hostent_max_size, 0);
|
||||
|
||||
return _sfdnsresDnsRequestCommand(&c, 6, ret, config, true, NULL);
|
||||
}
|
||||
|
||||
Result sfdnsresGetNameInfo(SfdnsresRequestResults *ret, const SfdnsresConfig *config,
|
||||
const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen,
|
||||
char *serv, size_t servlen, int flags) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendBuffer(&c, sa, salen, 0);
|
||||
|
||||
ipcAddRecvBuffer(&c, host, hostlen, 0);
|
||||
ipcAddRecvBuffer(&c, serv, servlen, 0);
|
||||
|
||||
return _sfdnsresDnsRequestCommand(&c, 7, ret, config, false, &flags);
|
||||
}
|
||||
|
||||
Result sfdnsresRequestCancelHandle(u32 *out_handle) {
|
||||
Result rc;
|
||||
IpcCommand c;
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 pid_placeholder;
|
||||
} raw;
|
||||
|
||||
ipcInitialize(&c);
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw.magic = SFCI_MAGIC;
|
||||
raw.cmd_id = 8;
|
||||
raw.pid_placeholder = 0;
|
||||
|
||||
rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw));
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 handle;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
*out_handle = resp->handle;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/// Bug: always sets errno ?
|
||||
Result sfdnsresCancelSocketCall(SfdnsresRequestResults *ret, u32 handle) {
|
||||
Result rc;
|
||||
IpcCommand c;
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 handle;
|
||||
u64 pid_placeholder;
|
||||
} raw;
|
||||
|
||||
ipcInitialize(&c);
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw.magic = SFCI_MAGIC;
|
||||
raw.cmd_id = 9;
|
||||
raw.handle = handle;
|
||||
raw.pid_placeholder = 0;
|
||||
|
||||
rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw));
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
int ret;
|
||||
int errno_;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
ret->ret = resp->ret;
|
||||
ret->errno_ = resp->errno_;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/// Bug: always sets errno ?
|
||||
Result sfdnsresCancelAllSocketCalls(SfdnsresRequestResults *ret) {
|
||||
Result rc;
|
||||
IpcCommand c;
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 pid_placeholder;
|
||||
} raw;
|
||||
|
||||
ipcInitialize(&c);
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw.magic = SFCI_MAGIC;
|
||||
raw.cmd_id = 10;
|
||||
raw.pid_placeholder = 0;
|
||||
|
||||
rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw));
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
int ret;
|
||||
int errno_;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
ret->ret = resp->ret;
|
||||
ret->errno_ = resp->errno_;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result sfdnsresClearDnsIpServerAddressArray(void) {
|
||||
Result rc;
|
||||
IpcCommand c;
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} raw;
|
||||
|
||||
ipcInitialize(&c);
|
||||
|
||||
raw.magic = SFCI_MAGIC;
|
||||
raw.cmd_id = 11;
|
||||
|
||||
rc = _sfdnsresDispatchCommand(&r, &c, &raw, sizeof(raw));
|
||||
if(R_FAILED(rc)) return rc;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
return rc;
|
||||
}
|
Loading…
Reference in New Issue
Block a user