Add VPN protocols - #2
Open
Titlehhhh wants to merge 4 commits into
Open
Conversation
Implements two VPN-style proxy protocols on the existing ConnectAsync(...) -> Stream model, plus supporting infrastructure. VLESS (security=none/tls): - VlessOptions + VlessShareLink single-pass span vless:// parser - VlessHelper zero-alloc request builder; VlessClient (none + TLS) - UuidCodec: big-endian RFC 4122 encoding (avoids the Guid.ToByteArray mixed-endian trap) Trojan (TLS-mandatory): - Sha224 primitive (absent from the BCL): scalar + guarded Vector128 message-schedule path, NIST-verified with a scalar-vs-vector sweep - TrojanOptions/parser, TrojanHelper, TrojanClient - ProxyAddress: shared address writer (atyp codes passed by protocol) Hardening (from subagent review): - reject unknown vless security= (no silent plaintext downgrade) - bracket IPv6 proxy hosts in ProxyClient - clear credential/password buffers before ArrayPool return - wrap a truncated VLESS response as ProxyProtocolException 107 unit tests; multi-target net8.0/net9.0/net10.0; benchmarks included. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Implements the full VMessAEAD client on the existing ConnectAsync(...) -> Stream model, alongside VLESS and Trojan. Crypto primitives: - VmessKdf: the nested/recursive HMAC-SHA256 KDF (an HMAC whose hash function is another HMAC — not expressible with HMACSHA256) - VmessCmdKey, VmessAuthId (CRC32-IEEE + AES-128-ECB), Crc32, Fnv1a32, VmessBodyKeys (ChaCha20 MD5 key expansion, response key/IV) Request path: - VmessRequest: command section (port before address, atyp 01/02/03, FNV-1a-32 checksum) + AEAD envelope authid(16) | encLen(18) | connNonce(8) | encHeader(L+16) - All randomness/time injectable via VmessRequestMaterial so the wire bytes are pinned byte-exactly in tests Body path: - VmessStream: chunked AEAD stream, per-chunk nonce (uint16 BE counter | bodyIV[2..12]), independent read/write counters, AES-128-GCM and ChaCha20-Poly1305 (gated on IsSupported) - Clean EOF is ONLY the authenticated empty chunk; truncation and tag failure are hard errors, never EOF - VmessResponse + VmessResponseStream: the response header is read LAZILY on first read. Reading it eagerly in ConnectAsync deadlocks every client-speaks-first protocol (HTTP, TLS, Minecraft), because v2ray/Xray only flush it after the target replies. Config/client: - VmessOptions, VmessShareLink (base64 JSON, URL-safe + unpadded), VmessClient, vmess scheme in the factory - alterId != 0 rejected: legacy MD5 auth is not implemented - Request option byte is 0x01 (ChunkStream only), never 0x1D — the stream implements baseline framing, so announcing M/P/A would make the server mask chunk lengths and desync Ground truth for every vector comes from an independent Python reference that first reproduces the previously committed KDF vectors. 334 tests; multi-target net8.0/net9.0/net10.0; benchmarks included. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Internal/ had grown to 18 files mixing protocol-agnostic crypto
primitives, shared utilities and per-protocol helpers.
- Internal/Crypto/: Crc32, Fnv1a32, Sha224, UuidCodec
- Internal/Vmess/: VmessAuthId, VmessBodyKeys, VmessCmdKey, VmessKdf,
VmessRequest, VmessResponse, VmessResponseStream,
VmessStream
- Internal/ root keeps the six shared/single-helper files
(ProxyAddress, HttpHelper, HttpResponseParser, SocksHelper,
VlessHelper, TrojanHelper) — no folder-per-single-file.
Pure file moves: all 12 are git renames with byte-identical content and
every file still declares the flat `namespace QuickProxyNet;`. That flat
namespace is load-bearing — it is what lets files be reorganised without
touching the public API or forcing `using` churn on consumers — so
.editorconfig now records the decision explicitly
(dotnet_style_namespace_match_folder = false) instead of leaving the
IDE0130 guidance to be "fixed" by a later renaming that would break the
API.
No behaviour change: 334/334 tests, clean Release build on
net8.0/net9.0/net10.0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.