From e6a144ddb05028110014bc9f2d6046f390131b5c Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Tue, 13 May 2025 08:54:38 +0300 Subject: [PATCH] [Libs] sceNet IV (#2867) * dummy returns in p2p sockets * added logging for sceNetSetsockopt * possible fix for ORBIS_NET_SO_LINGER set * logging for getsockoption as well * disable kernel getsockname (seems to create issues with cyberpunk) * some fixes with SetSocketOptions * arggg * posix_getsockname try * mutex protection * removed duplicated include (diegolix29) * posix_getsockname appears to have issues in cyberpunk , comment it for now --- src/core/libraries/kernel/kernel.cpp | 23 ++++++++++- src/core/libraries/network/net.cpp | 2 + src/core/libraries/network/p2p_sockets.cpp | 14 +++---- src/core/libraries/network/posix_sockets.cpp | 40 +++++++++++++++++++- src/core/libraries/network/sockets.h | 10 ++++- src/core/libraries/network/sys_net.cpp | 1 - 6 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index 81b6dfe50..c7eafe799 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -32,6 +32,8 @@ #include #endif #include +#include +#include #include "aio.h" namespace Libraries::Kernel { @@ -207,6 +209,24 @@ int PS4_SYSV_ABI posix_getpagesize() { return 16_KB; } +int PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s, + Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) { + auto* netcall = Common::Singleton::Instance(); + auto sock = netcall->FindSocket(s); + if (!sock) { + *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; + LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); + return -1; + } + int returncode = sock->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; +} void RegisterKernel(Core::Loader::SymbolsResolver* sym) { service_thread = std::jthread{KernelServiceThread}; @@ -244,8 +264,7 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("lUk6wrGXyMw", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_recvfrom); LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_setsockopt); - LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1, - Libraries::Net::sys_getsockname); + // LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1, posix_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_ ... diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 1f024277f..0ef4a84f5 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -886,6 +886,7 @@ int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* pa } int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) { + LOG_INFO(Lib_Net, "s={} level={} optname={}", s, level, optname); if (!g_isNetInitialized) { return ORBIS_NET_ERROR_ENOTINIT; } @@ -1449,6 +1450,7 @@ int PS4_SYSV_ABI sceNetSetDnsInfoToKernel() { int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval, u32 optlen) { + LOG_INFO(Lib_Net, "s={} level={} optname={} optlen={}", s, level, optname, optlen); if (!g_isNetInitialized) { return ORBIS_NET_ERROR_ENOTINIT; } diff --git a/src/core/libraries/network/p2p_sockets.cpp b/src/core/libraries/network/p2p_sockets.cpp index e9b710bb3..4f678dace 100644 --- a/src/core/libraries/network/p2p_sockets.cpp +++ b/src/core/libraries/network/p2p_sockets.cpp @@ -10,25 +10,25 @@ namespace Libraries::Net { int P2PSocket::Close() { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } int P2PSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } int P2PSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } int P2PSocket::Bind(const OrbisNetSockaddr* addr, u32 addrlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } int P2PSocket::Listen(int backlog) { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } int P2PSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to, @@ -49,12 +49,12 @@ SocketPtr P2PSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) { int P2PSocket::Connect(const OrbisNetSockaddr* addr, u32 namelen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } int P2PSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return -1; + return 0; } } // namespace Libraries::Net \ No newline at end of file diff --git a/src/core/libraries/network/posix_sockets.cpp b/src/core/libraries/network/posix_sockets.cpp index 140e4fd22..2df375262 100644 --- a/src/core/libraries/network/posix_sockets.cpp +++ b/src/core/libraries/network/posix_sockets.cpp @@ -143,6 +143,7 @@ static void convertPosixSockaddrToOrbis(sockaddr* src, OrbisNetSockaddr* dst) { } int PosixSocket::Close() { + std::scoped_lock lock{m_mutex}; #ifdef _WIN32 auto out = closesocket(sock); #else @@ -152,17 +153,20 @@ int PosixSocket::Close() { } int PosixSocket::Bind(const OrbisNetSockaddr* addr, u32 addrlen) { + std::scoped_lock lock{m_mutex}; sockaddr addr2; convertOrbisNetSockaddrToPosix(addr, &addr2); return ConvertReturnErrorCode(::bind(sock, &addr2, sizeof(sockaddr_in))); } int PosixSocket::Listen(int backlog) { + std::scoped_lock lock{m_mutex}; return ConvertReturnErrorCode(::listen(sock, backlog)); } int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to, u32 tolen) { + std::scoped_lock lock{m_mutex}; if (to != nullptr) { sockaddr addr; convertOrbisNetSockaddrToPosix(to, &addr); @@ -175,6 +179,7 @@ int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetS int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from, u32* fromlen) { + std::scoped_lock lock{m_mutex}; if (from != nullptr) { sockaddr addr; int res = recvfrom(sock, (char*)buf, len, flags, &addr, (socklen_t*)fromlen); @@ -187,6 +192,7 @@ int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* } SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) { + std::scoped_lock lock{m_mutex}; sockaddr addr2; net_socket new_socket = ::accept(sock, &addr2, (socklen_t*)addrlen); #ifdef _WIN32 @@ -202,12 +208,14 @@ SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) { } int PosixSocket::Connect(const OrbisNetSockaddr* addr, u32 namelen) { + std::scoped_lock lock{m_mutex}; sockaddr addr2; convertOrbisNetSockaddrToPosix(addr, &addr2); return ::connect(sock, &addr2, sizeof(sockaddr_in)); } int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) { + std::scoped_lock lock{m_mutex}; sockaddr addr; convertOrbisNetSockaddrToPosix(name, &addr); if (name != nullptr) { @@ -234,13 +242,15 @@ int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) { return 0 int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) { + std::scoped_lock lock{m_mutex}; level = ConvertLevels(level); + ::linger native_linger; if (level == SOL_SOCKET) { switch (optname) { CASE_SETSOCKOPT(SO_REUSEADDR); CASE_SETSOCKOPT(SO_KEEPALIVE); CASE_SETSOCKOPT(SO_BROADCAST); - CASE_SETSOCKOPT(SO_LINGER); + // CASE_SETSOCKOPT(SO_LINGER); CASE_SETSOCKOPT(SO_SNDBUF); CASE_SETSOCKOPT(SO_RCVBUF); CASE_SETSOCKOPT(SO_SNDTIMEO); @@ -251,6 +261,24 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3 CASE_SETSOCKOPT_VALUE(ORBIS_NET_SO_ONESBCAST, &sockopt_so_onesbcast); CASE_SETSOCKOPT_VALUE(ORBIS_NET_SO_USECRYPTO, &sockopt_so_usecrypto); CASE_SETSOCKOPT_VALUE(ORBIS_NET_SO_USESIGNATURE, &sockopt_so_usesignature); + case ORBIS_NET_SO_LINGER: { + if (socket_type != ORBIS_NET_SOCK_STREAM) { + return ORBIS_NET_EPROCUNAVAIL; + } + if (optlen < sizeof(OrbisNetLinger)) { + LOG_ERROR(Lib_Net, "size missmatched! optlen = {} OrbisNetLinger={}", optlen, + sizeof(OrbisNetLinger)); + return ORBIS_NET_ERROR_EINVAL; + } + + const void* native_val = &native_linger; + u32 native_len = sizeof(native_linger); + native_linger.l_onoff = reinterpret_cast(optval)->l_onoff; + native_linger.l_linger = reinterpret_cast(optval)->l_linger; + return ConvertReturnErrorCode( + setsockopt(sock, level, SO_LINGER, (const char*)native_val, native_len)); + } + case ORBIS_NET_SO_NAME: return ORBIS_NET_ERROR_EINVAL; // don't support set for name case ORBIS_NET_SO_NBIO: { @@ -269,7 +297,7 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3 } } else if (level == IPPROTO_IP) { switch (optname) { - CASE_SETSOCKOPT(IP_HDRINCL); + // CASE_SETSOCKOPT(IP_HDRINCL); CASE_SETSOCKOPT(IP_TOS); CASE_SETSOCKOPT(IP_TTL); CASE_SETSOCKOPT(IP_MULTICAST_IF); @@ -279,6 +307,13 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3 CASE_SETSOCKOPT(IP_DROP_MEMBERSHIP); CASE_SETSOCKOPT_VALUE(ORBIS_NET_IP_TTLCHK, &sockopt_ip_ttlchk); CASE_SETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, &sockopt_ip_maxttl); + case ORBIS_NET_IP_HDRINCL: { + if (socket_type != ORBIS_NET_SOCK_RAW) { + return ORBIS_NET_EPROCUNAVAIL; + } + return ConvertReturnErrorCode( + setsockopt(sock, level, optname, (const char*)optval, optlen)); + } } } else if (level == IPPROTO_TCP) { switch (optname) { @@ -311,6 +346,7 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3 return 0; int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) { + std::scoped_lock lock{m_mutex}; level = ConvertLevels(level); if (level == SOL_SOCKET) { switch (optname) { diff --git a/src/core/libraries/network/sockets.h b/src/core/libraries/network/sockets.h index e41671d88..c54e11e66 100644 --- a/src/core/libraries/network/sockets.h +++ b/src/core/libraries/network/sockets.h @@ -32,6 +32,10 @@ struct Socket; typedef std::shared_ptr SocketPtr; +struct OrbisNetLinger { + s32 l_onoff; + s32 l_linger; +}; struct Socket { explicit Socket(int domain, int type, int protocol) {} virtual ~Socket() = default; @@ -47,6 +51,7 @@ struct Socket { u32* fromlen) = 0; virtual int Connect(const OrbisNetSockaddr* addr, u32 namelen) = 0; virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0; + std::mutex m_mutex; }; struct PosixSocket : public Socket { @@ -59,8 +64,11 @@ struct PosixSocket : public Socket { int sockopt_ip_ttlchk = 0; int sockopt_ip_maxttl = 0; int sockopt_tcp_mss_to_advertise = 0; + int socket_type; explicit PosixSocket(int domain, int type, int protocol) - : Socket(domain, type, protocol), sock(socket(domain, type, protocol)) {} + : Socket(domain, type, protocol), sock(socket(domain, type, protocol)) { + socket_type = type; + } explicit PosixSocket(net_socket sock) : Socket(0, 0, 0), sock(sock) {} int Close() override; int SetSocketOptions(int level, int optname, const void* optval, u32 optlen) override; diff --git a/src/core/libraries/network/sys_net.cpp b/src/core/libraries/network/sys_net.cpp index fbf2a2456..087632159 100644 --- a/src/core/libraries/network/sys_net.cpp +++ b/src/core/libraries/network/sys_net.cpp @@ -1,4 +1,3 @@ -#include "sys_net.h" // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later