diff --git a/lib/Makefile.am b/lib/Makefile.am index bd7cadc..53ba683 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -17,6 +17,8 @@ libuasync_a_SOURCES = \ socket_compat.h \ platform_compat.c \ platform_compat.h \ + swm_min.c \ + swm_min.h \ mem.c \ mem.h diff --git a/lib/swm_min.c b/lib/swm_min.c index b6494a4..1f34a76 100644 --- a/lib/swm_min.c +++ b/lib/swm_min.c @@ -1,5 +1,5 @@ /* sliding_window_min.c */ -#include "sliding_window_min.h" +#include "swm_min.h" #include #include diff --git a/src/etcp.c b/src/etcp.c index 197c74f..ba91f19 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -94,7 +94,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n etcp->ack_q = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, "ack_q"); etcp->inflight_pool = memory_pool_init(sizeof(struct INFLIGHT_PACKET)); etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT)); - etcp->optimal_inflight=10000; + etcp->optimal_inflight=100000; etcp->initialized=0; etcp->links_up=0; etcp->name = u_strdup(name); diff --git a/src/etcp_connections.c b/src/etcp_connections.c index 0c3499a..d61313c 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -605,7 +605,11 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn link->link_status = 0; // down initially link->handshake_minsize = 100; link->handshake_maxsize = mtu;// 28 = udp header size - + link->rtt_swm=swm_create(1024); + if (!link->rtt_swm) { + u_free(link); + return NULL; + } // Initialize keepalive timeout from global config if (etcp->instance && etcp->instance->config) { @@ -721,6 +725,7 @@ void etcp_link_close(struct ETCP_LINK* link) { remove_link(link->conn, link->ip_port_hash); + swm_destroy(link->rtt_swm); u_free(link); } @@ -750,6 +755,35 @@ static void link_stats_timer_cb(void* arg) { link->stat_win[link->win_ptr].pkt_loss = (uint16_t)link->window_retransmissions; link->stat_win[link->win_ptr].pkt_transmitted = link->window_pkt_transmitted; + swm_add(link->rtt_avg10, link->rtt_avg10); + link->rtt_min=swm_get_min(link->rtt_swm); + +// пересчитываем BW + float rtt=(float)link->rtt_min/10000.f;// переводим в секунды + if (rtt<0.005f) rtt=0.005f;// 5 ms + if (rtt>1.f) rtt=1.f;// 1 sec + float win_size=link->inflight_lim_bytes*8.f;// переводим в биты + if (win_size<100000.f) win_size=100000.f;// 10kb min + if (win_size>10000000.f) win_size=10000000.f;// 1Mb max + link->bandwidth=(int)(win_size/rtt/1024.f*1.3f);// результат в кБит/сек + + if (link->inflight_lim_bytes<10000 || link->inflight_bytes > link->inflight_lim_bytes - 2000) {// очередь загружена + int new_lim=link->inflight_lim_bytes; + if (link->rtt_avg10*10 < link->rtt_min*16) {// подъема rtt нет, плавно увеличиваем win + new_lim+=new_lim/64+1; + if (new_lim>1000000) new_lim=1000000; + } + else { + new_lim-=new_lim/64+1; + if (new_lim<10000) new_lim=10000; + } + etcp_link_update_inflight_lim(link, new_lim); + } + + +// если окно забито - пробуем его расширить + + // DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] stats window updated (win_timebase=%u us, rtt=%u, retrans=%u, transmitted=%u)", // link->etcp->log_name, link->win_timebase, link->rtt_avg10, link->window_retransmissions, link->window_pkt_transmitted); @@ -761,11 +795,11 @@ static void link_stats_timer_cb(void* arg) { link->window_retransmissions = 0; // 4. Плавная подстройка win_timebase под rtt/2 (в микросекундах) - uint32_t target_us = (uint32_t)link->rtt_avg10 * 50ULL; // rtt_avg10 (0.1 ms) → rtt/2 в us - if (target_us < 10000) target_us = 10000; // минимум 10 ms - if (target_us > 500000) target_us = 500000; // максимум 0.5 s +// uint32_t target_us = (uint32_t)link->rtt_avg10 * 50ULL; // rtt_avg10 (0.1 ms) → rtt/2 в us +// if (target_us < 10000) target_us = 10000; // минимум 10 ms +// if (target_us > 500000) target_us = 500000; // максимум 0.5 s - link->win_timebase = (link->win_timebase * 7 + target_us) / 8; + link->win_timebase = 10000;// (link->win_timebase * 7 + target_us) / 8; // 5. Перезапускаем таймер с новым интервалом start_stats_timer(link); diff --git a/src/etcp_connections.h b/src/etcp_connections.h index 4023b5a..2ee2b91 100644 --- a/src/etcp_connections.h +++ b/src/etcp_connections.h @@ -6,6 +6,7 @@ #include "secure_channel.h" #include "utun_instance.h" #include "../lib/socket_compat.h" +#include "../lib/swm_min.h" #include #define UDP_HDR_SIZE 28// размер udp header + ethernet заголовков (ipv4) [для ipv6 = 48 байт] @@ -61,7 +62,7 @@ struct ETCP_LINK { struct ETCP_CONN* etcp; // подключение (parent) struct ETCP_SOCKET* conn; // сокет через который работаем - + SlidingWindowMin* rtt_swm; // Путь соединения struct sockaddr_storage remote_addr; // Удалённый адрес @@ -136,6 +137,7 @@ struct ETCP_LINK { uint16_t rtt_max_val; // Current max RTT in history uint8_t rtt_max_idx; // Index of max (255 = needs recalc) uint16_t rtt_avg10; // round trip average (excl. max) + uint16_t rtt_min; // round trip min (rtt_swm floating window) uint32_t recv_dt_avg_tx; // дельта времени для отправленных пакетов (относительное время отправки) x256 uint32_t recv_dt_avg_rx; // дельта времени для принятых пакетов (относительное время отправки) x256