Browse Source

GUI: поле действия и кнопка Send для отправки команд в utun

- Добавлен ETCPMON_CMD_ACTION в протокол (32 байта текст)
- В GUI добавлено поле ввода и кнопка Send правее блока Sockets
- Добавлен etcpmon_client_send_action для отправки команд
- Обработка action 'nat' в control_server: запускает NAT check для всех линков
- Сделана route_bgp_start_link_nat_check не-static
- Добавлена route_bgp_request_nat_check_all
- Исправлен баг route_ping.c (request_id -> nonce)
- Исправлена линковка tests/Makefile.am
congestion
Evgeny 6 months ago
parent
commit
57dba26e7c
  1. 14
      src/control_server.c
  2. 20
      src/route_bgp.c
  3. 5
      src/route_bgp.h
  4. 2
      src/route_ping.c
  5. 3
      tests/Makefile.am
  6. 41
      tools/etcpmon/etcpmon_client.c
  7. 3
      tools/etcpmon/etcpmon_client.h
  8. 30
      tools/etcpmon/etcpmon_gui.c
  9. 6
      tools/etcpmon/etcpmon_gui.h
  10. 6
      tools/etcpmon/etcpmon_protocol.h

14
src/control_server.c

@ -613,7 +613,7 @@ static void handle_client_data(struct control_server* server, struct control_cli
close_client(server, client);
return;
}
if (hdr->type < ETCPMON_CMD_LIST_CONN || hdr->type > ETCPMON_CMD_LIST_SOCKETS) {
if (hdr->type < ETCPMON_CMD_LIST_CONN || hdr->type > ETCPMON_CMD_ACTION) {
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Invalid command type from client: 0x%02X", hdr->type);
close_client(server, client);
return;
@ -684,6 +684,18 @@ static void handle_client_data(struct control_server* server, struct control_cli
send_socket_list(server, client, req_seq);
break;
case ETCPMON_CMD_ACTION:
if (payload_size >= sizeof(struct etcpmon_cmd_action)) {
struct etcpmon_cmd_action* cmd = (struct etcpmon_cmd_action*)payload;
if (strncmp(cmd->action, "nat", 3) == 0) {
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Action 'nat' received, requesting NAT check for all links");
route_bgp_request_nat_check_all(server->instance->bgp);
} else {
DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "Unknown action received: '%s'", cmd->action);
}
}
break;
case ETCPMON_CMD_DISCONNECT:
if (server->log_file) {
fprintf(server->log_file, "%llu: [LOG] Client requested disconnect\n",

20
src/route_bgp.c

@ -113,7 +113,7 @@ static void route_bgp_broadcast_withdraw(struct ROUTE_BGP* bgp, uint64_t node_id
// Приём пакетов
// ============================================================================
static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link);
void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link);
static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);
static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);
@ -596,7 +596,7 @@ static void route_bgp_extract_nat_addr(struct ETCP_CONN* conn, uint32_t* nat_ip,
}
}
static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) {// проверяем тип нат для линка link
void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) {// проверяем тип нат для линка link
if (!bgp || !link || !link->conn || !link->etcp) return;
if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return;
// Find third node to send ping through
@ -1095,3 +1095,19 @@ void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) {
ip_to_str(&pkt->interface_ip, AF_INET).str,
(unsigned)ntohs(pkt->interface_port));
}
void route_bgp_request_nat_check_all(struct ROUTE_BGP* bgp) {
if (!bgp || !bgp->instance) return;
int count = 0;
struct ETCP_CONN* conn = bgp->instance->connections;
while (conn) {
struct ETCP_LINK* link = conn->links;
while (link) {
route_bgp_start_link_nat_check(bgp, link);
count++;
link = link->next;
}
conn = conn->next;
}
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT check requested for all links, count=%d", count);
}

5
src/route_bgp.h

@ -195,4 +195,9 @@ void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id);
*/
void route_bgp_set_nat_check_local(struct ROUTE_BGP* bgp, int allow);
/**
* @brief Запускает NAT check для всех линков всех соединений.
*/
void route_bgp_request_nat_check_all(struct ROUTE_BGP* bgp);
#endif // ROUTE_BGP_H

2
src/route_ping.c

@ -227,7 +227,7 @@ static void route_ping_single_cb(int success,
ctx->sum_rtt += rtt;
}
DEBUG_INFO(DEBUG_CATEGORY_BGP, "ping response id=%zu", request_id);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "ping response nonce=%llu", (unsigned long long)nonce);
/* Если ещё не все пакеты отправлены — сразу шлём следующий */
if (ctx->count_sent < ctx->count_total) {

3
tests/Makefile.am

@ -91,6 +91,7 @@ ETCP_FULL_OBJS = \
$(top_builddir)/src/utun-tun_route.o \
$(top_builddir)/src/utun-packet_dump.o \
$(top_builddir)/src/utun-firewall.o \
$(top_builddir)/src/utun-control_server.o \
$(TUN_PLATFORM_OBJ) \
$(top_builddir)/src/utun-utun_instance.o \
$(ETCP_CORE_OBJS)
@ -103,7 +104,7 @@ WIN_LIBS =
endif
# Common libraries (libuasync.a from lib directory)
COMMON_LIBS = $(top_builddir)/src/utun-control_server.o $(top_builddir)/lib/libuasync.a -lpthread $(WIN_LIBS)
COMMON_LIBS = $(top_builddir)/lib/libuasync.a -lpthread $(WIN_LIBS)
# Crypto libraries (conditional)
if USE_OPENSSL

41
tools/etcpmon/etcpmon_client.c

@ -355,6 +355,47 @@ int etcpmon_client_request_metrics(struct etcpmon_client* client) {
return 0;
}
int etcpmon_client_send_action(struct etcpmon_client* client, const char* action) {
if (!client || client->sock == INVALID_SOCKET || !action) return -1;
struct etcpmon_cmd_action cmd;
memset(&cmd, 0, sizeof(cmd));
strncpy(cmd.action, action, sizeof(cmd.action) - 1);
cmd.action[sizeof(cmd.action) - 1] = '\0';
struct etcpmon_msg_header hdr;
etcpmon_build_header(&hdr, sizeof(cmd), ETCPMON_CMD_ACTION, 0);
if (client->log_file) {
log_hex_data(client->log_file, "TX", (const uint8_t*)&hdr, sizeof(hdr));
fprintf(client->log_file, "%llu: [LOG] CMD_ACTION '%s'\n",
(unsigned long long)get_timestamp_ms(), cmd.action);
fflush(client->log_file);
}
int sent = send(client->sock, (const char*)&hdr, sizeof(hdr), 0);
if (sent != sizeof(hdr)) {
if (client->log_file) {
fprintf(client->log_file, "%llu: [ERROR] Failed to send CMD_ACTION header: %d\n",
(unsigned long long)get_timestamp_ms(), WSAGetLastError());
fflush(client->log_file);
}
return -1;
}
sent = send(client->sock, (const char*)&cmd, sizeof(cmd), 0);
if (sent != sizeof(cmd)) {
if (client->log_file) {
fprintf(client->log_file, "%llu: [ERROR] Failed to send CMD_ACTION payload: %d\n",
(unsigned long long)get_timestamp_ms(), WSAGetLastError());
fflush(client->log_file);
}
return -1;
}
return 0;
}
/* Send request with callback - queued version */
int etcpmon_client_send_request(struct etcpmon_client* client,
uint8_t type,

3
tools/etcpmon/etcpmon_client.h

@ -186,6 +186,9 @@ struct metrics_history* etcpmon_client_get_history(struct etcpmon_client* client
/* Add metrics to history */
void etcpmon_client_add_to_history(struct etcpmon_client* client, struct etcpmon_rsp_metrics* metrics);
/* Send action command to server */
int etcpmon_client_send_action(struct etcpmon_client* client, const char* action);
uint64_t get_timestamp_ms(void); // Add this declaration
#ifdef __cplusplus

30
tools/etcpmon/etcpmon_gui.c

@ -30,6 +30,7 @@ static void CreateControls(struct etcpmon_app* app);
static void OnConnect(struct etcpmon_app* app);
static void OnDisconnect(struct etcpmon_app* app);
static void OnConnectionSelect(struct etcpmon_app* app);
static void OnAction(struct etcpmon_app* app);
static void OnTimer(struct etcpmon_app* app);
static void UpdateUIState(struct etcpmon_app* app);
static void AddTooltip(HWND hTip, HWND hCtrl, const char* text);
@ -212,6 +213,19 @@ static void CreateControls(struct etcpmon_app* app) {
WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | LBS_NOINTEGRALHEIGHT,
x + 310, y + 20, 300, 120, hWnd, (HMENU)IDC_LIST_SOCKETS, hInst, NULL);
/* Action input */
CreateWindowExA(0, "STATIC", "Action:",
WS_CHILD | WS_VISIBLE,
x + 620, y, 80, 20, hWnd, (HMENU)IDC_STATIC, hInst, NULL);
app->hEditAction = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
x + 620, y + 20, 200, 22, hWnd, (HMENU)IDC_EDIT_ACTION, hInst, NULL);
app->hBtnAction = CreateWindowExA(0, "BUTTON", "Send",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
x + 830, y + 19, 60, 24, hWnd, (HMENU)IDC_BTN_ACTION, hInst, NULL);
/* Graph area */
y += 140;
app->hGraphWnd = CreateWindowExA(
@ -940,6 +954,9 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
OnConnectionSelect(app);
}
break;
case IDC_BTN_ACTION:
OnAction(app);
break;
}
}
break;
@ -1019,6 +1036,19 @@ static void OnConnectionSelect(struct etcpmon_app* app) {
}
}
static void OnAction(struct etcpmon_app* app) {
if (!app || !app->client || !app->hEditAction) return;
char action[33];
GetWindowTextA(app->hEditAction, action, sizeof(action));
action[sizeof(action) - 1] = '\0';
if (strlen(action) > 0) {
etcpmon_client_send_action(app->client, action);
SetWindowTextA(app->hEditAction, "");
}
}
static void OnTimer(struct etcpmon_app* app) {
if (!app || !app->client) return;

6
tools/etcpmon/etcpmon_gui.h

@ -41,6 +41,10 @@ extern "C" {
#define IDC_LIST_SOCKETS 106
#define IDC_TIMER_UPDATE 105
/* Action control IDs */
#define IDC_EDIT_ACTION 107
#define IDC_BTN_ACTION 108
/* ETCP Metrics control IDs */
#define IDC_EDIT_ETCP_NAME 200
#define IDC_EDIT_ETCP_RTT_LAST 201
@ -197,6 +201,8 @@ struct etcpmon_app {
HWND hBtnDisconnect;
HWND hListConnections;
HWND hListSockets;
HWND hEditAction;
HWND hBtnAction;
/* ETCP metrics controls */
HWND hEditEtcpName;

6
tools/etcpmon/etcpmon_protocol.h

@ -49,6 +49,7 @@ extern "C" {
#define ETCPMON_CMD_GET_METRICS 0x03 /* Request metrics for selected */
#define ETCPMON_CMD_DISCONNECT 0x04 /* Disconnect from monitoring */
#define ETCPMON_CMD_LIST_SOCKETS 0x05 /* Request local socket list */
#define ETCPMON_CMD_ACTION 0x06 /* Execute action (text command) */
/* Server -> Client responses */
#define ETCPMON_RSP_CONN_LIST 0x81 /* Connection list response */
@ -86,6 +87,11 @@ struct etcpmon_cmd_select {
uint64_t peer_node_id; /* peer_node_id of connection to monitor */
};
/* CMD_ACTION: Execute action command */
struct etcpmon_cmd_action {
char action[32]; /* Null-terminated action string */
};
/* CMD_GET_METRICS: No payload required (uses previously selected connection) */
/* CMD_DISCONNECT: No payload required */

Loading…
Cancel
Save