diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 6df4f2f40..bbdf0338c 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -1388,12 +1388,12 @@ int PS4_SYSV_ABI sceNetResolverConnectDestroy() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetResolverCreate() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); +int PS4_SYSV_ABI sceNetResolverCreate(const char* name, int poolid, int flags) { + LOG_ERROR(Lib_Net, "(STUBBED) called, name = {}, poolid = {}, flags = {}", name, poolid, flags); return ORBIS_OK; } -int PS4_SYSV_ABI sceNetResolverDestroy() { +int PS4_SYSV_ABI sceNetResolverDestroy(OrbisNetId resolverid) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } @@ -1413,9 +1413,41 @@ int PS4_SYSV_ABI sceNetResolverStartAton6() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetResolverStartNtoa() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceNetResolverStartNtoa(OrbisNetId resolverid, const char* hostname, + OrbisNetInAddr* addr, int timeout, int retry, int flags) { + LOG_INFO(Lib_Net, + "called, resolverid = {}, hostname = {}, timeout = {}, retry = {}, flags = {}", + resolverid, hostname, timeout, retry, flags); + + if ((flags & ORBIS_NET_RESOLVER_ASYNC) != 0) { + // moves processing to EpollWait + UNREACHABLE_MSG("unimplemented"); + } + + const addrinfo hints = { + .ai_flags = AI_V4MAPPED | AI_ADDRCONFIG, + .ai_family = AF_INET, + }; + + addrinfo* info = nullptr; + auto gai_result = getaddrinfo(hostname, nullptr, &hints, &info); + + auto ret = ORBIS_OK; + if (gai_result != 0) { + // handle more errors + LOG_ERROR(Lib_Net, "address resolution for {} failed: {}", hostname, + gai_strerror(gai_result)); + *sceNetErrnoLoc() = ORBIS_NET_ERETURN; + ret = -ORBIS_NET_ERETURN | ORBIS_NET_ERROR_BASE; + } else { + ASSERT(info && info->ai_addr); + in_addr resolved_addr = ((sockaddr_in*)info->ai_addr)->sin_addr; + LOG_DEBUG(Lib_Net, "resolved address for {}: {}", hostname, inet_ntoa(resolved_addr)); + addr->s_addr = resolved_addr.s_addr; + } + + freeaddrinfo(info); + return ret; } int PS4_SYSV_ABI sceNetResolverStartNtoa6() { diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index a0a96c891..626719328 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -95,6 +95,11 @@ enum OrbisNetEpollEvents : u32 { ORBIS_NET_EPOLLDESCID = 0x10000, }; +enum OrbisNetResolverFlag : u32 { + ORBIS_NET_RESOLVER_ASYNC = 0x1, + ORBIS_NET_RESOLVER_START_NTOA_DISABLE_IPADDRESS = 0x10000, +}; + using OrbisNetId = s32; struct OrbisNetSockaddr { @@ -112,6 +117,12 @@ struct OrbisNetSockaddrIn { char sin_zero[6]; }; +using OrbisNetInAddr_t = u32; + +struct OrbisNetInAddr { + OrbisNetInAddr_t s_addr; +}; + struct OrbisNetIovec { void* iov_base; u64 iov_len; @@ -310,12 +321,13 @@ int PS4_SYSV_ABI sceNetResolverConnect(); int PS4_SYSV_ABI sceNetResolverConnectAbort(); int PS4_SYSV_ABI sceNetResolverConnectCreate(); int PS4_SYSV_ABI sceNetResolverConnectDestroy(); -int PS4_SYSV_ABI sceNetResolverCreate(); -int PS4_SYSV_ABI sceNetResolverDestroy(); +int PS4_SYSV_ABI sceNetResolverCreate(const char* name, int poolid, int flags); +int PS4_SYSV_ABI sceNetResolverDestroy(OrbisNetId resolverid); int PS4_SYSV_ABI sceNetResolverGetError(); int PS4_SYSV_ABI sceNetResolverStartAton(); int PS4_SYSV_ABI sceNetResolverStartAton6(); -int PS4_SYSV_ABI sceNetResolverStartNtoa(); +int PS4_SYSV_ABI sceNetResolverStartNtoa(OrbisNetId resolverid, const char* hostname, + OrbisNetInAddr* addr, int timeout, int retry, int flags); int PS4_SYSV_ABI sceNetResolverStartNtoa6(); int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecords(); int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx();