Post

Replies

Boosts

Views

Activity

Reply to How to send DNS data packets to a custom DNS server using NEDNSProxyProvider on a supervised device
@Matt thanks, that was really helpful. Better management of threads and writing datagrams to the correct end point did the trick. I came across NWConnection.batch and was wondering would it be better to do a batch send of datagrams as opposed to creating NWConnection's for each outgoing datagram. Would a solution like this be better ? Also, could you please advise on the best way to modify the DNS packets received in flow.readDatagrams before sending them to a custom DNS server ?
Apr ’21
Reply to How to send DNS data packets to a custom DNS server using NEDNSProxyProvider on a supervised device
@Matt Thanks for that. I would recommend even a separate outbound datagram class for each of these NWConnection's that is being opened from your flow. Yep, I've implemented this, creating a new NWConnection for each datagram received when reading the flow, but it still doesn't seem to be working. I seem to be getting a lot of (3303290176): Closing reads, not closed by plugin and (3303290176): Closing writes, not sending close error messages. Currently this is what I have implemented. The NEDNSProxyProvider class after handleNewFlow and flow.open is called: swift   private 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)         }       }     })   }       private func outBoundCopier(flow: NEAppProxyUDPFlow, datagrams: [Data]) {     for data in datagrams {       NSLog("DNSProxyProvider starting connection")                     let dnsServer = DNSServerConnection(flow: flow, data: data)       dnsServer.start()               dnsServer.onDataReceived = { (flow, data, isComplete, error, endpoint) in         self.inBoundCopier(flow: flow, data: data, isComplete: isComplete, error: error, endPoint: endpoint)       }             }   }       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)")         }         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")     }         } And the DNSServerConnection class which handles all the NWConnection's swift class DNSServerConnection {   private let connection: NWConnection   private let data: Data   private let flow: NEAppProxyUDPFlow       private let endPoint = NWHostEndpoint(hostname: CUSTOM_DNS_IP, port: CUSTOM_DNS_PORT)       var onDataReceived: ((NEAppProxyUDPFlow, Data?, Bool?, NWError?, NWHostEndpoint) - ())?       init(flow: NEAppProxyUDPFlow, data: Data) {     self.flow = flow     self.data = data     connection = NWConnection(host: CUSTOM_DNS_IP, port: CUSTOM_DNS_PORT, using: .udp)   }       func start() {     connection.stateUpdateHandler = connectionStateChanged(to:)     connection.start(queue: .main)   }       private func connectionStateChanged(to state: NWConnection.State) {     switch state {     case .waiting(let error):       NSLog("DNSProxyProvider Error opening connection: \(error.localizedDescription)")           case .ready:       NSLog("DNSProxyProvider connection ready")       sendDataToServer()           case .failed(let error):       connection.cancel()       NSLog("DNSProxyProvider Error opening connection: \(error.localizedDescription)")           default: break           }   }       private func sendDataToServer() {           connection.send(content: data, completion: .contentProcessed({ (error) in       if let error = error {         NSLog("DNSProxyProvider UDP outbound Error : \(error.localizedDescription)")       }               NSLog("DNSProxyProvider UDP outbound Success")       self.receiveData()     }))   }       private func receiveData() {     connection.receive(minimumIncompleteLength: 1, maximumLength: 2048, completion: { [self] (data, _, isComplete, error) in               if (isComplete) {         NSLog("DNSProxyProvider UDP outbound completed")                   self.connection.stateUpdateHandler = nil         self.connection.cancel()                 }                 onDataReceived?(flow, data, isComplete, error, endPoint)     })   } }
Apr ’21
Reply to NEDNSProxyProvider closes socket unexpectedly
Hey @scalo and @eskimo, this might seem a bit off topic from the question but am trying to do something similar. I am trying to figure out a way to send the data received with udpFlow.readDatagrams() to a custom DNS server. Could you please tell me how you have implemented the addEDNS0(datagrams) and the send(modifiedData) functions. That'll be really helpful. Thanks!
Apr ’21