How to send DNS data packets to a custom DNS server using NEDNSProxyProvider on a supervised iOS device

508 Views Asked by At

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 ?

0

There are 0 best solutions below