I found a problem where Network filter ends up in state "Connecting" when Network System Extension is slightly delayed during initialization.
func main() {
autoreleasepool {
NEProvider.startSystemExtensionMode()
}
DoSomething()
Thread.sleep(forTimeInterval: 5) // Simulating the task takes a little longer
CFRunLoopRun()
}
main()
This usually happens during Sysgem Extension upgrade and also possibly during reboot. When the client app registers system extension it get callback very quickly, becasue it has already been approved by the user. Then it calls loadFromPreferences() to load configuration, which already exists so it is quite fast, then Network filter switches into state "Connecting", however System Extension hasn't completed its init yet. Network filter remains in state Connecting and never recovers. I have to manually click "Disconnect" and it instantly connencts and filter ends up in proper state "Connected".
Why doesn't the filter get into Connected state, when extension is finally fully initialized? I understand that system extension needs to initialize as quickly as possible, but it shouldn't be so unreliable if somebody adds extra 100ms to the init process or some undeterministic code sequence, whther it takes 0.1s or 2s. Is there a way to fix it by using standard Apple APIs?
If not, how to resolve that issue? I see the following options:
- Run the Apple APIs startSystemExtensionMode(), etc. as fast as possible and do the other setup in background thread (updating network filter, adding filtering ports, etc) - however it still does not completely resolve the issue that System Extension init might be delayed by high CPU load (let's some other tasks are running or daemons are starting during reboot).
- Implement timer and when the timer expires, check if Network filter is in state "Connecting" and if not, disable and enable the filter to try reconnect (in this case there is no proxy server/daemon on the other side, we are not really connecting anywhere, just need to receive handleNewFlow() events).
- System Extension could notify client that it completed initialization and then client wpould check filter state and if still in "Connecting" state, it would try to disable and enebale it, so it could reconnect.
Any suggestions? Thanks.