фикс reorder для симплекса

This commit is contained in:
Maxim
2026-07-16 15:00:11 +03:00
parent 3b6a56e54c
commit 6294a472cd

View File

@@ -312,21 +312,20 @@ static void rb_force_to(uint32_t to) {
fflush(stdout);
}
// Вызывается ТОЛЬКО на FDD-пути (симплекс пишет в stdout напрямую — там нечего
// переупорядочивать), поэтому досылка по NACK всегда доступна.
static void rb_insert(uint32_t seq, const uint8_t *d, size_t len) {
if (len > GF_CHUNK) len = GF_CHUNK; // защита в глубину: len берётся из
// hdr, слот кольца — ровно GF_CHUNK
if (seq < next_out) return; // уже выведен: дубль ретрансмита
if (seq - next_out >= RB_CAP) {
// Дыра в голове старше окна. С ARQ это не тупик: дропаем новый кадр и
// возвращаем его seq в NACK — A дошлёт, когда голова разъедется. Без
// обратного канала досылать некому → схлопываем окно вперёд.
if (g_fb_fg) {
// Дыра в голове старше окна: дропаем новый кадр и возвращаем его seq в
// NACK — A дошлёт, когда голова разъедется. Схлопнуть окно нельзя: это
// молча потеряло бы кадр, который ARQ ещё способен закрыть.
rb_over++;
miss_add_sorted(seq);
return;
}
rb_force_to(seq - RB_CAP + 1);
}
rbslot_t *s = &rb[seq % RB_CAP];
s->seq = seq;
s->len = (uint16_t)len;
@@ -587,11 +586,19 @@ route:
if (flags & GF_FLAG_MODE) {
gf_seen = 1;
group_route(flags, seq, dec, dec_len, ok);
} else {
} else if (ok) {
if (g.active) group_flush(); // TX не мешает режимы, но подстрахуемся
if (ok) {
rb_insert(seq, dec, dec_len); // порядок восстанавливает кольцо:
rb_drain(); // ретрансмит приходит вне очереди
if (g_fb_fg) {
rb_insert(seq, dec, dec_len); // FDD: ретрансмит приходит вне
rb_drain(); // очереди — порядок держит кольцо
} else {
// Симплекс: ретрансмитов нет, seq всегда растёт — переупорядочивать
// нечего. Кольцо здесь только задержало бы вывод до EOF (дыра стопорит
// next_out, а закрыть её некому). Пишем сразу, как до этапа 3b.
fwrite(dec, 1, dec_len, stdout);
fflush(stdout);
total_bytes += dec_len;
crc_final++;
}
}
}