Post

Replies

Boosts

Views

Activity

Troubleshooting the Local Network Privacy alert appearing during NTP sync (DNS + UDP)
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); 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 broadcast 255.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.
1
4
854
Jul ’22
NWPath thread safety
Hello!We use `NWPathMonitor` within our SDK to read the network connection details. Recently, we discovered a crash which makes me considering the thread safety of `NWPath` struct. In following code, the program passed the line `12`, but crashed on line `13`:import Network @available(iOS 12, *) extension NWPathMonitor { var current: NetworkConnectionInfo { let info = currentPath return NetworkConnectionInfo( reachability: NetworkConnectionInfo.Reachability(from: info.status), availableInterfaces: Array(fromInterfaceTypes: info.availableInterfaces.map { $0.type }), supportsIPv4: info.supportsIPv4, // <- passed supportsIPv6: info.supportsIPv6, // <- crashed isExpensive: info.isExpensive ) } }To my best understanding, something did happen concurrently between the current thread advanced from line `12` to `13`. Thus, I consider thread safety issue around `NWPath` returned by the `currentPath`. What I can't understand however, is why this crashes at all, given that `NWPath` is a struct, so its immutable value captured on `let info` should be thread safe.Crash details:Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000020 VM Region Info: 0x20 is not in any region. Bytes before following region: 4369170400 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> __TEXT 00000001046c4000-0000000104ee8000 [ 8336K] r-x/r-x SM=COW ...g.app/Datadog Termination Signal: Segmentation fault: 11 Termination Reason: Namespace SIGNAL, Code 0xb Terminating Process: exc handler [18544] Thread 10 name: Dispatch queue: com.datadoghq.ios-sdk-logs-upload Thread 10 Crashed: 0 libswiftCore.dylib 0x00000001ba2cf978 swift_unknownObjectRelease + 16 1 Datadog 0x0000000106508694 0x1064bc000 + 312980 2 Datadog 0x0000000106506e78 0x1064bc000 + 306808 3 Datadog 0x00000001065069b8 0x1064bc000 + 305592 4 Datadog 0x0000000106507618 0x1064bc000 + 308760 5 Datadog 0x00000001064cbfa8 0x1064bc000 + 65448 6 Datadog 0x00000001064d133c 0x1064bc000 + 86844 7 Datadog 0x00000001064d251c 0x1064bc000 + 91420 8 libdispatch.dylib 0x00000001ac41033c _dispatch_client_callout + 20Note: we discovered this crash on iOS13.x device and couldn't manage to reproduce more times. In the crashing version of SDK, we do pass following `queue` to synchronize `NWPathMonitor` updates:let queue = DispatchQueue( label: "com.datadoghq.network-connection-info", qos: .utility, attributes: [], target: DispatchQueue.global(qos: .utility) )
4
0
2k
May ’20