mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-03 07:52:31 +00:00
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:
parent
f685233401
commit
6c34b86add
@ -298,12 +298,8 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, size_t nbytes) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else if (file->type == Core::FileSys::FileType::Socket) {
|
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||||
s64 result = file->socket->SendPacket(buf, nbytes, 0, nullptr, 0);
|
// Socket functions handle errnos internally.
|
||||||
if (result < 0) {
|
return file->socket->SendPacket(buf, nbytes, 0, nullptr, 0);
|
||||||
ErrSceToPosix(result);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return file->f.WriteRaw<u8>(buf, nbytes);
|
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;
|
return result;
|
||||||
} else if (file->type == Core::FileSys::FileType::Socket) {
|
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||||
s64 result = file->socket->ReceivePacket(buf, nbytes, 0, nullptr, 0);
|
// Socket functions handle errnos internally.
|
||||||
if (result < 0) {
|
return file->socket->ReceivePacket(buf, nbytes, 0, nullptr, 0);
|
||||||
ErrSceToPosix(result);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return ReadFile(file->f, buf, nbytes);
|
return ReadFile(file->f, buf, nbytes);
|
||||||
}
|
}
|
||||||
@ -685,12 +677,8 @@ s32 PS4_SYSV_ABI fstat(s32 fd, OrbisKernelStat* sb) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Core::FileSys::FileType::Socket: {
|
case Core::FileSys::FileType::Socket: {
|
||||||
s32 result = file->socket->fstat(sb);
|
// Socket functions handle errnos internally
|
||||||
if (result < 0) {
|
return file->socket->fstat(sb);
|
||||||
ErrSceToPosix(result);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -220,26 +220,6 @@ s32 PS4_SYSV_ABI posix_getpagesize() {
|
|||||||
return 16_KB;
|
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
|
// stubbed on non-devkit consoles
|
||||||
s32 PS4_SYSV_ABI sceKernelGetGPI() {
|
s32 PS4_SYSV_ABI sceKernelGetGPI() {
|
||||||
LOG_DEBUG(Kernel, "called");
|
LOG_DEBUG(Kernel, "called");
|
||||||
@ -308,7 +288,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||||||
Libraries::Net::sys_getsockopt);
|
Libraries::Net::sys_getsockopt);
|
||||||
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
Libraries::Net::sys_setsockopt);
|
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("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
|
||||||
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
|
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
|
||||||
|
@ -40,6 +40,7 @@ enum OrbisNetProtocol : u32 {
|
|||||||
ORBIS_NET_IPPROTO_IGMP = 2,
|
ORBIS_NET_IPPROTO_IGMP = 2,
|
||||||
ORBIS_NET_IPPROTO_TCP = 6,
|
ORBIS_NET_IPPROTO_TCP = 6,
|
||||||
ORBIS_NET_IPPROTO_UDP = 17,
|
ORBIS_NET_IPPROTO_UDP = 17,
|
||||||
|
ORBIS_NET_IPPROTO_IPV6 = 41,
|
||||||
ORBIS_NET_SOL_SOCKET = 0xFFFF
|
ORBIS_NET_SOL_SOCKET = 0xFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ constexpr int ORBIS_NET_EPERM = 1;
|
|||||||
constexpr int ORBIS_NET_ENOENT = 2;
|
constexpr int ORBIS_NET_ENOENT = 2;
|
||||||
constexpr int ORBIS_NET_EINTR = 4;
|
constexpr int ORBIS_NET_EINTR = 4;
|
||||||
constexpr int ORBIS_NET_EBADF = 9;
|
constexpr int ORBIS_NET_EBADF = 9;
|
||||||
|
constexpr int ORBIS_NET_ENOMEM = 12;
|
||||||
constexpr int ORBIS_NET_EACCES = 13;
|
constexpr int ORBIS_NET_EACCES = 13;
|
||||||
constexpr int ORBIS_NET_EFAULT = 14;
|
constexpr int ORBIS_NET_EFAULT = 14;
|
||||||
constexpr int ORBIS_NET_ENOTBLK = 15;
|
constexpr int ORBIS_NET_ENOTBLK = 15;
|
||||||
@ -15,6 +16,7 @@ constexpr int ORBIS_NET_EBUSY = 16;
|
|||||||
constexpr int ORBIS_NET_EEXIST = 17;
|
constexpr int ORBIS_NET_EEXIST = 17;
|
||||||
constexpr int ORBIS_NET_ENODEV = 19;
|
constexpr int ORBIS_NET_ENODEV = 19;
|
||||||
constexpr int ORBIS_NET_EINVAL = 22;
|
constexpr int ORBIS_NET_EINVAL = 22;
|
||||||
|
constexpr int ORBIS_NET_ENFILE = 23;
|
||||||
constexpr int ORBIS_NET_EMFILE = 24;
|
constexpr int ORBIS_NET_EMFILE = 24;
|
||||||
constexpr int ORBIS_NET_ENOSPC = 28;
|
constexpr int ORBIS_NET_ENOSPC = 28;
|
||||||
constexpr int ORBIS_NET_EPIPE = 32;
|
constexpr int ORBIS_NET_EPIPE = 32;
|
||||||
@ -37,6 +39,7 @@ constexpr int ORBIS_NET_ENETUNREACH = 51;
|
|||||||
constexpr int ORBIS_NET_ENETRESET = 52;
|
constexpr int ORBIS_NET_ENETRESET = 52;
|
||||||
constexpr int ORBIS_NET_ECONNABORTED = 53;
|
constexpr int ORBIS_NET_ECONNABORTED = 53;
|
||||||
constexpr int ORBIS_NET_ECONNRESET = 54;
|
constexpr int ORBIS_NET_ECONNRESET = 54;
|
||||||
|
constexpr int ORBIS_NET_ENOBUFS = 55;
|
||||||
constexpr int ORBIS_NET_EISCONN = 56;
|
constexpr int ORBIS_NET_EISCONN = 56;
|
||||||
constexpr int ORBIS_NET_ENOTCONN = 57;
|
constexpr int ORBIS_NET_ENOTCONN = 57;
|
||||||
constexpr int ORBIS_NET_ETOOMANYREFS = 59;
|
constexpr int ORBIS_NET_ETOOMANYREFS = 59;
|
||||||
@ -48,6 +51,7 @@ constexpr int ORBIS_NET_EHOSTDOWN = 64;
|
|||||||
constexpr int ORBIS_NET_EHOSTUNREACH = 65;
|
constexpr int ORBIS_NET_EHOSTUNREACH = 65;
|
||||||
constexpr int ORBIS_NET_ENOTEMPTY = 66;
|
constexpr int ORBIS_NET_ENOTEMPTY = 66;
|
||||||
constexpr int ORBIS_NET_EPROCUNAVAIL = 76;
|
constexpr int ORBIS_NET_EPROCUNAVAIL = 76;
|
||||||
|
constexpr int ORBIS_NET_ECANCELED = 87;
|
||||||
constexpr int ORBIS_NET_EPROTO = 92;
|
constexpr int ORBIS_NET_EPROTO = 92;
|
||||||
constexpr int ORBIS_NET_EADHOC = 160;
|
constexpr int ORBIS_NET_EADHOC = 160;
|
||||||
constexpr int ORBIS_NET_EINACTIVEDISABLED = 163;
|
constexpr int ORBIS_NET_EINACTIVEDISABLED = 163;
|
||||||
@ -77,10 +81,6 @@ constexpr int ORBIS_NET_RESOLVER_ESERVERREFUSED = 232;
|
|||||||
constexpr int ORBIS_NET_RESOLVER_ENORECORD = 233;
|
constexpr int ORBIS_NET_RESOLVER_ENORECORD = 233;
|
||||||
constexpr int ORBIS_NET_RESOLVER_EALIGNMENT = 234;
|
constexpr int ORBIS_NET_RESOLVER_EALIGNMENT = 234;
|
||||||
|
|
||||||
// common errno
|
|
||||||
constexpr int ORBIS_NET_ENOMEM = 12;
|
|
||||||
constexpr int ORBIS_NET_ENOBUFS = 55;
|
|
||||||
|
|
||||||
// error codes
|
// error codes
|
||||||
constexpr int ORBIS_NET_ERROR_BASE = 0x80410100; // not existed used for calculation
|
constexpr int ORBIS_NET_ERROR_BASE = 0x80410100; // not existed used for calculation
|
||||||
constexpr int ORBIS_NET_ERROR_EPERM = 0x80410101;
|
constexpr int ORBIS_NET_ERROR_EPERM = 0x80410101;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <common/assert.h>
|
#include <common/assert.h>
|
||||||
|
#include "core/libraries/kernel/kernel.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "net_error.h"
|
#include "net_error.h"
|
||||||
#include "sockets.h"
|
#include "sockets.h"
|
||||||
@ -12,10 +13,12 @@ int P2PSocket::Close() {
|
|||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int P2PSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
|
int P2PSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int P2PSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) {
|
int P2PSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return 0;
|
return 0;
|
||||||
@ -34,16 +37,19 @@ int P2PSocket::Listen(int backlog) {
|
|||||||
int P2PSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to,
|
int P2PSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to,
|
||||||
u32 tolen) {
|
u32 tolen) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_EAGAIN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int P2PSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from, u32* fromlen) {
|
int P2PSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from, u32* fromlen) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_EAGAIN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketPtr P2PSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
|
SocketPtr P2PSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
*Libraries::Kernel::__Error() = ORBIS_NET_EAGAIN;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <common/assert.h>
|
#include <common/assert.h>
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "core/libraries/kernel/file_system.h"
|
#include "core/libraries/kernel/file_system.h"
|
||||||
|
#include "core/libraries/kernel/kernel.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -16,11 +17,13 @@ namespace Libraries::Net {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define ERROR_CASE(errname) \
|
#define ERROR_CASE(errname) \
|
||||||
case (WSA##errname): \
|
case (WSA##errname): \
|
||||||
return ORBIS_NET_ERROR_##errname;
|
*Libraries::Kernel::__Error() = ORBIS_NET_##errname; \
|
||||||
|
return -1;
|
||||||
#else
|
#else
|
||||||
#define ERROR_CASE(errname) \
|
#define ERROR_CASE(errname) \
|
||||||
case (errname): \
|
case (errname): \
|
||||||
return ORBIS_NET_ERROR_##errname;
|
*Libraries::Kernel::__Error() = ORBIS_NET_##errname; \
|
||||||
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ConvertReturnErrorCode(int retval) {
|
static int ConvertReturnErrorCode(int retval) {
|
||||||
@ -107,7 +110,8 @@ static int ConvertReturnErrorCode(int retval) {
|
|||||||
ERROR_CASE(EHOSTUNREACH)
|
ERROR_CASE(EHOSTUNREACH)
|
||||||
ERROR_CASE(ENOTEMPTY)
|
ERROR_CASE(ENOTEMPTY)
|
||||||
}
|
}
|
||||||
return ORBIS_NET_ERROR_EINTERNAL;
|
*Libraries::Kernel::__Error() = ORBIS_NET_EINTERNAL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
// if it is 0 or positive return it as it is
|
// if it is 0 or positive return it as it is
|
||||||
return retval;
|
return retval;
|
||||||
@ -121,6 +125,8 @@ static int ConvertLevels(int level) {
|
|||||||
return IPPROTO_IP;
|
return IPPROTO_IP;
|
||||||
case ORBIS_NET_IPPROTO_TCP:
|
case ORBIS_NET_IPPROTO_TCP:
|
||||||
return IPPROTO_TCP;
|
return IPPROTO_TCP;
|
||||||
|
case ORBIS_NET_IPPROTO_IPV6:
|
||||||
|
return IPPROTO_IPV6;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -192,7 +198,7 @@ int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetS
|
|||||||
|
|
||||||
int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from,
|
int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from,
|
||||||
u32* fromlen) {
|
u32* fromlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{receive_mutex};
|
||||||
if (from != nullptr) {
|
if (from != nullptr) {
|
||||||
sockaddr addr;
|
sockaddr addr;
|
||||||
int res = recvfrom(sock, (char*)buf, len, flags, &addr, (socklen_t*)fromlen);
|
int res = recvfrom(sock, (char*)buf, len, flags, &addr, (socklen_t*)fromlen);
|
||||||
@ -258,16 +264,17 @@ int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
|||||||
#define CASE_SETSOCKOPT_VALUE(opt, value) \
|
#define CASE_SETSOCKOPT_VALUE(opt, value) \
|
||||||
case opt: \
|
case opt: \
|
||||||
if (optlen != sizeof(*value)) { \
|
if (optlen != sizeof(*value)) { \
|
||||||
return ORBIS_NET_ERROR_EFAULT; \
|
*Libraries::Kernel::__Error() = ORBIS_NET_EFAULT; \
|
||||||
|
return -1; \
|
||||||
} \
|
} \
|
||||||
memcpy(value, optval, optlen); \
|
memcpy(value, optval, optlen); \
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
|
int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
level = ConvertLevels(level);
|
s32 native_level = ConvertLevels(level);
|
||||||
::linger native_linger;
|
::linger native_linger;
|
||||||
if (level == SOL_SOCKET) {
|
if (native_level == SOL_SOCKET) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
CASE_SETSOCKOPT(SO_REUSEADDR);
|
CASE_SETSOCKOPT(SO_REUSEADDR);
|
||||||
CASE_SETSOCKOPT(SO_KEEPALIVE);
|
CASE_SETSOCKOPT(SO_KEEPALIVE);
|
||||||
@ -286,12 +293,14 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
|
|||||||
CASE_SETSOCKOPT_VALUE(ORBIS_NET_SO_USESIGNATURE, &sockopt_so_usesignature);
|
CASE_SETSOCKOPT_VALUE(ORBIS_NET_SO_USESIGNATURE, &sockopt_so_usesignature);
|
||||||
case ORBIS_NET_SO_LINGER: {
|
case ORBIS_NET_SO_LINGER: {
|
||||||
if (socket_type != ORBIS_NET_SOCK_STREAM) {
|
if (socket_type != ORBIS_NET_SOCK_STREAM) {
|
||||||
return ORBIS_NET_ERROR_EPROCUNAVAIL;
|
*Libraries::Kernel::__Error() = ORBIS_NET_EPROCUNAVAIL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if (optlen < sizeof(OrbisNetLinger)) {
|
if (optlen < sizeof(OrbisNetLinger)) {
|
||||||
LOG_ERROR(Lib_Net, "size missmatched! optlen = {} OrbisNetLinger={}", optlen,
|
LOG_ERROR(Lib_Net, "size missmatched! optlen = {} OrbisNetLinger={}", optlen,
|
||||||
sizeof(OrbisNetLinger));
|
sizeof(OrbisNetLinger));
|
||||||
return ORBIS_NET_ERROR_EINVAL;
|
*Libraries::Kernel::__Error() = ORBIS_NET_EINVAL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* native_val = &native_linger;
|
const void* native_val = &native_linger;
|
||||||
@ -299,14 +308,16 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
|
|||||||
native_linger.l_onoff = reinterpret_cast<const OrbisNetLinger*>(optval)->l_onoff;
|
native_linger.l_onoff = reinterpret_cast<const OrbisNetLinger*>(optval)->l_onoff;
|
||||||
native_linger.l_linger = reinterpret_cast<const OrbisNetLinger*>(optval)->l_linger;
|
native_linger.l_linger = reinterpret_cast<const OrbisNetLinger*>(optval)->l_linger;
|
||||||
return ConvertReturnErrorCode(
|
return ConvertReturnErrorCode(
|
||||||
setsockopt(sock, level, SO_LINGER, (const char*)native_val, native_len));
|
setsockopt(sock, native_level, SO_LINGER, (const char*)native_val, native_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
case ORBIS_NET_SO_NAME:
|
case ORBIS_NET_SO_NAME:
|
||||||
return ORBIS_NET_ERROR_EINVAL; // don't support set for name
|
*Libraries::Kernel::__Error() = ORBIS_NET_EINVAL;
|
||||||
|
return -1; // don't support set for name
|
||||||
case ORBIS_NET_SO_NBIO: {
|
case ORBIS_NET_SO_NBIO: {
|
||||||
if (optlen != sizeof(sockopt_so_nbio)) {
|
if (optlen != sizeof(sockopt_so_nbio)) {
|
||||||
return ORBIS_NET_ERROR_EFAULT;
|
*Libraries::Kernel::__Error() = ORBIS_NET_EFAULT;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(&sockopt_so_nbio, optval, optlen);
|
memcpy(&sockopt_so_nbio, optval, optlen);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -318,7 +329,7 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (level == IPPROTO_IP) {
|
} else if (native_level == IPPROTO_IP) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
// CASE_SETSOCKOPT(IP_HDRINCL);
|
// CASE_SETSOCKOPT(IP_HDRINCL);
|
||||||
CASE_SETSOCKOPT(IP_TOS);
|
CASE_SETSOCKOPT(IP_TOS);
|
||||||
@ -332,13 +343,14 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
|
|||||||
CASE_SETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, &sockopt_ip_maxttl);
|
CASE_SETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, &sockopt_ip_maxttl);
|
||||||
case ORBIS_NET_IP_HDRINCL: {
|
case ORBIS_NET_IP_HDRINCL: {
|
||||||
if (socket_type != ORBIS_NET_SOCK_RAW) {
|
if (socket_type != ORBIS_NET_SOCK_RAW) {
|
||||||
return ORBIS_NET_ERROR_EPROCUNAVAIL;
|
*Libraries::Kernel::__Error() = ORBIS_NET_EPROCUNAVAIL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return ConvertReturnErrorCode(
|
return ConvertReturnErrorCode(
|
||||||
setsockopt(sock, level, optname, (const char*)optval, optlen));
|
setsockopt(sock, native_level, optname, (const char*)optval, optlen));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (level == IPPROTO_TCP) {
|
} else if (native_level == IPPROTO_TCP) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
CASE_SETSOCKOPT(TCP_NODELAY);
|
CASE_SETSOCKOPT(TCP_NODELAY);
|
||||||
CASE_SETSOCKOPT(TCP_MAXSEG);
|
CASE_SETSOCKOPT(TCP_MAXSEG);
|
||||||
@ -362,7 +374,8 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
|
|||||||
case opt: \
|
case opt: \
|
||||||
if (*optlen < sizeof(value)) { \
|
if (*optlen < sizeof(value)) { \
|
||||||
*optlen = sizeof(value); \
|
*optlen = sizeof(value); \
|
||||||
return ORBIS_NET_ERROR_EFAULT; \
|
*Libraries::Kernel::__Error() = ORBIS_NET_EFAULT; \
|
||||||
|
return -1; \
|
||||||
} \
|
} \
|
||||||
*optlen = sizeof(value); \
|
*optlen = sizeof(value); \
|
||||||
*(decltype(value)*)optval = value; \
|
*(decltype(value)*)optval = value; \
|
||||||
@ -370,8 +383,8 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
|
|||||||
|
|
||||||
int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) {
|
int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
level = ConvertLevels(level);
|
s32 native_level = ConvertLevels(level);
|
||||||
if (level == SOL_SOCKET) {
|
if (native_level == SOL_SOCKET) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
CASE_GETSOCKOPT(SO_REUSEADDR);
|
CASE_GETSOCKOPT(SO_REUSEADDR);
|
||||||
CASE_GETSOCKOPT(SO_KEEPALIVE);
|
CASE_GETSOCKOPT(SO_KEEPALIVE);
|
||||||
@ -392,7 +405,7 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
|
|||||||
CASE_GETSOCKOPT_VALUE(ORBIS_NET_SO_NAME,
|
CASE_GETSOCKOPT_VALUE(ORBIS_NET_SO_NAME,
|
||||||
(char)0); // writes an empty string to the output buffer
|
(char)0); // writes an empty string to the output buffer
|
||||||
}
|
}
|
||||||
} else if (level == IPPROTO_IP) {
|
} else if (native_level == IPPROTO_IP) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
CASE_GETSOCKOPT(IP_HDRINCL);
|
CASE_GETSOCKOPT(IP_HDRINCL);
|
||||||
CASE_GETSOCKOPT(IP_TOS);
|
CASE_GETSOCKOPT(IP_TOS);
|
||||||
@ -405,7 +418,7 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
|
|||||||
CASE_GETSOCKOPT_VALUE(ORBIS_NET_IP_TTLCHK, sockopt_ip_ttlchk);
|
CASE_GETSOCKOPT_VALUE(ORBIS_NET_IP_TTLCHK, sockopt_ip_ttlchk);
|
||||||
CASE_GETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, sockopt_ip_maxttl);
|
CASE_GETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, sockopt_ip_maxttl);
|
||||||
}
|
}
|
||||||
} else if (level == IPPROTO_TCP) {
|
} else if (native_level == IPPROTO_TCP) {
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
CASE_GETSOCKOPT(TCP_NODELAY);
|
CASE_GETSOCKOPT(TCP_NODELAY);
|
||||||
CASE_GETSOCKOPT(TCP_MAXSEG);
|
CASE_GETSOCKOPT(TCP_MAXSEG);
|
||||||
|
@ -58,6 +58,7 @@ struct Socket {
|
|||||||
virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0;
|
virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0;
|
||||||
virtual int fstat(Libraries::Kernel::OrbisKernelStat* stat) = 0;
|
virtual int fstat(Libraries::Kernel::OrbisKernelStat* stat) = 0;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
|
std::mutex receive_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PosixSocket : public Socket {
|
struct PosixSocket : public Socket {
|
||||||
|
@ -26,10 +26,10 @@ int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 add
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -41,10 +41,10 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -66,10 +66,12 @@ int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen)
|
|||||||
new_file->socket = new_sock;
|
new_file->socket = new_sock;
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -81,10 +83,10 @@ int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* padd
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -96,10 +98,10 @@ int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optv
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -111,10 +113,10 @@ int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
||||||
u32 optlen) {
|
u32 optlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
@ -127,13 +129,14 @@ int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_shutdown(OrbisNetId s, int how) {
|
int PS4_SYSV_ABI sys_shutdown(OrbisNetId s, int how) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protocol) {
|
int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protocol) {
|
||||||
if (name == nullptr) {
|
if (name == nullptr) {
|
||||||
LOG_INFO(Lib_Net, "name = no-named family = {} type = {} protocol = {}", family, type,
|
LOG_INFO(Lib_Net, "name = no-named family = {} type = {} protocol = {}", family, type,
|
||||||
@ -169,13 +172,16 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
|
|||||||
sock->m_guest_name = name ? name : "anon_sock";
|
sock->m_guest_name = name ? name : "anon_sock";
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) {
|
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) {
|
||||||
return sys_socketex(nullptr, family, type, protocol);
|
return sys_socketex(nullptr, family, type, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags) {
|
int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -187,10 +193,10 @@ int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
||||||
const OrbisNetSockaddr* addr, u32 addrlen) {
|
const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
@ -203,14 +209,15 @@ int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags) {
|
int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||||
u32* paddrlen) {
|
u32* paddrlen) {
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
@ -223,10 +230,10 @@ s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, Orbis
|
|||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
*Libraries::Kernel::__Error() = returncode;
|
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
|
||||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
s64 PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user