Files
Easytier/easytier-contrib/easytier-ffi/examples/go
w568w e0745f4bab feat: Add data plane support to FFI (#2287)
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.
2026-06-04 17:17:41 +08:00
..

1. Go FFI Demo

This demo wraps EasyTier FFI data-plane TCP as Go net.Conn and net.Listener. It can connect to an SSH server through EasyTier and read its banner, or accept a TCP connection from another EasyTier peer and run a small ping/pong exchange.

1.1. Build the FFI library

Run from the repository root:

cargo build -p easytier-ffi --features ffi-dataplane

The demo loads the debug library by default:

target/debug/libeasytier_ffi.so

To use another library path, export EASYTIER_FFI_LIB=/path/to/libeasytier_ffi.so.

1.2. Configure the EasyTier config

EASYTIER_FFI_CONFIG is a string of the EasyTier config in TOML format which is passed to the FFI library. For example:

export EASYTIER_FFI_CONFIG='instance_name = "default"
ipv4 = "10.0.0.1"
peers = ["tcp://123.123.123.123:11010"]

[network_identity]
network_name = "testnet"
network_secret = "mysecret"

[flags]
no_tun = true # disable tun device to avoid permission issues.
'

You should configure with your own real values.

Set the local instance name and a SSH server target to connect through EasyTier:

export EASYTIER_FFI_INSTANCE=default
export EASYTIER_FFI_TARGET=10.0.0.2:22

To run the TCP listen integration test in the same go test process as the SSH test, use a separate instance name and config:

export EASYTIER_FFI_LISTEN_CONFIG='instance_name = "listener"
ipv4 = "10.0.0.3"
peers = ["tcp://123.123.123.123:11010"]

[network_identity]
network_name = "testnet"
network_secret = "mysecret"

[flags]
no_tun = true
'
export EASYTIER_FFI_LISTEN_INSTANCE=listener
export EASYTIER_FFI_LISTEN_PORT=12345

1.3. Run the demo

goffi is built without cgo on Linux, so run the test with CGO_ENABLED=0:

cd easytier-contrib/easytier-ffi/examples/go
CGO_ENABLED=0 go test -v ./...

Expected output includes an SSH banner similar to:

attempt 1: got banner "SSH-2.0-..."
PASS

For TestTCPListenIntegration, connect from another EasyTier peer to the local EasyTier IPv4 address and EASYTIER_FFI_LISTEN_PORT, send ping, and expect pong in response.