Skip to content

fix(udp): treat only n < len(b) as a short write (#1029)#37

Merged
MaurUppi merged 1 commit into
mainfrom
fix/udp-short-write-1029
Jun 29, 2026
Merged

fix(udp): treat only n < len(b) as a short write (#1029)#37
MaurUppi merged 1 commit into
mainfrom
fix/udp-short-write-1029

Conversation

@MaurUppi

Copy link
Copy Markdown
Owner

What

Minimal correctness fix for the UDP data-path retry storm: UdpEndpoint.WriteTo now treats only n < len(b) as a short write, instead of n != len(b).

A proxy WriteTo reports the on-wire byte count, which includes the outbound protocol's encapsulation overhead (shadowsocks AES-128-GCM + IPv4 = +39 bytes), so n can legitimately exceed len(b) on a fully successful write. UDP datagrams are atomic; only n < len(b) is a genuine short write. The old check retired healthy endpoints and exhausted the retry limit, surfacing as Touch max retry limit. warnings.

Evidence

  • Pre-fix: instrumented WriteTo errors showed 10655/10655 retry-exhaustion drops were exactly n = len(b)+39 over-writes (delivered on the wire), zero genuine under-writes.
  • Post-fix: 22.3h production window logged zero Touch max retry limit. events.

Scope

  • Correctness fix only — no instrumentation. Branched from upstream dae/main and cherry-picked clean (2 files, gofmt-clean).
  • Includes two regression tests: +39 over-write stays alive; genuine partial write still retires + io.ErrShortWrite.
  • This is the same change submitted upstream as fix(udp): treat only n < len(b) as a short write (#1029) daeuniverse/dae#1030; merging here lands it in our fork build ahead of upstream.
  • The diagnostic toolkit that found this (health-check gauges, UDP retry diagnostics, snapshot/correlate scripts) stays on the archived branch fix/healthcheck-retry-evidence-1026-1029, intentionally excluded here.

Replaces #36 (closed).

A proxy WriteTo may report the on-wire byte count including protocol
encapsulation overhead (shadowsocks AES-128-GCM + IPv4 = +39 bytes), so n
can legitimately exceed len(b). UDP datagrams are atomic; only n < len(b)
is a genuine short write. The old n != len(b) misread every over-count as
a short write, retiring healthy endpoints and exhausting the retry limit.

Evidence: 10655/10655 captured drops were exactly +39 over-writes with
retry exhausted and zero genuine under-writes.
@MaurUppi MaurUppi merged commit 4fd6bbb into main Jun 29, 2026
32 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant