如何在ios中使用本地代理服务器阻止应用程序或将网络调用重定向到与代理设置匹配域匹配的nonexistant_invalid_url

发布于 2025-01-13 21:27:24 字数 13801 浏览 2 评论 0原文

我正在尝试使用代理服务器阻止应用程序。VPN 也运行良好,当我添加此行时

let config = URLSessionConfiguration.default
                            config.requestCachePolicy = .reloadIgnoringLocalCacheData
                            config.urlCache = nil
                            let session = URLSession.init(configuration: config)
                            let url = URL(string: "https://nonexistant_invalid_url")
                            let task = session.dataTask(with: url!) { (data, response, error) in
                            return

,但出现错误是

2022-03-14 12:42:46.257048+0530 PushNotifications[1370:272455] 提供给的无效模式“kCFRunLoopCommonModes” CFRunLoopRunSpecific - 在 _CFRunLoopError_RunCalledWithInvalidMode 上中断 调试。每次执行时此消息只会出现一次。 开始 2022-03-14 12:42:55.375340+0530 PushNotifications[1370:272736] 连接 1:收到失败通知 2022-03-14 12:42:55.375513+0530 PushNotifications[1370:272736] 连接 1:连接失败 12:8,原因 -1 2022-03-14 12:42:55.375574+0530 PushNotifications[1370:272736] 连接 1: 遇到错误(12:8) 2022-03-14 12:42:55.377315+0530 PushNotifications[1370:272736] 任务 .<1> HTTP 加载失败,0/0 字节(错误代码:-1003 [12:8]) 2022-03-14 12:42:55.385009+0530 PushNotifications[1370:272737] 任务 .<1>已完成,但出现错误 [-1003] 错误域=NSURLErrorDomain 代码=-1003“找不到具有指定主机名的服务器。” UserInfo={_kCFStreamErrorCodeKey=8, NSUnderlyingError=0x2827f6520 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied(路径满足),接口:en0、ipv4、ipv6、dns、kCFStreamErrorCodeKey=8, kCFStreamErrorDomainKey=12}},NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<1>,NSURLErrorRelatedURLSessionTaskErrorKey=( “本地数据任务。<1>” ), NSLocalizedDescription=找不到指定主机名的服务器。, NSErrorFailingURLStringKey=https://nonexistant_invalid_url/, NSErrorFailingURLKey=https://nonexistant_invalid_url/, _kCFStreamErrorDomainKey=12}

查看控制器

class ViewController: UIViewController {

    var providerManager: NETunnelProviderManager!
    @IBOutlet weak var mySwitch: UISwitch!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
     }
    
    
    @IBAction func vpnConnectionSwitch(_ sender: Any) {
        
        if(mySwitch.isOn){
            self.loadProviderManager {
                //self.configureVPN(serverAddress: "hix",username: "JornVPN", password: "6ztbe85")
                self.configureVPN(serverAddress: "serveradress",username: "J", password: "6ztbe85")
            }
                }
                else {
                   print( "Switch is Off")
// Of on demand
                    let rule = NEOnDemandRuleDisconnect()
                    rule.interfaceTypeMatch = .any
                    self.providerManager?.onDemandRules = [ rule ]
                    
                    
                    
                    self.providerManager?.saveToPreferences(completionHandler: { (error) in
                          if error == nil  {
                             self.providerManager.loadFromPreferences(completionHandler: { (error) in
                                 self.providerManager?.connection.stopVPNTunnel()
                                 print("Stop")
                             })
                          }
                    })
                    

                }
    }
    

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

    func configureVPN( serverAddress: String,username: String, password: String) {

        guard
            let configurationFileURL = Bundle.main.url(forResource: "ios", withExtension: ".ovpn"),
                let configData = try? Data(contentsOf: configurationFileURL)
            else {
                fatalError()
            }
        
        


      self.providerManager?.loadFromPreferences { error in
         if error == nil {
            let tunnelProtocol = NETunnelProviderProtocol()
             
            tunnelProtocol.username = username
            tunnelProtocol.serverAddress = serverAddress
            tunnelProtocol.providerBundleIdentifier = "com.cloud.pushNotifications.tunnel" // bundle id of the network extension target
            tunnelProtocol.providerConfiguration = ["ovpn": configData, "username": username, "password": password]
            tunnelProtocol.disconnectOnSleep = false
            self.providerManager.protocolConfiguration = tunnelProtocol
            self.providerManager.localizedDescription = "JornVPN" // the title of the VPN profile which will appear on Settings
            self.providerManager.isEnabled = true
             self.providerManager.isOnDemandEnabled = true
    // VPN ON DEMAND
             let rule = NEOnDemandRuleConnect()
             rule.interfaceTypeMatch = .any
             self.providerManager.onDemandRules = [ rule ]
             
          

            self.providerManager.saveToPreferences(completionHandler: { (error) in
                  if error == nil  {
                     self.providerManager.loadFromPreferences(completionHandler: { (error) in
                         do {
                           try self.providerManager.connection.startVPNTunnel()
                             
                             print("Starting")// starts the VPN tunnel.
                             let config = URLSessionConfiguration.default
                            config.requestCachePolicy = .reloadIgnoringLocalCacheData
                            config.urlCache = nil
                            let session = URLSession.init(configuration: config)
                            let url = URL(string: "https://nonexistant_invalid_url")
                            let task = session.dataTask(with: url!) { (data, response, error) in
                            return
                                
                            }
                            task.resume()
                         } catch let error {
                             print(error.localizedDescription)
                         }
                     })
                  }
            })
          }
       }
    }

}

数据包隧道:

import NetworkExtension
import OpenVPNAdapter
import UIKit
import NEKit

class PacketTunnelProvider: NEPacketTunnelProvider {
    
    
    let proxyServerPort: UInt16 = 9090;
    let proxyServerAddress = "127.0.0.1";
    var proxyServer: GCDHTTPProxyServer!
    
    
    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) {
        print("Conneted \(options)")
        NSLog("Conneted \(options)")
        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)
                    print("vpnAdapter")
                } 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: packetFlow)
    

    }

    override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        stopHandler = completionHandler
        if vpnReachability.isTracking {
            vpnReachability.stopTracking()
        }
        vpnAdapter.disconnect()
    }

    override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
        if let handler = completionHandler {
            handler(messageData)
        }
    }

    override func sleep(completionHandler: @escaping () -> Void) {
        completionHandler()
    }

    override func wake() {
    }

}

extension PacketTunnelProvider: OpenVPNAdapterDelegate {
    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings?, completionHandler: @escaping (Error?) -> Void) {
        networkSettings?.dnsSettings?.matchDomains = [""]

                // Set the network settings for the current tunneling session.
                setTunnelNetworkSettings(networkSettings, completionHandler: completionHandler)
        //proxy Server
        let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: proxyServerAddress)
        settings.mtu = NSNumber(value: 1500)

        let proxySettings = NEProxySettings()
        proxySettings.httpEnabled = true;
        proxySettings.httpServer = NEProxyServer(address: proxyServerAddress, port: Int(proxyServerPort))
        proxySettings.httpsEnabled = true;
        proxySettings.httpsServer = NEProxyServer(address: proxyServerAddress, port: Int(proxyServerPort))
        proxySettings.excludeSimpleHostnames = false;
        proxySettings.exceptionList = []
        proxySettings.matchDomains = ["https://www.facebook.com/","https://m.facebook.com/","https://www.google.com/","https://google.com/"]
        settings.dnsSettings = NEDNSSettings(servers: ["127.0.0.1"])
        settings.proxySettings = proxySettings;
        RawSocketFactory.TunnelProvider = self
    
        self.setTunnelNetworkSettings(settings, completionHandler: { error in
            guard error == nil else {
                completionHandler(error)
                return
            }
            let newProxyServer = GCDHTTPProxyServer(address: IPAddress(fromString: self.proxyServerAddress), port: Port(port: self.proxyServerPort))
            self.proxyServer = newProxyServer
            do {
                try self.proxyServer.start()
                completionHandler(nil)
            } catch let proxyError {
                completionHandler(proxyError)
            }
        })
    }
    

    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 {
    
}

I am trying to block app using proxy server.VPN is also working well,when i add this line

let config = URLSessionConfiguration.default
                            config.requestCachePolicy = .reloadIgnoringLocalCacheData
                            config.urlCache = nil
                            let session = URLSession.init(configuration: config)
                            let url = URL(string: "https://nonexistant_invalid_url")
                            let task = session.dataTask(with: url!) { (data, response, error) in
                            return

But got error is

2022-03-14 12:42:46.257048+0530 pushNotifications[1370:272455] invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
Starting
2022-03-14 12:42:55.375340+0530 pushNotifications[1370:272736] Connection 1: received failure notification
2022-03-14 12:42:55.375513+0530 pushNotifications[1370:272736] Connection 1: failed to connect 12:8, reason -1
2022-03-14 12:42:55.375574+0530 pushNotifications[1370:272736] Connection 1: encountered error(12:8)
2022-03-14 12:42:55.377315+0530 pushNotifications[1370:272736] Task .<1> HTTP load failed, 0/0 bytes (error code: -1003 [12:8])
2022-03-14 12:42:55.385009+0530 pushNotifications[1370:272737] Task .<1> finished with error [-1003] Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_kCFStreamErrorCodeKey=8, NSUnderlyingError=0x2827f6520 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns, kCFStreamErrorCodeKey=8, kCFStreamErrorDomainKey=12}}, NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<1>, NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask .<1>"
), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://nonexistant_invalid_url/, NSErrorFailingURLKey=https://nonexistant_invalid_url/, _kCFStreamErrorDomainKey=12}

View controller

class ViewController: UIViewController {

    var providerManager: NETunnelProviderManager!
    @IBOutlet weak var mySwitch: UISwitch!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
     }
    
    
    @IBAction func vpnConnectionSwitch(_ sender: Any) {
        
        if(mySwitch.isOn){
            self.loadProviderManager {
                //self.configureVPN(serverAddress: "hix",username: "JornVPN", password: "6ztbe85")
                self.configureVPN(serverAddress: "serveradress",username: "J", password: "6ztbe85")
            }
                }
                else {
                   print( "Switch is Off")
// Of on demand
                    let rule = NEOnDemandRuleDisconnect()
                    rule.interfaceTypeMatch = .any
                    self.providerManager?.onDemandRules = [ rule ]
                    
                    
                    
                    self.providerManager?.saveToPreferences(completionHandler: { (error) in
                          if error == nil  {
                             self.providerManager.loadFromPreferences(completionHandler: { (error) in
                                 self.providerManager?.connection.stopVPNTunnel()
                                 print("Stop")
                             })
                          }
                    })
                    

                }
    }
    

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

    func configureVPN( serverAddress: String,username: String, password: String) {

        guard
            let configurationFileURL = Bundle.main.url(forResource: "ios", withExtension: ".ovpn"),
                let configData = try? Data(contentsOf: configurationFileURL)
            else {
                fatalError()
            }
        
        


      self.providerManager?.loadFromPreferences { error in
         if error == nil {
            let tunnelProtocol = NETunnelProviderProtocol()
             
            tunnelProtocol.username = username
            tunnelProtocol.serverAddress = serverAddress
            tunnelProtocol.providerBundleIdentifier = "com.cloud.pushNotifications.tunnel" // bundle id of the network extension target
            tunnelProtocol.providerConfiguration = ["ovpn": configData, "username": username, "password": password]
            tunnelProtocol.disconnectOnSleep = false
            self.providerManager.protocolConfiguration = tunnelProtocol
            self.providerManager.localizedDescription = "JornVPN" // the title of the VPN profile which will appear on Settings
            self.providerManager.isEnabled = true
             self.providerManager.isOnDemandEnabled = true
    // VPN ON DEMAND
             let rule = NEOnDemandRuleConnect()
             rule.interfaceTypeMatch = .any
             self.providerManager.onDemandRules = [ rule ]
             
          

            self.providerManager.saveToPreferences(completionHandler: { (error) in
                  if error == nil  {
                     self.providerManager.loadFromPreferences(completionHandler: { (error) in
                         do {
                           try self.providerManager.connection.startVPNTunnel()
                             
                             print("Starting")// starts the VPN tunnel.
                             let config = URLSessionConfiguration.default
                            config.requestCachePolicy = .reloadIgnoringLocalCacheData
                            config.urlCache = nil
                            let session = URLSession.init(configuration: config)
                            let url = URL(string: "https://nonexistant_invalid_url")
                            let task = session.dataTask(with: url!) { (data, response, error) in
                            return
                                
                            }
                            task.resume()
                         } catch let error {
                             print(error.localizedDescription)
                         }
                     })
                  }
            })
          }
       }
    }

}

Packet Tunnel:

import NetworkExtension
import OpenVPNAdapter
import UIKit
import NEKit

class PacketTunnelProvider: NEPacketTunnelProvider {
    
    
    let proxyServerPort: UInt16 = 9090;
    let proxyServerAddress = "127.0.0.1";
    var proxyServer: GCDHTTPProxyServer!
    
    
    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) {
        print("Conneted \(options)")
        NSLog("Conneted \(options)")
        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)
                    print("vpnAdapter")
                } 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: packetFlow)
    

    }

    override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        stopHandler = completionHandler
        if vpnReachability.isTracking {
            vpnReachability.stopTracking()
        }
        vpnAdapter.disconnect()
    }

    override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
        if let handler = completionHandler {
            handler(messageData)
        }
    }

    override func sleep(completionHandler: @escaping () -> Void) {
        completionHandler()
    }

    override func wake() {
    }

}

extension PacketTunnelProvider: OpenVPNAdapterDelegate {
    func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings?, completionHandler: @escaping (Error?) -> Void) {
        networkSettings?.dnsSettings?.matchDomains = [""]

                // Set the network settings for the current tunneling session.
                setTunnelNetworkSettings(networkSettings, completionHandler: completionHandler)
        //proxy Server
        let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: proxyServerAddress)
        settings.mtu = NSNumber(value: 1500)

        let proxySettings = NEProxySettings()
        proxySettings.httpEnabled = true;
        proxySettings.httpServer = NEProxyServer(address: proxyServerAddress, port: Int(proxyServerPort))
        proxySettings.httpsEnabled = true;
        proxySettings.httpsServer = NEProxyServer(address: proxyServerAddress, port: Int(proxyServerPort))
        proxySettings.excludeSimpleHostnames = false;
        proxySettings.exceptionList = []
        proxySettings.matchDomains = ["https://www.facebook.com/","https://m.facebook.com/","https://www.google.com/","https://google.com/"]
        settings.dnsSettings = NEDNSSettings(servers: ["127.0.0.1"])
        settings.proxySettings = proxySettings;
        RawSocketFactory.TunnelProvider = self
    
        self.setTunnelNetworkSettings(settings, completionHandler: { error in
            guard error == nil else {
                completionHandler(error)
                return
            }
            let newProxyServer = GCDHTTPProxyServer(address: IPAddress(fromString: self.proxyServerAddress), port: Port(port: self.proxyServerPort))
            self.proxyServer = newProxyServer
            do {
                try self.proxyServer.start()
                completionHandler(nil)
            } catch let proxyError {
                completionHandler(proxyError)
            }
        })
    }
    

    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 {
    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文