IOS/Network: Emulate socket fd table
This commit is contained in:
parent
4b53093acb
commit
5a9e61997c
|
@ -290,7 +290,7 @@ IPCCommandResult NetIPTop::HandleShutdownRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
u32 fd = Memory::Read_U32(request.buffer_in);
|
u32 fd = Memory::Read_U32(request.buffer_in);
|
||||||
u32 how = Memory::Read_U32(request.buffer_in + 4);
|
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));
|
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 fd = Memory::Read_U32(request.buffer_in);
|
||||||
u32 BACKLOG = Memory::Read_U32(request.buffer_in + 0x04);
|
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);
|
request.Log(GetDeviceName(), LogTypes::IOS_WC24);
|
||||||
return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false));
|
return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false));
|
||||||
|
@ -320,7 +320,8 @@ IPCCommandResult NetIPTop::HandleGetSockOptRequest(const IOCtlRequest& request)
|
||||||
u8 optval[20];
|
u8 optval[20];
|
||||||
u32 optlen = 4;
|
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);
|
const s32 return_value = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false);
|
||||||
|
|
||||||
Memory::Write_U32(optlen, request.buffer_out + 0xC);
|
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_level = MapWiiSockOptLevelToNative(level);
|
||||||
int nat_optname = MapWiiSockOptNameToNative(optname);
|
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));
|
return GetDefaultReply(WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +380,7 @@ IPCCommandResult NetIPTop::HandleGetSockNameRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
sockaddr sa;
|
sockaddr sa;
|
||||||
socklen_t sa_len = sizeof(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))
|
if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
|
||||||
WARN_LOG(IOS_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating");
|
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;
|
sockaddr sa;
|
||||||
socklen_t sa_len = sizeof(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))
|
if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
|
||||||
WARN_LOG(IOS_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating");
|
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)
|
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
|
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
|
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) "
|
DEBUG_LOG(IOS_NET, "IOCTL_SO_POLL(%d) "
|
||||||
"Sock: %08x, Unknown: %08x, Events: %08x, "
|
"Sock: %08x, Unknown: %08x, Events: %08x, "
|
||||||
"NativeEvents: %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
|
// Do not pass return-only events to the native poll
|
||||||
ufds[i].events &= ~(POLLERR | POLLHUP | POLLNVAL | UNSUPPORTED_WSAPOLL);
|
ufds[i].events &= ~(POLLERR | POLLHUP | POLLNVAL | UNSUPPORTED_WSAPOLL);
|
||||||
|
@ -1009,10 +1012,11 @@ IPCCommandResult NetIPTop::HandleICMPPingRequest(const IOCtlVRequest& request)
|
||||||
icmp_length = 22;
|
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)
|
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<u32>(timeout), icmp_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO proper error codes
|
// TODO proper error codes
|
||||||
|
|
|
@ -424,8 +424,10 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
|
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
|
||||||
ssl->sockfd = Memory::Read_U32(BufferOut2);
|
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);
|
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);
|
Memory::Write_U32(SSL_OK, BufferIn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct WII_SSL
|
||||||
mbedtls_x509_crt clicert;
|
mbedtls_x509_crt clicert;
|
||||||
mbedtls_pk_context pk;
|
mbedtls_pk_context pk;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
int hostfd;
|
||||||
std::string hostname;
|
std::string hostname;
|
||||||
bool active;
|
bool active;
|
||||||
};
|
};
|
||||||
|
|
|
@ -239,6 +239,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
||||||
}
|
}
|
||||||
case IOCTL_SO_ACCEPT:
|
case IOCTL_SO_ACCEPT:
|
||||||
{
|
{
|
||||||
|
s32 ret;
|
||||||
if (ioctl.buffer_out_size > 0)
|
if (ioctl.buffer_out_size > 0)
|
||||||
{
|
{
|
||||||
sockaddr_in local_name;
|
sockaddr_in local_name;
|
||||||
|
@ -246,18 +247,17 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
||||||
WiiSockMan::Convert(*wii_name, local_name);
|
WiiSockMan::Convert(*wii_name, local_name);
|
||||||
|
|
||||||
socklen_t addrlen = sizeof(sockaddr_in);
|
socklen_t addrlen = sizeof(sockaddr_in);
|
||||||
int ret = (s32)accept(fd, (sockaddr*)&local_name, &addrlen);
|
ret = static_cast<s32>(accept(fd, (sockaddr*)&local_name, &addrlen));
|
||||||
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true);
|
|
||||||
|
|
||||||
WiiSockMan::Convert(local_name, *wii_name, addrlen);
|
WiiSockMan::Convert(local_name, *wii_name, addrlen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ret = (s32)accept(fd, nullptr, nullptr);
|
ret = static_cast<s32>(accept(fd, nullptr, nullptr));
|
||||||
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WiiSockMan::GetInstance().AddSocket(ReturnValue);
|
ret = WiiSockMan::GetInstance().AddSocket(ret);
|
||||||
|
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true);
|
||||||
|
|
||||||
ioctl.Log("IOCTL_SO_ACCEPT", LogTypes::IOS_NET);
|
ioctl.Log("IOCTL_SO_ACCEPT", LogTypes::IOS_NET);
|
||||||
break;
|
break;
|
||||||
|
@ -604,23 +604,35 @@ void WiiSocket::DoSock(Request request, SSL_IOCTL type)
|
||||||
pending_sockops.push_back(so);
|
pending_sockops.push_back(so);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiiSockMan::AddSocket(s32 fd)
|
s32 WiiSockMan::AddSocket(s32 fd)
|
||||||
{
|
{
|
||||||
if (fd >= 0)
|
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);
|
sock.SetFd(fd);
|
||||||
|
return wii_fd;
|
||||||
}
|
}
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol)
|
s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol)
|
||||||
{
|
{
|
||||||
s32 fd = (s32)socket(af, type, protocol);
|
s32 fd = static_cast<s32>(socket(af, type, protocol));
|
||||||
s32 ret = GetNetErrorCode(fd, "NewSocket", false);
|
s32 wii_fd = AddSocket(fd);
|
||||||
AddSocket(ret);
|
s32 ret = GetNetErrorCode(wii_fd, "NewSocket", false);
|
||||||
return ret;
|
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 WiiSockMan::DeleteSocket(s32 s)
|
||||||
{
|
{
|
||||||
s32 ReturnValue = EBADF;
|
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.addr.addr = from.sin_addr.s_addr;
|
||||||
to.family = from.sin_family & 0xFF;
|
to.family = from.sin_family & 0xFF;
|
||||||
to.port = from.sin_port;
|
to.port = from.sin_port;
|
||||||
if (addrlen < 0 || addrlen > (s32)sizeof(WiiSockAddrIn))
|
if (addrlen < 0 || addrlen > static_cast<s32>(sizeof(WiiSockAddrIn)))
|
||||||
to.len = sizeof(WiiSockAddrIn);
|
to.len = sizeof(WiiSockAddrIn);
|
||||||
else
|
else
|
||||||
to.len = addrlen;
|
to.len = addrlen;
|
||||||
|
|
|
@ -221,7 +221,8 @@ public:
|
||||||
static void Convert(sockaddr_in const& from, WiiSockAddrIn& to, s32 addrlen = -1);
|
static void Convert(sockaddr_in const& from, WiiSockAddrIn& to, s32 addrlen = -1);
|
||||||
// NON-BLOCKING FUNCTIONS
|
// NON-BLOCKING FUNCTIONS
|
||||||
s32 NewSocket(s32 af, s32 type, s32 protocol);
|
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 DeleteSocket(s32 s);
|
||||||
s32 GetLastNetError() const { return errno_last; }
|
s32 GetLastNetError() const { return errno_last; }
|
||||||
void SetLastNetError(s32 error) { errno_last = error; }
|
void SetLastNetError(s32 error) { errno_last = error; }
|
||||||
|
|
Loading…
Reference in New Issue