diff --git a/src/core/libraries/network/posix_sockets.cpp b/src/core/libraries/network/posix_sockets.cpp index 2df375262..5a7c62bee 100644 --- a/src/core/libraries/network/posix_sockets.cpp +++ b/src/core/libraries/network/posix_sockets.cpp @@ -142,6 +142,12 @@ static void convertPosixSockaddrToOrbis(sockaddr* src, OrbisNetSockaddr* dst) { memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4); } +PosixSocket::PosixSocket(int domain, int type, int protocol) : Socket(domain, type, protocol) { + sock = socket(ConvertFamilies(domain), type, protocol); + LOG_DEBUG(Lib_Net, "socket = {}", sock); + socket_type = type; +} + int PosixSocket::Close() { std::scoped_lock lock{m_mutex}; #ifdef _WIN32 diff --git a/src/core/libraries/network/sockets.h b/src/core/libraries/network/sockets.h index c54e11e66..1d5485ef3 100644 --- a/src/core/libraries/network/sockets.h +++ b/src/core/libraries/network/sockets.h @@ -51,6 +51,8 @@ struct Socket { u32* fromlen) = 0; virtual int Connect(const OrbisNetSockaddr* addr, u32 namelen) = 0; virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0; + virtual bool IsValid() const = 0; + virtual net_socket Native() const = 0; std::mutex m_mutex; }; @@ -65,10 +67,7 @@ struct PosixSocket : public Socket { 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_type = type; - } + explicit PosixSocket(int domain, int type, int protocol); 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; @@ -81,6 +80,12 @@ struct PosixSocket : public Socket { SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override; int Connect(const OrbisNetSockaddr* addr, u32 namelen) override; int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override; + bool IsValid() const override { + return sock != -1; + } + net_socket Native() const override { + return sock; + } }; struct P2PSocket : public Socket { @@ -96,6 +101,12 @@ struct P2PSocket : public Socket { SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override; int Connect(const OrbisNetSockaddr* addr, u32 namelen) override; int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override; + bool IsValid() const override { + return true; + } + net_socket Native() const override { + return {}; + } }; class NetInternal { diff --git a/src/core/libraries/network/sys_net.cpp b/src/core/libraries/network/sys_net.cpp index 087632159..bd85c1480 100644 --- a/src/core/libraries/network/sys_net.cpp +++ b/src/core/libraries/network/sys_net.cpp @@ -4,6 +4,7 @@ #include #include #include +#include "common/error.h" #include "common/singleton.h" #include "net_error.h" #include "sockets.h" @@ -145,9 +146,16 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc switch (type) { case ORBIS_NET_SOCK_STREAM: case ORBIS_NET_SOCK_DGRAM: - case ORBIS_NET_SOCK_RAW: - sock = std::make_shared(family, type, protocol); + case ORBIS_NET_SOCK_RAW: { + const auto typed_socket = std::make_shared(family, type, protocol); + if (!typed_socket->IsValid()) { + *Libraries::Kernel::__Error() = ORBIS_NET_EPROTONOSUPPORT; + return -1; + } + + sock = std::move(typed_socket); break; + } case ORBIS_NET_SOCK_DGRAM_P2P: case ORBIS_NET_SOCK_STREAM_P2P: sock = std::make_shared(family, type, protocol);