Expected behavior of searchDomains

Based on https://developer.apple.com/documentation/networkextension/nednssettings/searchdomains , we expect the values mentioned in searchDomains to be appended to a single label DNS query. However, we are not seeing this behavior.

We have a packetTunnelProvider VPN, where we set searchDomains to a dns suffix (for ex: test.com) and we set matchDomains to applications and suffix (for ex: abc.com and test.com) . When a user tries to access https://myapp , we expect to see a DNS query packet for myapp.test.com . However, this is not happening when matchDomainsNoSearch is set to true. https://developer.apple.com/documentation/networkextension/nednssettings/matchdomainsnosearch

When matchDomainsNoSearch is set to false, we see dns queries for myapp.test.com and myapp.abc.com.

What is the expected behavior of searchDomains?

My understanding of these settings is pretty much aligned with yours. I would expect that if you have these settings:

dns.searchDomains = ["abc.com", "def.com"]
dns.matchDomains = ["ghi.com", "jkl.com"]
dns.matchDomainsNoSearch = true

then resolving myapp would look for myapp.abc.com and myapp.def.com. If that’s not working, then we’re probably in bug report territory.

Before you do that, however, I want to check how you’re actually resolving the address. Are you sure you’re using the system resolver? For example, Safari, URLSession, or Network framework.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hey Quinn, thank you for your reply. I am seeing this on iOS. An end user enters a single label field in a browser (tested with Safari and Chrome). For example, user enters https://myapp in Safari while my packetTunnelProvider VPN is connected, but we never see the DNS packet.

Thanks for confirming that.

Browsers have a lot of complex logic. If you create a small test app that uses the DNS more directly — for example, by fetching a resource with URLSession — does that have the same problem?

I expect it will, but I just want to be sure.

Also, I want to check some things about how your packet tunnel provider is set up:

  • It’s in destination IP mode, right? As opposed to source app mode? The latter being per-app VPN.
  • Have you set includeAllNetworks? I suspect you haven’t, but I just want to be sure.
  • If you haven’t set that, are you claiming the default route? That is, are you adding a NEIPv6Route.default() value to the includedRoutes property?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I tried with an app that lets us send ping, see the same issue there. Can try with a new sample app, but I expect it would behave the same.

Yes, for this experiment it was in destinationIP mode. IncludeAllNetworks is off. For split tunnel mode, we don't set the default route (Which was the mode for this test).

We do set the default route when testing with split tunnel off, where the expectation is all traffic goes through tunnel.

I tried with a sample app using URLSession, same problem.

Thanks for those answers.

The ultimate consumer of the matchDomainsNoSearch property is actually in Darwin, so you can see how the code works. Start here.

As you can see, the behaviour is pretty straightforward: If that property is set, it skips the code that adds the match domains to the search domains. However, it’s still not obvious why this is affecting your setup.

One possibility relates to the example you included in your original post, where you have test.com in both the search domains and the match domains. In that case setting matchDomainsNoSearch causes it to add the match domains to the search domains, as shown by the code referenced above, and that code can change the order of items in the search domains. However, without knowing exactly how this is set up, it’s hard to tell whether that’s relevant here.

I realise that you’re testing this on iOS, but do you also have the ability to test on macOS as well? If so, you could take advantage of macOS’s additional debugging features to learn more about what’s going on. Specifically:

  • Running scutil with the --dns arguments dumps the DNS resolver state as understand by System Configuration.
  • You can dig even deeper by using scutil to dump the dynamic store directly.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Expected behavior of searchDomains
 
 
Q