mirror of
https://github.com/safing/portmaster
synced 2026-04-28 03:20:31 +00:00
Implement initial proof-of-concept for split tunnel functionality on Windows, allowing applications to route traffic through a designated network interface while bypassing default system routing. Features: - Split tunnel module with TCP/UDP proxy infrastructure - Firewall integration with split tunnel verdict handling - SplitTunneling context attached to connections - Configuration options: enable toggle, interface selection, and policy rules - UI display of split tunnel connection details in connection info panel - Subsystem configuration for user-level access Windows-specific implementation: - Uses proxy-based interface routing on Windows - Automatic or manual interface detection and binding - Support for IPv4 and IPv6 traffic Note: Linux implementation is under development. SPN takes precedence over split tunnel when both are enabled, ensuring SPN connections bypass this feature.
68 lines
1.2 KiB
Go
68 lines
1.2 KiB
Go
package splittun
|
|
|
|
import (
|
|
"errors"
|
|
"sync/atomic"
|
|
|
|
"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 nil
|
|
}
|
|
|
|
func (s *SplitTunModule) Manager() *mgr.Manager {
|
|
return s.mgr
|
|
}
|
|
|
|
func (s *SplitTunModule) Start() error {
|
|
err := startProxies(s.mgr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ready.Store(true)
|
|
return nil
|
|
}
|
|
|
|
func (s *SplitTunModule) Stop() error {
|
|
ready.Store(false)
|
|
return stopProxies()
|
|
}
|
|
|
|
// INSTANCE
|
|
type instance interface{}
|