Skip to content

Remove Android QUIC GSO workaround after noq retransmit fix ships #388

Description

@momics

This was generated by AI during triage.

Summary

PR #389 carries a temporary Android-only QUIC configuration workaround for #387. It disables segmentation offload before application traffic starts because the released noq UDP path can lose the first batch rejected by an Android kernel.

This issue tracks deleting that policy as soon as the upstream transport can retry a rejected batch safely. The workaround is not intended to become permanent Android networking behavior in iroh-http.

Why the workaround exists

Some Android kernels advertise UDP segmentation offload but reject a batched sendmsg at runtime with an I/O error. The currently released noq implementation disables GSO after that rejection, but it does not immediately retransmit the rejected batch as individual datagrams. The resulting packet loss can stall an HTTP request body until timeout or path fallback.

PR #389 uses iroh's public QUIC transport configuration to disable the optimization on Android only. It does not implement UDP sending, retry behavior, or platform capability detection in iroh-http. Other platforms retain the upstream default.

Upstream tracking

A merged upstream PR is not sufficient by itself. We need the fix in a released noq version, adopted by a released iroh version, followed by physical-device validation through iroh-http.

Ownership and containment

  • noq-udp owns the sendmsg operation and must own retrying the rejected packet batch.
  • iroh owns adopting the corrected noq release and carrying its transport behavior.
  • iroh-http owns only the temporary Android configuration policy required for release correctness.
  • Keep the policy private to endpoint construction; do not expose it as a public option or recreate low-level UDP retry logic.
  • Keep this issue and [noq-udp] Retransmit failing GSO packets and split batches n0-computer/noq#746 linked from the compatibility comment in crates/iroh-http-core/src/endpoint/bind.rs.

Removal condition

Remove the workaround only after all of the following are true:

  1. [noq-udp] Retransmit failing GSO packets and split batches n0-computer/noq#746, or an equivalent fix, is merged and included in a released noq version.
  2. A released iroh version adopts that noq release.
  3. iroh-http updates every relevant manifest and lockfile to that released iroh/noq chain.
  4. The Android physical-device matrix confirms that a rejected GSO batch is recovered without application-data loss or body-transfer delay.

Expected deletion surface

The removal should remain deliberately small and localized to crates/iroh-http-core/src/endpoint/bind.rs:

  1. Delete segmentation_offload_enabled.
  2. Remove the explicit .enable_segmentation_offload(...) override so iroh's upstream default is restored on Android.
  3. Delete or replace transport_policy_tests while retaining meaningful transport regressions at the integration boundary.
  4. Remove the temporary compatibility comment and links.

No DNS-SD, adapter, HTTP framing, timeout, or public API changes should be necessary.

Exit criteria

  • Link the released noq version containing the rejected-batch retry.
  • Link the released iroh version that adopts it.
  • Update all relevant dependency locks consistently.
  • Confirm the upstream test covers retransmitting the batch that failed, not merely disabling GSO for later sends.
  • Remove the exact compatibility surface listed above.
  • Build and install a fresh embedded Android application.
  • Run one cold and at least two warm Android-to-desktop suites with 107 pass / 0 fail / 0 skip.
  • Confirm the 4 KiB, 64 KiB, 1 MiB, and 5 MiB request bodies complete without timeout or path fallback.
  • If Android rejects a GSO send, verify from logs that the rejected application datagrams are retried successfully.
  • Confirm ordinary throughput and direct-path behavior do not regress after GSO is re-enabled.
  • Run the normal cross-platform CI matrix.
  • Update comments and release notes so they no longer describe the upstream limitation.

Physical-device validation matrix

Device/scenario Required result
Android cold start -> desktop 107 pass / 0 fail / 0 skip; body cases complete on the first run
Same Android -> desktop, two warm reruns Both runs remain fully green with stable body latency
Android after Wi-Fi reconnect Direct transport recovers without a stalled first upload
Android generic DNS-SD smoke test Existing discovery behavior remains green; no unrelated regression

Relationship to PR #389

PR #389 should not be blocked on the upstream release: correctness is required now and the workaround is one private transport policy. PR #389 must keep the workaround directly linked to this issue so it cannot silently become permanent.

Blocked by n0-computer/noq#746. Follow-up to #387.

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

    P2Medium priorityconnectivityPeer discovery and connectiondependenciesPull requests that update a dependency filerustPull requests that update rust code

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions