Files
Easytier/easytier-contrib/easytier-ios/easytier-ios.h
T
KKRainbow 4a10d1c2b9 feat(mobile): add embedded runtime and managed network updates (#2532)
* feat(mobile): add embedded iOS runtime API

Add a thin panic-safe C ABI crate for embedding no-TUN instances
on iOS. Expose lifecycle, status, JSON-RPC, string ownership, and
error handling.

Build device and simulator XCFramework static libraries on macOS.
Add exact named-instance deletion to the iOS and Android wrappers.
Cover wrapper lifecycle and the port-forward patch flow on host
targets.

* fix(gateway): recover TCP port-forward listeners

Release an unusable TCP port-forward listener after an accept
failure. Retry binding until the forward is cancelled. Keep the old
listener released while rebinding so mobile sockets can recover.

Expose opt-in iOS diagnostics for listener and connection events.
Trace configuration removal and adapter shutdown. Add tests for
recovery, release-before-rebind, and cancellation.

* feat(web): persist incremental managed config patches

Add a revision-CAS PATCH contract for managed configs while keeping
the existing Full PUT path for compatibility and recovery.

Apply Full and Patch mutations with their revision in one SQLite
transaction. Reject ownership conflicts and invalidate revisions on
alternate web-owned writes.

Document limits, failure semantics, rollout order, and verification.
Cover delta updates, conflicts, idempotency, and transaction rollback.

* feat(web): apply managed config patches to live sessions

Carry Patch fences and touched instance IDs into live sessions.
Reconcile only those instances when the applied revision matches the
Patch base. Fall back to Full reconciliation for gaps and restarts.

Invalidate the applied revision around every direct runtime mutation.
Fence revision advancement with the runtime cache epoch so stale
reconcile rounds cannot overwrite a newer invalidation.

Require deletion responses to confirm each requested instance before
advancing the revision. Raise the managed PUT and PATCH body limit to
32 MiB and return typed conflicts for publisher recovery.

* fix(core): retry transient accepted TCP errors

Keep TCP tunnel listeners alive when an accepted socket fails during
upgrade with a retryable connection-state error.

Share the retryable I/O classifier with the socket listener. Cover a
rejected connection followed by success and propagation of permanent
errors.

* feat(core): add internal Peer Relay edge projection

Derive the local advertised OSPF row from physical adjacency and transport-authenticated credential relay coverage. Keep full local adjacency only in the temporary SPF snapshot so direct destinations retain a fallback route.

Leave Peer Relay disabled at the public configuration seam. A follow-up change can expose the preference without coupling route projection to credential reauthorization.

feat(config): expose Peer Relay routing preference

Add prefer_peer_relay to public protobuf, TOML, management patch, and
hosted runtime surfaces.

Read the preference from live peer context so runtime config updates take
effect. Refresh authenticated peer metadata when the option is enabled.

Cover dynamic enable and disable in a five-node, dual-admin credential
topology, including forwarded relay coverage and local fallback.
2026-08-28 00:43:26 +08:00

139 lines
4.6 KiB
C

/**
* @file easytier-ios.h
* @brief iOS-facing C ABI for EasyTier.
*
* This library embeds EasyTier into an iOS app without a TUN device or
* NEPacketTunnel: it manages EasyTier instances and bridges to the EasyTier
* management RPC surface. Loopback port forwarding into the virtual network
* is configured through easytier_ios_call_json_rpc() with
* api.config.ConfigRpcService/PatchConfig port-forward patches; there is no
* built-in forwarder.
*
* Error handling: functions returning `int` return 0 on success and -1 on
* failure; functions returning `char *` return NULL on failure. Call
* easytier_ios_last_error() on the same thread to retrieve details.
*
* Threading: all functions are safe to call from any thread. The last-error
* buffer is thread-local, so query it on the thread that received the
* failure.
*/
#ifndef EASYTIER_IOS_H
#define EASYTIER_IOS_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable diagnostic EasyTier logging to stderr.
*
* Installs a narrow global tracing subscriber that records port-forward
* lifecycle events. Repeated calls are idempotent.
*
* @return 0 on success, -1 if another tracing subscriber was installed first.
*/
int easytier_ios_enable_diagnostic_logging(void);
/**
* @brief Start one EasyTier network instance from a TOML config string.
*
* The config's `instance_name` must be unique among instances started
* through this library.
*
* @param toml Non-null pointer to a NUL-terminated UTF-8 TOML config string.
* @return 0 on success, -1 on failure.
*/
int easytier_ios_run_instance(const char *toml);
/**
* @brief Keep the named instances and stop all others.
*
* @param names_json Null, empty, or a NUL-terminated JSON array of instance
* name strings. Null / empty / `[]` stops every running
* instance.
* @return 0 on success, -1 on failure.
*/
int easytier_ios_retain_instances(const char *names_json);
/**
* @brief Stop exactly one named instance without affecting other instances.
*
* An unknown name is a no-op.
*
* @param instance_name Non-null NUL-terminated instance name.
* @return 0 on success, -1 on failure.
*/
int easytier_ios_delete_instance(const char *instance_name);
/**
* @brief Collect running instance information as a JSON object.
*
* The result maps each instance name to its running info JSON object.
*
* @param max_length Maximum number of instances to report.
* @return A newly allocated NUL-terminated JSON string on success, NULL on
* failure.
*
* @ownership The caller owns the returned string and must release it with
* easytier_ios_free_string().
*/
char *easytier_ios_collect_network_infos(int max_length);
/**
* @brief Call an exposed EasyTier management RPC method using protobuf JSON.
*
* `service_name` is the protobuf service name (e.g.
* "api.config.ConfigRpcService"), `method_name` the RPC method name (e.g.
* "PatchConfig"). `payload_json` must contain the protobuf JSON request,
* including any `instance` selector required by the target RPC.
*
* Port forwarding into the virtual network is driven through this bridge
* with api.config.ConfigRpcService/PatchConfig port-forward patches.
*
* @param service_name Non-null NUL-terminated RPC service name.
* @param method_name Non-null NUL-terminated RPC method name.
* @param payload_json Non-null NUL-terminated protobuf JSON request body.
* @return A newly allocated NUL-terminated JSON response string on success,
* NULL on failure.
*
* @ownership The caller owns the returned string and must release it with
* easytier_ios_free_string().
*/
char *easytier_ios_call_json_rpc(const char *service_name,
const char *method_name,
const char *payload_json);
/**
* @brief Return the last error message on this thread.
*
* Combines wrapper-side errors recorded by this library with the
* easytier-ffi last FFI error.
*
* @return A newly allocated NUL-terminated string, or NULL when there is no
* recorded error.
*
* @ownership The caller owns the returned string and must release it with
* easytier_ios_free_string().
*/
char *easytier_ios_last_error(void);
/**
* @brief Release a string returned by this library.
*
* Use this for strings returned by easytier_ios_collect_network_infos(),
* easytier_ios_call_json_rpc() and easytier_ios_last_error(). Passing NULL
* is a no-op. The string must not be used after this call.
*
* @param s NULL, or a string previously returned by this library.
*/
void easytier_ios_free_string(char *s);
#ifdef __cplusplus
}
#endif
#endif /* EASYTIER_IOS_H */