Posts

Post not yet marked as solved
3 Replies
215 Views
Description: I am experiencing a persistent issue with establishing a VPN connection through a custom app I've developed using Swift. While the VPN configuration appears to be loaded successfully, attempts to connect result in immediate disconnection. Here are the details: Problem Summary: I have implemented a VPN connection using Swift with the NetworkExtension and TunnelKit frameworks. My application successfully loads the VPN configuration, but when attempting to connect, the VPN status quickly changes from connecting to disconnected without ever achieving a stable connection. Manually attempting to toggle the connection from device settings results in the toggle switching off as soon as it is turned on. The console logs indicate a transition from 'connecting' to 'disconnected' almost simultaneously. Technical Details: Here is an overview of the relevant part of the code used for setting up and managing the VPN connection: import TunnelKitOpenVPNCore import NetworkExtension import TunnelKit class VPNManager { static let shared = VPNManager() private var providerManager: NETunnelProviderManager? init() { NotificationCenter.default.addObserver(self, selector: #selector(vpnStatusDidChange), name: .NEVPNStatusDidChange, object: nil) } deinit { NotificationCenter.default.removeObserver(self) } @objc func vpnStatusDidChange(notification: Notification) { guard let status = self.providerManager?.connection.status else { return } switch status { case .connecting: print("VPN is connecting") case .connected: print("VPN is connected") case .disconnecting: print("VPN is disconnecting") case .disconnected: print("VPN is disconnected") case .invalid: print("VPN configuration is invalid") case .reasserting: print("VPN is reasserting") @unknown default: print("Unknown VPN status") } } func loadAndCreateVPNProfile(completion: @escaping (Bool, Error?) -> Void) { self.providerManager = NETunnelProviderManager() guard let ovpnURL = Bundle.main.url(forResource: "client", withExtension: "ovpn"), let ovpnContents = try? String(contentsOf: ovpnURL) else { completion(false, NSError(domain: "VPNManagerError", code: 1, userInfo: [NSLocalizedDescriptionKey: "Configuration file could not be read or found."])) return } // Parsing and configuration logic here... self.providerManager?.saveToPreferences { error in if let error = error { print("Error saving preferences: \(error.localizedDescription)") completion(false, error) } else { print("VPN profile saved successfully.") completion(true, nil) } } } func connect() { self.providerManager?.loadFromPreferences { [weak self] error in guard let strongSelf = self else { print("Reference to VPNManager lost.") return } if let error = error { print("Failed to load preferences: \(error.localizedDescription)") return } do { try strongSelf.providerManager?.connection.startVPNTunnel() } catch NEVPNError.configurationInvalid { print("VPN Configuration is invalid.") } catch NEVPNError.configurationDisabled { print("VPN Configuration is disabled.") } catch let error { print("Unexpected error: \(error.localizedDescription)") } } } func disconnect() { providerManager?.connection.stopVPNTunnel() } }
Posted Last updated
.