From 09715fabd335613a511f594757a95b3e9dffa5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Papp?= Date: Tue, 8 Sep 2026 20:43:40 +0200 Subject: [PATCH] [client] Keep file drop out of the wasm build File drop needs a local filesystem to deliver into and a receiver it can bind, so wasm supports neither and never sets a manager. The code still linked in, because the Engine reached filedrop through an untagged field, and with it the net/http server and client. That put the wasm binary 0.97MiB over the 60MB budget, on a main that had 0.34MiB of headroom left. Split the feature on the js tag: the logic file and the OS dialer become !js, a js no-op carries the start, stop and rebind entry points the engine calls on its lifecycle paths, and a build-tagged alias types the manager so engine.go and connect.go stay untagged and lose the import. iOS keeps the full feature: the logic file is !js and the iOS dialer stays behind the ios tag. Drops the wasm binary to 59.89MiB, with no filedrop symbol left in it. --- client/internal/connect.go | 5 ++--- client/internal/engine.go | 5 ++--- client/internal/engine_filedrop.go | 2 ++ client/internal/engine_filedrop_dial.go | 2 +- client/internal/engine_filedrop_js.go | 14 ++++++++++++++ client/internal/engine_filedrop_type.go | 7 +++++++ client/internal/engine_filedrop_type_js.go | 9 +++++++++ 7 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 client/internal/engine_filedrop_js.go create mode 100644 client/internal/engine_filedrop_type.go create mode 100644 client/internal/engine_filedrop_type_js.go diff --git a/client/internal/connect.go b/client/internal/connect.go index c0b1a1082..6770a49a8 100644 --- a/client/internal/connect.go +++ b/client/internal/connect.go @@ -27,7 +27,6 @@ import ( "github.com/netbirdio/netbird/client/iface/device" "github.com/netbirdio/netbird/client/iface/netstack" "github.com/netbirdio/netbird/client/internal/dns" - "github.com/netbirdio/netbird/client/internal/filedrop" "github.com/netbirdio/netbird/client/internal/lazyconn" "github.com/netbirdio/netbird/client/internal/listener" "github.com/netbirdio/netbird/client/internal/metrics" @@ -70,7 +69,7 @@ type ConnectClient struct { engineMutex sync.Mutex clientMetrics *metrics.ClientMetrics updateManager *updater.Manager - fileDropManager *filedrop.Manager + fileDropManager fileDropManager persistSyncResponse bool @@ -117,7 +116,7 @@ func (c *ConnectClient) SetUpdateManager(um *updater.Manager) { // SetFileDropManager hands the engine the active profile's file drop manager, so // the transfer receiver starts and stops with the tunnel. Must be set before Run. -func (c *ConnectClient) SetFileDropManager(m *filedrop.Manager) { +func (c *ConnectClient) SetFileDropManager(m fileDropManager) { c.fileDropManager = m } diff --git a/client/internal/engine.go b/client/internal/engine.go index d9fe42059..a587b5f2d 100644 --- a/client/internal/engine.go +++ b/client/internal/engine.go @@ -40,7 +40,6 @@ import ( dnsconfig "github.com/netbirdio/netbird/client/internal/dns/config" "github.com/netbirdio/netbird/client/internal/dnsfwd" "github.com/netbirdio/netbird/client/internal/expose" - "github.com/netbirdio/netbird/client/internal/filedrop" "github.com/netbirdio/netbird/client/internal/ingressgw" "github.com/netbirdio/netbird/client/internal/lazyconn" "github.com/netbirdio/netbird/client/internal/metrics" @@ -191,7 +190,7 @@ type EngineServices struct { UpdateManager *updater.Manager ClientMetrics *metrics.ClientMetrics MetricsCtx context.Context - FileDrop *filedrop.Manager + FileDrop fileDropManager // NetMgr gates the reconnection loops on OS-reported network // availability; nil disables gating. NetMgr *netevents.Manager @@ -254,7 +253,7 @@ type Engine struct { sshServer sshServer - fileDrop *filedrop.Manager + fileDrop fileDropManager fileDropRunning bool fileDropPort uint16 overlayWait overlayWaiter //nolint:unused // only read by the iOS overlay wait diff --git a/client/internal/engine_filedrop.go b/client/internal/engine_filedrop.go index 229d86347..12bda3c78 100644 --- a/client/internal/engine_filedrop.go +++ b/client/internal/engine_filedrop.go @@ -1,3 +1,5 @@ +//go:build !js + package internal import ( diff --git a/client/internal/engine_filedrop_dial.go b/client/internal/engine_filedrop_dial.go index 175440b23..a798249f8 100644 --- a/client/internal/engine_filedrop_dial.go +++ b/client/internal/engine_filedrop_dial.go @@ -1,4 +1,4 @@ -//go:build !ios +//go:build !ios && !js package internal diff --git a/client/internal/engine_filedrop_js.go b/client/internal/engine_filedrop_js.go new file mode 100644 index 000000000..8049b8b28 --- /dev/null +++ b/client/internal/engine_filedrop_js.go @@ -0,0 +1,14 @@ +//go:build js + +package internal + +// File drop is not supported on wasm: there is no local filesystem to deliver +// into and no way to bind a receiver. The engine still calls these on the +// start, stop and overlay rebind paths, so they exist as no-ops and keep the +// filedrop package out of the wasm binary. + +func (e *Engine) startFileDrop() {} + +func (e *Engine) stopFileDrop() {} + +func (e *Engine) restartFileDrop() error { return nil } diff --git a/client/internal/engine_filedrop_type.go b/client/internal/engine_filedrop_type.go new file mode 100644 index 000000000..f5742a0e6 --- /dev/null +++ b/client/internal/engine_filedrop_type.go @@ -0,0 +1,7 @@ +//go:build !js + +package internal + +import "github.com/netbirdio/netbird/client/internal/filedrop" + +type fileDropManager = *filedrop.Manager diff --git a/client/internal/engine_filedrop_type_js.go b/client/internal/engine_filedrop_type_js.go new file mode 100644 index 000000000..a6208f862 --- /dev/null +++ b/client/internal/engine_filedrop_type_js.go @@ -0,0 +1,9 @@ +//go:build js + +package internal + +// fileDropManager keeps the engine and ConnectClient fields typed on wasm, +// where file drop is not supported and the manager is always nil. Aliasing a +// pointer keeps the nil guards and stays out of the filedrop package, so its +// HTTP server and client never reach the wasm binary. +type fileDropManager = *struct{}