Code Block swift import NetworkExtension class DNSProxyProvider: NEDNSProxyProvider { private var proxyFlow: NEAppProxyUDPFlow? override init() { super.init() } 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 }) } }
I am unsure of how to send the DNS request to my own DNS server. Should I use the NWConnection class for this ? Or is there any other method which can be used for this ? Thanks!
I wrote an article that describes the flow copying process here. Having said that, the general process for UDP flow copying is not the same as TCP, which is outlined in the referenced article. UDP is different as it could deal with many datagrams on a single flow.I am unsure of how to send the DNS request to my own DNS server. Should I use the NWConnection class for this ?
First I noticed that you are opening the local flow with the local endpoint, so you are off to a good start to this process. From there you need to build your outbound copier because your local flow is being opened first. So this is the copier reading/writing from the local flow. In this read you will get data for 1 or more outgoing datagrams that you will need to build and manage NWConnection's for. I would recommend even a separate outbound datagram class for each of these NWConnection's that is being opened from your flow.
Next is the inbound copier for data being read from the remote NWConnection. This is very similar to how TCP was done, but now you need to define an inbound copier for each one of your datagram connections so each one of these connections can receive data and write it to the local flow.
Lastly, you would close each of the datagram connections on finish or error just as you normally would with cancel, closeReadWithError, and closeWriteWithError.
There is no sample for this but please let me know if you have questions.
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com