encrypt overhead fix (33→36, noencrypt_len), mtu default 1280, connmonitor window, total_decrypted for TCP, check.sh
This commit is contained in:
1 parent
9846599086
commit
ca176e1f24
41 files changed
+643
-91
No files matched your search
@@ -0,0 +1,189 @@
|
||||
// connmonitorwindow.cpp — ETCP connection monitor (standalone, non-modal window)
|
||||
#include "connmonitorwindow.h"
|
||||
#include "../transport/gui_bridge.h"
|
||||
|
||||
extern "C" {
|
||||
#include "chat/chat_core.h"
|
||||
#include "../../lib/mem.h"
|
||||
}
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QSplitter>
|
||||
#include <QLabel>
|
||||
#include <QFont>
|
||||
#include <QScrollBar>
|
||||
#include <QHash>
|
||||
#include <QApplication>
|
||||
#include <cstring>
|
||||
|
||||
#define CONN_LIST_ENTRY_SIZE 46
|
||||
|
||||
static ConnMonitorWindow* g_activeConnMonitor = nullptr;
|
||||
|
||||
static void connListCb(const uint8_t* data, int len) {
|
||||
if (g_activeConnMonitor) g_activeConnMonitor->onConnList(data, len);
|
||||
}
|
||||
|
||||
static void connMetricsCb(const uint8_t* data, int len) {
|
||||
if (g_activeConnMonitor) g_activeConnMonitor->onConnMetrics(data, len);
|
||||
}
|
||||
|
||||
ConnMonitorWindow::ConnMonitorWindow(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setWindowTitle("Connection Monitor");
|
||||
resize(900, 550);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
auto* mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setSpacing(4);
|
||||
mainLayout->setContentsMargins(8, 8, 8, 8);
|
||||
|
||||
auto* title = new QLabel("Active ETCP Connections (10 fps)", this);
|
||||
title->setStyleSheet("font-weight: bold; font-size: 13px;");
|
||||
mainLayout->addWidget(title);
|
||||
|
||||
auto* splitter = new QSplitter(Qt::Horizontal, this);
|
||||
splitter->setStyleSheet(
|
||||
"QSplitter::handle { background: palette(mid); width: 2px; }");
|
||||
|
||||
m_connList = new QListWidget(splitter);
|
||||
m_connList->setFixedWidth(280);
|
||||
m_connList->setFont(QFont("monospace", 9));
|
||||
m_connList->setStyleSheet(
|
||||
"QListWidget { border: 1px solid palette(mid); border-radius: 4px;"
|
||||
" background: palette(base); }"
|
||||
"QListWidget::item { padding: 4px 6px; }"
|
||||
"QListWidget::item:selected { background: #3390EC; color: white; }");
|
||||
|
||||
m_details = new QPlainTextEdit(splitter);
|
||||
m_details->setReadOnly(true);
|
||||
m_details->setFont(QFont("monospace", 9));
|
||||
m_details->setStyleSheet(
|
||||
"QPlainTextEdit { border: 1px solid palette(mid); border-radius: 4px;"
|
||||
" padding: 8px; background: palette(base); }");
|
||||
m_details->setPlaceholderText("Select a connection to view metrics");
|
||||
|
||||
splitter->addWidget(m_connList);
|
||||
splitter->addWidget(m_details);
|
||||
splitter->setStretchFactor(0, 0);
|
||||
splitter->setStretchFactor(1, 1);
|
||||
|
||||
mainLayout->addWidget(splitter, 1);
|
||||
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setInterval(100);
|
||||
connect(m_timer, &QTimer::timeout, this, &ConnMonitorWindow::onTimerTick);
|
||||
connect(m_connList, &QListWidget::currentItemChanged,
|
||||
this, &ConnMonitorWindow::onConnSelected);
|
||||
|
||||
g_activeConnMonitor = this;
|
||||
gui_bridge_set_conn_list_cb(connListCb);
|
||||
gui_bridge_set_conn_metrics_cb(connMetricsCb);
|
||||
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
ConnMonitorWindow::~ConnMonitorWindow() {
|
||||
m_timer->stop();
|
||||
if (g_activeConnMonitor == this) g_activeConnMonitor = nullptr;
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::showEvent(QShowEvent* event) {
|
||||
QDialog::showEvent(event);
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::hideEvent(QHideEvent* event) {
|
||||
m_timer->stop();
|
||||
QDialog::hideEvent(event);
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::onTimerTick() {
|
||||
if (m_details->textCursor().hasSelection()) return;
|
||||
if (QApplication::mouseButtons()) return;
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_conn_list_trampoline, nullptr);
|
||||
if (m_selectedNodeId) requestMetricsForSelected();
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::onConnSelected(QListWidgetItem* current, QListWidgetItem* previous) {
|
||||
(void)previous;
|
||||
if (!current) { m_selectedNodeId = 0; m_details->clear(); return; }
|
||||
m_selectedNodeId = (uint64_t)current->data(Qt::UserRole).toULongLong();
|
||||
requestMetricsForSelected();
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::requestMetricsForSelected() {
|
||||
void* arg = u_malloc(sizeof(uint64_t));
|
||||
if (!arg) return;
|
||||
memcpy(arg, &m_selectedNodeId, sizeof(uint64_t));
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_conn_metrics_trampoline, arg);
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::onConnList(const uint8_t* data, int len) {
|
||||
if (len < 2) return;
|
||||
uint16_t count; memcpy(&count, data, 2);
|
||||
const uint8_t* p = data + 2;
|
||||
|
||||
QHash<uint64_t, QListWidgetItem*> existing;
|
||||
for (int i = 0; i < m_connList->count(); i++) {
|
||||
auto* item = m_connList->item(i);
|
||||
existing[(uint64_t)item->data(Qt::UserRole).toULongLong()] = item;
|
||||
}
|
||||
|
||||
m_connList->blockSignals(true);
|
||||
|
||||
for (uint16_t i = 0; i < count && (p + CONN_LIST_ENTRY_SIZE) <= (data + len); i++) {
|
||||
uint64_t nodeId; memcpy(&nodeId, p, 8); p += 8;
|
||||
uint8_t flags = *p++;
|
||||
uint8_t linkCount = *p++;
|
||||
uint16_t rtt; memcpy(&rtt, p, 2); p += 2;
|
||||
p += 2; /* inflightKb */
|
||||
char name[33]; memcpy(name, p, 32); name[32] = '\0'; p += 32;
|
||||
|
||||
if (!nodeId) continue;
|
||||
|
||||
bool linksUp = (flags & 1) != 0;
|
||||
bool initialized = (flags & 2) != 0;
|
||||
QString color = linksUp ? "#2E7D32" : "#C62828";
|
||||
QString status = linksUp ? "UP" : (initialized ? "init" : "DOWN");
|
||||
|
||||
QString nodeHex = QString("%1").arg(nodeId, 16, 16, QChar('0')).right(16).left(4);
|
||||
QString rttStr = rtt > 0 ? QString::number(rtt / 10.0f, 'f', 1) : "-";
|
||||
QString text = QString("[%1] %2 %3 rtt=%4ms")
|
||||
.arg(nodeHex)
|
||||
.arg(QString::fromUtf8(name).left(16), -16)
|
||||
.arg(status + QString(" %1L").arg(linkCount), -10)
|
||||
.arg(rttStr);
|
||||
|
||||
auto it = existing.find(nodeId);
|
||||
if (it != existing.end()) {
|
||||
auto* item = *it;
|
||||
item->setText(text);
|
||||
item->setForeground(QColor(color));
|
||||
existing.erase(it);
|
||||
} else {
|
||||
auto* item = new QListWidgetItem(text, m_connList);
|
||||
item->setData(Qt::UserRole, QVariant((qulonglong)nodeId));
|
||||
item->setForeground(QColor(color));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = existing.begin(); it != existing.end(); ++it)
|
||||
delete *it;
|
||||
|
||||
m_connList->blockSignals(false);
|
||||
|
||||
if (!m_selectedNodeId && m_connList->count() > 0) {
|
||||
m_connList->setCurrentRow(0);
|
||||
onConnSelected(m_connList->item(0), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::onConnMetrics(const uint8_t* data, int len) {
|
||||
if (len <= 0) return;
|
||||
int scrollVal = m_details->verticalScrollBar()->value();
|
||||
m_details->setPlainText(QString::fromUtf8((const char*)data, len));
|
||||
m_details->verticalScrollBar()->setValue(scrollVal);
|
||||
}
|
||||
Reference in new issue
Block a user