feat(macos): KillSwitch L0→L3 — NE includeAllNetworks+enforceRoutes+on-demand
macOS 走原生 NE,strict_route 不生效。补齐断网保护到天花板 L3: VpnChannel.swift - 缓存 killSwitchEnabled(默认 true,与 Dart AppSettings.killSwitch 对齐) - setKillSwitch 落地:存标志,manager 已装配则即时重写 NE 配置+保存 - configureKillSwitch:includeAllNetworks+enforceRoutes(L2 OS 强制、扛崩溃) + NEOnDemandRule 常开(L3)+ excludeLocalNetworks 放行 LAN (enforceRoutes/excludeLocalNetworks 为 macOS 11+ API,#available 守卫) - stop() gotcha:on-demand 常开时先关 isOnDemandEnabled+save 再 stop, 否则手动断开被 OS 立刻拉回 - start() options 带 killSwitch 传扩展 PacketTunnelProvider.swift - startTunnel 读 killSwitch 选项(OS on-demand 自启时 nil→默认 true) - libbox 回调 includeAllNetworks() 返回该值,与 NE 层对齐 docs/killswitch-design.html: 新增 §6.5 实现方案,状态表 macOS L0→L3 验证:xcodebuild CODE_SIGNING_ALLOWED=NO 两 target SwiftCompile 通过; 端到端 fail-closed/on-demand 需真机手测(NE 难单测)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -63,7 +63,12 @@ final class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
LibboxSetup(setup, &setupErr)
|
||||
if let setupErr { throw setupErr }
|
||||
|
||||
let platform = PangolinPlatformInterface(provider: self)
|
||||
// KillSwitch:主 app 经 startVPNTunnel options 下发;OS on-demand 自动拉起时
|
||||
// options 为 nil → 默认 true(on-demand 仅在 killswitch 开时存在)。libbox 平台回调
|
||||
// includeAllNetworks() 据此与 NE 层 includeAllNetworks 对齐,避免装绕行路由。
|
||||
let killSwitch = (options?["killSwitch"] as? NSNumber)?.boolValue ?? true
|
||||
log.info("startTunnel: killSwitch=\(killSwitch, privacy: .public)")
|
||||
let platform = PangolinPlatformInterface(provider: self, includeAllNetworks: killSwitch)
|
||||
self.platform = platform
|
||||
|
||||
var newErr: NSError?
|
||||
@@ -182,9 +187,11 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol
|
||||
private var monitor: NWPathMonitor?
|
||||
private var defaultInterfaceIndex: Int32 = -1
|
||||
private let monitorQueue = DispatchQueue(label: "pangolin.tunnel.pathmonitor")
|
||||
private let includeAllNetworksFlag: Bool
|
||||
|
||||
init(provider: NEPacketTunnelProvider) {
|
||||
init(provider: NEPacketTunnelProvider, includeAllNetworks: Bool) {
|
||||
self.provider = provider
|
||||
self.includeAllNetworksFlag = includeAllNetworks
|
||||
super.init()
|
||||
}
|
||||
|
||||
@@ -269,7 +276,7 @@ final class PangolinPlatformInterface: NSObject, LibboxPlatformInterfaceProtocol
|
||||
// MARK: 其余协议方法(取合理默认)
|
||||
func underNetworkExtension() -> Bool { true }
|
||||
func useProcFS() -> Bool { false }
|
||||
func includeAllNetworks() -> Bool { false }
|
||||
func includeAllNetworks() -> Bool { includeAllNetworksFlag }
|
||||
func clearDNSCache() {}
|
||||
func readWIFIState() -> LibboxWIFIState? { nil }
|
||||
func systemCertificates() -> (any LibboxStringIteratorProtocol)? { nil }
|
||||
|
||||
Reference in New Issue
Block a user