From 58ee548ed88122086712f58bf05495655b5fd3f7 Mon Sep 17 00:00:00 2001 From: Ryan Loebs Date: Fri, 1 Apr 2016 22:19:21 -0700 Subject: Rework sockopt translation to match the error translation code already in place --- src/core/hle/service/soc_u.cpp | 52 ++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 6ab246ba8..d3e5d4bca 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -151,6 +151,34 @@ static int TranslateError(int error) { return error; } +/// Holds the translation from system network socket options to 3DS network socket options +/// Note: -1 = No effect/unavailable +static const std::unordered_map sockopt_map = { { + { 0x0004, SO_REUSEADDR }, + { 0x0080, -1 }, + { 0x0100, -1 }, + { 0x1001, SO_SNDBUF }, + { 0x1002, SO_RCVBUF }, + { 0x1003, -1 }, +#ifdef _WIN32 + /// Unsupported in WinSock2 + { 0x1004, -1 }, +#else + { 0x1004, SO_RCVLOWAT }, +#endif + { 0x1008, SO_TYPE }, + { 0x1009, SO_ERROR }, +}}; + +/// Converts a socket option from 3ds-specific to platform-specific +static int TranslateSockOpt(int console_opt_name) { + auto found = sockopt_map.find(console_opt_name); + if (found != sockopt_map.end()) { + return found->second; + } + return console_opt_name; +} + /// Holds information about a particular socket struct SocketHolder { u32 socket_fd; ///< The socket descriptor @@ -295,26 +323,6 @@ union CTRSockAddr { } }; -/// Filters valid sockopt names and converts from platform-specific name if necessary -static int GetSockOptName(u32 name) { - switch(name) { - case SO_RCVLOWAT: -#ifdef _WIN32 - // LOWAT not supported by WinSock - return -1; -#endif - case SO_REUSEADDR: - case SO_SNDBUF: - case SO_RCVBUF: - case SO_TYPE: - case SO_ERROR: - return name; - default: - // all other options are either ineffectual or unsupported - return -1; - } -} - /// Holds info about the currently open sockets static std::unordered_map open_sockets; @@ -748,7 +756,7 @@ static void GetSockOpt(Service::Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 level = cmd_buffer[2]; - int optname = GetSockOptName(cmd_buffer[3]); + int optname = TranslateSockOpt(cmd_buffer[3]); socklen_t optlen = (socklen_t)cmd_buffer[4]; int ret = -1; @@ -783,7 +791,7 @@ static void SetSockOpt(Service::Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 level = cmd_buffer[2]; - int optname = GetSockOptName(cmd_buffer[3]); + int optname = TranslateSockOpt(cmd_buffer[3]); int ret = -1; int err = 0; -- cgit v1.2.3