Hello,
TL;DR; I'm looking for a way to recognise and filter out private IPs resolved from our NTP hosts using CFHostStartInfoResolution(_:_:_:)
. I suspect that it returns addresses within local network range sporadically, which leads to bringing up the Local Network Privacy alert when sending UDP packages (for NTP sync).
Our customers report that our SDK brings up the "Local Network Privacy" alert to the fraction of their end users. This behaviour is very rare and volatile, so we couldn't manage to reproduce it on our side on any device. We're trying to find out the the root cause, as local networking attempt is definitely not expected to happen in our SDK. I'm pretty familiar with the content of Local Network Privacy FAQ, but couldn't find an answer in there, hence I'm looking for any clues to move forward.
Certainly the issue is coming from NTP sync our SDK does with the use of CFNetwork
APIs. The logic starts with resolving one of our NTP pools:
0.datadog.pool.ntp.org
1.datadog.pool.ntp.org
2.datadog.pool.ntp.org
3.datadog.pool.ntp.org
into a sequence of IP addresses with CFHostStartInfoResolution(_:_:_:)
. Then we query each IP with CFSocketConnectToAddress(_:_:_:)
by exchanging NTP messages through CFSocket
.
Now, given that the issue is rare and volatile our first assumption was that in some network circumstances our DNS phase can lead to resolving private IPs. This hypothesis was proven in telemetry we collected with using NWConnection
API and method described in How do I use the unsatisfied reason property?. Among thousands of attempts, we found one that failed on .localNetworkDenied
when querying 192.168.1.250
.
To filter out local IPs, we ran through IETF RFCs on IPv4 and IPV6 specifics, coming up with the filter that should prevent from sending UDP to local network. Our "private IP" definition includes:
-
IPv6 addresses containing:
- local IP
FC00::/7
prefix (RFC-4193); - multicast IPs with
FF
prefix (RFC-4291);
- local IP
-
IPv4 addresses:
- reserved for private internets of ranges A, B and C (RFC-1918);
- multicast addresses within range
224.0.0.0 - 239.255.255.255
and broadcast255.255.255.255
(as suggested in What is a local network?)
With recent user reports, it turns out that this filter is either too weak or the entire idea of IP filtering is too flaky. The problem is still being reported. One report included a list of IPs out of which at least one must have lead to private networking and bringing up the alert on a device using regular 4G network:
82.64.172.48
178.170.37.31
62.210.244.146
188.165.236.162
193.200.43.105
51.15.175.180
95.81.173.74
51.195.117.133
151.80.211.8
92.222.117.115
51.75.17.219
64:ff9b::5be0:9529
2a05:f480:1400:53d::123
64:ff9b::a29f:c801
64:ff9b::253b:3f7d
2a05:f480:2000:1834::123
64:ff9b::c2b1:2274
64:ff9b::5cf3:605
2001:41d0:305:2100::3f3e
64:ff9b::33c3:7585
64:ff9b::d453:9e53
2001:41d0:8:7a7d::1
64:ff9b:1::5cde:7573
Looking at this list (even trying to hit these IPs with UDP) none seems to be commonly known local IP, hence my question is which IP ranges / RFCs are included in Apple's definition of local network? Is there anything obvious that I am missing?
PS1. I'm familiar with categories listed in What operations require local network access?
PS2. I know that CFNetwork
APIs are deprecated and we should use Network
APIs - however I don't suppose the problem will be gone only by migrating our logic to new code, hence I want to find the flaw in our filtering.