93 lines
2.7 KiB
Swift
93 lines
2.7 KiB
Swift
//
|
||
// VPNManager.swift
|
||
// sdlan
|
||
//
|
||
// Created by 安礼成 on 2024/1/17.
|
||
//
|
||
|
||
import Foundation
|
||
import NetworkExtension
|
||
import SwiftUI
|
||
|
||
// vpn管理类
|
||
class VPNManager {
|
||
static let shared = VPNManager()
|
||
|
||
private var observation: NSKeyValueObservation?
|
||
var vpnStatus: VPNStatus = .disconnected
|
||
|
||
enum VPNStatus {
|
||
case connected
|
||
case disconnected
|
||
}
|
||
|
||
private init() {
|
||
|
||
}
|
||
|
||
// 开启vpn
|
||
func enableVpn(options: [String : NSObject]) async throws {
|
||
NSLog("enable vpn with options: \(options)")
|
||
let manager = try await loadAndCreateProviderManager()
|
||
try await manager.loadFromPreferences()
|
||
self.addVPNStatusObserver(manager)
|
||
|
||
try manager.connection.startVPNTunnel(options: options)
|
||
}
|
||
|
||
// 关闭vpn
|
||
func disableVpn() async throws {
|
||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||
managers.first?.connection.stopVPNTunnel()
|
||
}
|
||
|
||
// MARK: - Private Methods
|
||
|
||
// 监控系统VPN的状态的变化
|
||
private func addVPNStatusObserver(_ manager: NETunnelProviderManager) {
|
||
self.observation = manager.connection.observe(\.status, options: [.initial, .new]) {[weak self] connection, change in
|
||
guard let status = change.newValue else {
|
||
return
|
||
}
|
||
switch status {
|
||
case .invalid, .disconnected, .disconnecting:
|
||
self?.vpnStatus = .disconnected
|
||
case .connecting, .connected, .reasserting:
|
||
self?.vpnStatus = .connected
|
||
@unknown default:
|
||
self?.vpnStatus = .disconnected
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - Private Methods
|
||
|
||
// 加载或者创建相关的配置
|
||
private func loadAndCreateProviderManager() async throws -> NETunnelProviderManager {
|
||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||
|
||
let manager = managers.first ?? NETunnelProviderManager()
|
||
manager.localizedDescription = "punchnetmac"
|
||
manager.isEnabled = true
|
||
|
||
// 设置相关参数,在PacketTunnel中可以用
|
||
let protocolConfiguration = NETunnelProviderProtocol()
|
||
protocolConfiguration.serverAddress = "punchnetmac"
|
||
protocolConfiguration.providerConfiguration = [String:AnyObject]()
|
||
protocolConfiguration.providerBundleIdentifier = "com.jihe.punchnetmac.tun"
|
||
manager.protocolConfiguration = protocolConfiguration
|
||
manager.isOnDemandEnabled = false
|
||
|
||
manager.isEnabled = true
|
||
|
||
try await manager.saveToPreferences()
|
||
|
||
return manager
|
||
}
|
||
|
||
deinit {
|
||
NotificationCenter.default.removeObserver(self)
|
||
}
|
||
|
||
}
|