mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-10-16 01:26:14 -08:00
0da58e68df70b68b1c71b97f9b8755c8b84f57f0
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
32dc7f1f40 |
feat: add shared virtual nic (#2352)
* Add shared virtual NIC core with per-member routing Share a named TUN across instances while keeping unnamed devices dedicated. Track member addresses, routes, and MTU, and reject overlapping destinations except the common Magic DNS host route. Dispatch packets between the physical TUN and member tunnels. Keep IPv4 and ordinary IPv6 source translation for mobile wrong-source traffic. Update platform configuration and runtime host integration, with unit and network namespace coverage for routing and lifecycle. Use smoltcp for packet parsing and checksum updates. Keep core CI matrix jobs independent. Reserve native inbound flows before source translations allocate their wire tuples. Keep active reservations under table pressure and leave forwarded subnet traffic outside the local flow table. Complete interface claim updates on the shared runtime and retain member registrations until the transaction commits. Keep address, route, and MTU cleanup ordered after cancelled callers, including device initialization. Project mobile VPN addresses, routes, and DNS from admitted native members. Prefer unchanged attached claims and report conflicting members individually. Apply each member's complete initial claims before opening the shared fd, so conflicts leave healthy members usable. Cover inbound IPv4/IPv6 collisions, cancellation during native changes and dispatcher acknowledgments, admission priority, and atomic mobile claim rejection with regression tests. Use scoped TestNetwork fixtures for shared TUN bridge setup and cleanup. Resolve public IPv6 namespace aliases through the lab's actual names so the new tests remain isolated under parallel upstream test runs. * Configure one mobile VPN from running TUN instances Use admitted native members to configure VpnService and attach its single fd to the core shared TUN. Wait for attachment completion and record the actual attached members before refreshing VPN state. Report rejected members in the GUI and preserve the VPN for unchanged healthy members. Reconcile ordinary configuration notifications without invalidating an arbitrary member. Invalidate attachments on instance lifecycle changes, including restarts that reuse an instance ID. Forward public IPv6 changes alongside proxy route changes to refresh the platform VPN configuration. Exclude confirmed IPv4-less members from readiness gating while retaining retries for unavailable status and pending addresses. Quick Settings stops all running TUN members and restores that group on the next start, skipping removed configurations and no_tun networks. Keep the FFI set_tun_fd call scoped to one instance and report attachment errors. Cover mobile configuration, member rejection and replacement, attachment completion, collection notifications, IPv4-less members, and tile stop/start restoration in GUI regression tests. Validate with 36 mobile VPN tests, vue-tsc --noEmit, Android GUI cargo check, workspace clippy, and shared TUN network namespace tests. * fix(tun): preserve shared NIC ownership and failure invariants Keep mobile address and route claims in dispatcher tables without applying desktop interface configuration to synthetic TUN names. Limit the Magic DNS overlap exemption to route claims and remove the shared route retry that bypassed claim accounting after invalidation. Invalidate and stop dispatchers on failed mobile TUN replacement or I/O. Bound TUN writes so stalled devices release pending source updates and member cleanup instead of retaining an unusable shared dispatcher. Treat missing Darwin and Windows addresses and routes as successful deletions while preserving permission and other configuration errors. Add regressions for claim conflicts, mobile configuration, failed TUN replacement, stalled writes, and platform deletion error handling. * fix(tun): forward single-member shared NIC traffic unchanged Deliver TUN packets directly to the sole attached member without destination matching or creating source translations. Keep native flow reservations so a later member cannot collide with existing connections, and continue applying mappings created before other members leave. Reuse flow preparation with the original source address. Preserve the desktop subnet forwarding bypass, including when the flow table is full. IPv4 fragments and IPv6 extension headers remain unchanged on flows that need no translation. Cover unknown sources and destinations, first and later IP fragments, native flows established before another member joins, and retained translations after returning to one member. Document the forwarding behavior and retain rejection coverage for multiple attached members. * fix(tun): preserve wildcard UDP replies on shared member ports Mark flow reservations created by incoming traffic separately from outgoing mappings. When a wildcard UDP socket replies with another member's source address, reuse the incoming reservation after source correction and preserve its service port and inbound destination. Keep exact outgoing mappings and outgoing flow collision handling ahead of this rule. Incoming UDP sessions take priority when packet tuples cannot distinguish a reply from a new client using identical endpoints. Cover IPv4 and IPv6 replies, checksum updates, repeated inbound traffic, existing outgoing mappings, TCP collisions, and single-to-shared member transitions with regression tests. * test(tun): wait for IPv6 activation in mobile configuration test Assert that the configured IPv6 address is registered before forwarding starts, then wait up to five seconds for the kernel to make it usable. Netlink acknowledges address creation before asynchronous IPv6 activation completes, so an immediate bind can fail under CI parallelism. Disable automatic link-local address generation in the test namespace to keep startup IPv6 control traffic out of member-routing assertions. Validation: the original test failed 40 of 320 runs at 32-way parallelism. The updated test passed all 320 runs; workspace fmt and clippy also pass. |
||
|
|
83baead059 |
fix(runtime): restore per-instance native thread configuration (#2658)
Restore per-instance Tokio executors for standard native instances, honoring multi_thread and multi_thread_count with a two-worker minimum in multi-thread mode. Preserve external execution for compact hosts. Run construction, lifecycle operations, FFI data-plane tasks, and hot-reloaded port forwards on the selected instance executor. Keep shutdown cleanup running when its caller is cancelled, and release owned executors without blocking their workers on runtime teardown. Add runtime ownership, cancellation, cross-runtime connectivity, and hot-reload regression coverage, and document the execution model. Validation: all 45 PR checks passed, including linting, integration tests, and cross-platform builds. |
||
|
|
d375d7e455 |
feat(mini): add compact native EasyTier client (#2479)
Add a native EasyTier proof-of-concept binary with TCP and UDP transports, TUN, UDP hole punching, AES-GCM, and a read-only RPC portal. Introduce a release-derived mini profile and musl linker policy so x86_64, big-endian MIPS, and little-endian MIPS stay below the strict 5,000,000-byte target without UPX. |
||
|
|
7fb42c3b73 |
perf(data-plane): restore native throughput after host portability (#2452)
* perf(core): make data-plane idle check constant time Avoid scanning every DashMap shard for each peer packet when no data-plane flows are active. Publish the flow count before insertion and release it after removal so an Acquire load is a safe O(1) idle signal. Reject count overflow and underflow instead of silently saturating. * test(perf): add repeatable two-node netns benchmark Create isolated underlay namespaces, pin both EasyTier cores and iperf3 endpoints, and measure a single TCP flow in both directions over either UDP or TCP peer transport. Keep every iperf3 JSON result and emit directional medians while cleaning up processes and namespaces on every exit path. * perf(tcp): preserve native owned stream halves Let each VirtualTcpSocket adapter consume itself into independent read and write halves. Portable adapters retain the generic shared split as a default. Use lock-free Tokio owned halves for native TCP and Unix streams so tunnel I/O no longer takes the generic split mutex on every poll. Cover full-duplex traffic and write-half shutdown. * perf(packet): preserve ownership across the Host seam Introduce an opaque, move-only HostPacket that retains core packet storage while exposing only the raw IP payload. Clear private headers before handing storage back to a native TUN adapter. Use an ownership-preserving bounded channel for native ingress and egress. Keep explicit copy adapters for Vec and WASI boundaries, and verify allocation identity, backpressure, shutdown, and end-to-end delivery. * perf(udp): preserve packet ownership through sessions Carry EasyTier tunnel packets through UDP session queues as owned values. Reuse the existing tunnel header for session framing instead of copying payloads into a second packet and rebuilding them on receive. Keep completion delivery for the public datagram socket API while removing the unused completion channel from streaming tunnel sends. Avoid the unconditional receive-side clone before QUIC routing is known. * perf(peer): publish packet filters as immutable snapshots Replace per-packet async and synchronous registry locks with ArcSwap snapshots. Permanent filters now need no activity checks, while managed registrations retain explicit acquire/release visibility. Closing a managed registration marks it inactive before atomically removing it. Existing snapshots keep in-flight filters alive, and registration mutations prune inactive entries while preserving newest-first order. * perf(instance): give native hosts direct packet egress Let the core create one bounded HostPacket channel and transfer its receiver directly to a PacketEgressHost during startup. Native TUN runtimes now consume that receiver without the intermediate PacketSink channel and forwarding task. Keep PacketSinkEgress as the compatibility adapter for callback and test hosts, and make receiver installation one-shot across desktop, mobile, and disabled runtimes. * perf(crypto): restore accelerated native AEAD backends Move Ring and OpenSSL implementations behind the core Encryptor seam. Portable builds continue selecting only supported backends. Restore historical precedence: OpenSSL, Ring, then RustCrypto. Keep backend availability consistent across secure transports and cover fixed-nonce wire compatibility between implementations. * perf(udp): receive native datagrams into owned buffers Extend the portable UDP socket seam with an owned-datagram receive path. Keep a compatible default for portable hosts. Native Unix sockets write recvmsg output directly into the final BytesMut allocation. This removes the per-packet stack-to-heap copy introduced by the portable socket boundary without exposing native socket resources to core. * perf(data-plane): remove portable hot-path overhead Restore native throughput lost while generalizing the host and UDP session layers. Read packet policy once per send, update traffic counters through registry guards, and preserve packet ownership while UDP dispatch borrows stable session state. Move UDP shutdown monitoring into a control task so forwarding avoids a select future per packet. Bound native datagram storage to 8 KiB, reject oversized sends, and drop truncated Unix receives. Keep accelerated AEAD selection warning-free when portable crypto features are also built. Cover session bounds, truncation, and idle shutdown with regression tests. * fix(udp): preserve portable datagram receive semantics Keep the public portable receive capacity at the theoretical UDP maximum instead of silently shrinking it to the native fast-path limit. Apply the 8 KiB session boundary after a complete portable receive, so Windows cannot turn an oversized datagram into a fatal listener error and other adapters cannot dispatch a truncated prefix. Cover dropping an oversized packet while the same portable socket continues to deliver the following valid datagram. * fix(ci): align feature gating with backend selection Compile the Ring implementation in production only when OpenSSL is not selected, while retaining it for cross-backend unit tests. Remove stale test imports and assert UDP dispatch results so the strict workspace Clippy job passes without suppressing diagnostics. |
||
|
|
021f523431 |
refactor(core): separate portable core from native runtime (#2451)
Create easytier-core as the portable owner of configuration, connectivity, tunnels, peer and routing state, gateways, management, the data plane, and instance lifecycle. Keep operating-system integration, native protocol engines, process startup, and presentation in easytier behind explicit Host capability adapters. Create easytier-proto to own schemas, generated RPC types, descriptors, and feature-scoped protocol slices. Remove runtime protobuf reflection from core while preserving unknown route-peer fields across forwarding. Normalize instance construction through CoreInstance, CoreHostAdapters, CoreProcessRuntime, and InstanceManager. Make the runtime config store the only authoritative mutable configuration after startup. Move the portable TCP/UDP data plane into core and extract a generic OperationBroker for completion, cancellation, disposal, and capacity accounting. Expose the session-based FFI v2 completion API and keep the WASI guest ABI, wire schemas, and adapters with core. Migrate CLI, GUI, web, FFI, Android JNI, OHOS, uptime, and mobile consumers to the shared manager and core state. Add explicit user/web config ownership and revision-aware web reconciliation. Preserve configuration, wire, and management behavior while fixing regressions discovered by the full platform and integration matrix: - inherit advertised relay capabilities in foreign networks; - refresh OSPF peer state immediately after runtime config changes; - restore CLI GlobalCtx event output without forcing GUI logging; - retain legacy encryption names and standalone RPC tunnel metadata; - restore ICMP host composition and fragmented UDP handling; - use portable 64-bit atomics on 32-bit MIPS targets; and - retain discarded operations until late cancellation completes. Validate the refactor across 45 GitHub checks, including Linux, macOS, Windows, FreeBSD, web, GUI, Android, OHOS, feature profiles, and three-node and subnet-proxy integration tests. BREAKING CHANGE: internal Rust module paths are not preserved. Legacy native data-plane APIs are replaced by the session-based FFI v2 API. The dedicated Android data-plane wrapper is removed. |