Skip to content

[WSLC] Proxy Pt. 2: Enable session host loopback - #1714

Draft
Elliot (theelliotm) wants to merge 1 commit into
user/emichlin/wslc-proxy-1-sdkfrom
user/emichlin/wslc-proxy-2-host-loopback
Draft

Elliot (theelliotm) wants to merge 1 commit into
user/emichlin/wslc-proxy-1-sdkfrom
user/emichlin/wslc-proxy-2-host-loopback

Conversation

@theelliotm

@theelliotm Elliot (theelliotm) commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

📖 Description

Second PR in the WSLC built-in proxy stack (#1625). Turns on WSL host loopback, so hostLoopback: allow reaches Windows 127.0.0.1. Before this, it was accepted but had no effect.

  • Every session MXC creates (create-and-run and the lifecycle daemon) sets the host loopback hostname host.wslc.internal, which WSL's CLI also uses.
  • On WSL older than 3.0.5, session creation returns WSLC_E_RUNTIME_UPDATE_NEEDED; MXC logs it and creates the session without host loopback.
  • Isolated (NONE) containers in a session with host loopback still can't reach Windows loopback, by name or by the relay address.

Behavior change: on WSL 3.0.5+, existing all-allow configs gain outbound access to every Windows loopback TCP port. There's no per-port filter; that comes with the controller later in the stack.

🔗 References

Refs #1462
Spec: #1625
Stacked on #1679

🔍 Validation

On ARM64 with WSL 3.0.5.0 and WSLC_SDK_PATH set to the local 3.0.5 SDK build:

  • cargo build -p wxc --features wslc --release and cargo build -p mxc-sdk --bin wxc-wslc-daemon --features wslc --release: passed
  • cargo fmt --all -- --check: passed
  • cargo clippy -p mxc-sdk --features wslc --all-targets -- -D warnings: passed
  • cargo test -p mxc-sdk --features wslc --lib wslc: passed (434 passed, 7 ignored)
  • tests/scripts/run_wslc_host_loopback_test.ps1 (new): passed. A bridged container gets a per-run token from a listener bound to Windows 127.0.0.1; an isolated container doesn't get it through host.wslc.internal or 169.254.73.254.
  • tests/scripts/run_wslc_state_aware_tests.ps1: passed (141/141), including new checks that a bridged sandbox reaches the listener and an isolated sandbox in the same daemon session doesn't.

Not run: x64, the full run_wslc_all_tests.ps1 after the final test changes, and WSL older than 3.0.5 (the fallback). CI WSLC builds fail on this stack until 3.0.5 is published.

✅ Checklist

  • Signed the Contributor License Agreement
  • Linked to an issue
  • For features or changes requiring a spec: linked the issue with maintainer-applied feature-accepted
  • For implementation: linked the required approved and merged design/API spec, or explained why no spec is required
  • Feature issue remains open unless this PR completes all agreed implementation, validation, and documentation
  • Updated documentation (if applicable)
  • Updated Copilot instructions (if build, architecture, or conventions changed)
  • If this PR changes Cargo.lock, the dependency-feed-check check passes (see pull request builds)

📋 Issue Type

  • Bug fix
  • Feature
  • Task
Microsoft Reviewers: Open in CodeFlow

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@theelliotm Elliot (theelliotm) changed the title enable hostLoopback on WSL 3.0.5 [WSLC] Proxy Pt. 2: Enable session host loopback Nov 9, 2026
@theelliotm
Elliot (theelliotm) force-pushed the user/emichlin/wslc-proxy-2-host-loopback branch from 7cbd0d1 to 30303eb Compare November 10, 2026 22:17
Copilot AI balanced review requested due to automatic review settings November 10, 2026 22:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The tests can miss shared-session relay exposure, incorrectly fail supported older WSL runtimes, and lack passing regression coverage for the non-loopback retry.

3 open issues
What changed in this PR

This PR adds Windows host-loopback access to WSLC workload sessions, advancing the built-in proxy stack. Bridged containers can reach Windows loopback services through host.wslc.internal on WSL 3.0.5+.

Changes:

  • Shares session-creation logic across create-and-run execution and the lifecycle daemon, with a fallback for older runtimes.
  • Adds token-based loopback reachability and isolation tests.
  • Documents runtime requirements and the expanded access granted to existing all-allow configurations.
File Description
tests/​scripts/​wslc_loopback_token_server.ps1 Provides a Windows loopback listener with a per-run token.
tests/​scripts/​run_wslc_state_aware_tests.ps1 Adds lifecycle loopback reachability and isolation checks.
tests/​scripts/​run_wslc_host_loopback_test.ps1 Drives create-and-run loopback tests.
tests/​scripts/​run_wslc_all_tests.ps1 Includes loopback tests in the full WSLC suite.
tests/​configs/​wslc_network_host_loopback.json Defines the bridged loopback probe.
tests/​configs/​wslc_network_host_loopback_isolated.json Defines isolated probes by hostname and relay address.
src/​mxc-sdk/​src/​backends/​wslc/​common/​wslc_bindings.rs Loads the loopback-setting API and defines the runtime-update error.
src/​mxc-sdk/​src/​backends/​wslc/​common/​wsl_container_runner.rs Uses shared session creation for create-and-run execution.
src/​mxc-sdk/​src/​backends/​wslc/​common/​container_steps.rs Enables session loopback and retries without it on older runtimes.
docs/​backends/​wslc/​wslc-state-aware.md Documents loopback access through daemon sessions.
docs/​backends/​wslc/​wsl-container-getting-started.md Explains prerequisites, usage, and networking behavior changes.

Review effort: Balanced

let mut session: WslcSession = ptr::null_mut();
let mut err_msg = CoTaskMemPWSTR::null();
let mut hr = sdk.WslcCreateSession(settings, &mut session, err_msg.as_mut_ptr());
if hr == WSLC_E_RUNTIME_UPDATE_NEEDED {
Comment on lines +66 to +68
} elseif ($bridged.Output -notmatch [regex]::Escape("HOST_LOOPBACK_GOT=[$($server.Token)]")) {
Write-Host "FAIL: bridged container did not reach the Windows 127.0.0.1:$port listener through host.wslc.internal" -ForegroundColor Red
$failed = $true
Comment on lines +1756 to +1758
if ($edgeStartedOk) {
Run-StateAwareTest "F: isolated exec cannot reach Windows loopback" {
Assert-True ([bool]$script:hostLoopbackAddr) "Lifecycle C resolved the host loopback address"

This branch has not been deployed

No deployments
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.

2 participants