NEDNSProxyProvider stop reasons ( NEProviderStopReason )

I'm implementing a DNS Proxy network extension on iOS 12 and I have a couple of simple questions, mostly due to the lack of documentation.


1) Implementing


func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void)


I need to handle all the different cases of the `NEProviderStopReason` enum. Every case could possibly be really different from another and I'll need to perform different actions like communicating special states to the main App, try to recover in some way and so on.

here the enum:



/*! @const NEProviderStopReasonNone No specific reason. */

case none


/*! @const NEProviderStopReasonUserInitiated The user stopped the provider. */

case userInitiated


/*! @const NEProviderStopReasonProviderFailed The provider failed. */

case providerFailed


/*! @const NEProviderStopReasonNoNetworkAvailable There is no network connectivity. */

case noNetworkAvailable


/*! @const NEProviderStopReasonUnrecoverableNetworkChange The device attached to a new network. */

case unrecoverableNetworkChange


/*! @const NEProviderStopReasonProviderDisabled The provider was disabled. */

case providerDisabled


/*! @const NEProviderStopReasonAuthenticationCanceled The authentication process was cancelled. */

case authenticationCanceled


/*! @const NEProviderStopReasonConfigurationFailed The provider could not be configured. */

case configurationFailed


/*! @const NEProviderStopReasonIdleTimeout The provider was idle for too long. */

case idleTimeout


/*! @const NEProviderStopReasonConfigurationDisabled The associated configuration was disabled. */

case configurationDisabled


/*! @const NEProviderStopReasonConfigurationRemoved The associated configuration was deleted. */

case configurationRemoved


/*! @const NEProviderStopReasonSuperceded A high-priority configuration was started. */

case superceded


/*! @const NEProviderStopReasonUserLogout The user logged out. */

case userLogout


/*! @const NEProviderStopReasonUserSwitch The active user changed. */

case userSwitch


/*! @const NEProviderStopReasonConnectionFailed Failed to establish connection. */

case connectionFailed


Apart from a few cases (userInitiated, configurationDisabled, configurationRemoved) the other cases are quite obscure, would be possible to have a better description and use cases for all of them?


2) Debugging the network extension and disabling it from the App using


NEDNSProxyManager.shared().isEnabled = false


I've noticed that the `stop` function is called twice, the first time with 'configurationDisabled' reason and the second time, ofter after several seconds, with `userInitiated` reason.

Is this a wanted behaviour, if yes, what's the reason? At the moment I'm ignoring the second call but it doesn't seem a future-proof approach.


Thank you.

Accepted Reply

1) … would be possible to have a better description and use cases for all of them?

I suspect I’m misunderstanding you here, but my answer to that specific question is “Yes!”, with a side order of “The best way to officially request this is to file an enhancement request against the documentation.”

2) … Is this a wanted behaviour, if yes, what's the reason?

That does seem weird, but I wouldn’t lose a lot of sleep about that because in the real world a DNS proxy provider is only supported on supervised devices. The scenario you described can’t occur in that context because configuration is always done via a configuration profile.

Overall my take on this issue is that you need to test your DNS proxy provider in a wide variety of circumstances because the documented behaviour of these stop reasons is only part of the story. You need to make sure your provider does sensible things in the face of the actual behaviour.

Having said that, you can use these stop reasons to inform that testing. For example, the existence of the

.userSwitch
implies that you want to be testing on Shared iPad.

If, during this testing, you run into cases where it’s not obvious how to handle a specific stop reason, feel free to post back with follow-up questions.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

1) … would be possible to have a better description and use cases for all of them?

I suspect I’m misunderstanding you here, but my answer to that specific question is “Yes!”, with a side order of “The best way to officially request this is to file an enhancement request against the documentation.”

2) … Is this a wanted behaviour, if yes, what's the reason?

That does seem weird, but I wouldn’t lose a lot of sleep about that because in the real world a DNS proxy provider is only supported on supervised devices. The scenario you described can’t occur in that context because configuration is always done via a configuration profile.

Overall my take on this issue is that you need to test your DNS proxy provider in a wide variety of circumstances because the documented behaviour of these stop reasons is only part of the story. You need to make sure your provider does sensible things in the face of the actual behaviour.

Having said that, you can use these stop reasons to inform that testing. For example, the existence of the

.userSwitch
implies that you want to be testing on Shared iPad.

If, during this testing, you run into cases where it’s not obvious how to handle a specific stop reason, feel free to post back with follow-up questions.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

1) I was simply trying to take advantage of your knowledge and get more info as possible. I'll raise an enhancement request, as suggested. Thank you.

2) This makes sense, even if in our case we have the possibility to switch off the DNSProxy manually.


Thank you very much for the prompt answer.

in our case we have the possibility to switch off the DNSProxy manually.

Does that work even when your app is production signed? My understanding is that

NEDNSProxyProvider
only lets your app configure your proxy when the app is signed for development.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

That's really a good point, I've tried only signing the app with a dev profile for now. Thanks for the hint!