stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll - stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close - utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP), add deferred drain in both Phase J and L - stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39, exchange ed25519_pubkey in both handshake directions - etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb - chat_sync.c: fix lk->conn NULL dereference for TCP links - test_stcp.c: update stcp_server_create/stcp_client_connect callsites - tools/chat_tcp_test: change transport udp→tcp
This commit is contained in:
1 parent
a3783b5f55
commit
38c9f229bc
1272 files changed
+968388
-1
No files matched your search
@@ -0,0 +1,133 @@
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QStyleFactory>
|
||||
#include <QDir>
|
||||
#include <cstdio>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#endif
|
||||
#include "mainwindow.h"
|
||||
#include "../db/db_manager.h"
|
||||
#include "../transport/node_config.h"
|
||||
#include "../transport/utun_node.h"
|
||||
#include "../../lib/debug_config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
static UtunNode* g_ctrl_node = nullptr;
|
||||
|
||||
static DWORD count_threads(void) {
|
||||
DWORD pid = GetCurrentProcessId(), count = 0;
|
||||
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
if (snap == INVALID_HANDLE_VALUE) return 0;
|
||||
THREADENTRY32 te = { sizeof(te) };
|
||||
if (Thread32First(snap, &te)) {
|
||||
do { if (te.th32OwnerProcessID == pid) count++; }
|
||||
while (Thread32Next(snap, &te));
|
||||
}
|
||||
CloseHandle(snap);
|
||||
return count;
|
||||
}
|
||||
|
||||
static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType) {
|
||||
if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) {
|
||||
if (g_ctrl_node) g_ctrl_node->requestStop();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct ShutdownSentinel {
|
||||
~ShutdownSentinel() {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "main: static destructors done");
|
||||
#ifdef _WIN32
|
||||
DWORD threads = count_threads();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "main: threads at exit=%lu", (unsigned long)threads);
|
||||
if (threads > 4) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "main: %lu hanging threads, TerminateProcess", (unsigned long)threads);
|
||||
fflush(nullptr);
|
||||
TerminateProcess(GetCurrentProcess(), 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} g_shutdown_sentinel;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName("Chat");
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
|
||||
app.setStyle(QStyleFactory::create("Fusion"));
|
||||
QPalette p;
|
||||
p.setColor(QPalette::Window, QColor(53, 53, 53));
|
||||
p.setColor(QPalette::WindowText, QColor(220, 220, 220));
|
||||
p.setColor(QPalette::Base, QColor(42, 42, 42));
|
||||
p.setColor(QPalette::AlternateBase, QColor(66, 66, 66));
|
||||
p.setColor(QPalette::ToolTipBase, QColor(25, 25, 25));
|
||||
p.setColor(QPalette::ToolTipText, QColor(220, 220, 220));
|
||||
p.setColor(QPalette::Text, QColor(220, 220, 220));
|
||||
p.setColor(QPalette::Button, QColor(53, 53, 53));
|
||||
p.setColor(QPalette::ButtonText, QColor(220, 220, 220));
|
||||
p.setColor(QPalette::BrightText, Qt::red);
|
||||
p.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||
p.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||
p.setColor(QPalette::HighlightedText, Qt::white);
|
||||
p.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
|
||||
p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127));
|
||||
app.setPalette(p);
|
||||
|
||||
QString cfgPath = QCoreApplication::applicationDirPath() + "/chatgui.cfg";
|
||||
|
||||
NodeConfig cfg(cfgPath);
|
||||
bool needSave = false;
|
||||
|
||||
if (!cfg.exists()) {
|
||||
if (!cfg.create("chatgui", 1333)) {
|
||||
qCritical("Failed to create config: %s", qPrintable(cfgPath));
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (!cfg.load()) {
|
||||
qCritical("Cannot open/read config file: %s", qPrintable(cfgPath));
|
||||
return 1;
|
||||
}
|
||||
if (cfg.hasErrors()) {
|
||||
for (const auto& err : cfg.errors())
|
||||
fprintf(stderr, "CONFIG ERROR: %s\n", qPrintable(err));
|
||||
return 1;
|
||||
}
|
||||
if (cfg.privKey().length() != 64 || cfg.pubKey().length() != 64) {
|
||||
qWarning("Config: keys missing/invalid, regenerating identity");
|
||||
cfg.generateIdentity();
|
||||
needSave = true;
|
||||
}
|
||||
if (cfg.nodeId().length() != 16) {
|
||||
qWarning("Config: my_node_id missing/invalid, regenerating identity");
|
||||
cfg.generateIdentity();
|
||||
needSave = true;
|
||||
}
|
||||
if (needSave)
|
||||
cfg.save();
|
||||
}
|
||||
|
||||
QString dbPath = cfg.dbPath();
|
||||
if (dbPath.isEmpty()) dbPath = "chat_data";
|
||||
if (!QDir::isAbsolutePath(dbPath))
|
||||
dbPath = QCoreApplication::applicationDirPath() + "/" + dbPath;
|
||||
QDir(dbPath).mkpath(".");
|
||||
|
||||
DbManager db;
|
||||
MainWindow w(nullptr, &db, cfgPath, dbPath, cfg.debugFile(),
|
||||
cfg.debugLevel(), cfg.debugCategories());
|
||||
w.show();
|
||||
|
||||
#ifdef _WIN32
|
||||
g_ctrl_node = w.utunNode();
|
||||
SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
|
||||
#endif
|
||||
|
||||
int ret = app.exec();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "main: app.exec() returned %d", ret);
|
||||
return ret;
|
||||
}
|
||||
Reference in new issue
Block a user