Skip to content

v0.11.0: Windows support (cfg-gate admin API + rusnel ctl) - #47

Merged
guyte149 merged 2 commits into
masterfrom
feat/windows-support
May 6, 2026
Merged

v0.11.0: Windows support (cfg-gate admin API + rusnel ctl)#47
guyte149 merged 2 commits into
masterfrom
feat/windows-support

Conversation

@guyte149

@guyte149 guyte149 commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary

The library failed to compile on `x86_64-pc-windows-msvc` because `src/server/admin.rs` and `src/ctl/mod.rs` use `tokio::net::UnixListener`, `UnixStream`, and POSIX `Permissions::set_mode(0o600)` unconditionally. None of these have direct Windows equivalents — Windows has named pipes (different API surface) and ACLs (different model).

Rather than block tunnel users on a full named-pipe backend, this PR `#[cfg(unix)]`-gates the admin surface so the rest of rusnel — forward/reverse TCP+UDP, SOCKS5, TLS, embedded credentials, auto-reconnect, all of `stdio:`, `--proxy`, `RUSNEL_EMBED_*` — compiles and runs on Windows. The admin API + `rusnel ctl` can be re-enabled later via a Windows named-pipe backend without changing any flags.

What changed

Library

  • `src/lib.rs`: `pub mod ctl;` is `cfg(unix)`.
  • `src/server/mod.rs`: `pub mod admin;`, the `admin_handle` setup, the spawn helper, the shutdown cleanup, and the unused-on-Windows `PathBuf` import are all `cfg(unix)`. `ServerConfig.admin_socket` stays declared on every platform so the public API doesn't fork.

Binary

  • `Mode::Ctl` and `CtlAction` are `cfg(unix)`. `rusnel --help` on Windows shows the platform-correct command list — no dangling `ctl` subcommand the user can't actually invoke.
  • `--admin-socket` and `--no-admin-socket` flags are still parsed on Windows so cross-platform automation that passes them keeps working. If `--admin-socket ` is set on Windows, rusnel prints a one-line warning to stderr and disables the admin API.

Tests + CI

  • `tests/admin.rs` is `#![cfg(unix)]`-gated. The other integration tests already use `admin_socket: None` and need no change.
  • New `windows-latest` job in `ci.yml` runs `cargo build --all` plus `cargo test --lib --bins` on every PR — Windows regressions get caught at PR time, not at release time.
  • `x86_64-pc-windows-msvc` is back in `release.yml`'s prebuilt-binary matrix.

Why `#[cfg(unix)]` instead of named pipes

Two reasons.

  1. Scope: a named-pipe backend means abstracting over `UnixListener` / `UnixStream` vs `tokio::net::windows::named_pipe::*` (different APIs), plus replacing the 0o600 permission gate with a Windows ACL (different model entirely). That's ~150–250 lines of new code touching auth-critical paths. Doing it as a follow-up keeps this PR small and reviewable.
  2. No-regret design: the `#[cfg(unix)]` gates are cheap to remove later. `ServerConfig.admin_socket` and the `--admin-socket` flag stay defined on every platform; whoever lands the named-pipe backend gates back the other way (or generalizes the path type) without touching the user-facing CLI shape.

Verified locally

  • `cargo build` on macOS aarch64 (host)
  • `cargo check --target x86_64-pc-windows-gnu` (cross-check; no warnings)
  • `cargo clippy --all -- -D warnings`
  • `cargo test --all` — 150 tests, 0 failures (same count as master).

Version 0.10.1 → 0.11.0 (minor — re-introduces a previously-broken target as a supported one).

Made with Cursor

guyte149 and others added 2 commits May 6, 2026 10:31
The library failed to compile on `x86_64-pc-windows-msvc` because
`src/server/admin.rs` and `src/ctl/mod.rs` use `tokio::net::UnixListener`,
`UnixStream`, and POSIX `Permissions::set_mode(0o600)` unconditionally.
None of these have direct Windows equivalents — Windows has named
pipes (different API surface) and ACLs (different model).

Rather than block tunnel users on a full named-pipe backend, this
PR `#[cfg(unix)]`-gates the admin surface so the rest of rusnel —
forward/reverse TCP+UDP, SOCKS5, TLS, embedded credentials,
auto-reconnect — compiles and runs on Windows. The admin API +
`rusnel ctl` can be added back later without breaking any flags.

### Library

- `src/lib.rs`: gate `pub mod ctl;` behind `cfg(unix)`.
- `src/server/mod.rs`: gate `pub mod admin;`, the `admin_handle`
  setup, the spawn helper, the shutdown cleanup, and the `PathBuf`
  import behind `cfg(unix)`. `ServerConfig.admin_socket` stays
  declared on every platform so the public API doesn't fork.

### Binary

- `Mode::Ctl` and `CtlAction` are `cfg(unix)`. `rusnel --help` on
  Windows shows the platform-correct command list (no `ctl`
  subcommand).
- `--admin-socket` / `--no-admin-socket` flags are still parsed on
  Windows so any cross-platform automation that passes them keeps
  working. If `--admin-socket <PATH>` is set on Windows, rusnel
  prints a one-line warning to stderr and ignores it.

### Tests + CI

- `tests/admin.rs` is `#![cfg(unix)]`-gated. Other integration
  tests already pass `admin_socket: None` and need no change.
- New `windows-latest` job in `ci.yml` runs `cargo build --all` plus
  `cargo test --lib --bins` on every PR — so future regressions are
  caught at PR time, not at release time.
- `x86_64-pc-windows-msvc` is back in `release.yml`'s prebuilt
  binary matrix.

### Verified locally

- `cargo build` on macOS aarch64 (host)
- `cargo check --target x86_64-pc-windows-gnu` (cross)
- `cargo clippy --all -- -D warnings`
- `cargo test --all` — 150 tests, 0 failures (same count as master).

Version 0.10.1 -> 0.11.0 (minor — re-introduces a previously-broken
target as a supported one).

Co-authored-by: Cursor <cursoragent@cursor.com>
Add `.cargo/config.toml` setting `-C target-feature=+crt-static` for
`cfg(target_env = "msvc")`. Without this the released `.exe`
depends on `vcruntime140.dll` and friends from the Visual C++
Redistributable, which is not present on a stock Windows install —
users hit a "missing DLL" popup the first time they run rusnel.

With static CRT linkage the binary is genuinely standalone and
matches the single-static-binary promise we make for Linux and
macOS. Cost: ~2 MB of extra binary size.

Scoped to `target_env = "msvc"` so MSYS2 / GNU Windows targets
(`*-windows-gnu`) and every non-Windows target are unaffected.
Verified locally: macOS host build and `cargo check --target
x86_64-pc-windows-gnu` are both no-op (rustflags don't apply).

Co-authored-by: Cursor <cursoragent@cursor.com>
@guyte149
guyte149 merged commit de119d5 into master May 6, 2026
2 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