Debugger: Add a Network widget
Display socket table, SSL context and options
This commit is contained in:
parent
88ae4c7914
commit
5e33cd48da
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace IOS::HLE::Device
|
namespace IOS::HLE::Device
|
||||||
{
|
{
|
||||||
WII_SSL NetSSL::_SSL[NET_SSL_MAXINSTANCES];
|
WII_SSL NetSSL::_SSL[IOS::HLE::NET_SSL_MAXINSTANCES];
|
||||||
|
|
||||||
static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
|
static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
|
||||||
/* Hashes from SHA-1 and above */
|
/* Hashes from SHA-1 and above */
|
||||||
|
@ -247,7 +247,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_NET_SSL_SHUTDOWN:
|
case IOCTLV_NET_SSL_SHUTDOWN:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
int ret =
|
int ret =
|
||||||
|
@ -333,7 +333,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
const std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
|
const std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
|
||||||
|
@ -380,7 +380,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
mbedtls_x509_crt_free(&ssl->clicert);
|
mbedtls_x509_crt_free(&ssl->clicert);
|
||||||
|
@ -399,7 +399,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
|
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
const std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
|
const std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
|
||||||
|
@ -437,7 +437,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_NET_SSL_CONNECT:
|
case IOCTLV_NET_SSL_CONNECT:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
|
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
|
||||||
|
@ -464,7 +464,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WiiSockMan& sm = WiiSockMan::GetInstance();
|
WiiSockMan& sm = WiiSockMan::GetInstance();
|
||||||
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_DOHANDSHAKE);
|
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_DOHANDSHAKE);
|
||||||
|
@ -479,7 +479,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_NET_SSL_WRITE:
|
case IOCTLV_NET_SSL_WRITE:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WiiSockMan& sm = WiiSockMan::GetInstance();
|
WiiSockMan& sm = WiiSockMan::GetInstance();
|
||||||
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_WRITE);
|
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_WRITE);
|
||||||
|
@ -503,7 +503,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WiiSockMan& sm = WiiSockMan::GetInstance();
|
WiiSockMan& sm = WiiSockMan::GetInstance();
|
||||||
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_READ);
|
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_READ);
|
||||||
|
@ -526,7 +526,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
|
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WriteReturnValue(SSL_OK, BufferIn);
|
WriteReturnValue(SSL_OK, BufferIn);
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
WriteReturnValue(SSL_OK, BufferIn);
|
WriteReturnValue(SSL_OK, BufferIn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,7 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
#define NET_SSL_MAXINSTANCES 4
|
constexpr int NET_SSL_MAXINSTANCES = 4;
|
||||||
|
|
||||||
// TODO: remove this macro.
|
|
||||||
#define SSLID_VALID(x) \
|
|
||||||
(x >= 0 && x < NET_SSL_MAXINSTANCES && ::IOS::HLE::Device::NetSSL::_SSL[x].active)
|
|
||||||
|
|
||||||
enum ssl_err_t : s32
|
enum ssl_err_t : s32
|
||||||
{
|
{
|
||||||
|
@ -103,5 +99,10 @@ public:
|
||||||
private:
|
private:
|
||||||
bool m_cert_error_shown = false;
|
bool m_cert_error_shown = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr bool IsSSLIDValid(int id)
|
||||||
|
{
|
||||||
|
return (id >= 0 && id < NET_SSL_MAXINSTANCES && IOS::HLE::Device::NetSSL::_SSL[id].active);
|
||||||
|
}
|
||||||
} // namespace Device
|
} // namespace Device
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
|
|
@ -33,8 +33,6 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
constexpr int WII_SOCKET_FD_MAX = 24;
|
|
||||||
|
|
||||||
char* WiiSockMan::DecodeError(s32 ErrorCode)
|
char* WiiSockMan::DecodeError(s32 ErrorCode)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -325,7 +323,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
||||||
if (it->is_ssl)
|
if (it->is_ssl)
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (IOS::HLE::Device::IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
switch (it->ssl_type)
|
switch (it->ssl_type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,8 @@ typedef struct pollfd pollfd_t;
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
|
constexpr int WII_SOCKET_FD_MAX = 24;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SO_MSG_OOB = 0x01,
|
SO_MSG_OOB = 0x01,
|
||||||
|
|
|
@ -176,6 +176,8 @@ add_executable(dolphin-emu
|
||||||
Debugger/MemoryViewWidget.h
|
Debugger/MemoryViewWidget.h
|
||||||
Debugger/MemoryWidget.cpp
|
Debugger/MemoryWidget.cpp
|
||||||
Debugger/MemoryWidget.h
|
Debugger/MemoryWidget.h
|
||||||
|
Debugger/NetworkWidget.cpp
|
||||||
|
Debugger/NetworkWidget.h
|
||||||
Debugger/NewBreakpointDialog.cpp
|
Debugger/NewBreakpointDialog.cpp
|
||||||
Debugger/NewBreakpointDialog.h
|
Debugger/NewBreakpointDialog.h
|
||||||
Debugger/PatchInstructionDialog.cpp
|
Debugger/PatchInstructionDialog.cpp
|
||||||
|
|
|
@ -0,0 +1,301 @@
|
||||||
|
// Copyright 2020 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "DolphinQt/Debugger/NetworkWidget.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Core/ConfigManager.h"
|
||||||
|
#include "Core/IOS/Network/SSL.h"
|
||||||
|
#include "Core/IOS/Network/Socket.h"
|
||||||
|
#include "DolphinQt/Host.h"
|
||||||
|
#include "DolphinQt/Settings.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
QTableWidgetItem* GetSocketDomain(s32 host_fd)
|
||||||
|
{
|
||||||
|
if (host_fd < 0)
|
||||||
|
return new QTableWidgetItem();
|
||||||
|
|
||||||
|
sockaddr sa;
|
||||||
|
socklen_t sa_len = sizeof(sa);
|
||||||
|
const int ret = getsockname(host_fd, &sa, &sa_len);
|
||||||
|
if (ret != 0)
|
||||||
|
return new QTableWidgetItem(QTableWidget::tr("Unknown"));
|
||||||
|
|
||||||
|
switch (sa.sa_family)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return new QTableWidgetItem(QLatin1Literal("AF_INET"));
|
||||||
|
case 23:
|
||||||
|
return new QTableWidgetItem(QLatin1Literal("AF_INET6"));
|
||||||
|
default:
|
||||||
|
return new QTableWidgetItem(QString::number(sa.sa_family));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableWidgetItem* GetSocketType(s32 host_fd)
|
||||||
|
{
|
||||||
|
if (host_fd < 0)
|
||||||
|
return new QTableWidgetItem();
|
||||||
|
|
||||||
|
int so_type;
|
||||||
|
socklen_t opt_len = sizeof(so_type);
|
||||||
|
const int ret =
|
||||||
|
getsockopt(host_fd, SOL_SOCKET, SO_TYPE, reinterpret_cast<char*>(&so_type), &opt_len);
|
||||||
|
if (ret != 0)
|
||||||
|
return new QTableWidgetItem(QTableWidget::tr("Unknown"));
|
||||||
|
|
||||||
|
switch (so_type)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return new QTableWidgetItem(QLatin1Literal("SOCK_STREAM"));
|
||||||
|
case 2:
|
||||||
|
return new QTableWidgetItem(QLatin1Literal("SOCK_DGRAM"));
|
||||||
|
default:
|
||||||
|
return new QTableWidgetItem(QString::number(so_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableWidgetItem* GetSocketState(s32 host_fd)
|
||||||
|
{
|
||||||
|
if (host_fd < 0)
|
||||||
|
return new QTableWidgetItem();
|
||||||
|
|
||||||
|
sockaddr_in peer_addr;
|
||||||
|
socklen_t peer_addr_len = sizeof(sockaddr_in);
|
||||||
|
if (getpeername(host_fd, reinterpret_cast<sockaddr*>(&peer_addr), &peer_addr_len) == 0)
|
||||||
|
return new QTableWidgetItem(QTableWidget::tr("Connected"));
|
||||||
|
|
||||||
|
int so_accept = 0;
|
||||||
|
socklen_t opt_len = sizeof(so_accept);
|
||||||
|
const int ret =
|
||||||
|
getsockopt(host_fd, SOL_SOCKET, SO_ACCEPTCONN, reinterpret_cast<char*>(&so_accept), &opt_len);
|
||||||
|
if (ret == 0 && so_accept > 0)
|
||||||
|
return new QTableWidgetItem(QTableWidget::tr("Listening"));
|
||||||
|
return new QTableWidgetItem(QTableWidget::tr("Unbound"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableWidgetItem* GetSocketName(s32 host_fd)
|
||||||
|
{
|
||||||
|
if (host_fd < 0)
|
||||||
|
return new QTableWidgetItem();
|
||||||
|
|
||||||
|
sockaddr_in sock_addr;
|
||||||
|
socklen_t sock_addr_len = sizeof(sockaddr_in);
|
||||||
|
if (getsockname(host_fd, reinterpret_cast<sockaddr*>(&sock_addr), &sock_addr_len) != 0)
|
||||||
|
return new QTableWidgetItem(QTableWidget::tr("Unknown"));
|
||||||
|
|
||||||
|
const QString sock_name = QStringLiteral("%1:%2")
|
||||||
|
.arg(QString::fromLatin1(inet_ntoa(sock_addr.sin_addr)))
|
||||||
|
.arg(ntohs(sock_addr.sin_port));
|
||||||
|
|
||||||
|
sockaddr_in peer_addr;
|
||||||
|
socklen_t peer_addr_len = sizeof(sockaddr_in);
|
||||||
|
if (getpeername(host_fd, reinterpret_cast<sockaddr*>(&peer_addr), &peer_addr_len) != 0)
|
||||||
|
return new QTableWidgetItem(sock_name);
|
||||||
|
|
||||||
|
const QString peer_name = QStringLiteral("%1:%2")
|
||||||
|
.arg(QString::fromLatin1(inet_ntoa(peer_addr.sin_addr)))
|
||||||
|
.arg(ntohs(peer_addr.sin_port));
|
||||||
|
return new QTableWidgetItem(QStringLiteral("%1->%2").arg(sock_name).arg(peer_name));
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NetworkWidget::NetworkWidget(QWidget* parent) : QDockWidget(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Network"));
|
||||||
|
setObjectName(QStringLiteral("network"));
|
||||||
|
|
||||||
|
setHidden(!Settings::Instance().IsNetworkVisible() || !Settings::Instance().IsDebugModeEnabled());
|
||||||
|
|
||||||
|
setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||||
|
|
||||||
|
CreateWidgets();
|
||||||
|
|
||||||
|
auto& settings = Settings::GetQSettings();
|
||||||
|
|
||||||
|
restoreGeometry(settings.value(QStringLiteral("networkwidget/geometry")).toByteArray());
|
||||||
|
// macOS: setHidden() needs to be evaluated before setFloating() for proper window presentation
|
||||||
|
// according to Settings
|
||||||
|
setFloating(settings.value(QStringLiteral("networkwidget/floating")).toBool());
|
||||||
|
|
||||||
|
ConnectWidgets();
|
||||||
|
|
||||||
|
connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, &NetworkWidget::Update);
|
||||||
|
|
||||||
|
connect(&Settings::Instance(), &Settings::NetworkVisibilityChanged,
|
||||||
|
[this](bool visible) { setHidden(!visible); });
|
||||||
|
|
||||||
|
connect(&Settings::Instance(), &Settings::DebugModeToggled, [this](bool enabled) {
|
||||||
|
setHidden(!enabled || !Settings::Instance().IsNetworkVisible());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkWidget::~NetworkWidget()
|
||||||
|
{
|
||||||
|
auto& settings = Settings::GetQSettings();
|
||||||
|
|
||||||
|
settings.setValue(QStringLiteral("networkwidget/geometry"), saveGeometry());
|
||||||
|
settings.setValue(QStringLiteral("networkwidget/floating"), isFloating());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkWidget::closeEvent(QCloseEvent*)
|
||||||
|
{
|
||||||
|
Settings::Instance().SetNetworkVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkWidget::showEvent(QShowEvent* event)
|
||||||
|
{
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkWidget::CreateWidgets()
|
||||||
|
{
|
||||||
|
auto* widget = new QWidget;
|
||||||
|
auto* layout = new QVBoxLayout;
|
||||||
|
widget->setLayout(layout);
|
||||||
|
layout->addWidget(CreateSocketTableGroup());
|
||||||
|
layout->addWidget(CreateSSLContextGroup());
|
||||||
|
layout->addWidget(CreateSSLOptionsGroup());
|
||||||
|
layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||||
|
setWidget(widget);
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkWidget::ConnectWidgets()
|
||||||
|
{
|
||||||
|
connect(m_dump_ssl_read_checkbox, &QCheckBox::stateChanged,
|
||||||
|
[](int state) { SConfig::GetInstance().m_SSLDumpRead = state == Qt::Checked; });
|
||||||
|
connect(m_dump_ssl_write_checkbox, &QCheckBox::stateChanged,
|
||||||
|
[](int state) { SConfig::GetInstance().m_SSLDumpWrite = state == Qt::Checked; });
|
||||||
|
connect(m_dump_root_ca_checkbox, &QCheckBox::stateChanged,
|
||||||
|
[](int state) { SConfig::GetInstance().m_SSLDumpRootCA = state == Qt::Checked; });
|
||||||
|
connect(m_dump_peer_cert_checkbox, &QCheckBox::stateChanged,
|
||||||
|
[](int state) { SConfig::GetInstance().m_SSLDumpPeerCert = state == Qt::Checked; });
|
||||||
|
connect(m_verify_certificates_checkbox, &QCheckBox::stateChanged,
|
||||||
|
[](int state) { SConfig::GetInstance().m_SSLVerifyCert = state == Qt::Checked; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkWidget::Update()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
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, GetSocketName(host_fd));
|
||||||
|
}
|
||||||
|
m_socket_table->resizeColumnsToContents();
|
||||||
|
|
||||||
|
m_ssl_table->setRowCount(0);
|
||||||
|
for (u32 ssl_id = 0; ssl_id < IOS::HLE::NET_SSL_MAXINSTANCES; ssl_id++)
|
||||||
|
{
|
||||||
|
m_ssl_table->insertRow(ssl_id);
|
||||||
|
s32 host_fd = -1;
|
||||||
|
if (IOS::HLE::Device::IsSSLIDValid(ssl_id) &&
|
||||||
|
IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio != nullptr)
|
||||||
|
{
|
||||||
|
host_fd =
|
||||||
|
static_cast<mbedtls_net_context*>(IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio)->fd;
|
||||||
|
}
|
||||||
|
m_ssl_table->setItem(ssl_id, 0, new QTableWidgetItem(QString::number(ssl_id)));
|
||||||
|
m_ssl_table->setItem(ssl_id, 1, GetSocketDomain(host_fd));
|
||||||
|
m_ssl_table->setItem(ssl_id, 2, GetSocketType(host_fd));
|
||||||
|
m_ssl_table->setItem(ssl_id, 3, GetSocketState(host_fd));
|
||||||
|
m_ssl_table->setItem(ssl_id, 4, GetSocketName(host_fd));
|
||||||
|
}
|
||||||
|
m_ssl_table->resizeColumnsToContents();
|
||||||
|
|
||||||
|
const auto& config = SConfig::GetInstance();
|
||||||
|
m_dump_ssl_read_checkbox->setChecked(config.m_SSLDumpRead);
|
||||||
|
m_dump_ssl_write_checkbox->setChecked(config.m_SSLDumpWrite);
|
||||||
|
m_dump_root_ca_checkbox->setChecked(config.m_SSLDumpRootCA);
|
||||||
|
m_dump_peer_cert_checkbox->setChecked(config.m_SSLDumpPeerCert);
|
||||||
|
m_verify_certificates_checkbox->setChecked(config.m_SSLVerifyCert);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox* NetworkWidget::CreateSocketTableGroup()
|
||||||
|
{
|
||||||
|
QGroupBox* socket_table_group = new QGroupBox(tr("Socket table"));
|
||||||
|
QGridLayout* socket_table_layout = new QGridLayout;
|
||||||
|
socket_table_group->setLayout(socket_table_layout);
|
||||||
|
|
||||||
|
m_socket_table = new QTableWidget();
|
||||||
|
QStringList header{tr("FD"), tr("Domain"), tr("Type"), tr("State"), tr("Name")};
|
||||||
|
m_socket_table->setColumnCount(header.size());
|
||||||
|
|
||||||
|
m_socket_table->setHorizontalHeaderLabels(header);
|
||||||
|
m_socket_table->setTabKeyNavigation(false);
|
||||||
|
m_socket_table->verticalHeader()->setVisible(false);
|
||||||
|
m_socket_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
m_socket_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
m_socket_table->setWordWrap(false);
|
||||||
|
|
||||||
|
socket_table_layout->addWidget(m_socket_table, 0, 0);
|
||||||
|
socket_table_layout->setSpacing(1);
|
||||||
|
return socket_table_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox* NetworkWidget::CreateSSLContextGroup()
|
||||||
|
{
|
||||||
|
QGroupBox* ssl_context_group = new QGroupBox(tr("SSL context"));
|
||||||
|
QGridLayout* ssl_context_layout = new QGridLayout;
|
||||||
|
ssl_context_group->setLayout(ssl_context_layout);
|
||||||
|
|
||||||
|
m_ssl_table = new QTableWidget();
|
||||||
|
QStringList header{tr("ID"), tr("Domain"), tr("Type"), tr("State"), tr("Name")};
|
||||||
|
m_ssl_table->setColumnCount(header.size());
|
||||||
|
|
||||||
|
m_ssl_table->setHorizontalHeaderLabels(header);
|
||||||
|
m_ssl_table->setTabKeyNavigation(false);
|
||||||
|
m_ssl_table->verticalHeader()->setVisible(false);
|
||||||
|
m_ssl_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
m_ssl_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
m_ssl_table->setWordWrap(false);
|
||||||
|
|
||||||
|
ssl_context_layout->addWidget(m_ssl_table, 0, 0);
|
||||||
|
ssl_context_layout->setSpacing(1);
|
||||||
|
return ssl_context_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox* NetworkWidget::CreateSSLOptionsGroup()
|
||||||
|
{
|
||||||
|
QGroupBox* ssl_options_group = new QGroupBox(tr("SSL options"));
|
||||||
|
QGridLayout* ssl_options_layout = new QGridLayout;
|
||||||
|
ssl_options_group->setLayout(ssl_options_layout);
|
||||||
|
|
||||||
|
m_dump_ssl_read_checkbox = new QCheckBox(tr("Dump SSL read"));
|
||||||
|
m_dump_ssl_write_checkbox = new QCheckBox(tr("Dump SSL write"));
|
||||||
|
m_dump_root_ca_checkbox = new QCheckBox(tr("Dump root CA"));
|
||||||
|
m_dump_peer_cert_checkbox = new QCheckBox(tr("Dump peer certificates"));
|
||||||
|
m_verify_certificates_checkbox = new QCheckBox(tr("Verify certificates"));
|
||||||
|
|
||||||
|
ssl_options_layout->addWidget(m_dump_ssl_read_checkbox, 0, 0);
|
||||||
|
ssl_options_layout->addWidget(m_dump_ssl_write_checkbox, 1, 0);
|
||||||
|
ssl_options_layout->addWidget(m_verify_certificates_checkbox, 2, 0);
|
||||||
|
ssl_options_layout->addWidget(m_dump_root_ca_checkbox, 0, 1);
|
||||||
|
ssl_options_layout->addWidget(m_dump_peer_cert_checkbox, 1, 1);
|
||||||
|
|
||||||
|
ssl_options_layout->setSpacing(1);
|
||||||
|
return ssl_options_group;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright 2020 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDockWidget>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
|
class QCloseEvent;
|
||||||
|
class QGroupBox;
|
||||||
|
class QShowEvent;
|
||||||
|
class QTableWidget;
|
||||||
|
class QTableWidgetItem;
|
||||||
|
|
||||||
|
class NetworkWidget : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NetworkWidget(QWidget* parent = nullptr);
|
||||||
|
~NetworkWidget();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent*) override;
|
||||||
|
void showEvent(QShowEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CreateWidgets();
|
||||||
|
void ConnectWidgets();
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
QGroupBox* CreateSocketTableGroup();
|
||||||
|
QGroupBox* CreateSSLContextGroup();
|
||||||
|
QGroupBox* CreateSSLOptionsGroup();
|
||||||
|
|
||||||
|
QTableWidget* m_socket_table;
|
||||||
|
QTableWidget* m_ssl_table;
|
||||||
|
QCheckBox* m_dump_ssl_read_checkbox;
|
||||||
|
QCheckBox* m_dump_ssl_write_checkbox;
|
||||||
|
QCheckBox* m_dump_root_ca_checkbox;
|
||||||
|
QCheckBox* m_dump_peer_cert_checkbox;
|
||||||
|
QCheckBox* m_verify_certificates_checkbox;
|
||||||
|
};
|
|
@ -147,6 +147,7 @@
|
||||||
<QtMoc Include="Debugger\JITWidget.h" />
|
<QtMoc Include="Debugger\JITWidget.h" />
|
||||||
<QtMoc Include="Debugger\MemoryWidget.h" />
|
<QtMoc Include="Debugger\MemoryWidget.h" />
|
||||||
<QtMoc Include="Debugger\MemoryViewWidget.h" />
|
<QtMoc Include="Debugger\MemoryViewWidget.h" />
|
||||||
|
<QtMoc Include="Debugger\NetworkWidget.h" />
|
||||||
<QtMoc Include="Debugger\NewBreakpointDialog.h" />
|
<QtMoc Include="Debugger\NewBreakpointDialog.h" />
|
||||||
<QtMoc Include="Debugger\PatchInstructionDialog.h" />
|
<QtMoc Include="Debugger\PatchInstructionDialog.h" />
|
||||||
<QtMoc Include="Debugger\RegisterWidget.h" />
|
<QtMoc Include="Debugger\RegisterWidget.h" />
|
||||||
|
@ -275,6 +276,7 @@
|
||||||
<ClCompile Include="$(QtMocOutPrefix)MappingWindow.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)MappingWindow.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)MemoryViewWidget.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)MemoryViewWidget.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)MemoryWidget.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)MemoryWidget.cpp" />
|
||||||
|
<ClCompile Include="$(QtMocOutPrefix)NetworkWidget.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)MenuBar.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)MenuBar.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)ModalMessageBox.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)ModalMessageBox.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)NetPlayBrowser.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)NetPlayBrowser.cpp" />
|
||||||
|
@ -377,6 +379,7 @@
|
||||||
<ClCompile Include="Debugger\JITWidget.cpp" />
|
<ClCompile Include="Debugger\JITWidget.cpp" />
|
||||||
<ClCompile Include="Debugger\MemoryWidget.cpp" />
|
<ClCompile Include="Debugger\MemoryWidget.cpp" />
|
||||||
<ClCompile Include="Debugger\MemoryViewWidget.cpp" />
|
<ClCompile Include="Debugger\MemoryViewWidget.cpp" />
|
||||||
|
<ClCompile Include="Debugger\NetworkWidget.cpp" />
|
||||||
<ClCompile Include="DiscordHandler.cpp" />
|
<ClCompile Include="DiscordHandler.cpp" />
|
||||||
<ClCompile Include="DiscordJoinRequestDialog.cpp" />
|
<ClCompile Include="DiscordJoinRequestDialog.cpp" />
|
||||||
<ClCompile Include="FIFO\FIFOAnalyzer.cpp" />
|
<ClCompile Include="FIFO\FIFOAnalyzer.cpp" />
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
#include "DolphinQt/Debugger/CodeWidget.h"
|
#include "DolphinQt/Debugger/CodeWidget.h"
|
||||||
#include "DolphinQt/Debugger/JITWidget.h"
|
#include "DolphinQt/Debugger/JITWidget.h"
|
||||||
#include "DolphinQt/Debugger/MemoryWidget.h"
|
#include "DolphinQt/Debugger/MemoryWidget.h"
|
||||||
|
#include "DolphinQt/Debugger/NetworkWidget.h"
|
||||||
#include "DolphinQt/Debugger/RegisterWidget.h"
|
#include "DolphinQt/Debugger/RegisterWidget.h"
|
||||||
#include "DolphinQt/Debugger/WatchWidget.h"
|
#include "DolphinQt/Debugger/WatchWidget.h"
|
||||||
#include "DolphinQt/DiscordHandler.h"
|
#include "DolphinQt/DiscordHandler.h"
|
||||||
|
@ -389,6 +390,7 @@ void MainWindow::CreateComponents()
|
||||||
m_log_widget = new LogWidget(this);
|
m_log_widget = new LogWidget(this);
|
||||||
m_log_config_widget = new LogConfigWidget(this);
|
m_log_config_widget = new LogConfigWidget(this);
|
||||||
m_memory_widget = new MemoryWidget(this);
|
m_memory_widget = new MemoryWidget(this);
|
||||||
|
m_network_widget = new NetworkWidget(this);
|
||||||
m_register_widget = new RegisterWidget(this);
|
m_register_widget = new RegisterWidget(this);
|
||||||
m_watch_widget = new WatchWidget(this);
|
m_watch_widget = new WatchWidget(this);
|
||||||
m_breakpoint_widget = new BreakpointWidget(this);
|
m_breakpoint_widget = new BreakpointWidget(this);
|
||||||
|
@ -643,6 +645,7 @@ void MainWindow::ConnectStack()
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, m_watch_widget);
|
addDockWidget(Qt::LeftDockWidgetArea, m_watch_widget);
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, m_breakpoint_widget);
|
addDockWidget(Qt::LeftDockWidgetArea, m_breakpoint_widget);
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, m_memory_widget);
|
addDockWidget(Qt::LeftDockWidgetArea, m_memory_widget);
|
||||||
|
addDockWidget(Qt::LeftDockWidgetArea, m_network_widget);
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, m_jit_widget);
|
addDockWidget(Qt::LeftDockWidgetArea, m_jit_widget);
|
||||||
|
|
||||||
tabifyDockWidget(m_log_widget, m_log_config_widget);
|
tabifyDockWidget(m_log_widget, m_log_config_widget);
|
||||||
|
@ -651,6 +654,7 @@ void MainWindow::ConnectStack()
|
||||||
tabifyDockWidget(m_log_widget, m_watch_widget);
|
tabifyDockWidget(m_log_widget, m_watch_widget);
|
||||||
tabifyDockWidget(m_log_widget, m_breakpoint_widget);
|
tabifyDockWidget(m_log_widget, m_breakpoint_widget);
|
||||||
tabifyDockWidget(m_log_widget, m_memory_widget);
|
tabifyDockWidget(m_log_widget, m_memory_widget);
|
||||||
|
tabifyDockWidget(m_log_widget, m_network_widget);
|
||||||
tabifyDockWidget(m_log_widget, m_jit_widget);
|
tabifyDockWidget(m_log_widget, m_jit_widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ class MemoryWidget;
|
||||||
class MenuBar;
|
class MenuBar;
|
||||||
class NetPlayDialog;
|
class NetPlayDialog;
|
||||||
class NetPlaySetupDialog;
|
class NetPlaySetupDialog;
|
||||||
|
class NetworkWidget;
|
||||||
class RegisterWidget;
|
class RegisterWidget;
|
||||||
class RenderWidget;
|
class RenderWidget;
|
||||||
class SearchBar;
|
class SearchBar;
|
||||||
|
@ -225,6 +226,7 @@ private:
|
||||||
LogWidget* m_log_widget;
|
LogWidget* m_log_widget;
|
||||||
LogConfigWidget* m_log_config_widget;
|
LogConfigWidget* m_log_config_widget;
|
||||||
MemoryWidget* m_memory_widget;
|
MemoryWidget* m_memory_widget;
|
||||||
|
NetworkWidget* m_network_widget;
|
||||||
RegisterWidget* m_register_widget;
|
RegisterWidget* m_register_widget;
|
||||||
WatchWidget* m_watch_widget;
|
WatchWidget* m_watch_widget;
|
||||||
CheatsManager* m_cheats_manager;
|
CheatsManager* m_cheats_manager;
|
||||||
|
|
|
@ -169,6 +169,7 @@ void MenuBar::OnDebugModeToggled(bool enabled)
|
||||||
m_show_watch->setVisible(enabled);
|
m_show_watch->setVisible(enabled);
|
||||||
m_show_breakpoints->setVisible(enabled);
|
m_show_breakpoints->setVisible(enabled);
|
||||||
m_show_memory->setVisible(enabled);
|
m_show_memory->setVisible(enabled);
|
||||||
|
m_show_network->setVisible(enabled);
|
||||||
m_show_jit->setVisible(enabled);
|
m_show_jit->setVisible(enabled);
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
|
@ -469,6 +470,14 @@ void MenuBar::AddViewMenu()
|
||||||
connect(&Settings::Instance(), &Settings::MemoryVisibilityChanged, m_show_memory,
|
connect(&Settings::Instance(), &Settings::MemoryVisibilityChanged, m_show_memory,
|
||||||
&QAction::setChecked);
|
&QAction::setChecked);
|
||||||
|
|
||||||
|
m_show_network = view_menu->addAction(tr("&Network"));
|
||||||
|
m_show_network->setCheckable(true);
|
||||||
|
m_show_network->setChecked(Settings::Instance().IsNetworkVisible());
|
||||||
|
|
||||||
|
connect(m_show_network, &QAction::toggled, &Settings::Instance(), &Settings::SetNetworkVisible);
|
||||||
|
connect(&Settings::Instance(), &Settings::NetworkVisibilityChanged, m_show_network,
|
||||||
|
&QAction::setChecked);
|
||||||
|
|
||||||
m_show_jit = view_menu->addAction(tr("&JIT"));
|
m_show_jit = view_menu->addAction(tr("&JIT"));
|
||||||
m_show_jit->setCheckable(true);
|
m_show_jit->setCheckable(true);
|
||||||
m_show_jit->setChecked(Settings::Instance().IsJITVisible());
|
m_show_jit->setChecked(Settings::Instance().IsJITVisible());
|
||||||
|
|
|
@ -235,6 +235,7 @@ private:
|
||||||
QAction* m_show_watch;
|
QAction* m_show_watch;
|
||||||
QAction* m_show_breakpoints;
|
QAction* m_show_breakpoints;
|
||||||
QAction* m_show_memory;
|
QAction* m_show_memory;
|
||||||
|
QAction* m_show_network;
|
||||||
QAction* m_show_jit;
|
QAction* m_show_jit;
|
||||||
QMenu* m_cols_menu;
|
QMenu* m_cols_menu;
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,20 @@ bool Settings::IsMemoryVisible() const
|
||||||
return QSettings().value(QStringLiteral("debugger/showmemory")).toBool();
|
return QSettings().value(QStringLiteral("debugger/showmemory")).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Settings::SetNetworkVisible(bool enabled)
|
||||||
|
{
|
||||||
|
if (IsNetworkVisible() == enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GetQSettings().setValue(QStringLiteral("debugger/shownetwork"), enabled);
|
||||||
|
emit NetworkVisibilityChanged(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::IsNetworkVisible() const
|
||||||
|
{
|
||||||
|
return GetQSettings().value(QStringLiteral("debugger/shownetwork")).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
void Settings::SetJITVisible(bool enabled)
|
void Settings::SetJITVisible(bool enabled)
|
||||||
{
|
{
|
||||||
if (IsJITVisible() == enabled)
|
if (IsJITVisible() == enabled)
|
||||||
|
|
|
@ -126,6 +126,8 @@ public:
|
||||||
bool IsCodeVisible() const;
|
bool IsCodeVisible() const;
|
||||||
void SetMemoryVisible(bool enabled);
|
void SetMemoryVisible(bool enabled);
|
||||||
bool IsMemoryVisible() const;
|
bool IsMemoryVisible() const;
|
||||||
|
void SetNetworkVisible(bool enabled);
|
||||||
|
bool IsNetworkVisible() const;
|
||||||
void SetJITVisible(bool enabled);
|
void SetJITVisible(bool enabled);
|
||||||
bool IsJITVisible() const;
|
bool IsJITVisible() const;
|
||||||
QFont GetDebugFont() const;
|
QFont GetDebugFont() const;
|
||||||
|
@ -168,6 +170,7 @@ signals:
|
||||||
void BreakpointsVisibilityChanged(bool visible);
|
void BreakpointsVisibilityChanged(bool visible);
|
||||||
void CodeVisibilityChanged(bool visible);
|
void CodeVisibilityChanged(bool visible);
|
||||||
void MemoryVisibilityChanged(bool visible);
|
void MemoryVisibilityChanged(bool visible);
|
||||||
|
void NetworkVisibilityChanged(bool visible);
|
||||||
void JITVisibilityChanged(bool visible);
|
void JITVisibilityChanged(bool visible);
|
||||||
void DebugModeToggled(bool enabled);
|
void DebugModeToggled(bool enabled);
|
||||||
void DebugFontChanged(QFont font);
|
void DebugFontChanged(QFont font);
|
||||||
|
|
Loading…
Reference in New Issue