We're seeing reports from customers that there are issues with our NetworkExtension (NEFilterDataProvider) performance. We must see all content so we have an NERule for filtering all traffic for IPv4 and IPv6.
It also seems like the issue is compounded, or perhaps exists ONLY when there are two network extensions involved--ours and a 3rd party, any third party NetworkExtension.
So far we haven't been able to get a "real world" reproducible case, but we have a contrived case that involves sub-second ICMP pings using ping -i 0.001. I suspect the real world cases involve something using UDP, but no luck so far.
We have sample files that indicate that most of the time is spent outside our network extension. In particular:
Call graph:
541 Thread_2477: Main Thread DispatchQueue_<multiple>
+ 541 _dispatch_sig_thread (in libdispatch.dylib) + 49 [0x7ff80c8447f7]
+ 541 _dispatch_sigsuspend (in libdispatch.dylib) + 36 [0x7ff80c84481b]
+ 541 __sigsuspend_nocancel (in libsystem_kernel.dylib) + 10 [0x7ff80c9b71d2]
541 Thread_2830419
+ 541 start_wqthread (in libsystem_pthread.dylib) + 15 [0x7ff80c9e9f57]
+ 541 _pthread_wqthread (in libsystem_pthread.dylib) + 426 [0x7ff80c9eb034]
+ 541 __workq_kernreturn (in libsystem_kernel.dylib) + 10 [0x7ff80c9b305a]
540 Thread_2832749 DispatchQueue_49: NEFilterExtensionProviderContext queue (serial)
+ 540 start_wqthread (in libsystem_pthread.dylib) + 15 [0x7ff80c9e9f57]
+ 540 _pthread_wqthread (in libsystem_pthread.dylib) + 326 [0x7ff80c9eafd0]
+ 540 _dispatch_workloop_worker_thread (in libdispatch.dylib) + 753 [0x7ff80c843eee]
+ 540 _dispatch_lane_invoke (in libdispatch.dylib) + 366 [0x7ff80c839dfd]
+ 528 _dispatch_lane_serial_drain (in libdispatch.dylib) + 342 [0x7ff80c8391cd]
+ ! 528 _dispatch_source_invoke (in libdispatch.dylib) + 2179 [0x7ff80c847208]
+ ! 528 _dispatch_continuation_pop (in libdispatch.dylib) + 453 [0x7ff80c835d7c]
+ ! 528 _dispatch_client_callout (in libdispatch.dylib) + 8 [0x7ff80c833317]
+ ! 520 -[NEFilterDataExtensionProviderContext handleSocketSourceEventWithSocket:] (in NetworkExtension) + 2950 [0x7ff81b2a9b16]
+ ! : 520 -[NEFilterDataExtensionProviderContext handleData:offset:forFlow:direction:reply:controlSocket:completionHandler:] (in NetworkExtension) + 433 [0x7ff81b2a6576]
+ ! : 520 -[NEFilterDataSavedMessageHandler enqueueWithFlow:context:] (in NetworkExtension) + 188 [0x7ff81b2ab67e]
+ ! : 515 -[NEFilterDataSavedMessageHandler executeWithFlow:context:] (in NetworkExtension) + 297 [0x7ff81b2ab7c9]
+ ! : | 515 -[NEFilterDataSavedMessageHandler executeVerdictHandlerWithFlow:verdict:context:] (in NetworkExtension) + 305 [0x7ff81b2ab9a6]
+ ! : | 515 __114-[NEFilterDataExtensionProviderContext handleData:offset:forFlow:direction:reply:controlSocket:completionHandler:]_block_invoke.317 (in NetworkExtension) + 133 [0x7ff81b2a671a]
+ ! : | 515 -[NEFilterSocketFlow createDataReply:controlSocket:direction:verdict:context:] (in NetworkExtension) + 86 [0x7ff81b2b1393]
+ ! : | 515 -[NEFilterSocketFlow writeCurrentVerdictWithMessage:controlSocket:] (in NetworkExtension) + 371 [0x7ff81b2b15ec]
+ ! : | 515 +[NEFilterSocketFlow writeMessageWithControlSocket:drop:socketID:inboundPassOffset:inboundPeekOffset:outboundPassOffset:outboundPeekOffset:statsReportFrequency:] (in NetworkExtension) + 158 [0x7ff81b2b1a4e]
+ ! : | 515 write (in libsystem_kernel.dylib) + 10 [0x7ff80c9b475e]
+ ! : 5 -[NEFilterDataSavedMessageHandler executeWithFlow:context:] (in NetworkExtension) + 81 [0x7ff81b2ab6f1]
+ ! : 5 __114-[NEFilterDataExtensionProviderContext handleData:offset:forFlow:direction:reply:controlSocket:completionHandler:]_block_invoke (in NetworkExtension) + 117 [0x7ff81b2a666a]
+ ! : 5 @objc FilterDataProvider.handleOutboundData(from:readBytesStartOffset:readBytes:) (in com.my.system-extension) + 91 [0x10900a02b]
In this case, we're not doing much for ICMP in our handleInboundData/handleOutboundData except looking at data stream metadata, seeing it's ICMP and getting the type/code. Those frames don't even appear in the samples.
Anybody else seen an issue like this?