Feat/build#1
Conversation
- scripts/build-musl-deps.sh cross-builds zlib/OpenSSL/libevent/json-c as musl static libraries via Zig, into a sysroot consumable by -Ddep-prefix - README: add 'Build with Zig' section covering native build and the fully-static Linux binary workflow (~3.5MB ReleaseSmall)
- .github/workflows/release.yml: on v* tags, cross-build fully-static musl binaries for linux amd64/arm64/armv7 via scripts/build-musl-deps.sh + zig -Dstatic, UPX-compress on stable tags, publish a GitHub Release (pre-release for -alpha/-beta). Modeled on the zigo release workflows. - build.zig: use abi.isMusl() so armv7 (musleabihf) also skips libcrypt - build-musl-deps.sh: idempotent short-circuit so CI dep cache is reused
- scripts/build-macos-deps.sh: build zlib/OpenSSL/libevent/json-c as static .a per arch (Apple clang -arch), with idempotent cache short-circuit - build.zig: add -Ddep-static (link C deps static, keep exe dynamic so macOS libSystem stays dynamic); when dep-prefix is set, skip Homebrew auto-paths - release.yml: add build-macos matrix on native macos-13 (x86_64) and macos-14 (arm64) runners; release job now needs [build, build-macos] - README: document the portable macOS build
…ated) GitHub's Intel macOS runners (macos-13) are being deprecated and the darwin_amd64 job was stuck 'waiting for a runner'. Build both macOS arches on the macos-14 (arm64) runner instead, cross-compiling x86_64. - build.zig: when targeting macOS, add the SDK include/lib/framework paths from $SDKROOT so cross builds find system headers like <arpa/telnet.h> (native builds already resolve the SDK automatically) - release.yml: build-macos now runs only on macos-14, passes explicit -Dtarget=, exports SDKROOT, and skips running the x86_64 binary - README: document the SDKROOT-based macOS cross-compile
There was a problem hiding this comment.
Code Review
This pull request introduces Zig build support (build.zig) alongside helper scripts to cross-compile static dependencies for macOS and musl/Linux, enabling fully static or portable binaries. It also resolves several cross-platform compatibility issues for macOS/BSD in config.c, plugins/telnetd.c, and utils.c. Feedback on these changes includes increasing the MAC address buffer validation length to 13 to prevent truncation, fixing a formatting regression in telnetd.c, adding libevent_openssl.a to the dependency cache checks in both build scripts, and avoiding overriding exported LDFLAGS and CPPFLAGS when configuring libevent on macOS.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (!net_if_name || !mac || mac_len < 12) { | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
The validation check mac_len < 12 is insufficient. A MAC address formatted as 12 hexadecimal characters (e.g., XXXXXXXXXXXX) requires at least 13 bytes to include the null terminator (\0). If mac_len is exactly 12, the loop formatting the MAC address will pass a size of 2 to snprintf for the last byte (i = 5), which truncates the last character and results in an incomplete 11-character MAC address string. Increasing the minimum required length to 13 prevents this truncation.
| if (!net_if_name || !mac || mac_len < 12) { | |
| return 1; | |
| } | |
| if (!net_if_name || !mac || mac_len < 13) { | |
| return 1; | |
| } |
| termbuf.c_lflag |= ECHO; /* if we use readline we dont want this */ | ||
| termbuf.c_oflag |= ONLCR | XTABS; | ||
| termbuf.c_iflag |= ICRNL; | ||
| termbuf.c_oflag |= ONLCR | XTABS; termbuf.c_iflag |= ICRNL; |
There was a problem hiding this comment.
| have_all_libs() { | ||
| [ -f "$SYSROOT/lib/libz.a" ] && | ||
| [ -f "$SYSROOT/lib/libevent.a" ] && | ||
| [ -f "$SYSROOT/lib/libjson-c.a" ] && | ||
| { [ -f "$SYSROOT/lib/libssl.a" ] || [ -f "$SYSROOT/lib64/libssl.a" ]; } && | ||
| { [ -f "$SYSROOT/lib/libcrypto.a" ] || [ -f "$SYSROOT/lib64/libcrypto.a" ]; } | ||
| } |
There was a problem hiding this comment.
The have_all_libs check is missing a check for libevent_openssl.a. Since build.zig explicitly links against event_openssl, if libevent_openssl.a is missing but other libraries are present, the script will incorrectly skip the build, leading to compilation failures later. Adding libevent_openssl.a to the check ensures build completeness.
| have_all_libs() { | |
| [ -f "$SYSROOT/lib/libz.a" ] && | |
| [ -f "$SYSROOT/lib/libevent.a" ] && | |
| [ -f "$SYSROOT/lib/libjson-c.a" ] && | |
| { [ -f "$SYSROOT/lib/libssl.a" ] || [ -f "$SYSROOT/lib64/libssl.a" ]; } && | |
| { [ -f "$SYSROOT/lib/libcrypto.a" ] || [ -f "$SYSROOT/lib64/libcrypto.a" ]; } | |
| } | |
| have_all_libs() { | |
| [ -f "$SYSROOT/lib/libz.a" ] && | |
| [ -f "$SYSROOT/lib/libevent.a" ] && | |
| [ -f "$SYSROOT/lib/libevent_openssl.a" ] && | |
| [ -f "$SYSROOT/lib/libjson-c.a" ] && | |
| { [ -f "$SYSROOT/lib/libssl.a" ] || [ -f "$SYSROOT/lib64/libssl.a" ]; } && | |
| { [ -f "$SYSROOT/lib/libcrypto.a" ] || [ -f "$SYSROOT/lib64/libcrypto.a" ]; } | |
| } |
| have_all_libs() { | ||
| [ -f "$SYSROOT/lib/libz.a" ] && | ||
| [ -f "$SYSROOT/lib/libevent.a" ] && | ||
| [ -f "$SYSROOT/lib/libjson-c.a" ] && | ||
| { [ -f "$SYSROOT/lib/libssl.a" ] || [ -f "$SYSROOT/lib64/libssl.a" ]; } && | ||
| { [ -f "$SYSROOT/lib/libcrypto.a" ] || [ -f "$SYSROOT/lib64/libcrypto.a" ]; } | ||
| } |
There was a problem hiding this comment.
The have_all_libs check is missing a check for libevent_openssl.a. Since build.zig explicitly links against event_openssl, if libevent_openssl.a is missing but other libraries are present, the script will incorrectly skip the build, leading to compilation failures later. Adding libevent_openssl.a to the check ensures build completeness.
| have_all_libs() { | |
| [ -f "$SYSROOT/lib/libz.a" ] && | |
| [ -f "$SYSROOT/lib/libevent.a" ] && | |
| [ -f "$SYSROOT/lib/libjson-c.a" ] && | |
| { [ -f "$SYSROOT/lib/libssl.a" ] || [ -f "$SYSROOT/lib64/libssl.a" ]; } && | |
| { [ -f "$SYSROOT/lib/libcrypto.a" ] || [ -f "$SYSROOT/lib64/libcrypto.a" ]; } | |
| } | |
| have_all_libs() { | |
| [ -f "$SYSROOT/lib/libz.a" ] && | |
| [ -f "$SYSROOT/lib/libevent.a" ] && | |
| [ -f "$SYSROOT/lib/libevent_openssl.a" ] && | |
| [ -f "$SYSROOT/lib/libjson-c.a" ] && | |
| { [ -f "$SYSROOT/lib/libssl.a" ] || [ -f "$SYSROOT/lib64/libssl.a" ]; } && | |
| { [ -f "$SYSROOT/lib/libcrypto.a" ] || [ -f "$SYSROOT/lib64/libcrypto.a" ]; } | |
| } |
| ./configure --host="$HOST_TRIPLE" --disable-shared --enable-static \ | ||
| --disable-samples --disable-libevent-regress --disable-debug-mode \ | ||
| --prefix="$SYSROOT" \ | ||
| CPPFLAGS="-I$SYSROOT/include" LDFLAGS="-L$SYSROOT/lib" |
There was a problem hiding this comment.
Overriding LDFLAGS and CPPFLAGS as arguments to ./configure for libevent removes the exported LDFLAGS which contains the crucial -arch $ARCH and -mmacosx-version-min=11.0 flags. Since they are already exported, they do not need to be passed as arguments. Removing them ensures that the correct architecture and deployment target flags are preserved during compilation.
| ./configure --host="$HOST_TRIPLE" --disable-shared --enable-static \ | |
| --disable-samples --disable-libevent-regress --disable-debug-mode \ | |
| --prefix="$SYSROOT" \ | |
| CPPFLAGS="-I$SYSROOT/include" LDFLAGS="-L$SYSROOT/lib" | |
| ./configure --host="$HOST_TRIPLE" --disable-shared --enable-static \ | |
| --disable-samples --disable-libevent-regress --disable-debug-mode \ | |
| --prefix="$SYSROOT" |
Parse frp v1 TOML configs directly (tomlc99), send user and raw JWT privilege_key for cloud auth, and forward HTTP request_headers.Referer. INI configs remain supported for backward compatibility. Co-authored-by: Cursor <cursoragent@cursor.com>
TLS wrapping after bufferevent_socket_connect_hostname failed because the socket fd is not available until DNS resolution completes. Co-authored-by: Cursor <cursoragent@cursor.com>
Embedded devices have no system trust store; fall back to the cert bundle path used by edgecam when trustedCaFile is not set in config. Co-authored-by: Cursor <cursoragent@cursor.com>
Reinitializing the control stream with get_next_session_id() could move login to stream 3 while frps expects stream 1. Also register proxies immediately after a successful muxed login. Co-authored-by: Cursor <cursoragent@cursor.com>
Advertise the 6MB stream window on SYN like hashicorp yamux/frpc, read tcp_mux from config on each call instead of caching it, and emit the mux mode at LOG_ERR so release builds show whether control traffic is wrapped. Co-authored-by: Cursor <cursoragent@cursor.com>
Runtime endian detection fixes hton64/ntoh64 when __BYTE_ORDER is wrong under zig cc, which caused frps message length errors on tcp_mux login. Also align yamux window, JWT scopes, and control login timing with frpc. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace std.c.access in build.zig with Zig 0.16 Io API so Release CI does not require libc in the build script. Co-authored-by: Cursor <cursoragent@cursor.com>
frps only applies request header overrides from the "headers" JSON field in NewProxy, not "request_headers". Also treat remote_addr as optional in NewProxyResp for HTTP subdomain proxies. Co-authored-by: Cursor <cursoragent@cursor.com>
Parse requestHeaders.set.Origin from TOML and include it in NewProxy headers so frps can rewrite websocket Origin alongside Referer/Host. Co-authored-by: Cursor <cursoragent@cursor.com>
Stop UPX compression in release artifacts to improve runtime RSS/page sharing on memory-constrained devices, and enable strip + function/data section GC. Co-authored-by: Cursor <cursoragent@cursor.com>
Parse all requestHeaders.set entries from TOML and forward them through NewProxy.headers so websocket-related header overrides work consistently. Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce -Dminimal to exclude bundled plugin/httpd sources and enable it for linux_armv7 release builds to reduce binary size while keeping core proxy paths. Co-authored-by: Cursor <cursoragent@cursor.com>
No description provided.