Net: Fix various socket-related issues (#3347)

* Store platform-specific level in a separate variable

So the level logged in the getsockopt/setsockopt unreachable is actually useful in cases where the level is unknown.

* Define ORBIS_NET_IPPROTO_IPV6

Not implemented yet, but since it's known we might as well add it.

* Fix error codes

Our libSceNet code expects accurate ORBIS_NET_E* errors, while the sys_net code returns ORBIS_NET_ERROR_* errors.

* Remove duplicate getsockname implementation

* Use separate mutex for ReceivePacket calls

Calls to ReceivePacket shouldn't block other socket functions, and allowing them to block these functions frequently causes deadlocks in games that use multiple threads for socket behaviors.
That said, concurrent receives are still a potential issue, so the function should still have a mutex.

* Add missing error codes

* Clang

* Minor nit

Not sure why these were left separate from the rest of the net errnos

* Set __Error() in ConvertReturnErrorCode

Because the new error values are positive, the logic of "negative return is an error" doesn't work anymore. The easiest fix, while retaining corrected error values, is to just set __Error() in ConvertReturnErrorCode, and have that return -1 instead.
I also added some formatting fixes here too.

* Set errno on stubbed P2P socket error returns.

Otherwise the errno is just whatever was set by a previous failing function, which may cause issues in some games.
I used EAGAIN here since it appears to be valid for all three of these functions, but this can be changed if requested.

* Fix missed error returns

* Fix socket methods in file_system

Missed these
This commit is contained in:
Stephen Miller
2025-07-30 13:54:28 -05:00
committed by GitHub
parent f685233401
commit 6c34b86add
8 changed files with 79 additions and 82 deletions

View File

@@ -298,12 +298,8 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, size_t nbytes) {
}
return result;
} else if (file->type == Core::FileSys::FileType::Socket) {
s64 result = file->socket->SendPacket(buf, nbytes, 0, nullptr, 0);
if (result < 0) {
ErrSceToPosix(result);
return -1;
}
return result;
// Socket functions handle errnos internally.
return file->socket->SendPacket(buf, nbytes, 0, nullptr, 0);
}
return file->f.WriteRaw<u8>(buf, nbytes);
@@ -486,12 +482,8 @@ s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) {
}
return result;
} else if (file->type == Core::FileSys::FileType::Socket) {
s64 result = file->socket->ReceivePacket(buf, nbytes, 0, nullptr, 0);
if (result < 0) {
ErrSceToPosix(result);
return -1;
}
return result;
// Socket functions handle errnos internally.
return file->socket->ReceivePacket(buf, nbytes, 0, nullptr, 0);
}
return ReadFile(file->f, buf, nbytes);
}
@@ -685,12 +677,8 @@ s32 PS4_SYSV_ABI fstat(s32 fd, OrbisKernelStat* sb) {
break;
}
case Core::FileSys::FileType::Socket: {
s32 result = file->socket->fstat(sb);
if (result < 0) {
ErrSceToPosix(result);
return -1;
}
return result;
// Socket functions handle errnos internally
return file->socket->fstat(sb);
}
default:
UNREACHABLE();

View File

@@ -220,26 +220,6 @@ s32 PS4_SYSV_ABI posix_getpagesize() {
return 16_KB;
}
s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) {
LOG_INFO(Lib_Kernel, "s = {}", s);
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto file = h->GetSocket(s);
if (!file) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1;
}
s32 returncode = file->socket->GetSocketAddress(addr, paddrlen);
if (returncode >= 0) {
LOG_ERROR(Lib_Net, "return code : {:#x}", (u32)returncode);
return 0;
}
*Libraries::Kernel::__Error() = 0x20;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
return -1;
}
// stubbed on non-devkit consoles
s32 PS4_SYSV_ABI sceKernelGetGPI() {
LOG_DEBUG(Kernel, "called");
@@ -308,7 +288,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
Libraries::Net::sys_getsockopt);
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sys_setsockopt);
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1, posix_getsockname);
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sys_getsockname);
LIB_FUNCTION("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...