Files
Alexandr Stelnykovych 192980b757 splittun: add splittun/enable config option with dynamic enable/disable
- New config.go registers the "splittun/enable" boolean option
- subsystems.ts: change ToggleOptionKey from splittun/use to splittun/enable
- Module Start/Stop replaced with enable()/disable() helpers driven by
  the config option; a callback on EventConfigChange toggles state at runtime
2026-04-30 18:18:53 +03:00

108 lines
2.1 KiB
Go

package splittun
import (
"errors"
"sync/atomic"
"github.com/safing/portmaster/base/config"
"github.com/safing/portmaster/service/mgr"
)
const SplitTunPort = 719
type SplitTunModule struct {
mgr *mgr.Manager
instance instance
}
var (
module *SplitTunModule
shimLoaded atomic.Bool
ready atomic.Bool // ready indicates whether the module is fully initialized and ready to handle requests.
)
func IsReady() bool {
return ready.Load()
}
func New(instance instance) (*SplitTunModule, error) {
if !shimLoaded.CompareAndSwap(false, true) {
return nil, errors.New("only one instance allowed")
}
m := mgr.New("SplitTunModule")
module = &SplitTunModule{
mgr: m,
instance: instance,
}
if err := prep(); err != nil {
return nil, err
}
return module, nil
}
func prep() error {
return prepConfig()
}
func (s *SplitTunModule) Manager() *mgr.Manager {
return s.mgr
}
func (s *SplitTunModule) Start() error {
module.instance.Config().EventConfigChange.AddCallback("splittun enable check", func(wc *mgr.WorkerCtx, t struct{}) (bool, error) {
if cfgOptionSplitTunEnable() {
s.enable()
} else {
s.disable()
}
return false, nil
})
if cfgOptionSplitTunEnable() {
s.enable()
}
return nil
}
func (s *SplitTunModule) Stop() error {
return s.disable()
}
func (s *SplitTunModule) enable() error {
if !ready.CompareAndSwap(false, true) {
return nil // already enabled
}
s.mgr.Info("splittun: enabling Split Tunnel functionality")
err := startProxies(s.mgr)
if err != nil {
s.mgr.Error("splittun: failed to start Split Tunnel proxies: ", err)
ready.Store(false)
}
return err
}
func (s *SplitTunModule) disable() error {
if !ready.CompareAndSwap(true, false) {
return nil // already disabled
}
s.mgr.Info("splittun: disabling Split Tunnel functionality")
clearPendingRequests()
err := stopProxies()
if err != nil {
s.mgr.Error("splittun: failed to stop Split Tunnel proxies: ", err)
}
return err
}
// INSTANCE
type instance interface {
Config() *config.Config
}