punchnet-macos/punchnet/Core/VPNManager.swift
2026-01-14 11:13:15 +08:00

101 lines
3.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// VPNManager.swift
// sdlan
//
// Created by on 2024/1/17.
//
import Foundation
import NetworkExtension
import SwiftUI
// vpn
class VPNManager: ObservableObject {
static let shared = VPNManager()
@Published var vpnStatus: VPNStatus = .disconnected
@Published var title: String = "启动"
@Published var color: Color = .white
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) {
NotificationCenter.default.removeObserver(self)
NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: manager.connection, queue: .main) { [unowned self] (notification) -> Void in
// vpn
switch manager.connection.status {
case .invalid, .disconnected, .disconnecting:
self.vpnStatus = .disconnected
self.title = "启动"
self.color = .white
case .connecting, .connected, .reasserting:
self.vpnStatus = .connected
self.title = "停止"
self.color = .red
@unknown default:
self.vpnStatus = .disconnected
self.title = "启动"
self.color = .red
}
}
}
// 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)
}
}