I am trying to set a custom DNS server to all networking calls on a supervised device, using the NEDNSProxyProvider
in Network Extension. I have been able to monitor the network calls and am able to receive data packets in the handleNewFlow(_ flow: NEAppProxyFlow)
method, but I am not sure on how to send the data packets to my custom DNS server, to resolve them
Currently my NEDNSProxyProvider class is set up like this:
import NetworkExtension
class DNSProxyProvider: NEDNSProxyProvider {
private var proxyFlow: NEAppProxyUDPFlow?
override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) {
NSLog("DNSProxyProvider: startProxy")
completionHandler(nil)
}
override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
NSLog("DNSProxyProvider: stopProxy")
completionHandler()
}
override func sleep(completionHandler: @escaping () -> Void) {
NSLog("DNSProxyProvider: sleep")
completionHandler()
}
override func wake() {
NSLog("DNSProxyProvider: wake")
}
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
NSLog("DNSProxyProvider: handleFlow")
if let udpFlow = flow as? NEAppProxyUDPFlow {
let localHost = (udpFlow.localEndpoint as! NWHostEndpoint).hostname
let localPort = (udpFlow.localEndpoint as! NWHostEndpoint).port
NSLog("DNSProxyProvider UDP HOST : \(localHost)")
NSLog("DNSProxyProvider UDP PORT : \(localPort)")
proxyFlow = udpFlow
open()
}
return true
}
private func open() {
guard let flow = proxyFlow else { return }
guard let endPoint = flow.localEndpoint as? NWHostEndpoint else { return }
flow.open(withLocalEndpoint: endPoint) { (error) in
if (error != nil) {
NSLog("DNSProxyProvider UDP Open flow Error : \(error.debugDescription)")
} else {
NSLog("DNSProxyProvider UDP Open flow Success")
self.handleData()
}
}
}
private func handleData() {
proxyFlow?.readDatagrams(completionHandler: { (data, endpoint, error) in
if let error = error {
NSLog("DNSProxyProvider UDP read data Error : \(error.localizedDescription)")
return
}
// modify EDNS
// Send data to custom DNS server to resolve
// Write the response back to flow
})
}
}
Should I be using the NWConnection
class for this ? Or is there any other way which can be used ?