Hi @eskimo,
Thanks for reply,
This is what I have done so far:
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
NSLog("DNSProxyProvider: handleFlow")
if #available(iOSApplicationExtension 14.2, *) {
hostName = flow.remoteHostname!
} else {}
if let udpFlow = flow as? NEAppProxyUDPFlow {
let localHost = (udpFlow.localEndpoint as! NWHostEndpoint).hostname
let localPort = (udpFlow.localEndpoint as! NWHostEndpoint).port
proxyUDPFlow = udpFlow
open()
}
return false
}
func open() {
guard let flow = proxyUDPFlow 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(for: flow)
}
}
}
func handleData(for flow: NEAppProxyUDPFlow) {
flow.readDatagrams(completionHandler: { (data, endpoint, error) in
if let error = error {
NSLog("DNSProxyProvider UDP read data Error : \(error.localizedDescription)")
return
} else {
if let datagrams = data, let _ = endpoint, !datagrams.isEmpty {
self.outBoundCopier(flow: flow, datagrams: datagrams,endPointValue: (flow.localEndpoint as? NWHostEndpoint)!)
}
}
})
}
func outBoundCopier(flow: NEAppProxyUDPFlow, datagrams: [Data], endPointValue:NWHostEndpoint) {
Read DNS query messages off the flow.
Parse them into the format needed by your resolver.
Send it to your resolve.
Get the response.
Format it into a DNS reply message.
Send it to inBoundCopier to Write that to the flow on which you received the query.
}
private func inBoundCopier(flow: NEAppProxyUDPFlow, data: Data?, isComplete: Bool?, error: NWError?, endPoint: NWHostEndpoint) {
switch(data, isComplete, error) {
case (let data?, _ , _):
flow.writeDatagrams([data], sentBy: [endPoint], completionHandler: { (error) in
if let error = error {
NSLog("DNSProxyProvider UDP write Error : \(error.localizedDescription)")
}
else{
NSLog("DNSProxyProvider UDP write completed")
}
})
case(_, true, _):
flow.closeReadWithError(error)
flow.closeWriteWithError(error)
NSLog("DNSProxyProvider inbound copier completed")
case (_, _, let error?):
NSLog("DNSProxyProvider inbound copier Error : \(error.localizedDescription)")
default: NSLog("DNSProxyProvider inbound copier error")
}
}
Read DNS query messages off the flow.
This Im assuming extract/read each data object from datagrams array.
Parse them into the format needed by your resolver.
Basically we have an API that takes hostname as a query parameter, that sends us Json response. There is not any specific format we use for our resolver.