From 68982c8aaad221569f3a9a8e9e51965f8e090321 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 1 Jul 2026 19:11:01 +0000 Subject: [PATCH] fixes for non BSD --- src/core/hle/service/sockets/bsd.cpp | 7 ++- src/core/internal_network/network.cpp | 69 ++++++++++++++++------ src/core/internal_network/socket_proxy.cpp | 17 +++++- src/core/internal_network/socket_proxy.h | 11 +--- src/core/internal_network/socket_types.h | 22 +++++-- src/core/internal_network/sockets.h | 23 ++------ 6 files changed, 96 insertions(+), 53 deletions(-) diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index a5f6b0f766..6cedd888ff 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -803,7 +803,6 @@ Network::Errno BSD::SetSockOptImpl(s32 fd, u32 level, Network::OptName optname, ASSERT(optval.size() == sizeof(u32)); auto value = GetValue(optval); - switch (optname) { case Network::OptName::REUSEADDR: ASSERT(value == 0 || value == 1); @@ -825,6 +824,12 @@ Network::Errno BSD::SetSockOptImpl(s32 fd, u32 level, Network::OptName optname, case Network::OptName::NOSIGPIPE: LOG_WARNING(Service, "(STUBBED) setting NOSIGPIPE to {}", value); return Network::Errno::SUCCESS; + case Network::OptName::REUSEPORT: + return socket->SetReusePort(value); + case Network::OptName::TIMESTAMP: + return socket->SetTimeStamp(value); + case Network::OptName::ACCEPTFILTER: + return socket->SetAcceptFilter(value); default: UNIMPLEMENTED_MSG("Unimplemented optname={}", optname); return Network::Errno::SUCCESS; diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index ee5a5e5584..b290339492 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -120,8 +120,15 @@ bool EnableNonBlock(SOCKET fd, bool enable) { Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { switch (e) { - case 0: - return Errno::SUCCESS; + case 0: return Errno::SUCCESS; + case WSAECONNABORTED: + if (call_type == CallType::Send) { + // Winsock yields WSAECONNABORTED from `send` in situations where Unix + // systems, and actual Switches, yield EPIPE. + return Errno::PIPE; + } else { + return Errno::CONNABORTED; + } case WSAEBADF: return Errno::BADF; case WSAEINVAL: @@ -134,14 +141,6 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { return Errno::AGAIN; case WSAECONNREFUSED: return Errno::CONNREFUSED; - case WSAECONNABORTED: - if (call_type == CallType::Send) { - // Winsock yields WSAECONNABORTED from `send` in situations where Unix - // systems, and actual Switches, yield EPIPE. - return Errno::PIPE; - } else { - return Errno::CONNABORTED; - } case WSAECONNRESET: return Errno::CONNRESET; case WSAEHOSTUNREACH: @@ -160,6 +159,18 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { return Errno::ISCONN; case WSAEADDRINUSE: return Errno::ADDRINUSE; + case WSAEADDRNOTAVAIL: + return Errno::ADDRNOTAVAIL; + case WSAEPROTOTYPE: + return Errno::PROTOTYPE; + case WSAENOPROTOOPT: + return Errno::NOPROTOOPT; + case WSAEPROTONOSUPPORT: + return Errno::PROTONOSUPPORT; + case WSAESOCKTNOSUPPORT: + return Errno::SOCKTNOSUPPORT; + case WSAENOTSUP: + return Errno::NOTSUP; default: UNIMPLEMENTED_MSG("Unimplemented errno={}", e); return Errno::OTHER; @@ -285,7 +296,13 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { NETWORK_ERROR_ELEM(TIMEDOUT) \ NETWORK_ERROR_ELEM(INPROGRESS) \ NETWORK_ERROR_ELEM(ISCONN) \ - NETWORK_ERROR_ELEM(ADDRINUSE) + NETWORK_ERROR_ELEM(PROTOTYPE) \ + NETWORK_ERROR_ELEM(NOPROTOOPT) \ + NETWORK_ERROR_ELEM(PROTONOSUPPORT) \ + NETWORK_ERROR_ELEM(SOCKTNOSUPPORT) \ + NETWORK_ERROR_ELEM(NOTSUP) \ + NETWORK_ERROR_ELEM(ADDRINUSE) \ + NETWORK_ERROR_ELEM(ADDRNOTAVAIL) #define NETWORK_ERROR_ELEM(name) case E##name: return Errno::name; NETWORK_ERROR_LIST #undef NETWORK_ERROR_ELEM @@ -400,9 +417,9 @@ GetAddrInfoError TranslateGetAddrInfoErrorFromNative(int gai_err) { NETWORK_DOMAIN_TRANSLATE_ELEM(IPX) \ NETWORK_DOMAIN_TRANSLATE_ELEM(ISDN) \ NETWORK_DOMAIN_TRANSLATE_ELEM(INET6) \ - NETWORK_DOMAIN_TRANSLATE_ELEM(ATM) \ + /*NETWORK_DOMAIN_TRANSLATE_ELEM(ATM)*/ \ NETWORK_DOMAIN_TRANSLATE_ELEM(BLUETOOTH) \ - NETWORK_DOMAIN_TRANSLATE_ELEM(NETLINK) + /*NETWORK_DOMAIN_TRANSLATE_ELEM(NETLINK)*/ #elif defined(_WIN32) #define NETWORK_DOMAIN_TRANSLATE_LIST \ NETWORK_DOMAIN_TRANSLATE_ELEM(UNIX) \ @@ -422,8 +439,7 @@ GetAddrInfoError TranslateGetAddrInfoErrorFromNative(int gai_err) { NETWORK_DOMAIN_TRANSLATE_ELEM(APPLETALK) \ NETWORK_DOMAIN_TRANSLATE_ELEM(NETBIOS) \ NETWORK_DOMAIN_TRANSLATE_ELEM(ATM) \ - NETWORK_DOMAIN_TRANSLATE_ELEM(INET6) \ - NETWORK_DOMAIN_TRANSLATE_ELEM(CLUSTER) + NETWORK_DOMAIN_TRANSLATE_ELEM(INET6) #else #define NETWORK_DOMAIN_TRANSLATE_LIST \ NETWORK_DOMAIN_TRANSLATE_ELEM(INET) \ @@ -936,15 +952,18 @@ Errno Socket::SetSockOpt(SOCKET fd_so, int option, T value) { } Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { - fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), TranslateProtocolToNative(protocol)); - if (fd != INVALID_SOCKET) { - return Errno::SUCCESS; + if (type == Type::STREAM && protocol == Protocol::UDP) { + LOG_WARNING(Network, "Using IPPROTO_UDP with SOCK_STREAM"); + type = Type::DGRAM; } + fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), TranslateProtocolToNative(protocol)); + if (fd != INVALID_SOCKET) + return Errno::SUCCESS; return GetAndLogLastError(); } -std::pair Socket::Accept() { +std::pair Socket::Accept() { sockaddr_in addr; socklen_t addrlen = sizeof(addr); @@ -1171,6 +1190,18 @@ Errno Socket::SetRcvTimeo(u32 value) { return SetSockOpt(fd, SO_RCVTIMEO, value); } +Errno Socket::SetReusePort(u32 value) { + return SetSockOpt(fd, SO_REUSEPORT, value); +} + +Errno Socket::SetTimeStamp(u32 value) { + return SetSockOpt(fd, SO_TIMESTAMP, value); +} + +Errno Socket::SetAcceptFilter(u32 value) { + return SetSockOpt(fd, SO_ACCEPTFILTER, value); +} + Errno Socket::SetNonBlock(bool enable) { if (EnableNonBlock(fd, enable)) { is_non_blocking = enable; diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp index 8ebbead4f7..da54b68acd 100644 --- a/src/core/internal_network/socket_proxy.cpp +++ b/src/core/internal_network/socket_proxy.cpp @@ -247,13 +247,12 @@ Errno ProxySocket::Close() { } Errno ProxySocket::SetLinger(bool enable, u32 linger) { - struct Linger { + struct { u16 linger_enable; u16 linger_time; } values; values.linger_enable = enable ? 1 : 0; - values.linger_time = static_cast(linger); - + values.linger_time = u16(linger); return SetSockOpt(fd, SO_LINGER, values); } @@ -288,6 +287,18 @@ Errno ProxySocket::SetRcvTimeo(u32 value) { return SetSockOpt(fd, SO_RCVTIMEO, static_cast(value)); } +Errno ProxySocket::SetReusePort(u32 value) { + return SetSockOpt(fd, SO_REUSEPORT, value); +} + +Errno ProxySocket::SetTimeStamp(u32 value) { + return SetSockOpt(fd, SO_TIMESTAMP, value); +} + +Errno ProxySocket::SetAcceptFilter(u32 value) { + return SetSockOpt(fd, SO_ACCEPTFILTER, value); +} + Errno ProxySocket::SetNonBlock(bool enable) { blocking = !enable; return Errno::SUCCESS; diff --git a/src/core/internal_network/socket_proxy.h b/src/core/internal_network/socket_proxy.h index 8ba8ffbdd9..9b7c3fb4c9 100644 --- a/src/core/internal_network/socket_proxy.h +++ b/src/core/internal_network/socket_proxy.h @@ -56,21 +56,16 @@ public: const Network::SockAddrIn* addr) override; Errno SetLinger(bool enable, u32 linger) override; - Errno SetReuseAddr(bool enable) override; - Errno SetBroadcast(bool enable) override; - Errno SetKeepAlive(bool enable) override; - Errno SetSndBuf(u32 value) override; - Errno SetRcvBuf(u32 value) override; - Errno SetSndTimeo(u32 value) override; - Errno SetRcvTimeo(u32 value) override; - + Errno SetReusePort(u32 value) override; + Errno SetTimeStamp(u32 value) override; + Errno SetAcceptFilter(u32 value) override; Errno SetNonBlock(bool enable) override; template diff --git a/src/core/internal_network/socket_types.h b/src/core/internal_network/socket_types.h index bc0be4300e..454b13446f 100644 --- a/src/core/internal_network/socket_types.h +++ b/src/core/internal_network/socket_types.h @@ -26,7 +26,13 @@ enum class Errno : u32 { MFILE = 24, PIPE = 32, MSGSIZE = 90, + PROTOTYPE = 91, + NOPROTOOPT = 92, + PROTONOSUPPORT = 93, + SOCKTNOSUPPORT = 94, + NOTSUP = 95, ADDRINUSE = 98, + ADDRNOTAVAIL = 99, NETDOWN = 100, NETUNREACH = 101, CONNABORTED = 103, @@ -233,16 +239,22 @@ enum class SocketLevel : u32 { }; enum class OptName : u32 { - REUSEADDR = 0x4, - KEEPALIVE = 0x8, - BROADCAST = 0x20, - LINGER = 0x80, + REUSEADDR = 0x0004, + KEEPALIVE = 0x0008, + DONTROUTE = 0x0010, + BROADCAST = 0x0020, + USELOOPBACK = 0x0040, + LINGER = 0x0080, + OOBINLINE = 0x0100, + REUSEPORT = 0x0200, + TIMESTAMP = 0x0400, + NOSIGPIPE = 0x0800, // at least according to libnx + ACCEPTFILER = 0x1000, SNDBUF = 0x1001, RCVBUF = 0x1002, SNDTIMEO = 0x1005, RCVTIMEO = 0x1006, ERROR_ = 0x1007, // avoid name collision with Windows macro - NOSIGPIPE = 0x800, // at least according to libnx ACCEPTFILTER = 0x1000, BINTIME = 0x2000, NO_OFFLOAD = 0x4000, diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h index abea299bcd..3aa9c29970 100644 --- a/src/core/internal_network/sockets.h +++ b/src/core/internal_network/sockets.h @@ -68,21 +68,16 @@ public: const Network::SockAddrIn* addr) = 0; virtual Errno SetLinger(bool enable, u32 linger) = 0; - virtual Errno SetReuseAddr(bool enable) = 0; - virtual Errno SetKeepAlive(bool enable) = 0; - virtual Errno SetBroadcast(bool enable) = 0; - virtual Errno SetSndBuf(u32 value) = 0; - virtual Errno SetRcvBuf(u32 value) = 0; - virtual Errno SetSndTimeo(u32 value) = 0; - virtual Errno SetRcvTimeo(u32 value) = 0; - + virtual Errno SetReusePort(u32 value) = 0; + virtual Errno SetTimeStamp(u32 value) = 0; + virtual Errno SetAcceptFilter(u32 value) = 0; virtual Errno SetNonBlock(bool enable) = 0; virtual std::pair GetPendingError() = 0; @@ -95,7 +90,6 @@ public: return fd; } -protected: SOCKET fd = INVALID_SOCKET; }; @@ -136,21 +130,16 @@ public: const Network::SockAddrIn* addr) override; Errno SetLinger(bool enable, u32 linger) override; - Errno SetReuseAddr(bool enable) override; - Errno SetKeepAlive(bool enable) override; - Errno SetBroadcast(bool enable) override; - Errno SetSndBuf(u32 value) override; - Errno SetRcvBuf(u32 value) override; - Errno SetSndTimeo(u32 value) override; - Errno SetRcvTimeo(u32 value) override; - + Errno SetReusePort(u32 value) override; + Errno SetTimeStamp(u32 value) override; + Errno SetAcceptFilter(u32 value) override; Errno SetNonBlock(bool enable) override; template