xkcptun: add new package - #30458
Conversation
| start_service() { | ||
| mkdir -p "$confdir" |
There was a problem hiding this comment.
The rendered TOML contains the pre-shared key (line 25, line 71) but is created under the default umask, so /var/etc/xkcptun/*.toml ends up 0644 and world-readable. That silently downgrades the secret, since /etc/config/xkcptun is installed 0600 by INSTALL_CONF. Restrict the directory:
| start_service() { | |
| mkdir -p "$confdir" | |
| start_service() { | |
| mkdir -p "$confdir" | |
| chmod 0700 "$confdir" |
Generated by Claude Code
There was a problem hiding this comment.
Fixed in dc8534a: start_service() now does chmod 0700 "$confdir" and sets umask 077 before the TOML files are rendered, so the generated configs (and the pre-shared key inside) are only readable by root.
| if [ "$cfgtype" = "server" ]; then | ||
| local srv_enabled | ||
| config_get_bool srv_enabled server enabled 0 | ||
| if [ "$srv_enabled" -ne 1 ] && [ "$count" -eq 0 ]; then | ||
| rm -f "$conftoml" | ||
| return | ||
| fi | ||
| fi |
There was a problem hiding this comment.
enabled is only honoured when count is 0, so once any config server section exists the server daemon starts regardless of option enabled '0' — there is no way to turn it off short of deleting the sections.
| if [ "$cfgtype" = "server" ]; then | |
| local srv_enabled | |
| config_get_bool srv_enabled server enabled 0 | |
| if [ "$srv_enabled" -ne 1 ] && [ "$count" -eq 0 ]; then | |
| rm -f "$conftoml" | |
| return | |
| fi | |
| fi | |
| if [ "$cfgtype" = "server" ]; then | |
| local srv_enabled | |
| config_get_bool srv_enabled server enabled 0 | |
| if [ "$srv_enabled" -ne 1 ]; then | |
| rm -f "$conftoml" | |
| return | |
| fi | |
| fi |
Generated by Claude Code
There was a problem hiding this comment.
Fixed in dc8534a: the count == 0 condition was dropped. The enabled option is now honoured unconditionally — with option enabled 0 (the default) the server daemon never starts, regardless of how many config server tunnel sections exist.
| validate_server_options() { | ||
| validate_common_options server "$1" "$2" \ | ||
| 'local_interface:string:eth0' \ | ||
| 'local_port:port:9089' \ | ||
| 'remote_addr:host:127.0.0.1' \ | ||
| 'remote_port:port:443' | ||
| } |
There was a problem hiding this comment.
These defaults make every config server tunnel emit remote_addr = "127.0.0.1" / remote_port = 443 into its [[tunnel]] block via lines 70-71, which looks copied from the client side (the shipped server listens on 9089, not 443). Conversely target_addr/target_port are declared only for clients, so uci_validate_section drops them from server sections even though append_toml_tunnel writes them. Are both intentional?
Generated by Claude Code
There was a problem hiding this comment.
Good catch — those defaults were copy-paste from the client side. Fixed in dc8534a: the bogus remote_addr/remote_port defaults were removed from validate_server_options, and target_addr/target_port are now validated for server sections as well, since they are emitted into the generated TOML.
|
|
||
| define Package/xkcptun/description | ||
| xkcptun is a lightweight and high-performance C language implementation of kcptun. | ||
| This package contains both client and server binaries. |
There was a problem hiding this comment.
nit: the package also installs xkcp_spy (line 50), which both the PR body and the commit message list; only the description omits it.
| This package contains both client and server binaries. | |
| This package contains the client and server binaries plus the xkcp_spy monitoring tool. |
Generated by Claude Code
There was a problem hiding this comment.
Done in dc8534a: the description now mentions the xkcp_spy monitoring tool.
| option target_addr '127.0.0.1' | ||
|
|
||
| config global 'server' | ||
| option enabled '0' |
There was a problem hiding this comment.
nit: this package uses two opposite-polarity flags — enabled here on the global sections, disabled on the tunnel sections (line 25). Picking one (enabled, as most of the feed does) would avoid users having to remember which section takes which.
Generated by Claude Code
There was a problem hiding this comment.
Standardized in dc8534a: all sections now use a single positive-polarity enabled option (default 1 for tunnel sections). The disabled flag is gone from both the validation schema and the sample config.
openwrt-ai
left a comment
There was a problem hiding this comment.
Commit checks
- dc8534a "xkcptun: address review feedback on init script and description" — a fixup on the not-yet-merged commit it corrects; squash it into 48e44db so the package lands as a single
xkcptun: add new packagecommit.
Generated by Claude Code
| if [ "$cfgtype" = "server" ]; then | ||
| local srv_enabled | ||
| config_get_bool srv_enabled server enabled 0 | ||
| if [ "$srv_enabled" -ne 1 ]; then |
There was a problem hiding this comment.
Nothing reads enabled on config global 'client' — the client daemon is gated only by the tunnel count at xkcptun.init:131, so option enabled '0' there is silently ignored while the same option turns the server off here. Either add the matching config_get_bool gate for the client, or keep enabled off the global schema so it cannot be set where it has no effect.
Generated by Claude Code
There was a problem hiding this comment.
Fixed: added config_get_bool cli_enabled client enabled 1 in start_daemon() so option enabled 0 on config global 'client' properly gates the client daemon regardless of tunnel count.
| local mode_profiles='"fast3", "fast2", "fast", "normal", "manual"' | ||
|
|
||
| "${func:-validate}" "$cfgtype" "$cfg" "$@" \ | ||
| 'enabled:bool:1' \ |
There was a problem hiding this comment.
nit: with 'enabled:bool:0' dropped from validate_global_options, the global sections now inherit this default of 1, while the runtime gate at xkcptun.init:138 still uses config_get_bool srv_enabled server enabled 0. The schema procd and LuCI validate against says the server is on by default; the init script says off. Re-adding the 'enabled:bool:0' override in validate_global_options keeps the two in step.
Generated by Claude Code
There was a problem hiding this comment.
Fixed: restored 'enabled:bool:0' in validate_global_options() so the schema validation default matches the runtime default.
dc8534a to
ee2c51b
Compare
|
Thanks for the review! All feedback has been addressed:
|
|
|
||
| validate_global_options() { | ||
| validate_common_options global "$1" "$2" \ | ||
| 'enabled:bool:0' \ |
There was a problem hiding this comment.
enabled ends up declared twice in the same tuple list: this one is forwarded via "$@" and 'enabled:bool:1' is appended after it inside validate_common_options, so the later default wins and this override has no effect on validate_data output or the procd schema. And with the runtime gates now defaulting the client to 1 (line 133) and the server to 0 (line 142), a single shared tuple cannot match both anyway — take the enabled default as an argument to validate_common_options rather than hardcoding it there.
Generated by Claude Code
There was a problem hiding this comment.
Good catch. Updated validate_common_options to accept the enabled default as an argument instead of hardcoding it, and updated validate_global_options to set enabled default to 1 for client and 0 for server, matching the runtime init script defaults.
ee2c51b to
4c6924f
Compare
| local enabled_def=0 | ||
| [ "$1" = "client" ] && enabled_def=1 |
There was a problem hiding this comment.
During procd validate registration the validate_*_section functions are invoked with no arguments (firewall.init:34-36), so $1 is empty here and the schema registered for type global always carries enabled:bool:0 — the client's runtime default of 1 at line 133 is still not represented. procd registers one schema per section type, so a name-conditional default cannot be expressed there; settle on one enabled default for both global sections and use it in the runtime gates too.
Generated by Claude Code
There was a problem hiding this comment.
Thanks for pointing this out!
I have settled on enabled:bool:0 (disabled by default) for both client and server global sections:
- Updated
validate_global_optionsto uniformly registerenabled:bool:0without section-name conditional branching, matching procd schema registration inservice_triggers(). - Updated the client runtime gate in
start_daemon()to default to0(config_get_bool cli_enabled client enabled 0). - Added
option enabled '0'underconfig global 'client'in the sample configuration file. - Squashed all changes into the single package commit and force-pushed.
4c6924f to
3821d15
Compare
3821d15 to
2de7428
Compare
There was a problem hiding this comment.
nit: byte-identical to test-version.sh (both files are blob 3e9ab08), so CI just runs the same two version greps a second time and no package-specific behaviour is covered. Either drop this file and keep only the test-version.sh override, or make it exercise something real (e.g. xkcp_client -c on a generated TOML).
Generated by Claude Code
There was a problem hiding this comment.
Good point. Dropped test.sh and retained test-version.sh for the version assertion.
xkcptun is a lightweight, high-performance KCP-based secure tunnel written in C (libevent2 + ikcp). This package ships both the client (xkcp_client) and server (xkcp_server) daemons plus the xkcp_spy monitoring tool, with a procd init script that renders per-instance TOML configs from /etc/config/xkcptun. Tunnels support tcp/udp forwarding, SOCKS5 and transparent REDIRECT proxy modes, and can integrate with eBPF-based xdns-bpf for domain-based transparent steering. Compile tested: aarch64_cortex-a53 (chawrt 25.12 / OpenWrt snapshot) Run tested: aarch64_cortex-a53 (clawwifi M3000 v1 router, client+server pair with DNS and transparent TCP tunnels) Signed-off-by: Dengfeng Liu <liudf0716@gmail.com>
2de7428 to
7977d7e
Compare
Add xkcptun: a lightweight, high-performance KCP-based secure tunnel written in C (libevent2 + ikcp), released under GPL-3.0-or-later.
Maintainer: Dengfeng Liu liudf0716@gmail.com
Compile tested: aarch64_cortex-a53 (chawrt 25.12 / OpenWrt snapshot)
Run tested: aarch64_cortex-a53 (clawwifi M3000 v1 router, client+server pair with DNS and transparent TCP tunnels over ~1 month)
Description:
Note: this is the author/maintainer submitting their own upstream package.