Replace per-packet socket.send_to() with batch drain + GSO sendmsg
in forward_from_ring_to_udp. Uses quinn-udp's UdpSocketState to
leverage UDP_SEGMENT (GSO) when the kernel supports it.
Architecture:
1. Await first packet from RingStream
2. Non-blocking drain up to 8 more packets (noop_waker poll_next)
3. If all same size + GSO supported: concatenate + single sendmsg
with UDP_SEGMENT → kernel splits into N UDP datagrams
4. Otherwise: fallback to per-packet send
Feature gated behind 'udp-gso' (enabled in default features).
Falls back to per-packet send on older kernels (no GSO support).
Benchmark (localhost, no hotpath):
Before GSO: 1,066K pps
After GSO: 1,070K pps (noise — localhost has no NIC driver overhead)
GSO will have larger impact on real WAN interfaces where syscall
overhead dominates. Implementation is correct and ready for that.
All 208 peers tests pass. 6 netns tests fail (require root, unchanged).
Replace all UnsafeCell-based counters with safe alternatives:
- New ShardedCounter: per-thread TLS accumulation (thread_local crate)
with periodic publish to static AtomicU64. Zero atomic RMW on hot path.
- ACL RuleStatsTracker: remove unsafe Arc<RuleStats> raw pointer
mutation, use two ShardedCounter fields.
- ZCPacket: replace set_len on uninitialized BytesMut with
write_bytes + copy_nonoverlapping before set_len.
- StatsManager UnsafeCounter/MetricData: remove UnsafeCell and
unsafe impl Send/Sync, wrap ShardedCounter. last_updated uses
AtomicU64 epoch millis.
- Throughput: replace UnsafeCell with AtomicU64.
- secure_datagram: fix grace-window test timestamp.
Replace std::time::Instant with quanta::Instant on per-packet, per-RPC,
and per-session paths. TSC-based, ~5ns vs ~25ns per now() call.
Reuses the existing `extern crate self as hotpath` alias so
`use hotpath::instant::Instant;` resolves to the same quanta type with
or without the hotpath feature. Leaves tokio::time::Instant and
smoltcp::time::Instant untouched.
* refactor(web): use generated proto network types
* fix(core): preserve dumped config flags
* test(web): cover config flag save paths
* fix(ci): use system protoc before frontend codegen
* fix(ci): serialize frontend-lib builds
Remove quinn-plaintext to fix connection errors caused
by different hash values across platforms.
On x64, maintain compatibility with quinn-plaintext.
Use pbjson to support string deserialization for enum fields
This allows TOML configs like:
chainType = "Inbound"
instead of:
chainType = 1
- Maintain backward compatibility with integer values
- Default serialization format is now string
1. Overview
This PR adds data plane APIs to easytier-ffi:
TCP Outbound:
- data_plane_tcp_connect
- data_plane_tcp_read
- data_plane_tcp_write
- data_plane_tcp_close
TCP Listener:
- data_plane_tcp_bind
- data_plane_tcp_accept
- data_plane_tcp_listener_close
UDP:
- data_plane_udp_bind
- data_plane_udp_send_to
- data_plane_udp_recv_from
- data_plane_udp_close
2. Key Changes
The main changes are focused on:
- easytier-contrib/easytier-ffi/src/lib.rs: Added FFI interfaces;
made ERROR_MSG thread-safe.
- easytier/src/gateway/socks5.rs: Bridges the data plane to the
existing Socks5 server logic.
- Added EasyTierUdpSocket, mainly wrapping ref-counting and
critical object (e.g., Socks5EntrySet) hold & drop logic,
and exposing common fields (e.g., local_addr).
- Extended Socks5Server functionality to expose TCP and UDP
socket creation interfaces for FFI calls.
- Other files: Mostly pass-through logic.
- Added a relatively large Go usage example.
- extend web controller bindings to cover full RPC service set
- update rpc_service API wiring and session/controller integration
- generate trait-level json_call_method in rpc codegen
- route restful proxy-rpc requests via scoped typed clients
- add json-call regression tests and required Sync bound fixes~
* feat: separate faketcp into a feature
* fix: no need to initialize out_len
* feat: separate zstd into a feature
* clippy: remove unnecessary cast, because for unix size_t always equals usize
* use quinn-plaintext
* remove server_cert in QUICTunnelListener
* remove some customized transport config
* leave max_concurrent_bidi_streams as default
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- drop low-priority columns when tables exceed terminal width
- truncate optional columns to fit remaining width
- add --no-trunc flag to disable truncation
- compute column widths using unicode display width
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Use noise protocol on handshake. Check peer's public key if needed. Also support rekey and replay attack prevention.
E2EE and temporary password will be implemented based on this.