28 changes: 16 additions & 12 deletions Source/Core/Core/IOS/Network/Socket.cpp
Expand Up @@ -85,6 +85,10 @@ static s32 TranslateErrorCode(s32 native_error, bool is_rw)
}
}

WiiSockMan::WiiSockMan() = default;

WiiSockMan::~WiiSockMan() = default;

// Don't use string! (see https://github.com/dolphin-emu/dolphin/pull/3143)
s32 WiiSockMan::GetNetErrorCode(s32 ret, std::string_view caller, bool is_rw)
{
Expand All @@ -96,15 +100,15 @@ s32 WiiSockMan::GetNetErrorCode(s32 ret, std::string_view caller, bool is_rw)

if (ret >= 0)
{
WiiSockMan::GetInstance().SetLastNetError(ret);
SetLastNetError(ret);
return ret;
}

ERROR_LOG_FMT(IOS_NET, "{} failed with error {}: {}, ret= {}", caller, error_code,
Common::DecodeNetworkError(error_code), ret);

const s32 return_value = TranslateErrorCode(error_code, is_rw);
WiiSockMan::GetInstance().SetLastNetError(return_value);
SetLastNetError(return_value);

return return_value;
}
Expand Down Expand Up @@ -158,7 +162,7 @@ s32 WiiSocket::Shutdown(u32 how)

// Adjust pending operations
// Values based on https://dolp.in/pr8758 hwtest
const s32 ret = WiiSockMan::GetNetErrorCode(shutdown(fd, how), "SO_SHUTDOWN", false);
const s32 ret = m_socket_manager.GetNetErrorCode(shutdown(fd, how), "SO_SHUTDOWN", false);
const bool shut_read = how == 0 || how == 2;
const bool shut_write = how == 1 || how == 2;
for (auto& op : pending_sockops)
Expand Down Expand Up @@ -198,11 +202,11 @@ s32 WiiSocket::CloseFd()
if (fd >= 0)
{
s32 ret = closesocket(fd);
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "CloseFd", false);
ReturnValue = m_socket_manager.GetNetErrorCode(ret, "CloseFd", false);
}
else
{
ReturnValue = WiiSockMan::GetNetErrorCode(EITHER(WSAENOTSOCK, EBADF), "CloseFd", false);
ReturnValue = m_socket_manager.GetNetErrorCode(EITHER(WSAENOTSOCK, EBADF), "CloseFd", false);
}
fd = -1;

Expand Down Expand Up @@ -273,7 +277,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
WiiSockMan::ToNativeAddrIn(addr, &local_name);

int ret = bind(fd, (sockaddr*)&local_name, sizeof(local_name));
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_BIND", false);
ReturnValue = m_socket_manager.GetNetErrorCode(ret, "SO_BIND", false);

INFO_LOG_FMT(IOS_NET, "IOCTL_SO_BIND ({:08X}, {}:{}) = {}", wii_fd,
inet_ntoa(local_name.sin_addr), Common::swap16(local_name.sin_port), ret);
Expand All @@ -286,7 +290,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
WiiSockMan::ToNativeAddrIn(addr, &local_name);

int ret = connect(fd, (sockaddr*)&local_name, sizeof(local_name));
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_CONNECT", false);
ReturnValue = m_socket_manager.GetNetErrorCode(ret, "SO_CONNECT", false);
UpdateConnectingState(ReturnValue);

INFO_LOG_FMT(IOS_NET, "IOCTL_SO_CONNECT ({:08x}, {}:{}) = {}", wii_fd,
Expand All @@ -312,7 +316,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
ret = static_cast<s32>(accept(fd, nullptr, nullptr));
}

ReturnValue = WiiSockMan::GetInstance().AddSocket(ret, true);
ReturnValue = m_socket_manager.AddSocket(ret, true);

ioctl.Log("IOCTL_SO_ACCEPT", Common::Log::LogType::IOS_NET);
break;
Expand Down Expand Up @@ -593,7 +597,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
auto* to = has_destaddr ? reinterpret_cast<sockaddr*>(&local_name) : nullptr;
socklen_t tolen = has_destaddr ? sizeof(sockaddr) : 0;
const int ret = sendto(fd, data, BufferInSize, flags, to, tolen);
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_SENDTO", true);
ReturnValue = m_socket_manager.GetNetErrorCode(ret, "SO_SENDTO", true);
if (ret > 0)
system.GetPowerPC().GetDebugInterface().NetworkLogger()->LogWrite(data, ret, fd, to);

Expand Down Expand Up @@ -651,8 +655,8 @@ void WiiSocket::Update(bool read, bool write, bool except)
auto* from = BufferOutSize2 ? reinterpret_cast<sockaddr*>(&local_name) : nullptr;
socklen_t* fromlen = BufferOutSize2 ? &addrlen : nullptr;
const int ret = recvfrom(fd, data, data_len, flags, from, fromlen);
ReturnValue =
WiiSockMan::GetNetErrorCode(ret, BufferOutSize2 ? "SO_RECVFROM" : "SO_RECV", true);
ReturnValue = m_socket_manager.GetNetErrorCode(
ret, BufferOutSize2 ? "SO_RECVFROM" : "SO_RECV", true);
if (ret > 0)
system.GetPowerPC().GetDebugInterface().NetworkLogger()->LogRead(data, ret, fd, from);

Expand Down Expand Up @@ -862,7 +866,7 @@ s32 WiiSockMan::AddSocket(s32 fd, bool is_rw)
}
else
{
WiiSocket& sock = WiiSockets[wii_fd];
WiiSocket& sock = WiiSockets.emplace(wii_fd, *this).first->second;
sock.SetFd(fd);
sock.SetWiiFd(wii_fd);
Core::System::GetInstance().GetPowerPC().GetDebugInterface().NetworkLogger()->OnNewSocket(fd);
Expand Down
27 changes: 13 additions & 14 deletions Source/Core/Core/IOS/Network/Socket.h
Expand Up @@ -174,10 +174,12 @@ struct WiiSockAddrIn
};
#pragma pack(pop)

class WiiSockMan;

class WiiSocket
{
public:
WiiSocket() = default;
explicit WiiSocket(WiiSockMan& socket_manager) : m_socket_manager(socket_manager) {}
WiiSocket(const WiiSocket&) = delete;
WiiSocket(WiiSocket&&) = default;
~WiiSocket();
Expand Down Expand Up @@ -225,6 +227,8 @@ class WiiSocket
bool IsValid() const { return fd >= 0; }
bool IsTCP() const;

WiiSockMan& m_socket_manager;

s32 fd = -1;
s32 wii_fd = -1;
bool nonBlock = false;
Expand All @@ -251,14 +255,15 @@ class WiiSockMan
s64 timeout = 0;
};

static s32 GetNetErrorCode(s32 ret, std::string_view caller, bool is_rw);
static char* DecodeError(s32 ErrorCode);
WiiSockMan();
WiiSockMan(const WiiSockMan&) = delete;
WiiSockMan& operator=(const WiiSockMan&) = delete;
WiiSockMan(WiiSockMan&&) = delete;
WiiSockMan& operator=(WiiSockMan&&) = delete;
~WiiSockMan();

s32 GetNetErrorCode(s32 ret, std::string_view caller, bool is_rw);

static WiiSockMan& GetInstance()
{
static WiiSockMan instance; // Guaranteed to be destroyed.
return instance; // Instantiated on first use.
}
void Update();
static void ToNativeAddrIn(const u8* from, sockaddr_in* to);
static void ToWiiAddrIn(const sockaddr_in& from, u8* to,
Expand Down Expand Up @@ -296,12 +301,6 @@ class WiiSockMan
void UpdateWantDeterminism(bool want);

private:
WiiSockMan() = default;
WiiSockMan(const WiiSockMan&) = delete;
WiiSockMan& operator=(const WiiSockMan&) = delete;
WiiSockMan(WiiSockMan&&) = delete;
WiiSockMan& operator=(WiiSockMan&&) = delete;

void UpdatePollCommands();

std::unordered_map<s32, WiiSocket> WiiSockets;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/State.cpp
Expand Up @@ -96,7 +96,7 @@ static size_t s_state_writes_in_queue;
static std::condition_variable s_state_write_queue_is_empty;

// Don't forget to increase this after doing changes on the savestate system
constexpr u32 STATE_VERSION = 161; // Last changed in PR 11655
constexpr u32 STATE_VERSION = 162; // Last changed in PR 11767

// Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list,
Expand Down
20 changes: 16 additions & 4 deletions Source/Core/DolphinQt/Debugger/NetworkWidget.cpp
Expand Up @@ -24,8 +24,10 @@

#include "Common/FileUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/IOS/Network/SSL.h"
#include "Core/IOS/Network/Socket.h"
#include "Core/System.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/Settings.h"

Expand Down Expand Up @@ -95,9 +97,8 @@ QTableWidgetItem* GetSocketState(s32 host_fd)
return new QTableWidgetItem(QTableWidget::tr("Unbound"));
}

QTableWidgetItem* GetSocketBlocking(s32 wii_fd)
static QTableWidgetItem* GetSocketBlocking(const IOS::HLE::WiiSockMan& socket_manager, s32 wii_fd)
{
const auto& socket_manager = IOS::HLE::WiiSockMan::GetInstance();
if (socket_manager.GetHostSocket(wii_fd) < 0)
return new QTableWidgetItem();
const bool is_blocking = socket_manager.IsSocketBlocking(wii_fd);
Expand Down Expand Up @@ -238,16 +239,27 @@ void NetworkWidget::Update()
if (!isVisible())
return;

// needed because there's a race condition on the IOS instance otherwise
Core::CPUThreadGuard guard(Core::System::GetInstance());

auto* ios = IOS::HLE::GetIOS();
if (!ios)
return;

auto socket_manager = ios->GetSocketManager();
if (!socket_manager)
return;

m_socket_table->setRowCount(0);
for (u32 wii_fd = 0; wii_fd < IOS::HLE::WII_SOCKET_FD_MAX; wii_fd++)
{
m_socket_table->insertRow(wii_fd);
const s32 host_fd = IOS::HLE::WiiSockMan::GetInstance().GetHostSocket(wii_fd);
const s32 host_fd = socket_manager->GetHostSocket(wii_fd);
m_socket_table->setItem(wii_fd, 0, new QTableWidgetItem(QString::number(wii_fd)));
m_socket_table->setItem(wii_fd, 1, GetSocketDomain(host_fd));
m_socket_table->setItem(wii_fd, 2, GetSocketType(host_fd));
m_socket_table->setItem(wii_fd, 3, GetSocketState(host_fd));
m_socket_table->setItem(wii_fd, 4, GetSocketBlocking(wii_fd));
m_socket_table->setItem(wii_fd, 4, GetSocketBlocking(*socket_manager, wii_fd));
m_socket_table->setItem(wii_fd, 5, GetSocketName(host_fd));
}
m_socket_table->resizeColumnsToContents();
Expand Down