From 5a9e61997cb45f7f3f66a8f9f6e39f4a1b7abc06 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Mon, 15 May 2017 16:56:17 +0100 Subject: [PATCH] IOS/Network: Emulate socket fd table --- Source/Core/Core/IOS/Network/IP/Top.cpp | 24 +++++++++-------- Source/Core/Core/IOS/Network/SSL.cpp | 4 ++- Source/Core/Core/IOS/Network/SSL.h | 1 + Source/Core/Core/IOS/Network/Socket.cpp | 34 +++++++++++++++++-------- Source/Core/Core/IOS/Network/Socket.h | 3 ++- 5 files changed, 43 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp index 2cb5fb0164..cd25283e1a 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.cpp +++ b/Source/Core/Core/IOS/Network/IP/Top.cpp @@ -290,7 +290,7 @@ IPCCommandResult NetIPTop::HandleShutdownRequest(const IOCtlRequest& request) u32 fd = Memory::Read_U32(request.buffer_in); u32 how = Memory::Read_U32(request.buffer_in + 4); - int ret = shutdown(fd, how); + int ret = shutdown(WiiSockMan::GetInstance().GetHostSocket(fd), how); return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false)); } @@ -299,7 +299,7 @@ IPCCommandResult NetIPTop::HandleListenRequest(const IOCtlRequest& request) { u32 fd = Memory::Read_U32(request.buffer_in); u32 BACKLOG = Memory::Read_U32(request.buffer_in + 0x04); - u32 ret = listen(fd, BACKLOG); + u32 ret = listen(WiiSockMan::GetInstance().GetHostSocket(fd), BACKLOG); request.Log(GetDeviceName(), LogTypes::IOS_WC24); return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false)); @@ -320,7 +320,8 @@ IPCCommandResult NetIPTop::HandleGetSockOptRequest(const IOCtlRequest& request) u8 optval[20]; u32 optlen = 4; - int ret = getsockopt(fd, nat_level, nat_optname, (char*)&optval, (socklen_t*)&optlen); + int ret = getsockopt(WiiSockMan::GetInstance().GetHostSocket(fd), nat_level, nat_optname, + (char*)&optval, (socklen_t*)&optlen); const s32 return_value = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false); Memory::Write_U32(optlen, request.buffer_out + 0xC); @@ -366,7 +367,8 @@ IPCCommandResult NetIPTop::HandleSetSockOptRequest(const IOCtlRequest& request) int nat_level = MapWiiSockOptLevelToNative(level); int nat_optname = MapWiiSockOptNameToNative(optname); - int ret = setsockopt(fd, nat_level, nat_optname, (char*)optval, optlen); + int ret = setsockopt(WiiSockMan::GetInstance().GetHostSocket(fd), nat_level, nat_optname, + (char*)optval, optlen); return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false)); } @@ -378,7 +380,7 @@ IPCCommandResult NetIPTop::HandleGetSockNameRequest(const IOCtlRequest& request) sockaddr sa; socklen_t sa_len = sizeof(sa); - int ret = getsockname(fd, &sa, &sa_len); + int ret = getsockname(WiiSockMan::GetInstance().GetHostSocket(fd), &sa, &sa_len); if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(IOS_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating"); @@ -402,7 +404,7 @@ IPCCommandResult NetIPTop::HandleGetPeerNameRequest(const IOCtlRequest& request) sockaddr sa; socklen_t sa_len = sizeof(sa); - int ret = getpeername(fd, &sa, &sa_len); + int ret = getpeername(WiiSockMan::GetInstance().GetHostSocket(fd), &sa, &sa_len); if (request.buffer_out_size < 2 + sizeof(sa.sa_data)) WARN_LOG(IOS_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating"); @@ -555,7 +557,8 @@ IPCCommandResult NetIPTop::HandlePollRequest(const IOCtlRequest& request) for (int i = 0; i < nfds; ++i) { - ufds[i].fd = Memory::Read_U32(request.buffer_out + 0xc * i); // fd + s32 wii_fd = Memory::Read_U32(request.buffer_out + 0xc * i); + ufds[i].fd = WiiSockMan::GetInstance().GetHostSocket(wii_fd); // fd int events = Memory::Read_U32(request.buffer_out + 0xc * i + 4); // events ufds[i].revents = Memory::Read_U32(request.buffer_out + 0xc * i + 8); // revents @@ -571,7 +574,7 @@ IPCCommandResult NetIPTop::HandlePollRequest(const IOCtlRequest& request) DEBUG_LOG(IOS_NET, "IOCTL_SO_POLL(%d) " "Sock: %08x, Unknown: %08x, Events: %08x, " "NativeEvents: %08x", - i, ufds[i].fd, unknown, events, ufds[i].events); + i, wii_fd, unknown, events, ufds[i].events); // Do not pass return-only events to the native poll ufds[i].events &= ~(POLLERR | POLLHUP | POLLNVAL | UNSUPPORTED_WSAPOLL); @@ -1009,10 +1012,11 @@ IPCCommandResult NetIPTop::HandleICMPPingRequest(const IOCtlVRequest& request) icmp_length = 22; } - int ret = icmp_echo_req(fd, &addr, data, icmp_length); + int ret = icmp_echo_req(WiiSockMan::GetInstance().GetHostSocket(fd), &addr, data, icmp_length); if (ret == icmp_length) { - ret = icmp_echo_rep(fd, &addr, (u32)timeout, icmp_length); + ret = icmp_echo_rep(WiiSockMan::GetInstance().GetHostSocket(fd), &addr, + static_cast(timeout), icmp_length); } // TODO proper error codes diff --git a/Source/Core/Core/IOS/Network/SSL.cpp b/Source/Core/Core/IOS/Network/SSL.cpp index ca3160bee8..ef826a7a58 100644 --- a/Source/Core/Core/IOS/Network/SSL.cpp +++ b/Source/Core/Core/IOS/Network/SSL.cpp @@ -424,8 +424,10 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request) WII_SSL* ssl = &_SSL[sslID]; mbedtls_ssl_setup(&ssl->ctx, &ssl->config); ssl->sockfd = Memory::Read_U32(BufferOut2); + WiiSockMan& sm = WiiSockMan::GetInstance(); + ssl->hostfd = sm.GetHostSocket(ssl->sockfd); INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", ssl->sockfd); - mbedtls_ssl_set_bio(&ssl->ctx, &ssl->sockfd, mbedtls_net_send, mbedtls_net_recv, nullptr); + mbedtls_ssl_set_bio(&ssl->ctx, &ssl->hostfd, mbedtls_net_send, mbedtls_net_recv, nullptr); Memory::Write_U32(SSL_OK, BufferIn); } else diff --git a/Source/Core/Core/IOS/Network/SSL.h b/Source/Core/Core/IOS/Network/SSL.h index f1f9f4c611..c1253e8189 100644 --- a/Source/Core/Core/IOS/Network/SSL.h +++ b/Source/Core/Core/IOS/Network/SSL.h @@ -81,6 +81,7 @@ struct WII_SSL mbedtls_x509_crt clicert; mbedtls_pk_context pk; int sockfd; + int hostfd; std::string hostname; bool active; }; diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp index 1698eed629..08033f5801 100644 --- a/Source/Core/Core/IOS/Network/Socket.cpp +++ b/Source/Core/Core/IOS/Network/Socket.cpp @@ -239,6 +239,7 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTL_SO_ACCEPT: { + s32 ret; if (ioctl.buffer_out_size > 0) { sockaddr_in local_name; @@ -246,18 +247,17 @@ void WiiSocket::Update(bool read, bool write, bool except) WiiSockMan::Convert(*wii_name, local_name); socklen_t addrlen = sizeof(sockaddr_in); - int ret = (s32)accept(fd, (sockaddr*)&local_name, &addrlen); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true); + ret = static_cast(accept(fd, (sockaddr*)&local_name, &addrlen)); WiiSockMan::Convert(local_name, *wii_name, addrlen); } else { - int ret = (s32)accept(fd, nullptr, nullptr); - ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true); + ret = static_cast(accept(fd, nullptr, nullptr)); } - WiiSockMan::GetInstance().AddSocket(ReturnValue); + ret = WiiSockMan::GetInstance().AddSocket(ret); + ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true); ioctl.Log("IOCTL_SO_ACCEPT", LogTypes::IOS_NET); break; @@ -604,23 +604,35 @@ void WiiSocket::DoSock(Request request, SSL_IOCTL type) pending_sockops.push_back(so); } -void WiiSockMan::AddSocket(s32 fd) +s32 WiiSockMan::AddSocket(s32 fd) { if (fd >= 0) { - WiiSocket& sock = WiiSockets[fd]; + s32 wii_fd = 0; + while (WiiSockets.count(wii_fd) > 0) + wii_fd += 1; + WiiSocket& sock = WiiSockets[wii_fd]; sock.SetFd(fd); + return wii_fd; } + return fd; } s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol) { - s32 fd = (s32)socket(af, type, protocol); - s32 ret = GetNetErrorCode(fd, "NewSocket", false); - AddSocket(ret); + s32 fd = static_cast(socket(af, type, protocol)); + s32 wii_fd = AddSocket(fd); + s32 ret = GetNetErrorCode(wii_fd, "NewSocket", false); return ret; } +s32 WiiSockMan::GetHostSocket(s32 wii_fd) const +{ + if (WiiSockets.count(wii_fd) > 0) + return WiiSockets.at(wii_fd).fd; + return EBADF; +} + s32 WiiSockMan::DeleteSocket(s32 s) { s32 ReturnValue = EBADF; @@ -694,7 +706,7 @@ void WiiSockMan::Convert(sockaddr_in const& from, WiiSockAddrIn& to, s32 addrlen to.addr.addr = from.sin_addr.s_addr; to.family = from.sin_family & 0xFF; to.port = from.sin_port; - if (addrlen < 0 || addrlen > (s32)sizeof(WiiSockAddrIn)) + if (addrlen < 0 || addrlen > static_cast(sizeof(WiiSockAddrIn))) to.len = sizeof(WiiSockAddrIn); else to.len = addrlen; diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h index de9d4b4761..a1fbe61332 100644 --- a/Source/Core/Core/IOS/Network/Socket.h +++ b/Source/Core/Core/IOS/Network/Socket.h @@ -221,7 +221,8 @@ public: static void Convert(sockaddr_in const& from, WiiSockAddrIn& to, s32 addrlen = -1); // NON-BLOCKING FUNCTIONS s32 NewSocket(s32 af, s32 type, s32 protocol); - void AddSocket(s32 fd); + s32 AddSocket(s32 fd); + s32 GetHostSocket(s32 wii_fd) const; s32 DeleteSocket(s32 s); s32 GetLastNetError() const { return errno_last; } void SetLastNetError(s32 error) { errno_last = error; }