Post

Replies

Boosts

Views

Activity

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
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 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