runtime: Multicast doesn't work with XCode 12.5 and higher on iOS

mDNS, and anything else that needs multicast on iOS, no longer works with XCode 12.5. See the discussion here: https://github.com/novotnyllc/Zeroconf/issues/195#issuecomment-841508002

@rcinge has a working theory:

After thinking about this, this is my guess/story about what is going on:

The reason this issue appeared with Xcode 12.5 is that the new multicast restriction policy is implemented in Apple-shipped library code (the NWConnectionGroup API), and an updated version of that library would ship with the new Xcode. Likewise, the library wrappers for all system calls would also ship with the new release of Xcode.

The core bit: there’s some undocumented socket option or system call argument that signals to the macOS kernel that multicast traffic is allowed on this specific socket. The NWConnectionGroup API knows this secret and will enable multicast traffic on a socket if: (1) the desired mDNS protocols and description are coded in Info.plist (2) the protocols specified do not violate Apple’s restrictions (3) the device user consents to allow the app to examine network traffic. Finally, as results from the multicast query are returned by the Receive() system call, the NWConnectionGroup API then gets to filter the data it returns to the caller.

The legacy BSD Sockets system call wrappers also know the secret. Before Xcode 12.5, they would enable multicast traffic unconditionally, but starting with Xcode 12.5, they don’t enable any multicast traffic.

Final bit: In the macOS kernel, when the network receive system call is executed, if the secret option has been set and the user consent flag is set, all is well. If the secret option is not set, the kernel looks for the multicast entitlement; if the entitlement exists, the receive call proceeds (legacy mode), otherwise it returns the “No route to host” error.

Apple denied my request for the multicast entitlement because it gives away the keys to the kingdom: the BSD Socket API is basically a set of kernel system calls-- it’s just too low level for all the policy enforcement. Since I am still developing my app, their logic of “well, use this API instead” is sound.

If the story is true, to make Zeroconf function again on iOS requires code that calls the NWConnectionGroup API.’

As the Zeroconf library uses the UdpClient APIs, it seems like the runtime might need to be updated to use the NWConnectionGroup APIs.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 1
  • Comments: 16 (14 by maintainers)

Most upvoted comments

Any progress here?

It was working for years until iOS changed something recently and it stopped. That’s a regression to me, even if we didn’t cause it.