Network Extension performance issue

We have a scenario where a daemon process is generating lot of network operations which is nearly 250+ requests per seconds. Due to this the handleNewFlow() is not able to process the real browser/Application network operations in realtime and browser is getting timed out. This is resulting in all user network operations to be in waiting and finally timed out.

Filter setting (We are capturing all the network operations):
  let filterRules = ["0.0.0.0", "::"].map { address -> NEFilterRule in
      let bothNetworkRule = NENetworkRule(remoteNetwork: nil,
                         remotePrefix: 0,
                         localNetwork: nil,
                         localPrefix: 0,
                         protocol: .any,
                         direction: .any )
      return NEFilterRule(networkRule: bothNetworkRule, action: .filterData)
    }

override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict {
      return .allow();
 }

As we are not doing any processing in handleNewFlow() function and just returning allow verdict. But this is also resulting in same behaviour and not able to handle when some process is doing lot of network operations.
Please let us know if we are missing something here.

We have a scenario where a daemon process is generating lot of network operations which is nearly 250+ requests per seconds

Is this a daemon process that is under your control? Do you know why this type of volume is being generated from a daemon? Also, are these 250 unique connections per-second?

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Yes
Yes, this process we are running for our purpose. 

We have servers where many USB devices connected, the VMs can connect to these USB devices using "Eltima USB Network Gate" software. This software daemon generates huge number of connections per seconds. The approx 250 is the lower end of the count, sometimes it is more per seconds. The majority of connections are unique in terms of IP and port numbers. 

We have tested after stopping this daemon and then everything works fine that include browsing, ssh connections and all other network operations. But this is temporary solution as we don't know in in future some other process can start behaving similar way which may lead to similar behaviour on Network Extension and all other connections will timeout.
Thank you for this context. In that case I think the only performance optimizations that can be made here are dialing back the traffic captured to specific subsets of your NEFilterRules. For example, it looks like you are just allowing the NEFilterNewFlowVerdict in handleNewFlow. If that is actually the case, do you need to setup a filter for the default route on IPv4 for both TCP and UDP?


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
@Matt is there any way we can make specific process as trusted process with "NENetworkRule" for Network extension with its name or PID rather than network traffic characteristics which varies ?. so that network extension / content filters always allows the traffic.

I don't find this here https://developer.apple.com/documentation/networkextension/nenetworkrule

You'll essentially want to take a look at the NEFilterFlow's sourceAppAuditToken to get the PID. Quinn actually discussed this topic on a recent thread here. Take a look at that thread for the specifics.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
@Matt ,
We can check PID in handleNewFlow and allow the traffic as it is trusted process , but we would like to avoid that and stop filtering the traffic of a trusted process before handleNewflow with NEFilterRule as below . is it possible ?. and other thing is NE content filter is not able to handle the plenty traffic . I see it is limitation or bug in NE content filter . Let me know any README on how many network operations network extension content filter can handle ??.

class FilterDataProvider: NEFilterDataProvider {

  override func startFilter(completionHandler: @escaping (Error?) -> Void) {
    DGNetopsFilterCommsInit()

    //For all traffic
    let filterRules = ["0.0.0.0", "::"].map { address -> NEFilterRule in
      let bothNetworkRule = NENetworkRule(remoteNetwork: nil,
                         remotePrefix: 0,
                         localNetwork: nil,
                         localPrefix: 0,
                         protocol: .any,
                         direction: .any )
      return NEFilterRule(networkRule: bothNetworkRule, action: .filterData)
    }

    // Allow all flows that do not match the filter rules by default action as allow.
    let filterSettings = NEFilterSettings(rules: filterRules, defaultAction: .allow)

    apply(filterSettings) { error in
       if let applyError = error {
         os_log("Failed to apply filter settings: %@", applyError.localizedDescription)
       }
       completionHandler(error)
    }
  }


but we would like to avoid that and stop filtering the traffic of a trusted process before handleNewflow with NEFilterRule as below . is it possible ?

Not exactly. You could attempt to reconfigure your NEFilterSettings while running to ignore these addresses that you have already cached to be trusted address traffic, but that would require filtering a subset of traffic first to get those baseline addresses.

and other thing is NE content filter is not able to handle the plenty traffic . I see it is limitation or bug in NE content filter . Let me know any README on how many network operations network extension.

Can you be more specific here? If this is in regards to the volume of traffic you are trying to handle (250 connections per second) then I suggest you open a bug report for this for this specific use case regarding performance optimizations.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
@Matt ,
We have opened a bug report here https://feedbackassistant.apple.com/feedback/8881629 . it has been more than a week . we don't see any action there ?. is it the right place ? whom should we contact ?. Thanks
Thank you for opening a bug report. I see it internally and, yes, your bug report landed in the right place.

it has been more than a week . we don't see any action there ?

Opening a Bug Report does not mean a guaranteed fix. We will evaluate your report and respond back when there is next steps on any actions to take.

whom should we contact ?

Keep checking back on your Bug Report and if you have questions, please post them there. If there is further information to share, we will also post this information directly to you on your Bug Report.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
@Matt , it has been more than 3 weeks with bug in open state https://feedbackassistant.apple.com/feedback/8900239 . How to make this acknowledged by Apple Engineering team . it is not necessarily fix , at-least the decision by engineering team

it has been more than 3 weeks with bug in open state. How to make this acknowledged by Apple Engineering team . it is not necessarily fix , at-least the decision by engineering team

Opening a bug report does not guarantee an immediate response, a fix, or immediate feedback. My advice to you would be to keep updating your bug report with new information as you continue to investigate this issue on your end.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I am seeing this behaviour also with the FilterPacketProvider. In the simple example at the bottom, we allow every packet flowing.

With this extension enabled and about 15 Mbit/s receiving and 4 Mbit/s sending the connections in the browser timeout. This is more frequent with video conferencing tools like Meet and Teams, which are UDP based and a lot of traffic is generated

Is there any news regarding the tickets? We are facing a lot of trouble with clients that have a contentFilter installed like for example some enterprise anti malware and firewalls agent like Cortex, where they keeps disconnecting from the video conference

import NetworkExtension
import os.log

class FilterPacketProvider: NEFilterPacketProvider {
        
        static let log = OSLog(subsystem: "com.example.apple-...", category: "PacketProvider")
        private let log: OSLog
        override init() {
                self.log = Self.log
                os_log(.info, log: self.log, "FilterPacketProvider: init")
                super.init()
        }
        
        override func startFilter(completionHandler: @escaping (Error?) -> Void) {
                os_log(.info, log: self.log, "FilterPacketProvider: startFilter")
                self.packetHandler = self.handlePacketwithContext;
                completionHandler(nil)
        }
    
        override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
                os_log(.info, log: self.log, "FilterPacketProvider: stopFilter")
                completionHandler()
        }
    
    
        private func handlePacketwithContext(context: NEFilterPacketContext,
                                    interface: nw_interface_t,
                                    direction: NETrafficDirection,
                                    _ packetBytes: UnsafeRawPointer,
                                     packetLength: Int) -> NEFilterPacketProvider.Verdict {            
            return Verdict.allow;
        }
}

Is there any news regarding the tickets?

It does look like 8900239 has been addressed. Are you running the NEFilterPacketProvider on Monterey? If not, I would upgrade to Monterey and see if you are still seeing degraded performance.

Network Extension performance issue
 
 
Q