Define retry path history and fast stall state contracts
This commit is contained in:
1 parent
acde6bda9d
commit
39ee5b392b
3 files changed
+15
-1
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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; // число таких пакетов
|
||||
|
||||
@@ -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)); дельты от снимка при отправке.
|
||||
|
||||
Reference in new issue
Block a user