From 6294a472cdffdeee2df228f93bc8c8315761ca31 Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 16 Jul 2026 15:00:11 +0300 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20reorder=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=81=D0=B8=D0=BC=D0=BF=D0=BB=D0=B5=D0=BA=D1=81?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/receiver.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/receiver.c b/src/receiver.c index f85c21a..fed5607 100644 --- a/src/receiver.c +++ b/src/receiver.c @@ -312,20 +312,19 @@ 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) { - rb_over++; - miss_add_sorted(seq); - return; - } - rb_force_to(seq - RB_CAP + 1); + // Дыра в голове старше окна: дропаем новый кадр и возвращаем его seq в + // NACK — A дошлёт, когда голова разъедется. Схлопнуть окно нельзя: это + // молча потеряло бы кадр, который ARQ ещё способен закрыть. + rb_over++; + miss_add_sorted(seq); + return; } rbslot_t *s = &rb[seq % RB_CAP]; s->seq = seq; @@ -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++; } } }