While researching this as part of an official DTS incident I came across a reasonably nice workaround that I thought I’d share: namely, if the target device supports Bonjour you can add an ATS exception for “local” and everything within “local” will just work.
As part of its operation Bonjour service discovery requires that every device has a .local name. Specifically, when you resolve a service you get back:
the device’s .local name (A) — In NSNetService, this is the
hostName
propertythe IP addresses associated with that name (B) — In NSNetService, this is the
addresses
property.the port number on which to connect (C) — In NSNetService, this is the
port
property.
For example, if I browse for HTTP services on my local network:
$ dns-sd -B _http._tcp. local.
Browsing for _http._tcp..local.
DATE: ---Thu 15 Oct 2015---
11:01:51.968 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
11:01:51.969 Add 3 4 local. _http._tcp. Darth Inker
^C
I get back a list of services including
Darth Inker
. If I resolve that:
$ dns-sd -L "Darth Inker" _http._tcp. local.
Lookup Darth Inker._http._tcp..local.
DATE: ---Thu 15 Oct 2015---
11:02:42.973 ...STARTING...
11:02:43.289 Darth\032Inker._http._tcp.local. …at… darth-inker.local.:80 …
^C
I get the .local name (
darth-inker.local.
, point A) and the port number (80, point C). Finally, I can resolve the .local name into IPv4 and IPv6 addresses (point B).
$ dns-sd -q darth-inker.local. A
DATE: ---Thu 15 Oct 2015---
11:03:38.570 ...STARTING...
Timestamp A/R Flags if Name Type Class Rdata
11:03:38.571 Add 2 4 darth-inker.local. Addr IN 192.168.1.40
^C
$ dns-sd -q darth-inker.local. AAAA
DATE: ---Thu 15 Oct 2015---
11:03:41.963 ...STARTING...
Timestamp A/R Flags if Name Type Class Rdata
11:03:41.963 Add 2 4 darth-inker.local. AAAA IN FE80:0000:00…
^C
The point here is that I don’t need to use these IP addresses in order to connect to the service. I can simply put the .local name into a URL and pass that URL to NSURL{Session,Connection}.
This is relevant for ATS because, if you always connect via the .local name, you can add an ATS exception for everything in the “local” domain (see below) and ATS will get out of the way.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>local</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Obviously this only works if the target device supports Bonjour but, hey, in my opinion, devices without Bonjour support are broken anyway (-;
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"