Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4d6168a
Move to .NET 10 and refresh NuGet packages
psnwd Oct 10, 2026
d047569
Fix share-link and ShareMode bugs; add round-trip tests
psnwd Oct 10, 2026
5fa20b2
Update CI workflows
psnwd Oct 10, 2026
d02afba
Add modernization plan docs and CLAUDE.md
psnwd Oct 10, 2026
633474b
v2ray-sn: build with go.mod versions, drop go get -u
psnwd Oct 10, 2026
7c0b973
CI: publish tail of build.ps1 output as an error annotation
psnwd Oct 10, 2026
7eaff0e
P4: update aiodns module, document bundled binaries, fail on GeoIP error
psnwd Oct 10, 2026
c67034d
Bump HMBSbige.SingleInstance to 7.0.0
psnwd Oct 10, 2026
c3f72b8
CI: catch terminating errors from build.ps1 and report them as annota…
psnwd Oct 10, 2026
4668488
CI: capture all streams of build.ps1 into an absolute log path
psnwd Oct 10, 2026
81ba855
CI: build v2ray-sn with Go 1.18
psnwd Oct 10, 2026
2e945ec
v2ray-sn: pin Dreamacro/clash to v1.11.0
psnwd Oct 10, 2026
5d3efdd
TASK: record green CI and remaining items
psnwd Oct 10, 2026
27d77e0
Add WebMode: Windows system proxy mode
psnwd Oct 10, 2026
b64e873
WebMode: restore the system proxy after a crash
psnwd Oct 10, 2026
c2b704f
Replace WebRequest with HttpClient
psnwd Oct 10, 2026
dfbddeb
Safer update path: rollback, asset match, hash handling
psnwd Oct 10, 2026
b8e81a2
Add controller tests: Guard, WebController, V2ray config
psnwd Oct 10, 2026
dcc66a2
Guard: fail fast when the child exits without a start keyword
psnwd Oct 10, 2026
08a8a70
Document and partially recover tun2socks.bin from its binary
psnwd Oct 10, 2026
6248152
aiodns: answer SERVFAIL on upstream failure, add response cache
psnwd Oct 11, 2026
f385c43
Rebuild tun2socks from recovered source, wire into build
psnwd Oct 11, 2026
07b479a
Vendor pcap2socks source, build from source
psnwd Oct 11, 2026
f856824
Netch: TUN IPv6, tun2socks counters, startup and route timing, netsh …
psnwd Oct 11, 2026
a496e8b
Build, CI, docs: perf harness, task list, README
psnwd Oct 11, 2026
b9c0dec
STUN: default to stun.nextcloud.com, refresh server list
psnwd Oct 11, 2026
e388f9d
Add sample mode: Global Bypass Apps
psnwd Oct 11, 2026
e39027d
STUN list: keep only servers that support NAT behavior tests (OTHER-A…
psnwd Oct 11, 2026
5f5219e
STUN: drop nextcloud (OTHER-ADDRESS on same IP, unsupported), default…
psnwd Oct 11, 2026
20d22f7
tun2socks: reject IPv6 connections when the server has no IPv6 path
psnwd Oct 11, 2026
4ad6837
Docs: perf results, task list, bench IPv4 flag
psnwd Oct 11, 2026
64af3f6
Netch: IPv6 probe, signed updates, help window, tooltips, Segoe UI font
psnwd Oct 11, 2026
5fd379d
Rebrand to Netrix: rename project, namespace and folders, new logo an…
psnwd Oct 11, 2026
ffabe88
Version 2.0.0
psnwd Oct 11, 2026
70f240f
Help window: open centered on screen
psnwd Oct 11, 2026
2d520a9
README: rewrite for Netrix
psnwd Oct 11, 2026
614baa4
README: details, tables, screenshots, Netrix logo; Help: settings.jso…
psnwd Oct 11, 2026
559a53b
Stop: route cleanup steps are independent; update check: no releases …
psnwd Oct 11, 2026
e881e29
Stop: never stay in Stopping, per-part timeout, fix Guard stop throwi…
psnwd Oct 11, 2026
f72ea60
Translate Chinese comments and messages to English; drop zh-CN issue …
psnwd Oct 11, 2026
0fba06a
Cleanup: remove RedirectorTester and Other/_Archive, add .gitattributes
psnwd Oct 11, 2026
edab871
Build output: .build\dev and .build\release (-Release switch); CI and…
psnwd Oct 11, 2026
7cae429
Add CHANGELOG; Storage README: where each bundled part comes from
psnwd Oct 11, 2026
519cccb
Update check: accept v-prefixed release tags (2.0.0 and v2.0.0)
psnwd Oct 11, 2026
bc20775
CHANGELOG: date 2.0.0
psnwd Oct 11, 2026
bc13d3e
CI: parallel test job, hashFiles caches, concurrency, least-privilege…
psnwd Oct 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added .assets/Netrix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/Netrix_BG.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/Netrix_BG_Text.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/screenshot-modes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/screenshot-skip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions .docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# ARCHITECTURE

Current state (`main` @ 9d99eb1) plus target-state notes for the modernization in [PLAN.md](PLAN.md).

## Components
```
Netrix.exe (WinForms, .NET) native / external (bin\)
├─ Forms/ UI ├─ Redirector.bin + nfapi.dll + nfdriver.sys process capture (Netfilter)
├─ Controllers/ runtime lifecycle ──► ├─ tun2socks.bin + wintun.dll TUN mode
├─ Servers/ per-protocol ├─ pcap2socks / Npcap Share mode
├─ Models/ Server, Mode, Setting ├─ aiodns.bin DNS
├─ Interops/ P/Invoke wrappers ├─ RouteHelper.bin route table
├─ Services/ Utils/ └─ xray / v2ray-sn / ss / ssr / trojan cores protocol back-ends
└─ Program.cs
```

## Runtime flow
1. `Program.Main`: single-instance guard, set cwd, append `bin\` to PATH, create dirs (`mode\Custom`, `data`, `i18n`, `logging`), load config + modes + i18n, show `MainForm`.
2. User picks Server + Mode; `MainController` starts:
1. Server's `IServerUtil.GetController()` returns an `IServerController` that starts the protocol core and exposes a local SOCKS5 (`Socks5Server`).
2. Mode controller (`IModeController`: `NFController`, `TUNController`, `PcapController`) starts with that SOCKS5 + the `Mode`.
3. `DNSController` (aiodns) starts as needed; `Guard` watches child processes.
3. Stop reverses order via `IController.StopAsync`.

## Extension points
- **Protocol**: `Servers/<Name>/` = `*Server` (model) + `*Util : IServerUtil` (URI scheme, share link, parse, check) + `*Form` + optional `*Controller : IServerController`. Polymorphic JSON via `ServerConverterWithTypeDiscriminator`.
- **Mode**: `Models/Modes/*` + `ModeConverterWithTypeDiscriminator`; behavior in matching `IModeController`.
- **Native call**: declare in `NativeMethods.txt` (CsWin32) or hand-write in `Interops/`.

## Persistence
`data\` (settings, servers, subscriptions JSON), `mode\` (mode files), `i18n\`, `logging\` (Serilog). Formats must stay backward compatible.

## Build graph
`build.ps1` runs `Other/build.ps1` (Go, MSYS2 C++, Rust builds), then `dotnet publish Netrix` (win-x64, single-file, self-contained), then `msbuild Redirector`, then `msbuild RouteHelper`, then assembles `release\` (+ `Storage\` assets, GeoIP mmdb download).

## Target-state changes
- TFM `net10.0-windows`; `Tests` same TFM (currently `net5.0`).
- CsWin32 on stable release; adjust `NativeMethods.txt` if APIs renamed.
- Keep `System.Text.Json` converters; no source-gen unless trimming is enabled (not planned).
- No structural refactor: controller/server interfaces stay as is.
- Binary provenance table (name, version, source URL, sha256) kept in `Storage/README.md`.
43 changes: 43 additions & 0 deletions .docs/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# CLAUDE.md

Netrix 2.0: Windows proxy client (WinForms, .NET 10, x64 only). Needs admin at runtime (see `Netrix/App.manifest`). GPLv3.

## Layout

- `Netrix/` — main WinForms app (`net10.0-windows`). Entry: `Program.cs`.
- `Controllers/` — runtime pieces started/stopped by `MainController` (`NFController`, `TUNController`, `PcapController`, `DNSController`, `Guard`, `UpdateChecker`). Implement `IController` / `IModeController`.
- `Servers/<Protocol>/` — one folder per protocol (Shadowsocks, ShadowsocksR, Socks5, SSH, Trojan, V2ray, VLESS, VMess, WireGuard). Each has `*Server` (model), `*Util` (`IServerUtil`: URI parse, share link, controller factory), `*Form` (edit UI), and often `*Controller`.
- `Models/Modes/` — `ProcessMode`, `TunMode`, `ShareMode`; JSON polymorphism via `JsonConverter/*TypeDiscriminator.cs`.
- `Interops/` — P/Invoke wrappers for native bins (Redirector, RouteHelper, tun2socks, aiodns). `NativeMethods.txt` feeds CsWin32.
- `Utils/`, `Services/`, `Forms/`, `Models/Settings/` — helpers, services, UI, config.
- `Redirector/` — C++ (vcxproj) Netfilter-based process redirector → `nfapi.dll`, `Redirector.bin`.
- `RouteHelper/` — C++ (vcxproj) route table helper → `RouteHelper.bin`.
- `Other/` — third-party deps built from source (aiodns, pcap2socks, v2ray-sn, wintun); each has own `build.ps1`; `Other/build.ps1` runs all.
- `Storage/` — runtime assets copied into release: `i18n/`, `mode/`, `stun.txt`, `nfdriver.sys`, `aiodns.conf`, prebuilt `tun2socks.bin`.
- `Tests/` — MSTest project (net10.0-windows): share-link and mode/setting JSON round-trips. Run `dotnet test Tests\Tests.csproj -p:Platform=x64`.

## Build

Windows only. Needs .NET 10 SDK, MSBuild + C++ toolchain (for Redirector/RouteHelper), Go etc. for `Other/`.

```powershell
.\build.ps1 # dev build into .\.build\dev (builds Other, Netrix, Redirector, RouteHelper); keeps .build\dev\data
.\build.ps1 -Release # release build into .\.build\release (what CI packages)
.\build.ps1 -PlatformToolset v145 # machine with only Visual Studio 2026 (the .vcxproj files say v143); needs msbuild on PATH, Go 1.17.1/1.18.10 via GO117/GO118, run under pwsh
.\build.ps1 -Configuration Debug # debug
dotnet build Netrix\Netrix.csproj -c Debug -p:Platform=x64 # app only
dotnet test Tests\Tests.csproj
.\clean.ps1
```

`build.ps1` skips a component if its output dir (`Netrix\bin\<cfg>`, `Redirector\bin\<cfg>`, `RouteHelper\bin\<cfg>`, `Other\release`) already exists — run `.\clean.ps1` to force rebuild. It downloads `GeoLite2-Country.mmdb` at build time. CI: `.github/workflows/build.yml` (caches keyed by `hashFiles` of each source dir; `release.yml` reuses it).

## Conventions

- `common.props` + csproj: nullable/implicit usings on, analyzers with `CodeAnalysisTreatWarningsAsErrors` and `EnforceCodeStyleInBuild` — style/analyzer warnings break the build.
- Uses `Microsoft.VisualStudio.Threading` analyzers (VSTHRD*) and Fody (`ConfigureAwait.Fody`): don't hand-write `ConfigureAwait`; async-void only for event handlers.
- Runtime layout expects `bin\` next to `Netrix.exe` (added to PATH); user data in `data\`, `mode\`, `i18n\`, `logging\`.
- Adding a protocol: new `Servers/<Name>/` with Server/Util/Form(/Controller). `ServerHelper` finds every public `IServerUtil` by reflection and the JSON converter resolves server types through it, so no registration is needed. Add a round-trip test in `Tests/ShareLinkTests.cs`.
- Translations: `Storage/i18n/` and `Netrix/Resources/zh-CN`; strings go through `i18N.Translate`.
- Dependabot PRs dominate git history; keep commits small.
- Modernization plan/status: `.docs/PLAN.md`, `.docs/TASK.md`, `.docs/QA.md`.
12 changes: 12 additions & 0 deletions .docs/PERF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Performance results

CPU = % of one core summed over Netrix, v2ray-sn during the run. Url/ping host fixed in bench.ps1 defaults.

| date | label | 1 stream Mbps | CPU% | 16 streams Mbps | CPU% | ping ms | dns ms | mem MB | 40 small req ms |
|---|---|---|---|---|---|---|---|---|---|
| 2026-10-11 12:06 | direct-baseline | 178.8 | 0 | 34.1 | 0 | 5.1 | 86 | 0 | n/a |
| 2026-10-11 12:29 | direct-with-small | 87.4 | 7 | 270.3 | 16 | 0.0 | 728 | 169 | 321 |
| 2026-10-11 17:39 | tun-current-running-build | 144 | 12 | 14.6 | 2 | 0.0 | 105 | 377 | 1667 |
| 2026-10-11 17:41 | tun-current-running-build-repeat | 148.4 | 1 | 29.3 | 2 | 0.0 | 661 | 361 | 532 |
| 2026-10-11 17:49 | old-r2 | 25.3 | 6 | 7.3 | 8 | 0.0 | 247 | 340 | 1528 |
| 2026-10-11 17:55 | old-r1 | 55 | 17 | 1.7 | 8 | 0.0 | 80 | 349 | 1564 |
39 changes: 39 additions & 0 deletions .docs/PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# PLAN — Modernize Netrix 1.x

Goal: move off EOL .NET 6, refresh deps and bundled binaries, make CI/build reliable, add real tests. No new features, no behavior change.

See [ARCHITECTURE.md](ARCHITECTURE.md), [TASK.md](TASK.md), [QA.md](QA.md), [RISKS.md](RISKS.md).

## Why
- `net6.0-windows` EOL since Nov 2024; `Tests` still on `net5.0`.
- GitHub Actions pinned to old majors (`upload-artifact@v3`, `cache@v3`, `checkout@v3`, `setup-go@v3`, `actions-rs/toolchain@v1` unmaintained).
- Pre-release package (`CsWin32 0.1.588-beta`); `Stun.Net`, `WindowsJobAPI` possibly stale.
- Bundled binaries (`tun2socks.bin`, `nfdriver.sys`, xray/v2ray, wintun) likely behind upstream.
- Tests near-empty: no safety net for refactors.

## Decisions
| Decision | Choice | Reason |
|---|---|---|
| Target framework | `net10.0-windows` (LTS). Fallback `net8.0-windows` | net8 EOL Nov 2026; SDK 10 already installed on dev box |
| Scope | x64 only, WinForms kept | Matches current product |
| Behavior | Unchanged; config/mode JSON stay compatible | Users keep `data\` and `mode\` |
| Tests first | Characterization tests before framework bump | Catch regressions |

## Phases
1. **Baseline** — build current `main` clean, record output tree, add characterization tests (share-link parse/format, mode JSON round-trip, config load). Exit: green CI on unchanged code.
2. **Framework bump** — `common.props`, `Netrix.csproj`, `Tests` to new TFM; fix analyzer/CsWin32 breaks (warnings are errors). Exit: app starts, connects in each mode.
3. **NuGet refresh** — bump one group at a time (Serilog, System.*, Fody/ConfigureAwait, CsWin32 to stable, MaxMind, TraceEvent, TaskScheduler, Stun.Net). Replace dead packages if needed. Exit: `dotnet list package --vulnerable --deprecated` clean.
4. **Native + bundled binaries** — rebuild `Redirector`/`RouteHelper` on current VS toolset; update `Other/*` (aiodns Go modules, pcap2socks, v2ray-sn, wintun) and prebuilt `Storage/` binaries; record versions + hashes. Exit: Process/TUN/Share modes pass QA.
5. **CI/CD** — bump actions, replace `actions-rs`, `upload-artifact@v4`, add `dotnet test` step, pin Go/Rust, fix cache keys. Exit: green PR build, release artifact layout identical.
6. **Cleanup + release** — remove dead code, update README/CLAUDE.md, tag RC, full QA pass.

7. **Performance and optimization** (after the release candidate) - measure first, then change one thing at a time; see the Performance section in [TASK.md](TASK.md). Goals: higher throughput and lower latency through TUN mode, faster start, smaller and lighter app. Rule: no optimization without a before/after number from the same test.

## Out of scope
New protocols, UI redesign, ARM64 (blocked on x64-only prebuilt binaries), Netrix 2.0 rewrite. WebMode and IPv6 in TUN mode were added during the update. A sing-box based core (TUN and process routing) is an open option, see TASK.md.

## Done when
All [QA.md](QA.md) release gates pass and every [TASK.md](TASK.md) item is checked.

## Status notes
- 2026-10-11: a full local build ran end to end. TUN mode was started on Windows by the owner and carries traffic after two fixes found in testing: `aiodns` panicked on a failed upstream DNS lookup (killed the process), and IPv6 bypassed the tunnel (now routed into it, setting `TUNTAP.ProxyIPv6`). Process mode, Share mode and WebMode are still untested on real traffic.
37 changes: 37 additions & 0 deletions .docs/QA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# QA

Verify no regression after each phase in [PLAN.md](PLAN.md). Windows 10 22H2 and Windows 11, x64, admin account, clean VM snapshot per run.

## Automated (CI)
- `dotnet build -c Release`: zero warnings
- `dotnet test`: green
- `dotnet list package --vulnerable --deprecated`: empty
- Release artifact layout diff vs baseline: same files in `.build\release\` and `.build\release\bin\`

## Manual matrix
| Area | Cases |
|---|---|
| Startup | Fresh extract; missing `bin\` shows error; second instance blocked; non-admin prompts UAC |
| Upgrade | Old `data\`, `mode\Custom` from previous release load unchanged |
| Protocols | Add via form, share link/clipboard, subscription: SS, SSR, VMess, VLESS, Trojan, Socks5, WireGuard, SSH |
| Share links | Export then re-import gives identical server |
| Process mode | Chosen app proxied; others direct; stop restores traffic; driver install/uninstall ok |
| TUN mode | Adapter created, routes set, DNS works; stop removes adapter/routes; no leak after crash + restart |
| Share mode | Second device via hotspot/Npcap routes through proxy |
| DNS | aiodns rule split; custom DNS setting honored |
| Tools | Delay test, STUN NAT test, bandwidth counter, GeoIP flag, update check |
| UI | i18n en + zh-CN, high-DPI 125/150/200%, log window, tray icon |
| Failure | Bad server, port in use, core crash (Guard cleans up), network drop |
| Shutdown | Exit while running leaves no stray processes, routes, firewall rules, scheduled tasks |

## Release gates
1. Manual matrix passes on Win10 + Win11.
2. No crash in 30 min soak per mode.
3. Memory flat (±10%) over soak.
4. Artifact SHA256 recorded; binaries table in `Storage/README.md` current.
5. Rollback: previous release still opens the new `data\`.

## Bug triage
- S1: data loss, traffic leak, system network left broken. Blocks release.
- S2: a mode is broken. Blocks release.
- S3: UI/cosmetic. Ship.
13 changes: 13 additions & 0 deletions .docs/RISKS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# RISKS

| Risk | Impact | Mitigation |
|---|---|---|
| CsWin32 stable renames/changes APIs vs `0.1.588-beta` | Build breaks in Interops/Utils | Bump alone in its own PR; fix callers |
| `nfdriver.sys` is a signed prebuilt; Redirector is tied to it | Process mode breaks | Do not rebuild driver; only rebuild user-mode Redirector; test with RedirectorTester |
| Netfilter / wintun / tun2socks update changes behavior | TUN/process regressions | Pin versions + hashes; QA matrix per mode |
| Warnings-as-errors with newer analyzers | Many build errors on TFM bump | Fix per rule; suppress with justification in `.editorconfig`, not blanket `NoWarn` |
| Config JSON compatibility | Users lose servers/modes | Characterization tests (P1); upgrade case in QA |
| Single-file publish differences on new runtime | Startup/extract failures | Test on clean VM; keep `IncludeNativeLibrariesForSelfExtract` |
| CI toolchain drift (Go stable, Rust nightly, MSYS2 rolling) | Flaky, irreproducible builds | Pin versions; record in TASK P5 |
| GeoIP file downloaded from third party at build | Supply-chain / build break | Pin release tag + sha256 |
| Windows-only; cannot run elsewhere | Slow feedback | Keep Windows runners; keep unit tests platform-neutral where possible |
Loading
Loading