Skip to content

fix(net): preserve TCP dual-stack binding and listener domains - #2314

Merged
fslongjin merged 3 commits into
DragonOS-Community:masterfrom
fslongjin:codex/fix-tcp-dual-stack-listeners
Sep 21, 2026
Merged

fslongjin merged 3 commits into
DragonOS-Community:masterfrom
fslongjin:codex/fix-tcp-dual-stack-listeners

Conversation

@fslongjin

@fslongjin fslongjin commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

Problem

Default nginx binds both IPv4 and IPv6-only wildcard listeners to port 80. The TCP port table rejected the second bind by port number alone, while IPV6_V6ONLY was ignored and wildcard listeners lost their IP version.

Changes

  • Track TCP reservations per network namespace using address coverage and unique ownership, preserving existing connection states and precise release behavior.
  • Implement IPV6_V6ONLY and retain its policy through listening and accept-slot replacement.
  • Preserve sockaddr family until TCP validates mapped addresses; keep other protocols on the existing decoder behavior.
  • Keep listener names and backlog state isolated by receive domain.
  • Add 11 dunitest regressions and include them in both execution lists.

Dependency

DragonOS-Community/smoltcp#29 is merged into dragonos/v0.12.0. Both manifest and lockfile now pin merge commit 5bde8e535227803879c4a6a36533959e5a439cc1; its source tree is identical to the previously validated commit.

Validation

  • make kernel, make fmt, FMT_CHECK=1 make fmt: passed.
  • Linux: all 11 new tests passed.
  • DragonOS guest: 71/71 focused tests passed (11 new, 27 existing TCP, 22 UDP IPv6, 11 socket options).
  • Default nginx configuration check, dual-stack startup and IPv4/IPv6 HTTP: passed without disabling IPv6.
  • Fresh guest boot: 11/11 new tests and 10/10 alternating IPv4/IPv6 HTTP requests passed.
  • smoltcp: 636 library tests on Rust 1.80 plus IPv4-only/IPv6-only builds passed.
  • Independent three-role review completed. A mapped-sockaddr decoder regression caught during guest testing was corrected and re-reviewed.

Scope

This does not implement complete TCP TIME_WAIT reuse semantics or fix the existing repeated-listen warning. Default nginx graceful shutdown still leaves processes running; the same symptom was reproduced on the pre-fix kernel using an IPv4-only diagnostic configuration. This PR fixes dual-stack binding and dispatch, not full nginx compatibility.

CI test-fixture correction

The failed utimensat_symlink suite assumed its working filesystem supports symlinks. CI boots a FAT root; all 15 cwd cases failed during fixture setup. Reuse the existing isolated ext4 loop fixture via a shared header, retaining all 30 assertions without skips or kernel workarounds.

Validation on DragonOS from a FAT working directory: original suite reproduced 15 failures; corrected suite passed 30/30 (262 ms), and existing ext4 regressions passed 46/46 (4384 ms). Static builds, updated-revision kernel build and independent review passed. Remote CI rerun remains authoritative.

Replace per-interface port-number ownership with network-namespace TCP reservations that compare local address coverage and carry a unique release identity through existing connection states. Keep accepted children independent of listener reservation ownership and isolate backlog registration by receive domain.

Implement IPV6_V6ONLY state and bind-time immutability. Preserve mapped sockaddr input until TCP validates its original family, retaining the existing decoder behavior for other protocols. Return mapped AF_INET6 names for dual-stack children and preserve listener identity across accept slot replenishment.

Pin the smoltcp passive-listener IP version primitive from DragonOS-Community/smoltcp#29. Add 11 dunitest regressions for options, conflict rules, bind order, cleanup isolation, actual IPv4/IPv6 dispatch, repeated accepts, mapped names, concrete addresses and implicit listen.

Validation: make kernel, make fmt and FMT_CHECK=1 make fmt passed. Linux passed all 11 new tests. DragonOS passed 71 focused tests, including 27 existing TCP and 33 UDP/socket-option tests. Default nginx dual-stack startup and both HTTP families passed; reboot repeated the 11 new tests and 10 alternating HTTP requests. Three-role adversarial review and follow-up confirmed the mapped-parser correction.

Existing nginx repeated-listen warnings and default graceful-shutdown limitations are not addressed. The shutdown limitation was also reproduced on the pre-fix kernel with an IPv4-only diagnostic configuration.

Signed-off-by: longjin <longjin@dragonos.org>
@github-actions github-actions Bot added the Bug fix A bug is fixed in this pull request label Sep 21, 2026
@fslongjin

Copy link
Copy Markdown
Member Author

@codex review

Update the manifest and lockfile to the merge commit of smoltcp PR DragonOS-Community#29 on dragonos/v0.12.0. The merged tree matches the previously validated listener-family implementation.

Validation: make kernel passed.
Signed-off-by: longjin <longjin@dragonos.org>
The CI root filesystem is FAT, so the cwd parameter fails all 15 cases while creating symlinks before exercising utimensat. Replace that implicit filesystem assumption with an isolated ext4 loop fixture and retain all 30 assertions without skips.

Extract the existing LoopExt4 helper into a shared header and track it in both binary build dependencies. Keep permission-test traversal focused on its target directory.

Validation: reproduced 15 failures from a FAT cwd in DragonOS; fixed suite passes 30/30 in 262 ms. Existing ext4 suite passes 46/46 in 4384 ms. Both static test builds and independent review passed.
Signed-off-by: longjin <longjin@dragonos.org>
@fslongjin

Copy link
Copy Markdown
Member Author

@codex review

@fslongjin
fslongjin merged commit c02689a into DragonOS-Community:master Sep 21, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug fix A bug is fixed in this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant