Proto commits in eycorsican/leaf

These 64 commits are when the Protocol Buffers files have changed:

Commit:a77273f
Author:eric
Committer:eric

feat(plugins): run plugins compiled into the client, named by builtin iOS will not load code from a file, and Android will not from anywhere an app can write, so there a plugin is linked in at build time instead. It is registered under a name with register_builtin_plugin, and a config refers to it with `builtin`, in conf ([Plugin] builtin=) and JSON alike. A registered builtin wins over path and url, which are then only the fallback for a client without it: nothing is downloaded and no cache directory is needed. A client with none of the three fails to start and lists the builtins it has. A builtin's descriptor goes through the same validation as a library's; only the file's checks -- path, permissions, sha256 -- do not apply, since there is no file. Loaded plugins are now keyed by source, so two outbounds on one builtin share it. Only plugins written in other languages are linked in. Plugins exist for protocols written in something other than Rust; one written in Rust belongs in leaf as an outbound of its own. Linking a Rust plugin in would also merge its dependencies' features with leaf's -- the TLS plugin's rustls with ring on top of leaf's aws-lc-rs, for one, which leaves rustls with no default provider and panics the DoH client. The in-tree Rust plugins stay loadable libraries only. For C, defining LEAF_PLUGIN_STATIC_NAME renames the descriptor function to leaf_plugin_<name>_get_descriptor and drops its export, through the canonical header, so the plugin's source does not change and any number of C plugins can be linked into one binary. leaf-ffi's plugin-socks5-c feature links the SOCKS5 C plugin into the library (compiled by build.rs) and registers it as the builtin socks5-c on the first call that reads a config. leaf_register_plugin registers one the app links itself. Its unit tests load the linked-in plugin through the host. The builtin/ e2e cases register a fixture's descriptor function and show that it carries TCP and UDP to a stock leaf server, wins over a path and over a url (with no cache directory to fall back on), gives way to the url on a client without it, fails clearly with nothing to fall back on, and is held to the same descriptor validation as a library. The READMEs describe builtins and how to link a plugin in, and plugin-test and CI run the linked-in tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Commit:488ff34
Author:eric
Committer:eric

feat(plugins): download the plugins a config names by url A plugin outbound can now give a url instead of a path. With the new plugin-fetch feature, a start downloads what the cache is missing into <cache>/<sha256>/<file> before any outbound is built, and points the outbounds at it; a reload, and testing an outbound, resolve from the cache only and refuse what they would have to download. - https only, redirects included, and only together with a sha256 pin. - Downloads go to a temporary file, are hashed as they arrive, and are renamed into place only once the digest matches, under the url's own name, with the platform's library suffix added when it has no extension, which is what Windows needs to load it. A download past the declared size, or past 64 MiB without one, is stopped. - The cache directory comes from FetchOptions or PLUGIN_CACHE_DIR, with no default: whether a directory is safe to load code from is the embedding app's call. - prefetch() reports QUEUED/CACHED for every plugin before any download, then STARTED, PROGRESS (at most every 100 ms) and exactly one DONE or FAILED each, on the calling thread; the callback can cancel. A download that has not finished gets a PROGRESS heartbeat at least once a second, before STARTED too, so that one stuck connecting or in the handshake can be cancelled as well as one stuck mid-body. conf gains a [Plugin] section that declares each plugin once (path, url, sha256, size) and a `plugin` proxy protocol that refers to it by name, with args= or args-b64= for arguments that contain commas. Proxy parameters are now split at the first `=` only, which used to drop any value that contained one. leaf-ffi gains leaf_prefetch_plugins, so that an app can download the plugins as soon as it has the config, and show progress, and the start that follows finds everything in the cache. Events arrive as a LeafFetchEvent whose first field is its size, on the calling thread and never after the call returns. Adds ERR_PLUGIN_FETCH, ERR_CANCELLED and ERR_UNSUPPORTED, and the plugin and plugin-fetch features. It is tested by unit tests rather than end to end: the library is a Rust dylib, which does not link in a Windows debug build (LNK1189). Twenty-three fetch/ e2e cases download from a per-case https server whose routes can announce a wrong length, omit it, fail, redirect, or hold a body at a gate until the case opens it. Every case checks its events against one statement of the progress contract, and every failure, cancel and timeout case checks that the cache is left empty. One checks that testing an outbound reads the cache, including a file put there by hand, and never downloads. The READMEs describe plugins in conf files and downloading them, and plugin-test and CI run the new unit tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Commit:b6a63ac
Author:eric
Committer:eric

feat(plugin)!: replace the in-process plugin API with a C ABI host The old API handed dynamic libraries Rust trait objects, tying every plugin to leaf's exact compiler and crate versions and ruling out other languages. It is removed, along with its shadowsocks sample, which returns on the new ABI in a later commit. The host loads plugins over leaf-plugin-abi instead. It validates the descriptor, dials the endpoint, and drives the engines as sans-io codecs over its own transport, exposing them as ordinary outbound handlers. Datagram engines are either unreliable, with a UDP socket of their own, or reliable, framed over the stream transport. Plugin failures carry the plugin's last error string, and plugin logs join the session's tracing span. Everything crossing the boundary is treated as untrusted: counts are checked against the buffers they describe, reported strings are bounded and escaped, engines get an opaque id rather than a pointer for host_ctx, and an engine that takes no input is backpressure rather than failure. A poll does a bounded amount of work, and a datagram the receiver cannot take is dropped instead of the session. An outbound names its path, host and port, and may pin the sha256 of the library it loads -- the only check on this path that still holds against someone who can write the file. `leaf --verify-plugin <path>` runs the same checks without a config file and prints what the plugin declares: its ABI version, its engines, whether the outbound must carry host and port, and the digest to pin it to. A build can then be vetted before it is in the path of any traffic.

Commit:1d20301
Author:eric

Revert "feat(inbound): limit data transfer and concurrent connections per IP" This reverts commit 05e872ac0aa85d9514125be2393afc87a672cd06.

Commit:05e872a
Author:eric

feat(inbound): limit data transfer and concurrent connections per IP

Commit:a3459cc
Author:eric
Committer:eric

Support ECH config DNS lookup

Commit:822889c
Author:eric

Support ECH

Commit:428f448
Author:eric

Support raw certificate configuration for JSON

Commit:f7b288e
Author:eric
Committer:eric

Add MPTP protocol

Commit:1303e3e
Author:eric

Add wintun support

Commit:8f43c2b
Author:eric

Refine Socks and tests

Commit:b1b64d5
Author:eric
Committer:eric

Add VLess + Reality (experimental)

Commit:1d0e982
Author:eric

Add netstack-smoltcp tun2socks backend

Commit:a86f91a
Author:eric

Support compact log format

Commit:d764286
Author:eric
Committer:eric

Added hc inbound for management purposes

Commit:033213d
Author:eric
Committer:eric

Support PROCESS-NAME rule

The documentation is generated from this commit.

Commit:ea912cc
Author:eric
Committer:eric

Support PROCESS-NAME rule

The documentation is generated from this commit.

Commit:93000df
Author:eric
Committer:eric

Support NetFilter inbound

Commit:49aa8f8
Author:eric

Added NONE loglevel to skip logger setup

Commit:a6070a7
Author:eric
Committer:eric

Support multiple health check requests for the failover outbound

Commit:09d1a97
Author:eric

Added healthCheckWait option for failover outbound

Commit:b1ef030
Author:eric

Added healthCheckOnStart option to failover outbound

Commit:ed261b6
Author:eric
Committer:eric

Added healthCheckPrefers parameter for failover outbound

Commit:6f9d426
Author:eric

outbound/direct: allow to specify an outbound interface

Commit:8517bb3
Author:eric

outbound/amux: new parameters max-recv-bytes and max-lifetime to control connection behavior

Commit:af24da9
Author:eric
Committer:eric

outbound/shadowsocks: support customizable salt prefix Note the prefix must specify in percent-encoded form and the length must less than the used cipher key length.

Commit:1de877a
Author:eric
Committer:eric

outbound/tls: added an option to disable certificate verification

Commit:85cfa4c
Author:bdbai
Committer:eycorsican

Add http obfs outbound

Commit:a358f7e
Author:eric
Committer:eric

inbound/cat: a new inbound makes leaf act as netcat Running leaf with the following config: ```json { "inbounds": [ { "protocol": "cat", "settings": { "address": "1.1.1.1", "network": "tcp", "port": 80 }, "tag": "cat" } ], "log": { "level": "warn" }, "outbounds": [ { "protocol": "socks", "settings": { "address": "127.0.0.1", "port": 1080 }, "tag": "socks" } ] } ``` is similar to the following `nc` command: ```shell nc -X5 -x127.0.0.1:1080 1.1.1.1 80 ``` Which establishes a TCP connection to 1.1.1.1:80 via a local SOCKS5 proxy. But leaf supports sending UDP over SOCKS5 as well as other supported outbounds.

Commit:a70d98d
Author:lemos
Committer:GitHub

outbound/socks: add authentication support for socks (#356)

Commit:5fa702d
Author:eric
Committer:eric

quic: configurable ALPN

Commit:b291177
Author:eric
Committer:eric

outbound/failover: skip health checking at inactivity

Commit:09775d6
Author:eric
Committer:eric

outbound/failover: configurable health check delay

Commit:aad085f
Author:eric
Committer:eric

outbound/vmess: re-introduce

Commit:96294a6
Author:eric
Committer:eric

Added statistics manager

Commit:c3afb38
Author:eric
Committer:eric

outbound/random, outbound/rr, outbound/static: combined random and rr into static

Commit:cbef2f9
Author:eric

outbound/retry: removed

Commit:290831c
Author:eric
Committer:eric

outbound/failover: configurable health check timeout

Commit:769c48d
Author:eric
Committer:eric

outbound/failover: allows a single outbound as a last resort

Commit:ae32f7a
Author:eric
Committer:eric

inbound/trojan: accept multiple passwords

Commit:ed8b128
Author:eric

conf: support logoutput

Commit:8e7c0b4
Author:eric
Committer:eric

router, conf: support INBOUND-TAG rule

Commit:028f294
Author:eric
Committer:eric

conf: support NETWORK rule

Commit:fbe3a5a
Author:eric
Committer:eric

inbound/tls: new inbound

Commit:d35e649
Author:eric
Committer:eric

Experimental plugin system

Commit:489d80f
Author:eric

outbound/rr: new outbound to dispatch requests in a round-robin manner

Commit:5dfbcaa
Author:eric
Committer:eric

config, router: make doman-resolve option reloadable

Commit:c1d6852
Author:eric
Committer:eric

outbound/tun: automate tun setup

Commit:47071b8
Author:eric
Committer:eric

outbound/select: persists selector state

Commit:f8163d1
Author:eric

config/json, test: enable api on json config and fix tests

Commit:a2dadff
Author:eric

outbound/select: new outbound

Commit:ae5f0f6
Author:eric
Committer:eric

proxy/quic: a UDP-based multiplexed and secure transport

Commit:8b1268b
Author:eric
Committer:eric

amux: a multiplexing transport

Commit:5b1582f
Author:eric
Committer:eric

proxy: elementary support for multiplexing transports This adds an `Incoming` transport to represent a `futures::stream::Stream` of incoming transports from a multiplexing handler which accepts a single stream as input and returns multiple streams as output. A work in progress `amux` handler is also included.

Commit:6ef895a
Author:eric

inbound/shadowsocks: new inbound

Commit:99680ab
Author:eric

dns: support DNS static hosts

Commit:f764670
Author:eric

outbound/ws: support custom headers

Commit:0ac84b7
Author:eric

outbound/retry: added retry outbound retry outbound allows multiple attempts on a list of outbounds.

Commit:87d52fb
Author:eric

router: support port range matching

Commit:82545d4
Author:eric

Refactor

Commit:d52a49e
Author:eric

failover: Add the option to cache fallback actors

Commit:807ad5a
Author:eric
Committer:eric

Added several inbounds * Added WebSocket inbound * Added trojan inbound * Added chain inbound Similar to the chain outbound, chain inbound can be used to chain multiple inbounds. The Nginx/CDN (TLS) + WebSocket + trojan setup is tested. There are also breaking changes to the JSON config format. Fake DNS now can operate in either Include or Exclude mode. SOCKS inbound settings no longer has the `bind` option, the local_addr of the TCP socket is used as the UDP relay address.

Commit:d1112c0
Author:eric

add h2 support

Commit:897fc87
Author:eric

initial commit