From 194907953a9d39db0dc12e5a40f30acf4fdbc161 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 5 Jan 2025 17:31:11 +0200 Subject: [PATCH] added sceNetBind,sceNetListen --- src/core/libraries/network/net.cpp | 22 +++++++++++--- src/core/libraries/network/net.h | 11 ++++++- src/core/libraries/network/posix_sockets.cpp | 32 +++++++++++++++++++- src/core/libraries/network/sockets.h | 7 ++++- 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index a83f6ef8a..8892252db 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -124,8 +124,14 @@ int PS4_SYSV_ABI sceNetBandwidthControlSetPolicy() { } int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; + auto* netcall = Common::Singleton::Instance(); + auto sock = netcall->FindSocket(s); + if (!sock) { + net_errno = ORBIS_NET_EBADF; + LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); + return ORBIS_NET_ERROR_EBADF; + } + return sock->Bind(addr, addrlen); } int PS4_SYSV_ABI sceNetClearDnsCache() { @@ -784,9 +790,15 @@ int PS4_SYSV_ABI sceNetIoctl() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetListen() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceNetListen(OrbisNetId s, int backlog) { + auto* netcall = Common::Singleton::Instance(); + auto sock = netcall->FindSocket(s); + if (!sock) { + net_errno = ORBIS_NET_EBADF; + LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); + return ORBIS_NET_ERROR_EBADF; + } + return sock->Listen(backlog); } int PS4_SYSV_ABI sceNetMemoryAllocate() { diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index 6df45a865..3dfe6b328 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -83,6 +83,15 @@ struct OrbisNetSockaddr { char sa_data[14]; }; +struct OrbisNetSockaddrIn { + u8 sin_len; + u8 sin_family; + u16 sin_port; + u32 sin_addr; + u16 sin_vport; + char sin_zero[6]; +}; + int PS4_SYSV_ABI in6addr_any(); int PS4_SYSV_ABI in6addr_loopback(); int PS4_SYSV_ABI sce_net_dummy(); @@ -233,7 +242,7 @@ int PS4_SYSV_ABI sceNetInfoDumpStop(); int PS4_SYSV_ABI sceNetInit(); int PS4_SYSV_ABI sceNetInitParam(); int PS4_SYSV_ABI sceNetIoctl(); -int PS4_SYSV_ABI sceNetListen(); +int PS4_SYSV_ABI sceNetListen(OrbisNetId s, int backlog); int PS4_SYSV_ABI sceNetMemoryAllocate(); int PS4_SYSV_ABI sceNetMemoryFree(); u32 PS4_SYSV_ABI sceNetNtohl(u32 net32); diff --git a/src/core/libraries/network/posix_sockets.cpp b/src/core/libraries/network/posix_sockets.cpp index 36a6aba5c..06c6a255c 100644 --- a/src/core/libraries/network/posix_sockets.cpp +++ b/src/core/libraries/network/posix_sockets.cpp @@ -19,15 +19,45 @@ static int ConvertLevels(int level) { return -1; } +static int ConvertReturnErrorCode(int retval) { + if (retval < 0) { + UNREACHABLE_MSG("Function returned an errorCode = {}", retval); + } + // if it is 0 or positive return it as it is + return retval; +} + +static void convertOrbisNetSockaddrToPosix(const OrbisNetSockaddr* src, sockaddr* dst) { + if (src == nullptr || dst == nullptr) + return; + memset(dst, 0, sizeof(sockaddr)); + const OrbisNetSockaddrIn* src_in = (const OrbisNetSockaddrIn*)src; + sockaddr_in* dst_in = (sockaddr_in*)dst; + dst_in->sin_family = src_in->sin_family; + dst_in->sin_port = src_in->sin_port; + memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4); +} + int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, unsigned int optlen) { level = ConvertLevels(level); if (level == SOL_SOCKET) { switch (optname) { case ORBIS_NET_SO_REUSEADDR: - return setsockopt(sock, level, SO_REUSEADDR, (const char*)optval, optlen); + return ConvertReturnErrorCode( + setsockopt(sock, level, SO_REUSEADDR, (const char*)optval, optlen)); } } UNREACHABLE_MSG("Unknown level ={} optname ={}", level, optname); return 0; } +int PosixSocket::Bind(const OrbisNetSockaddr* addr, unsigned int addrlen) { + sockaddr addr2; + convertOrbisNetSockaddrToPosix(addr, &addr2); + return ConvertReturnErrorCode(::bind(sock, &addr2, sizeof(sockaddr_in))); +} + +int PosixSocket::Listen(int backlog) { + return ConvertReturnErrorCode(::listen(sock, backlog)); +} + } // namespace Libraries::Net \ No newline at end of file diff --git a/src/core/libraries/network/sockets.h b/src/core/libraries/network/sockets.h index 1369451a8..de2b61e85 100644 --- a/src/core/libraries/network/sockets.h +++ b/src/core/libraries/network/sockets.h @@ -22,6 +22,7 @@ typedef int socklen_t; typedef int net_socket; #endif #include +#include #include namespace Libraries::Net { @@ -35,6 +36,8 @@ struct Socket { virtual ~Socket() = default; virtual int SetSocketOptions(int level, int optname, const void* optval, unsigned int optlen) = 0; + virtual int Bind(const OrbisNetSockaddr* addr, unsigned int addrlen) = 0; + virtual int Listen(int backlog) = 0; }; struct PosixSocket : public Socket { @@ -42,6 +45,8 @@ struct PosixSocket : public Socket { explicit PosixSocket(int domain, int type, int protocol) : Socket(domain, type, protocol), sock(socket(domain, type, protocol)) {} int SetSocketOptions(int level, int optname, const void* optval, unsigned int optlen) override; + int Bind(const OrbisNetSockaddr* addr, unsigned int addrlen) override; + int Listen(int backlog) override; }; class NetInternal { @@ -54,7 +59,7 @@ public: if (it != socks.end()) { return it->second; } - return nullptr; + return 0; } public: