Error "Remote endpoints array contains a non-NWEndpoint object" invoking writeDatagrams on NEAppProxyUDPFlow

Hi. I'm working on a AppProxyProvider that captures TCP and UDP flows. The invocation of the method to open the flow and read bytes from it are working as expected. But I'm getting this error invoking writeDatagram: sentByEndpoints:

_NEAppProxyFlowErrorInvalidArgument An invalid argument was passed to one of the NEAppProxyFlow methods _ This is shown in the console:

error 14:56:27.628074-0300 XXXXX -[NEAppProxyUDPFlow writeDatagrams:sentByEndpoints:completionHandler:]: Remote endpoints array contains a non-NWEndpoint object

In the code I'm creating an array with an instance of NWHostEndpoint

NWHostEndpoint * endPoint = [NWHostEndpoint endpointWithHostname:[NSString stringWithFormat: @"%s", hostname] port:[NSString stringWithFormat: @"%d", srcPort]]; NSArray * endpoints = @[endPoint];

Was this issue observed by someone else?

In the code I'm creating an array with an instance of NWHostEndpoint NWHostEndpoint * endPoint = [NWHostEndpoint endpointWithHostname:[NSString stringWithFormat: @"%s", hostname] port:[NSString stringWithFormat: @"%d", srcPort]];

You could be bumping up against an endpoint that is not a .hostPort style endpoint. For example in the NetworkExtension world it would look like:

extension Network.NWEndpoint {

    /// Returns an NetworkExtension framework `NWEndpoint` that’s equivalent to
    /// this Network framework `NWEndpoint`.

    var neEndpoint: NetworkExtension.NWEndpoint {
        switch self {
        case .hostPort(let host, let port):
            return NWHostEndpoint(hostname: "\(host)", port: "\(port)")
        case .service(let name, let type, let domain, _):
            return NWBonjourServiceEndpoint(name: name, type: type, domain: domain)
        case .unix(_):
            // Handle unix domain socket endpoint
        case .url(_):
            // Handle url endpoint
        @unknown default:
            fatalError()
        }
    }
}

And in the Network Framework world it would look like:

extension NetworkExtension.NWEndpoint {
    
    /// Returns an Network framework `NWEndpoint` that’s equivalent to this
    /// NetworkExtension framework `NWEndpoint`.
    
    var nwEndpoint: Network.NWEndpoint {
        if let ep = self as? NetworkExtension.NWHostEndpoint {
            return Network.NWEndpoint.hostPort(host: NWEndpoint.Host(ep.hostname), port: NWEndpoint.Port(ep.port)!)
        } else if let ep = self as? NetworkExtension.NWBonjourServiceEndpoint {
            return Network.NWEndpoint.service(name: ep.name, type: ep.type, domain: ep.domain, interface: nil)
        } else {
            fatalError()
        }
    }
}

Then the usage for a TCP example would look something like the following:

// Network Framework Endpoint
let connection = NWConnection(to: flow.remoteEndpoint.nwEndpoint, using: .tcp)

// Network Extension Endpoint

guard let localEndpoint = copier.connection.currentPath?.localEndpoint?.neEndpoint as? NWHostEndpoint else {
    return
}
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Error "Remote endpoints array contains a non-NWEndpoint object" invoking writeDatagrams on NEAppProxyUDPFlow
 
 
Q