Lib.Net: Proper resolver errors when isConnectedToNetwork is disabled (#4081)

* Force resolver errors when not connected to network

Error values are based on real hardware testing.
sceNetResolverGetError is based on libSceNet decompilation.

* Update net_resolver.h
This commit is contained in:
Stephen Miller 2026-02-27 16:50:41 -06:00 committed by GitHub
parent 19d2027105
commit 8bb29695ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 5 deletions

View File

@ -887,6 +887,10 @@ int PS4_SYSV_ABI sceNetEpollWait(OrbisNetId epollid, OrbisNetEpollEvent* events,
}
file->resolver->Resolve();
if (file->resolver->resolution_error != ORBIS_OK) {
// Resolution failed, shouldn't appear.
continue;
}
const auto it =
std::ranges::find_if(epoll->events, [&](auto& el) { return el.first == rid; });
@ -1402,8 +1406,21 @@ int PS4_SYSV_ABI sceNetResolverDestroy(OrbisNetId resolverid) {
}
int PS4_SYSV_ABI sceNetResolverGetError(OrbisNetId resolverid, s32* status) {
LOG_ERROR(Lib_Net, "(STUBBED) called rid = {}", resolverid);
*status = 0;
if (!status) {
LOG_ERROR(Lib_Net, "status == nullptr");
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
return ORBIS_NET_ERROR_EINVAL;
}
auto file = FDTable::Instance()->GetResolver(resolverid);
if (!file) {
LOG_ERROR(Lib_Net, "invalid resolverid {}", resolverid);
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
return ORBIS_NET_ERROR_EBADF;
}
*status = file->resolver->resolution_error;
LOG_INFO(Lib_Net, "called rid = {}, error = {:#x}", resolverid, static_cast<u32>(*status));
return ORBIS_OK;
}
@ -1425,10 +1442,17 @@ int PS4_SYSV_ABI sceNetResolverStartNtoa(OrbisNetId resolverid, const char* host
auto file = FDTable::Instance()->GetResolver(resolverid);
if (!file) {
LOG_ERROR(Lib_Net, "invalid resolverid {}", resolverid);
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
return ORBIS_NET_ERROR_EBADF;
}
if (!Config::getIsConnectedToNetwork()) {
*sceNetErrnoLoc() = ORBIS_NET_RESOLVER_ENODNS;
file->resolver->resolution_error = ORBIS_NET_ERROR_RESOLVER_ENODNS;
return ORBIS_NET_ERROR_RESOLVER_ENODNS;
}
if ((flags & ORBIS_NET_RESOLVER_ASYNC) != 0) {
return file->resolver->ResolveAsync(hostname, addr, timeout, retry, flags);
}

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h"
#include "common/config.h"
#include "common/singleton.h"
#include "common/types.h"
#include "core/libraries/error_codes.h"
@ -26,11 +27,16 @@ int Resolver::ResolveAsync(const char* hostname, OrbisNetInAddr* addr, int timeo
}
void Resolver::Resolve() {
if (!Config::getIsConnectedToNetwork()) {
resolution_error = ORBIS_NET_ERROR_RESOLVER_ENODNS;
return;
}
if (async_resolution) {
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
auto ret = netinfo->ResolveHostname(async_resolution->hostname, async_resolution->addr);
resolution_error = ret;
// Resolver errors are stored as ORBIS_NET_ERROR values.
resolution_error = -ret | ORBIS_NET_ERROR_BASE;
} else {
LOG_ERROR(Lib_Net, "async resolution has not been set-up");
}

View File

@ -18,6 +18,8 @@ public:
int ResolveAsync(const char* hostname, OrbisNetInAddr* addr, int timeout, int retry, int flags);
void Resolve();
int resolution_error = ORBIS_OK;
private:
struct AsyncResolution {
const char* hostname;
@ -31,7 +33,6 @@ private:
int poolid;
int flags;
std::optional<AsyncResolution> async_resolution{};
int resolution_error = ORBIS_OK;
std::mutex m_mutex;
};