Browse Source

win_upd

master
Evgeny 1 day ago
parent
commit
fb386976c5
  1. 2
      lib/Makefile.am
  2. 2
      lib/swm_min.c
  3. 2
      src/etcp.c
  4. 44
      src/etcp_connections.c
  5. 4
      src/etcp_connections.h

2
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

2
lib/swm_min.c

@ -1,5 +1,5 @@
/* sliding_window_min.c */
#include "sliding_window_min.h"
#include "swm_min.h"
#include <stdlib.h>
#include <limits.h>

2
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);

44
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);

4
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 <stdint.h>
#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

Loading…
Cancel
Save