diff --git a/src/control_server.c b/src/control_server.c index ba6b93f..054b714 100644 --- a/src/control_server.c +++ b/src/control_server.c @@ -753,6 +753,8 @@ static void send_metrics(struct control_server* server, struct control_client* c link_info[i].total_decrypted = link->total_decrypted; link_info[i].bandwidth = link->bandwidth; link_info[i].nat_changes_count = link->nat_changes_count; + link_info[i].rtt_last = link->rtt_last; + link_info[i].tt_last = link->tt_last; link = link->next; } diff --git a/src/etcp.c b/src/etcp.c index fe1f5c1..1a3c2db 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -768,7 +768,7 @@ void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t d } // Calculate RTT if timestamps are valid - if (ts != (uint16_t)-1 && dts != (uint16_t)-1) { +/* if (ts != (uint16_t)-1 && dts != (uint16_t)-1) { uint16_t rtt = timestamp_diff(ts, dts); etcp->rtt_last = rtt; @@ -797,7 +797,7 @@ void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t d // DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] RTT updated - last=%u, avg_10=%u, avg_100=%u, jitter=%u", // etcp->log_name, rtt, etcp->rtt_avg_10, etcp->rtt_avg_100, etcp->jitter); } - +*/ // Update connection statistics etcp->unacked_bytes -= acked_pkt->ll.len; etcp->bytes_sent_total += acked_pkt->ll.len; @@ -860,6 +860,19 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) { pkt->link->rtt_last=cur_ts-ret_ts; pkt->link->recv_dt_last=recv_dt; data+=5; len-=5; + + struct ETCP_LINK* c=etcp->links; + int rtt_sum=0; + int tt_sum=0; + int cnt=0; + while (c) { + rtt_sum += c->rtt_last; + tt_sum += c->tt_last; + cnt++; + c=c->next; + } + etcp->rtt_last=rtt_sum/cnt; + etcp->tt_last=tt_sum/cnt; break; } case ETCP_SECTION_PAYLOAD: { diff --git a/src/etcp.h b/src/etcp.h index 4f8abc2..77a63d3 100644 --- a/src/etcp.h +++ b/src/etcp.h @@ -105,6 +105,7 @@ struct ETCP_CONN { // Metrics (RTT, jitter, etc.) // uint16_t retrans_delay; // Not used uint16_t rtt_last; + uint16_t tt_last; uint16_t rtt_avg_10; uint16_t rtt_avg_100; uint16_t jitter; diff --git a/src/etcp_connections.h b/src/etcp_connections.h index 6df481e..fa045e8 100644 --- a/src/etcp_connections.h +++ b/src/etcp_connections.h @@ -92,8 +92,10 @@ struct ETCP_LINK { size_t total_encrypted; size_t total_decrypted; - uint16_t rtt_last; - uint16_t recv_dt_last; + uint16_t rtt_last; // round trip (время отправки + приёма) + uint16_t recv_dt_last; // дельта времени для отправленных пакетов (относительное время отправки) + + uint16_t tt_last; // transmit time (время отправки пакета) uint32_t bandwidth; // Link bandwidth in Kbits/sec // NAT address tracking (from INIT_RESPONSE) diff --git a/tools/bping/Makefile b/tools/bping/Makefile new file mode 100644 index 0000000..a66d7c2 --- /dev/null +++ b/tools/bping/Makefile @@ -0,0 +1,32 @@ +# Makefile для burstping → bping + +CC = gcc +CFLAGS = -O2 -Wall -Wextra -std=gnu11 +LDFLAGS = + +TARGET = bping +SRC = bping.c + +.PHONY: all clean install uninstall + +all: $(TARGET) + +$(TARGET): $(SRC) + $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ + @echo "✅ Собрано: $(TARGET)" + +clean: + rm -f $(TARGET) + @echo "🧹 Очищено" + +install: $(TARGET) + sudo install -m 755 $(TARGET) /usr/local/bin/ + @echo "🚀 Установлено в /usr/local/bin/bping" + +uninstall: + sudo rm -f /usr/local/bin/$(TARGET) + @echo "🗑️ Удалено из /usr/local/bin" + +# Для отладки +debug: + $(CC) $(CFLAGS) -g $(SRC) -o $(TARGET) diff --git a/tools/bping/bping.c b/tools/bping/bping.c new file mode 100644 index 0000000..32de0d7 --- /dev/null +++ b/tools/bping/bping.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static char* host = NULL; +static int size = 56; +static int pings_per_burst = 10; +static int bursts = 0; // 0 = бесконечно +static double interval = 1.0; + +void usage() { + printf("Использование: burstping [-s размер] [-p посылок] [-b пачек] [-i интервал] host\n\n"); + printf(" -s размер Размер данных в ICMP-пакете (по умолчанию 56)\n"); + printf(" -p посылок Количество пингов в одной пачке (по умолчанию 10)\n"); + printf(" -b пачек Количество пачек (0 = бесконечно, по умолчанию 0)\n"); + printf(" -i интервал Интервал между пачками в секундах (можно 0.3, 0.05 и т.д., по умолчанию 1.0)\n\n"); + printf("Примеры:\n"); + printf(" burstping 8.8.8.8\n"); + printf(" burstping -s 1472 -p 100 -i 0.2 1.1.1.1\n"); + printf(" burstping -p 50 -b 30 -i 1 google.com\n"); + printf(" burstping -p 200 -i 0.05 -b 0 10.0.0.1 # бесконечный burst\n"); + exit(1); +} + +void sigint_handler(int sig) { + printf("\n\n⛔ burstping остановлен по Ctrl+C\n"); + exit(0); +} + +int main(int argc, char** argv) { + int opt; + while ((opt = getopt(argc, argv, "s:p:b:i:h")) != -1) { + switch (opt) { + case 's': size = atoi(optarg); break; + case 'p': pings_per_burst = atoi(optarg); break; + case 'b': bursts = atoi(optarg); break; + case 'i': interval = strtod(optarg, NULL); break; + case 'h': + case '?': usage(); + } + } + + if (optind >= argc) usage(); + host = argv[optind]; + + if (size < 0 || pings_per_burst < 1) usage(); + + signal(SIGINT, sigint_handler); + + printf("🚀 burstping → %s\n", host); + printf("Пакет: %d байт | Посылок в пачке: %d | Пачек: %s | Интервал: %.3f сек\n\n", + size, pings_per_burst, (bursts == 0 ? "∞" : "ограничено"), interval); + + int burst_num = 0; + while (1) { + burst_num++; + printf("=== Пачка #%d ===\n", burst_num); + + // Запускаем пачку параллельно + int launched = 0; + for (int i = 0; i < pings_per_burst; i++) { + pid_t pid = fork(); + if (pid == 0) { + // Дочерний процесс + char sz[16], cnt[4]; + snprintf(sz, sizeof(sz), "%d", size); + snprintf(cnt, sizeof(cnt), "1"); + execlp("ping", "ping", "-c", cnt, "-s", sz, "-W", "2", "-n", host, (char*)NULL); + perror("execlp ping"); + exit(1); + } else if (pid > 0) { + launched++; + } else { + perror("fork"); + } + } + + // Ждём завершения всех пингов этой пачки + for (int i = 0; i < launched; i++) { + wait(NULL); + } + + if (bursts > 0 && burst_num >= bursts) { + break; + } + + // Интервал между пачками + if (interval > 0.0) { + struct timespec ts; + ts.tv_sec = (time_t)interval; + ts.tv_nsec = (long)((interval - ts.tv_sec) * 1e9); + nanosleep(&ts, NULL); + } + } + + printf("✅ burstping завершён.\n"); + return 0; +} diff --git a/tools/etcpmon/etcpmon_gui.c b/tools/etcpmon/etcpmon_gui.c index b01eee2..a938c66 100644 --- a/tools/etcpmon/etcpmon_gui.c +++ b/tools/etcpmon/etcpmon_gui.c @@ -663,7 +663,7 @@ void etcpmon_gui_update_metrics(struct etcpmon_app* app, snprintf(display, sizeof(display), "Link %u: Status=%s, EncErrors=%u, DecErrors=%u, " "SendErr=%u, RecvErr=%u, BytesEnc=%llu, BytesDec=%llu, " - "BW=%u Kbps, NATChg=%u", + "BW=%u Kbps, NATChg=%u, RTT=%u us, TT=%u us", links[i].local_link_id, links[i].status ? "UP" : "DOWN", links[i].encrypt_errors, @@ -673,7 +673,9 @@ void etcpmon_gui_update_metrics(struct etcpmon_app* app, (unsigned long long)links[i].total_encrypted, (unsigned long long)links[i].total_decrypted, links[i].bandwidth, - links[i].nat_changes_count); + links[i].nat_changes_count, + links[i].rtt_last * 100, + links[i].tt_last * 100); SendMessageA(app->hListLinks, LB_ADDSTRING, 0, (LPARAM)display); } InvalidateRect(app->hListLinks, NULL, FALSE); diff --git a/tools/etcpmon/etcpmon_protocol.h b/tools/etcpmon/etcpmon_protocol.h index 24ba50e..efb93e5 100644 --- a/tools/etcpmon/etcpmon_protocol.h +++ b/tools/etcpmon/etcpmon_protocol.h @@ -116,9 +116,11 @@ struct etcpmon_link_metrics { uint32_t send_errors; /* Send errors */ uint32_t recv_errors; /* Receive errors */ uint64_t total_encrypted; /* Total bytes encrypted/sent */ - uint64_t total_decrypted; /* Total bytes decrypted/received */ + uint64_t total_decrypted; /* Total bytes decrypted/received */ uint32_t bandwidth; /* Configured bandwidth (Kbps) */ uint32_t nat_changes_count; /* NAT address changes */ + uint32_t rtt_last; /* Last RTT (0.1ms units) */ + uint32_t tt_last; /* Last transmit time (0.1ms units) */ }; /* TUN interface metrics */