feat: Add per-app proxy (Split Tunneling) for desktop platforms
Some checks are pending
CI / run (push) Waiting to run
Some checks are pending
CI / run (push) Waiting to run
- Add PerAppProxyOptions struct with Mode, IncludedApplications, ExcludedApplications - Implement routing rules for include/exclude modes - Include mode: selected apps use VPN, others go direct - Exclude mode: selected apps bypass VPN, others use VPN - Only active on non-Android platforms (Windows, Linux, macOS) - Logging added for debugging per-app routing decisions Part of v1.7.6 Split Tunneling feature
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
dns "github.com/sagernet/sing-dns"
|
||||
)
|
||||
@@ -494,6 +495,53 @@ func setRoutingOptions(options *option.Options, opt *HiddifyOptions) {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Per-App Proxy for Desktop platforms (Windows, Linux, macOS)
|
||||
if runtime.GOOS != "android" {
|
||||
if opt.PerAppProxyOptions.Mode == "include" && len(opt.PerAppProxyOptions.IncludedApplications) > 0 {
|
||||
// Mode: Only selected apps use VPN
|
||||
log.Info("[Per-App] Mode: include - ", len(opt.PerAppProxyOptions.IncludedApplications), " apps will use VPN")
|
||||
|
||||
// Rule 1: Selected apps → VPN
|
||||
routeRules = append(
|
||||
routeRules,
|
||||
option.Rule{
|
||||
Type: C.RuleTypeDefault,
|
||||
DefaultOptions: option.DefaultRule{
|
||||
ProcessName: opt.PerAppProxyOptions.IncludedApplications,
|
||||
Outbound: OutboundSelectTag,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// Rule 2: All other apps → Direct
|
||||
routeRules = append(
|
||||
routeRules,
|
||||
option.Rule{
|
||||
Type: C.RuleTypeDefault,
|
||||
DefaultOptions: option.DefaultRule{
|
||||
Outbound: OutboundDirectTag,
|
||||
},
|
||||
},
|
||||
)
|
||||
} else if opt.PerAppProxyOptions.Mode == "exclude" && len(opt.PerAppProxyOptions.ExcludedApplications) > 0 {
|
||||
// Mode: Excluded apps DON'T use VPN
|
||||
log.Info("[Per-App] Mode: exclude - ", len(opt.PerAppProxyOptions.ExcludedApplications), " apps will bypass VPN")
|
||||
|
||||
// Rule: Excluded apps → Direct (rest goes through VPN by default)
|
||||
routeRules = append(
|
||||
routeRules,
|
||||
option.Rule{
|
||||
Type: C.RuleTypeDefault,
|
||||
DefaultOptions: option.DefaultRule{
|
||||
ProcessName: opt.PerAppProxyOptions.ExcludedApplications,
|
||||
Outbound: OutboundDirectTag,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
routeRules = append(routeRules, option.Rule{
|
||||
Type: C.RuleTypeDefault,
|
||||
DefaultOptions: option.DefaultRule{
|
||||
|
||||
@@ -26,6 +26,13 @@ type HiddifyOptions struct {
|
||||
InboundOptions
|
||||
URLTestOptions
|
||||
RouteOptions
|
||||
PerAppProxyOptions
|
||||
}
|
||||
|
||||
type PerAppProxyOptions struct {
|
||||
Mode string `json:"per-app-proxy-mode"` // "off", "include", "exclude"
|
||||
IncludedApplications []string `json:"included-applications"` // ["chrome.exe", "firefox.exe"]
|
||||
ExcludedApplications []string `json:"excluded-applications"` // ["steam.exe", "uTorrent.exe"]
|
||||
}
|
||||
|
||||
type DNSOptions struct {
|
||||
|
||||
Reference in New Issue
Block a user