TCP tunnel uses FramedWriter (not RingSink), but start_send is still
sync (writes to BufList in memory). poll_flush does actual TCP write
syscall — noop_waker returns Ok for Pending (data stays in BufList,
flushed on next send when BufList >= 64).
Add TCP benchmark support via HOTPATH_TUNNEL=tcp. Note: TCP/UDP
convergence requires netns in bench environment (connector multi-bind
address behavior doesn't work for localhost without namespaces).
All 210 peers tests pass. Ring tunnel benchmark: 234K -> 508K pps (+117%).
UDP tunnel uses RingSink internally (same as ring tunnel). Extend
direct mode to include UDP. Fix poll_flush Pending to return Ok.
Add UDP benchmark support via HOTPATH_TUNNEL=udp env variable.
All 208 peers tests pass. Netns tests unchanged (require root).
FuturesUnordered-based pipeline to overlap encrypt with mpsc_send.
Tested depths 1/4/8/16: max +1.6% at depth=4, within noise. Pipeline
has limited value because try_send fast path eliminates await gaps
that would allow overlap. Default remains depth=1 (serial).
Add #[global_allocator] behind feature flags so the bench can test
different allocators. Previously the example used glibc malloc by
default (easytier-core.rs sets jemalloc/mimalloc only for the bin
target, not examples).
Benchmark (4 threads, 1400B, 15s, clone mode):
glibc: 246K pps, 3.13us/pkt
jemalloc: 246K pps, 3.21us/pkt
mimalloc: 242K pps, 3.25us/pkt
All within noise. Single-threaded clone has low malloc contention;
~1500B small allocs are served efficiently by all tcaches.