Define retry path history and fast stall state contracts

This commit is contained in:
evgeny committed 2026-10-24 11:27:48 +02:00
1 parent acde6bda9d
commit 39ee5b392b
3 files changed
+15 -1

No files matched your search

+7
View File
@@ -65,6 +65,7 @@ uint16_t get_current_timestamp(void);
#define INFLIGHT_STATE_WAIT_ACK 0
#define INFLIGHT_STATE_WAIT_SEND 1
#define INFLIGHT_INITIAL_HASH_SIZE 1024
#define ETCP_LINK_HISTORY_BYTES 32 // по одному биту для локального слота линка 0..255
#define MAX_INFLIGHT_SIZE 16384 // максимальное число элементов в inflight приёмной очереди (для предотвращения атак)
#define ETCP_ACK_GAP_MAX_PACKETS 8192 // предел кумулятивного ACK за приём: 8192 × PACKET_DATA_SIZE(2048) = 16 MB (защита от DoS)
@@ -84,8 +85,14 @@ struct INFLIGHT_PACKET {// выделяется из etcp->inflight_pool
uint32_t active_attempts; // Попытки этого seq, ещё занимающие окна каналов
uint8_t state; // WAIT_SEND — готов к отправке; WAIT_ACK — логически ожидает доставки
uint8_t send_hist[8]; // local_link_id последних попыток; send_count%8 — следующая позиция до насыщения счётчика
uint8_t used_links[ETCP_LINK_HISTORY_BYTES]; // принятые отправки текущего обхода; слот очищается до удаления/повторной выдачи ID
};
/* Проверить текущий обход каналов пакета; бит описывает живой локальный слот, а не идентичность физической попытки. */
static inline int etcp_packet_link_used(const struct INFLIGHT_PACKET* packet, uint8_t link_id) {
return !!(packet->used_links[link_id >> 3] & (1u << (link_id & 7)));
}
// Список пакетов для сборки. собирается в ll_queue (используем быстрый поиск с хешем)
struct ETCP_FRAGMENT {// выделяется из пула etcp->rx_pool
struct ll_entry ll;
+3
View File
@@ -269,6 +269,9 @@ struct ETCP_LINK {
uint64_t retrans_deadline_us; // Уже запланированная проверка: более ранний таймер можно сохранить
uint32_t data_rtt_us; // Сглаженный RTT DATA->ACK этого пути; 0 до первого измерения
uint32_t data_jitter_us; // Сглаженное абсолютное отклонение собственного DATA RTT
uint8_t data_rto_streak; // 0..3: RTO попыток без подтверждённого прогресса; после3 tx_stalled=1
uint8_t tx_stalled; // исключить из повторов при наличии незастрявшего UP-пути; новые DATA/UP не меняются
uint64_t tx_stalled_since_us; // момент установки флага; снять его может ACK принятой после этого DATA-попытки
uint32_t inflight_bytes; // DATA-байты физических попыток этого линка, включая синхронный резерв send
uint32_t inflight_packets; // число таких пакетов
+5 -1
View File
@@ -14,6 +14,8 @@ struct ETCP_LINK;
struct ETCP_DGRAM;
struct INFLIGHT_PACKET;
#define ETCP_TX_STALL_THRESHOLD 3 // три RTO физических попыток без ACK-прогресса, включая один пакетный вызов таймера
/* Внутренний ключ пары seq/номер без padding. Номер 1..65535; wire содержит seq:u32 и номер:u16 отдельно. */
static inline uint64_t etcp_tx_attempt_id(uint32_t seq, uint16_t number) {
return ((uint64_t)seq << 16) | number;
@@ -36,7 +38,7 @@ struct ETCP_TX_ATTEMPT {
/* Инициализировать очереди attempts/ACK линка. 0 — успех, -1 — OOM (с логом); при ошибке очереди очищены. */
int etcp_tx_link_init(struct ETCP_LINK* link);
/* Снять попытки/таймер/ACK линка перед reset или free. retry=1 возвращает недоставленные DATA на отправку.
/* Снять попытки/таймер/ACK/флаг застревания линка перед reset или free. retry=1 возвращает недоставленные DATA на отправку.
* reset не меняет физический UP; destroy дополнительно освобождает очереди. */
void etcp_tx_link_reset(struct ETCP_LINK* link, int retry);
void etcp_tx_link_destroy(struct ETCP_LINK* link);
@@ -51,10 +53,12 @@ uint32_t etcp_tx_rto_us(const struct ETCP_LINK* link);
* После номера 65535 новый prepare сбрасывает поток со сменой эпохи, не оборачивает счётчик. */
struct ETCP_TX_ATTEMPT* etcp_tx_prepare(struct ETCP_LINK* link, struct INFLIGHT_PACKET* packet);
/* Завершить синхронный send: success=1 принят транспортом, 0 — снять резерв без сетевой потери.
* Принятие DATA фиксирует историю каналов и RR; повторно использованный слот начинает новый обход.
* Вызвать ровно один раз до освобождения dgram и до следующего poll; dgram->attempt обнуляется. */
void etcp_tx_complete(struct ETCP_DGRAM* dgram, int success);
/* Принятый ACK: seq подтверждает логическую доставку; внутренний attempt_id=(seq<<16)|номер обновляет только свой линк.
* Неизвестный старый ID не создаёт измерение и не вычитает окно. UINT32_MAX delay — RTT недостоверен.
* Действующий ACK сбрасывает серию RTO; флаг застревания снимается только для отправки после его установки.
* peer_rx_bytes/time_us — согласованная точка приёма пути из ACK; 0/0 — неизвестна.
* Достоверная пара ограничивает BW темпом приёма, сохраняя границы send/ACK; RTT и доставка от неё не зависят.
* interval=max(send_us,ack_us,ceil(delivered*delta_rx_us/delta_rx_bytes)); дельты от снимка при отправке.