c84b6ea7da
合并冲突补救:原分支从 merge base 7871512 分叉,仅修改 client/ 目录,
与 main 新增的 server/(apierr/idgen/CONVENTIONS.md) 完全不重叠,
无真实文件冲突,手动应用 feature branch 的全部 client/ 改动。
client 侧新增:
- lib/bridge/vpn_bridge.dart — Dart↔原生通道契约(冻结)
- lib/bridge/vpn_bridge_mock.dart — 假内核,UI 联调用
- lib/bridge/kernel_process.dart — 桌面子进程管理接口
- ios/PacketTunnel/{Info.plist,PacketTunnelProvider.swift} — NEPacketTunnel 骨架
- ios/Runner/VpnManager.swift — NETunnelProviderManager 封装
- android/.../PangolinVpnService.kt — VpnService 骨架
- android/.../VpnEventBus.kt — Application 级状态总线
- test/bridge/vpn_bridge_mock_test.dart — 桥接层单元测试
client 侧修改:
- android/.../MainActivity.kt — 注册三通道(MethodChannel + 2×EventChannel)
- android/.../AndroidManifest.xml — 声明 FOREGROUND_SERVICE + PangolinVpnService
- ios/Runner/AppDelegate.swift — 注册通道 + VpnManager 初始化
- ios/Runner/Info.plist — 新增 NSVPNUsageDescription
- ios/Runner.xcodeproj/project.pbxproj — 添加 PacketTunnel extension target
- lib/widgets/connect_button.dart — VpnStatus 迁移到 bridge/vpn_bridge.dart
- lib/widgets/home_shell.dart — error 状态 UI 分支补全
79 lines
2.6 KiB
Swift
79 lines
2.6 KiB
Swift
// PacketTunnelProvider.swift — Packet Tunnel Extension 骨架
|
||
//
|
||
// Target: PacketTunnel (NEPacketTunnelProvider extension)
|
||
// Bundle: com.pangolin.pangolinVpn.PacketTunnel
|
||
//
|
||
// 生命周期占位日志;实际 TUN 隧道建立与 libbox 接线由 11F 完成。
|
||
//
|
||
// 与主 App 通信:
|
||
// 主 App → extension: NETunnelProviderSession.sendProviderMessage(_:responseHandler:)
|
||
// extension → 主 App: 通过 NEProvider.cancelTunnelWithError 或 NETunnelProviderSession 回调
|
||
//
|
||
// TODO(11F): 在 startTunnel 中初始化 sing-box/libbox TUN 模式内核。
|
||
|
||
import NetworkExtension
|
||
import os.log
|
||
|
||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||
|
||
private let log = OSLog(
|
||
subsystem: "com.pangolin.pangolinVpn.PacketTunnel",
|
||
category: "VPN"
|
||
)
|
||
|
||
// ── NEPacketTunnelProvider 生命周期 ──────────────────────────
|
||
|
||
override func startTunnel(
|
||
options: [String: NSObject]?,
|
||
completionHandler: @escaping (Error?) -> Void
|
||
) {
|
||
os_log(
|
||
"PacketTunnelProvider: startTunnel — options keys: %{public}@",
|
||
log: log, type: .info,
|
||
(options?.keys.joined(separator: ", ") ?? "(none)")
|
||
)
|
||
// TODO(11F): 解析 options["config"] → 写入临时配置文件
|
||
// → 调用 libbox/sing-box TUN 启动 API
|
||
// → 配置 packetFlow / setTunnelNetworkSettings
|
||
completionHandler(nil)
|
||
}
|
||
|
||
override func stopTunnel(
|
||
with reason: NEProviderStopReason,
|
||
completionHandler: @escaping () -> Void
|
||
) {
|
||
os_log(
|
||
"PacketTunnelProvider: stopTunnel — reason=%d",
|
||
log: log, type: .info,
|
||
reason.rawValue
|
||
)
|
||
// TODO(11F): 停止 sing-box 内核 → 关闭 TUN fd
|
||
completionHandler()
|
||
}
|
||
|
||
override func handleAppMessage(
|
||
_ messageData: Data,
|
||
completionHandler: ((Data?) -> Void)?
|
||
) {
|
||
os_log(
|
||
"PacketTunnelProvider: handleAppMessage — %d bytes",
|
||
log: log, type: .debug,
|
||
messageData.count
|
||
)
|
||
// TODO(11F): 解码 messageData(JSON 或 protobuf)→ 路由到内核命令
|
||
// 如 selectOutbound / getStats 等
|
||
completionHandler?(nil)
|
||
}
|
||
|
||
override func sleep(completionHandler: @escaping () -> Void) {
|
||
os_log("PacketTunnelProvider: sleep", log: log, type: .debug)
|
||
// TODO(11F): 挂起内核流量处理
|
||
completionHandler()
|
||
}
|
||
|
||
override func wake() {
|
||
os_log("PacketTunnelProvider: wake", log: log, type: .debug)
|
||
// TODO(11F): 恢复内核流量处理
|
||
}
|
||
}
|