diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/soc_u.cpp | 52 |
1 files 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) { | |||
| 151 | return error; | 151 | return error; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | /// Holds the translation from system network socket options to 3DS network socket options | ||
| 155 | /// Note: -1 = No effect/unavailable | ||
| 156 | static const std::unordered_map<int, int> sockopt_map = { { | ||
| 157 | { 0x0004, SO_REUSEADDR }, | ||
| 158 | { 0x0080, -1 }, | ||
| 159 | { 0x0100, -1 }, | ||
| 160 | { 0x1001, SO_SNDBUF }, | ||
| 161 | { 0x1002, SO_RCVBUF }, | ||
| 162 | { 0x1003, -1 }, | ||
| 163 | #ifdef _WIN32 | ||
| 164 | /// Unsupported in WinSock2 | ||
| 165 | { 0x1004, -1 }, | ||
| 166 | #else | ||
| 167 | { 0x1004, SO_RCVLOWAT }, | ||
| 168 | #endif | ||
| 169 | { 0x1008, SO_TYPE }, | ||
| 170 | { 0x1009, SO_ERROR }, | ||
| 171 | }}; | ||
| 172 | |||
| 173 | /// Converts a socket option from 3ds-specific to platform-specific | ||
| 174 | static int TranslateSockOpt(int console_opt_name) { | ||
| 175 | auto found = sockopt_map.find(console_opt_name); | ||
| 176 | if (found != sockopt_map.end()) { | ||
| 177 | return found->second; | ||
| 178 | } | ||
| 179 | return console_opt_name; | ||
| 180 | } | ||
| 181 | |||
| 154 | /// Holds information about a particular socket | 182 | /// Holds information about a particular socket |
| 155 | struct SocketHolder { | 183 | struct SocketHolder { |
| 156 | u32 socket_fd; ///< The socket descriptor | 184 | u32 socket_fd; ///< The socket descriptor |
| @@ -295,26 +323,6 @@ union CTRSockAddr { | |||
| 295 | } | 323 | } |
| 296 | }; | 324 | }; |
| 297 | 325 | ||
| 298 | /// Filters valid sockopt names and converts from platform-specific name if necessary | ||
| 299 | static int GetSockOptName(u32 name) { | ||
| 300 | switch(name) { | ||
| 301 | case SO_RCVLOWAT: | ||
| 302 | #ifdef _WIN32 | ||
| 303 | // LOWAT not supported by WinSock | ||
| 304 | return -1; | ||
| 305 | #endif | ||
| 306 | case SO_REUSEADDR: | ||
| 307 | case SO_SNDBUF: | ||
| 308 | case SO_RCVBUF: | ||
| 309 | case SO_TYPE: | ||
| 310 | case SO_ERROR: | ||
| 311 | return name; | ||
| 312 | default: | ||
| 313 | // all other options are either ineffectual or unsupported | ||
| 314 | return -1; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | /// Holds info about the currently open sockets | 326 | /// Holds info about the currently open sockets |
| 319 | static std::unordered_map<u32, SocketHolder> open_sockets; | 327 | static std::unordered_map<u32, SocketHolder> open_sockets; |
| 320 | 328 | ||
| @@ -748,7 +756,7 @@ static void GetSockOpt(Service::Interface* self) { | |||
| 748 | u32* cmd_buffer = Kernel::GetCommandBuffer(); | 756 | u32* cmd_buffer = Kernel::GetCommandBuffer(); |
| 749 | u32 socket_handle = cmd_buffer[1]; | 757 | u32 socket_handle = cmd_buffer[1]; |
| 750 | u32 level = cmd_buffer[2]; | 758 | u32 level = cmd_buffer[2]; |
| 751 | int optname = GetSockOptName(cmd_buffer[3]); | 759 | int optname = TranslateSockOpt(cmd_buffer[3]); |
| 752 | socklen_t optlen = (socklen_t)cmd_buffer[4]; | 760 | socklen_t optlen = (socklen_t)cmd_buffer[4]; |
| 753 | 761 | ||
| 754 | int ret = -1; | 762 | int ret = -1; |
| @@ -783,7 +791,7 @@ static void SetSockOpt(Service::Interface* self) { | |||
| 783 | u32* cmd_buffer = Kernel::GetCommandBuffer(); | 791 | u32* cmd_buffer = Kernel::GetCommandBuffer(); |
| 784 | u32 socket_handle = cmd_buffer[1]; | 792 | u32 socket_handle = cmd_buffer[1]; |
| 785 | u32 level = cmd_buffer[2]; | 793 | u32 level = cmd_buffer[2]; |
| 786 | int optname = GetSockOptName(cmd_buffer[3]); | 794 | int optname = TranslateSockOpt(cmd_buffer[3]); |
| 787 | 795 | ||
| 788 | int ret = -1; | 796 | int ret = -1; |
| 789 | int err = 0; | 797 | int err = 0; |