diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 15493a327..e335930a5 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -65,8 +65,21 @@ int PS4_SYSV_ABI sce_net_in6addr_nodelocal_allnodes() { } OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { - 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; + } + auto new_sock = sock->Accept(addr, paddrlen); + if (!new_sock) { + LOG_ERROR(Lib_Net, "error creating new socket for accepting"); + return -1; + } + auto id = ++netcall->next_sock_id; + netcall->socks.emplace(id, new_sock); + return id; } int PS4_SYSV_ABI sceNetAddrConfig6GetInfo() { @@ -1048,7 +1061,7 @@ int PS4_SYSV_ABI sceNetSetDnsInfoToKernel() { int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval, u32 optlen) { - LOG_ERROR(Lib_Net, "s = {} level = {} optname = {} optlen = {}", s, level, optname, optlen); + LOG_INFO(Lib_Net, "s = {} level = {} optname = {} optlen = {}", s, level, optname, optlen); auto* netcall = Common::Singleton::Instance(); auto sock = netcall->FindSocket(s); if (!sock) { @@ -1145,8 +1158,8 @@ int PS4_SYSV_ABI sceNetShutdown() { } OrbisNetId PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol) { - LOG_ERROR(Lib_Net, "name = {} family = {} type = {} protocol = {}", std::string(name), family, - type, protocol); + LOG_INFO(Lib_Net, "name = {} family = {} type = {} protocol = {}", std::string(name), family, + type, protocol); SocketPtr sock; switch (type) { case ORBIS_NET_SOCK_STREAM: diff --git a/src/core/libraries/network/p2p_sockets.cpp b/src/core/libraries/network/p2p_sockets.cpp index c03883cce..50ef84410 100644 --- a/src/core/libraries/network/p2p_sockets.cpp +++ b/src/core/libraries/network/p2p_sockets.cpp @@ -24,4 +24,8 @@ int P2PSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSoc return -1; // fake value makes peggle2 work } +SocketPtr P2PSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) { + return nullptr; +} + } // 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 bece54262..4dc5a70ad 100644 --- a/src/core/libraries/network/posix_sockets.cpp +++ b/src/core/libraries/network/posix_sockets.cpp @@ -39,6 +39,17 @@ static void convertOrbisNetSockaddrToPosix(const OrbisNetSockaddr* src, sockaddr memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4); } +static void convertPosixSockaddrToOrbis(sockaddr* src, OrbisNetSockaddr* dst) { + if (src == nullptr || dst == nullptr) + return; + memset(dst, 0, sizeof(OrbisNetSockaddr)); + OrbisNetSockaddrIn* dst_in = (OrbisNetSockaddrIn*)dst; + sockaddr_in* src_in = (sockaddr_in*)src; + dst_in->sin_family = static_cast(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) { @@ -104,4 +115,19 @@ int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetS } } +SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) { + sockaddr addr2; + net_socket new_socket = ::accept(sock, &addr2, (socklen_t*)addrlen); +#ifdef _WIN32 + if (new_socket != INVALID_SOCKET) { +#else + if (new_socket >= 0) { +#endif + convertPosixSockaddrToOrbis(&addr2, addr); + *addrlen = sizeof(OrbisNetSockaddrIn); + return std::make_shared(new_socket); + } + return nullptr; +} + } // 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 f6c3bec82..8997374ec 100644 --- a/src/core/libraries/network/sockets.h +++ b/src/core/libraries/network/sockets.h @@ -40,6 +40,7 @@ struct Socket { virtual int Listen(int backlog) = 0; virtual int SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to, u32 tolen) = 0; + virtual SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) = 0; }; struct PosixSocket : public Socket { @@ -48,11 +49,13 @@ struct PosixSocket : public Socket { int sockopt_so_onesbcast = 0; explicit PosixSocket(int domain, int type, int protocol) : Socket(domain, type, protocol), sock(socket(domain, type, protocol)) {} + explicit PosixSocket(net_socket sock) : Socket(0, 0, 0), sock(sock) {} 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; int SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to, u32 tolen) override; + SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override; }; struct P2PSocket : public Socket { @@ -62,6 +65,7 @@ struct P2PSocket : public Socket { int Listen(int backlog) override; int SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to, u32 tolen) override; + SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override; }; class NetInternal {