dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.25k stars 4.73k forks source link

Multicast doesn't work with XCode 12.5 and higher on iOS #53767

Open clairernovotny opened 3 years ago

clairernovotny commented 3 years ago

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.

dotnet-issue-labeler[bot] commented 3 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 3 years ago

Tagging subscribers to this area: @dotnet/ncl See info in area-owners.md if you want to be subscribed.

Issue Details
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.
Author: clairernovotny
Assignees: -
Labels: `area-System.Net.Sockets`, `untriaged`
Milestone: -
clairernovotny commented 3 years ago

Ping, can anyone please take a look? This is a regression and is breaking apps.

karelz commented 3 years ago

@marek-safar ping?

marek-safar commented 3 years ago

@steveisok please have a look. Although I'd not classify this as regression.

clairernovotny commented 3 years ago

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.

clairernovotny commented 3 years ago

Any progress here?

steveisok commented 3 years ago

No progress yet. If we do make this fix, it'll likely need to be made during the RC period.

steveisok commented 3 years ago

I'm going to set the milestone to 7, but I am still considering this for 6 and may change it back.

clairernovotny commented 2 years ago

Hi folks, just looking for an update on this?

steveisok commented 2 years ago

@clairernovotny it's in our backlog, but at this point I do not know if it'll make it when MAUI goes GA.

clairernovotny commented 2 years ago

Have we independently confirmed the issue, that multicast is not working today on iOS with the latest SDK's?

steveisok commented 2 years ago

No, I don't believe so. We'll verify and if necessary, fix when the issue gets picked up.

danardelean commented 2 years ago

8 months and nobody took a look at it yet and yes still doesn't work with the new version of XCode

antonfirsov commented 2 years ago

@steveisok @simonrozsival do you still plan to take a look at this for 7.0?

directhex commented 2 years ago

@antonfirsov short version: no, it's exceedingly unlikely to happen for 7.0 given the number of issues we have left to handle, the amount of work it looks like rewriting System.Net.Sockets for iOS will involve, and the number of weeks left for handling issues.

I've done some quick scoping, and Simon did a deeper exercise before me. It's not clear it's even feasible for us to implement UdpClient over top of NWConnectionGroup - better to use the high level Bonjour APIs directly, at an app level.

I know it's not what anyone wants to hear, but I'm going to retarget this for 8.0. That's not a commitment to implementing it for 8.0, more an acknowledgement that it's just not going to happen for 7.0

Tapanila commented 3 months ago

Any plans to look into this?