Skip to content

Multi-message packet bundling (4-pass drain algorithm) #195

Open

Description

@Cadacious

Summary

Server currently sends one TGMessage per UDP datagram. Stock packs up to 255 messages per datagram (512-byte MTU) via a 4-pass drain algorithm. Without bundling, OpenBC produces many small datagrams; bandwidth less efficient and burst-absorption pattern differs noticeably from stock.

Stock drain algorithm

Pass Queue Retx gate Behavior
P1 priority reliable retx < 3 multi-msg; break on won't-fit or 255 msg cap
P2 reliable (cV stale) ONE-SHOT — unconditional break after first attempt
P3 unreliable (firstSkip) multi-msg; drains + dequeues + frees; promotes to reliable on first delivery
P4 priority reliable retx >= 3, free at >= 9 gated on (msg_count > 0 OR peer disconnecting) AND ack_count > 0

Per-datagram constants:

  • MTU 512 bytes (per bc_winsock_network MTU field)
  • Header = 2 bytes: [u8:senderPeerId][u8:messageCount]
  • msgCount max = 255
  • Fragment chunk max = 412 bytes (MTU - 100, decided at queue time)
  • Round-robin cursor across peers for fairness

Symptom

  • OpenBC emits many small UDP datagrams under load; stock emits fewer larger ones
  • Bandwidth headers + cipher state amortized poorly
  • Different burst-absorption behavior — stock can pack 200+ messages on a tick; OpenBC sends them as 200 datagrams

Fix

Implement the 4-pass drain in bc_send_outgoing_packets. Pass-4 gate logic is the ACK-outbox deadlock described in docs/bugs/ack-outbox-deadlock.md — match the binary truth gate exactly to preserve interop.

Scope

Large (~200 LoC, architectural — buffer management + per-peer drain state)

Companion docs

  • docs/bugs/bug-reports/20260529-packet-bundling-missing.md
  • docs/bugs/ack-outbox-deadlock.md (P4 gate is the deadlock)
  • docs/networking/fragmented-ack-bug.md

Tier 3 — Throughput & efficiency

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions