Files
KKRainbow d55e63b88e perf(wasi): optimize data plane and extend host ABI to v3 (#2455)
Overhaul the WASI guest data plane for throughput and add the host
capabilities it relies on. The externally driven Tokio runtime now
runs its timer pre-turn only when a tracked deadline has expired,
and all WASI-reachable timers (STUN, port mapping, WebClient, UDP
flow cleanup) go through the portable time facade so conditional
timer driving cannot starve them.

Data plane:

- Move read/write deadlines onto TCP and UDP resources with one ABI
  setter per direction, reuse a single expiration timer per
  resource, and drop timeout arguments from the four hot data-plane
  submissions (ABI v3). Checked absolute instants treat
  unrepresentable finite timeouts as unbounded instead of panicking.
- Batch host traffic: vectored TCP frame writes combine queued
  slices into one host operation, and reads request a bounded 64
  KiB while retaining excess bytes in the stream buffer.
- Complete TCP writes inside the guest with cancellation-safe
  writes, reporting the completed prefix before honoring
  cancellation or timeout so hosts never replay bytes.
- Repoll smoltcp egress immediately on zero poll delay, enlarge
  virtual UDP receive queues to 128 KiB payload with 128 metadata
  slots, and bound UDP session receive buffers to 8 KiB plus one
  byte while keeping oversized-datagram detection.

Host integration:

- Add optional algorithm-neutral AEAD seal/open imports with the
  ring backend as fallback, and pin the ring AES-128-GCM wire vector
  so the Go host stays interoperable.
- Forward instance events to hosts through one best-effort,
  synchronous, non-blocking import.
- Add a repository-owned build entry point for the Go host artifact:
  Binaryen 131 at -O4 with cached, SHA-256-verified official
  archives.
2026-07-28 00:29:08 +08:00

3.4 KiB

Native data-plane ABI v3

The native data-plane ABI is a thin adapter over the instance-owned DataPlaneSession. It does not own sockets, operation state, completion queues, routing policy, or timeouts.

Conventions

  • Every immediate call returns 0 on success or a negative DataPlaneErrorKind value on failure.
  • data_plane_completion_wait returns 1 when a completion is ready, 0 on timeout or session close, and a negative error value on failure.
  • data_plane_completion_drain returns a non-negative descriptor count or a negative error value.
  • Handle zero is invalid.
  • timeout_ms == UINT64_MAX means no deadline.
  • TCP connect/bind/accept and UDP bind timeouts start when submission is accepted.
  • TCP streams and UDP sockets have persistent read and write deadlines. data_plane_resource_deadline_set replaces the selected directions' deadlines immediately, including for active operations. An expired deadline remains expired until it is replaced or cleared with UINT64_MAX.
  • Deadline direction 1 selects reads, 2 selects writes, and 3 selects both.
  • Request and write bytes are copied before a submit call returns.
  • Socket-address fields use native-endian integers. Address bytes are in network order. ABI v3 accepts IPv4 only.

DataPlaneSocketAddr is:

typedef struct {
    uint16_t family;      /* 4 */
    uint16_t port;
    uint8_t address[16];  /* IPv4 uses the first four bytes */
} DataPlaneSocketAddr;

DataPlaneCompletion is:

typedef struct {
    uint64_t operation_id;
    uint16_t operation_kind;
    uint16_t status; /* 0 or DataPlaneErrorKind */
} DataPlaneCompletion;

Lifecycle

One native session may be open for an EasyTier instance at a time:

data_plane_session_open
  -> set resource deadlines
  -> submit operations
  -> completion_wait
  -> completion_drain
  -> typed result_take
  -> resource_close / operation_free
data_plane_session_close

Closing a native session cancels and discards its outstanding operations and resources and wakes a thread blocked in data_plane_completion_wait.

The resource and operation IDs returned by the ABI belong to that session. They must always be passed together with the same session handle.

Completion and result ownership

Submission returns an operation ID immediately. Completion descriptors carry only the operation ID, operation kind, and terminal status. Draining a descriptor makes its typed result available but does not consume it.

data_plane_result_size reports the TCP-read or UDP-receive payload size. Typed result-take functions consume the result exactly once. If a supplied buffer is too small, they return -BufferTooSmall and leave the result available for a later call.

Call data_plane_operation_free when a drained result is intentionally abandoned. Call data_plane_resource_close for TCP streams, listeners, and UDP sockets.

Operation kinds

Value Operation
1 TCP connect
2 TCP bind
3 TCP accept
4 TCP read
5 TCP write
6 UDP bind
7 UDP receive
8 UDP send

The exported function families are:

  • data_plane_tcp_*_submit
  • data_plane_udp_*_submit
  • data_plane_resource_deadline_set
  • data_plane_completion_wait
  • data_plane_completion_drain
  • data_plane_*_result_take
  • data_plane_operation_cancel
  • data_plane_operation_free
  • data_plane_resource_close