Add the shared NIC dispatcher that owns the underlying VirtualNic tunnel.
Connect member ring tunnels through a private member table.
Track reverse flow ownership from packets written by a member.
Replies read from the shared device go back to the same member.
Packets without an owner fall back to any active member.
Mark the shared NIC invalid when the underlying tunnel closes or fails.
Notify members so their NicCtx can rebuild.
Use create_ring_tunnel_pair for member-level shared NIC tunnels.
That replaces the custom packet stream and sink implementation.
Keep one side of each ring tunnel in SharedVirtualNic's member map.
Later dispatcher code can connect those endpoints to the shared device.
Add a shared NicCtx constructor that obtains a SharedVirtualNicMember from the registry and wraps it in NicBackend::Shared.
Keep NicCtx::new on the dedicated backend path so existing runtime behavior does not change before the shared tunnel implementation is ready.
Replace NicCtx's direct VirtualNic field with NicBackend while keeping the constructor on the dedicated backend path.
Move existing device creation, ifcfg lookup, IP assignment, and public IPv6 updater calls through backend helpers so shared mode can be wired in a later commit without changing the dedicated flow.
Introduce SharedVirtualNicMember as the per-instance handle for a shared virtual NIC and add a registry helper to create members.
Add NicBackend so NicCtx can later choose between dedicated VirtualNic and shared member-backed tunnel creation without changing the existing dedicated path.
Add a small registry keyed by dev_name so shared-mode setup can reuse one SharedVirtualNic per device name.
Track invalid shared NICs through a shared flag and replace them on the next get_or_create call.
Move TUN-specific configuration into VirtualNicConfig so VirtualNic and SharedVirtualNic no longer depend on ArcGlobalCtx.
Keep global context side effects in NicCtx, including the Windows generated device-name writeback.
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.
Adds a Linux-only socket_mark u32 config flag (CLI: --socket-mark, env:
ET_SOCKET_MARK, TOML/proto: flags.socket_mark, 0 = disabled) that is
applied as SO_MARK to every outbound underlay socket EasyTier creates:
TCP, UDP, QUIC, WebSocket, WireGuard connectors and listeners, plus the
FakeTCP decoy socket. Lets the host policy-route or filter EasyTier
underlay traffic with 'ip rule fwmark ...' or iptables -m mark.
Plumbing mirrors the existing bind_device pattern:
- FlagsInConfig.socket_mark (proto) + default 0 in gen_default_flags
- bind() builder gets a socket_mark arg; setup_socket2_ext calls
apply_socket_mark which is a no-op for mark=0 and on non-Linux
- TunnelConnector trait gets set_socket_mark(u32) default-no-op method
- IP-based connectors override; create_listener_by_url and the connector
factory pass mark from global_ctx flags
- QUIC threads mark through QuicEndpointManager::{server,connect}
- WebSocket/FakeTCP/TCP default-bind bypass paths apply mark via
socket2::SockRef::from(&tokio_socket)
- ForeignNetworkEntry propagates parent socket_mark into its derived ctx
Includes a Linux smoke test plus a CAP_NET_ADMIN-gated test that does a
getsockopt(SO_MARK) round-trip to confirm the kernel applied the value.
SO_MARK requires CAP_NET_ADMIN; ignored silently on non-Linux. FakeTCP's
TUN-written segments are not covered (kernel doesn't tag raw TUN
writes); operators relying on fwmark for FakeTCP must apply an iptables
rule on the FakeTCP TUN device separately.
Co-authored-by: Claude <noreply@anthropic.com>
This may helps games to find rooms in virtual network.
- add opt-in Windows UDP broadcast relay config flag and CLI/env plumbing
- capture local UDP broadcasts with Windows raw sockets, normalize packets, and inject them via PeerManager
* feat: support allocating public IPv6 addresses from a provider
Add a provider/leaser architecture for public IPv6 address allocation
between nodes in the same network:
- A node with `--ipv6-public-addr-provider` advertises a delegable
public IPv6 prefix (auto-detected from kernel routes or manually
configured via `--ipv6-public-addr-prefix`).
- Other nodes with `--ipv6-public-addr-auto` request a /128 lease from
the selected provider via a new RPC service (PublicIpv6AddrRpc).
- Leases have a 30s TTL, renewed every 10s by the client routine.
- The provider allocates addresses deterministically from its prefix
using instance-UUID-based hashing to prefer stable assignments.
- Routes to peer leases are installed on the TUN device, and each
client's own /128 is assigned as its IPv6 address.
Also includes netlink IPv6 route table inspection, integration tests,
and event-driven route/address reconciliation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Normalize composite tunnel display values before rendering peer and
debug output so IPv6 tunnel types no longer append `6` to the port.
- Preserve prefixes like `txt-` while converting tunnel schemes to
their IPv6 form.
- Recover malformed values such as `txt-tcp://...:110106` into
`txt-tcp6://...:11010`.
- Reuse the normalized remote address display in CLI debug output.
- add lazy_p2p so nodes only start background P2P for peers that actually have recent business traffic
- add need_p2p so specific peers can still request eager background P2P even when other nodes enable lazy mode
- cover the new behavior with focused connector/peer-manager tests plus three-node integration tests that verify relay-to-direct route transition
- add credential manager and RPC/CLI for generate/list/revoke
- support credential-based Noise authentication and revocation handling
- propagate trusted credential metadata through OSPF route sync
- classify direct peers by auth level in session maintenance
- normalize sender credential flag for legacy non-secure compatibility
- add unit/integration tests for credential join, relay and revocation
PeerCenterRpc was only registered in the per-instance peer-to-peer RPC
manager (domain = network_name), but not in the management API server
(domain = ""). The CLI connects to the management API with an empty
domain, causing "Invalid service name: PeerCenterRpc" errors.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Magic DNS updates are full snapshots, so appending routes keeps old IPs and returns duplicate A records. Replace each client's previous routes on update and add a regression test to ensure hostname resolution keeps only the latest IP.
* 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
Also rename stale interfaces from previous runs before creating new ones.
Works around rust-tun reusing existing tun0 instead of configured name.
Tested on FreeBSD 14.1
support faketcp to avoid tcp-over-tcp problem.
linux/macos/windows are supported.
better to be used in internet env, the maximum
performance is majorly limited by windivert/raw socket.