【问题标题】:Network Extension didn't called网络扩展未调用
【发布时间】:2021-08-22 04:17:33
【问题描述】:

我正在尝试使用 OpenVPNAdapter 连接 VPN,但控制器未调用 PacketTunnelProvider。我在这里错过了什么?

Controller.swift

import NetworkExtension

var providerManager: NETunnelProviderManager!
var provider = PacketTunnelProvider()

override func viewDidLoad() {
    super.viewDidLoad()
    self.loadProviderManager {
        self.configureVPN(response: self.arrResponse[0], serverAddress: self.arrResponse[0].iP, username: "vpn", password: "vpn")
    }
}

func loadProviderManager(completion:@escaping () -> Void) {
    NETunnelProviderManager.loadAllFromPreferences { (managers, error) in
        if error == nil {
            self.providerManager = managers?.first ?? NETunnelProviderManager()
            completion()
        }
    }
}

func configureVPN(response:Response,serverAddress: String, username: String, password: String) {
    
    let data = Data(base64Encoded:response.openVPNConfigDataBase64, options: .ignoreUnknownCharacters)
    print(data!)
    let decodedString = String(data: data!, encoding: .utf8)!
    print(decodedString)
    self.providerManager?.loadFromPreferences { error in
        if error == nil {
            let tunnelProtocol = NETunnelProviderProtocol()
            tunnelProtocol.username = username
            tunnelProtocol.serverAddress = serverAddress
            tunnelProtocol.providerBundleIdentifier = "***.*****.********.***********.********"
            tunnelProtocol.providerConfiguration = ["ovpn": data!, "username": username, "password": password]
            tunnelProtocol.disconnectOnSleep = false
            self.providerManager.protocolConfiguration = tunnelProtocol
            self.providerManager.localizedDescription = "SMVPN"
            self.providerManager.isEnabled = true
            self.providerManager.saveToPreferences(completionHandler: { (error) in
                if error == nil  {
                    self.providerManager.loadFromPreferences(completionHandler: { (error) in
                        if error == nil {
                            self.provider.startTunnel(options: nil) { error in //this  called here not in network extension
                                if error != nil {
                                    print(error!)
                                }else {
                                    
                                }
                            }
                        }else {
                            print(error!.localizedDescription)
                        }
                    })
                }
            })
        }
    }
}

项目授权

PacketTunnelProvider.swift

import NetworkExtension
import OpenVPNAdapter

class PacketTunnelProvider: NEPacketTunnelProvider {
    
    var startHandler: ((Error?) -> Void)?
    var stopHandler: (() -> Void)?
    var vpnReachability = OpenVPNReachability()

    var configuration: OpenVPNConfiguration!
    var properties: OpenVPNConfigurationEvaluation!
    var UDPSession: NWUDPSession!
    var TCPConnection: NWTCPConnection!

    lazy var vpnAdapter: OpenVPNAdapter = {
        let adapter = OpenVPNAdapter()
        adapter.delegate = self
        return adapter
    }()

    override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
        // Add code here to start the process of connecting the tunnel.
        guard
            let protocolConfiguration = protocolConfiguration as? NETunnelProviderProtocol,
            let providerConfiguration = protocolConfiguration.providerConfiguration
            else {
                fatalError()
        }
        guard let ovpnFileContent: Data = providerConfiguration["ovpn"] as? Data else { return }
            let configuration = OpenVPNConfiguration()
            configuration.fileContent = ovpnFileContent
            do {
                properties = try vpnAdapter.apply(configuration: configuration)
            } catch {
                completionHandler(error)
                return
            }
        configuration.tunPersist = true

        if !properties.autologin {
            if let username: String = providerConfiguration["username"] as? String, let password: String = providerConfiguration["password"] as? String {
                let credentials = OpenVPNCredentials()
                credentials.username = username
                credentials.password = password
                do {
                    try vpnAdapter.provide(credentials: credentials)
                } catch {
                    completionHandler(error)
                    return
                }
            }
        }

        vpnReachability.startTracking { [weak self] status in
            guard status != .notReachable else { return }
            self?.vpnAdapter.reconnect(afterTimeInterval: 5)
        }

        startHandler = completionHandler
        vpnAdapter.connect(using: self)
    }
    
    override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        // Add code here to start the process of stopping the tunnel.
        stopHandler = completionHandler
        if vpnReachability.isTracking {
            vpnReachability.stopTracking()
        }
        vpnAdapter.disconnect()
        completionHandler()
    }
    
    override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
        // Add code here to handle the message.
        if let handler = completionHandler {
            handler(messageData)
        }
    }
    
    override func sleep(completionHandler: @escaping () -> Void) {
        // Add code here to get ready to sleep.
        completionHandler()
    }
    
    override func wake() {
        // Add code here to wake up.
    }
}

extension PacketTunnelProvider: OpenVPNAdapterDelegate {
    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings?, completionHandler: @escaping (Error?) -> Void) {
        setTunnelNetworkSettings(networkSettings) { (error) in
            completionHandler(error == nil ? self.packetFlow as? Error : nil)
        }
    }


    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings?, completionHandler: @escaping (OpenVPNAdapterPacketFlow?) -> Void) {
        setTunnelNetworkSettings(networkSettings) { (error) in
            completionHandler(error == nil ? self.packetFlow : nil)
        }
    }

    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, handleEvent event: OpenVPNAdapterEvent, message: String?) {
        switch event {
        case .connected:
            if reasserting {
                reasserting = false
            }
            guard let startHandler = startHandler else { return }
            startHandler(nil)
            self.startHandler = nil
        case .disconnected:
            guard let stopHandler = stopHandler else { return }
            if vpnReachability.isTracking {
                vpnReachability.stopTracking()
            }
            stopHandler()
            self.stopHandler = nil
        case .reconnecting:
            reasserting = true
        default:
            break
        }
    }

    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, handleError error: Error) {
        guard let fatal = (error as NSError).userInfo[OpenVPNAdapterErrorFatalKey] as? Bool, fatal == true else {
            return
        }
        NSLog("Error: \(error.localizedDescription)")
        NSLog("Connection Info: \(vpnAdapter.connectionInformation.debugDescription)")
        if vpnReachability.isTracking {
            vpnReachability.stopTracking()
        }

        if let startHandler = startHandler {
            startHandler(error)
            self.startHandler = nil
        } else {
            cancelTunnelWithError(error)
        }
    }

    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, handleLogMessage logMessage: String) {
        NSLog("Log: \(logMessage)")
    }

}

extension PacketTunnelProvider: OpenVPNAdapterPacketFlow {
    func readPackets(completionHandler: @escaping ([Data], [NSNumber]) -> Void) {
        packetFlow.readPackets(completionHandler: completionHandler)
    }

    func writePackets(_ packets: [Data], withProtocols protocols: [NSNumber]) -> Bool {
        return packetFlow.writePackets(packets, withProtocols: protocols)
    }

}

extension NEPacketTunnelFlow: OpenVPNAdapterPacketFlow {}

扩展授权

self.provider.startTunnel(options: nil) { error in // 此处调用,不在网络扩展中

这个方法是从控制器调用的,但没有在网络扩展中被调用。

我发布了我所有的代码,所以如果我遗漏了什么,请告诉我。任何帮助表示赞赏。

我发现了这个问题,但我还没有弄清楚。 PacketTunnelProvider network extension not called Swift 3

【问题讨论】:

  • 您发布的代码可能对上下文有用,但我很难准确指出您遇到问题的行。缩小您提供的代码范围可能会有所帮助,或者查明哪一行没有像您预期的那样工作。
  • @BRoyDawson 我尝试使用类对象调用网络扩展,正如我在这里提到的var provider = PacketTunnelProvider() 并尝试在控制器self.provider.startTunnel(options: nil) { error in //this called here not in network extension 中使用此对象启动隧道。而不是我在这里做错了什么。所以,我在下面发布了一个答案,请检查一下。
  • @BRoyDawson 我只是想告诉self.provider.startTunnel(options: nil) 这个方法应该叫networkextension private tunnle 但它不会。

标签: ios swift networkextension


【解决方案1】:

您没有提到任何关于如何测试网络扩展的内容。在运行项目进行调试之前,您应该附加一个网络扩展进程。那么只有网络扩展方法会触发调试。

【讨论】:

  • 表示我需要附加调试器进程。对吗?
  • 首先点击debug -> attach a process by name,输入你的扩展名。在调试导航器中检查进程是否正在等待连接。如果它在等待,那么你运行你的主项目
  • 好的,我会尝试并告诉你。谢谢。
  • 我在那里找不到我的应用名称。
  • 您需要先运行您的应用程序才能显示在该菜单中
【解决方案2】:

最后我发现我的错误是我试图调用网络扩展但它永远不会调用。所以我直接打电话给NETunnelProviderManager,它会工作的。

self.providerManager.loadFromPreferences(completionHandler: { (error) in
                            if error == nil {
                                do {
                                    try self.providerManager.connection.startVPNTunnel()

                                } catch let error {
                                    print(error.localizedDescription)
                                }
                            }else {
                                print(error!.localizedDescription)
                            }
                        })

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多