Firstly, I'm completely new to native Swift/iOS Development so apologies if this is a simple question that I'm seemingly misunderstanding.
I have an app which has the Multicast Networking entitlement and works fine on my own iPhone, however it only has one interface when I list them (en0)
The multicast networking, however, fails entirely on another test iPhone but this also appears to have one or more 'ipsecX' interfaces both with the IP 192.0.0.6 - I'm guessing but I wonder if this is related to a connection to Apple Watch as I've noticed two devices that have these additional interfaces, and both of them are connected to Apple Watch (with no VPNs configured) and that's the only thing that differentiates them from my own iPhone.
I can reproduce the symptoms on my own iPhone by connecting to a VPN which creates a utunX interface (but in my case disconnecting from the VPN removes this interface and it works as expected)
I expect a solution would be to bind my Multicast Group to the WiFi IP but I've tried a few things without success;
- Setting
params.requiredInterfaceType = .wifi
- Looping through each interface to try and 'find' en0 and bind this way;
let queue = DispatchQueue(label: "En0MonitorQueue")
monitor.pathUpdateHandler = { [weak self] path in
// Find the en0 interface
if let en0 = path.availableInterfaces.first(where: { $0.name == "en0" }) {
monitor.cancel() // Stop monitoring once found
let params = NWParameters.udp
params.allowLocalEndpointReuse = true
params.requiredInterface = en0
guard let multicast = try? NWMulticastGroup(for: [
.hostPort(
host: NWEndpoint.Host(self?.settings.multicastIP ?? "224.224.0.77"),
port: NWEndpoint.Port(rawValue: UInt16(self?.settings.multicastPort ?? 23019))
)
]) else {
print("Failed to Start Multicast Group")
return
}
let group = NWConnectionGroup(with: multicast, using: params)
// previous multicast stuff is here
} else {
print("en0 interface not found, waiting...")
}
}
monitor.start(queue: queue)
Neither seems to work.
I feel I must be missing something simple, because it should not be the case that simply enabling a VPN (or having another interface created by something else) breaks Multicast on en0/WiFi.
That said, I also don't want to limit the user to en0 as they may wish to use Ethernet interfaces, but for now it would be good to make it work to confirm this is the problem.
I have a bunch of hints and tips about multicasts in the Broadcasts and Multicasts, Hints and Tips post linked to by Extra-ordinary Networking.
In that post I say:
There are other limitations, but I don’t have a good feel for them.
Since then I’ve had a little more experience with this stuff and, yeah, I’m not exactly happy about that )-:
Consider this thread. In it I explain how we believe that multicasts should work with Network framework. However, the developer there is reporting a significant difference between that and what they actually see )-:
Looking at your code, you seem to be hard-coding en0
, which is not a good idea in general (I talk about that more in other posts hanging off Extra-ordinary Networking). However, I recognise that this is just your attempt at getting this to work at all, not necessarily what you plan to ship. And assuming that en0
is the Wi-Fi interface on your test device — which, statistically speaking is a reasonable assumption, and also something you can check — then pinning requiredInterface
to that should work.
If it doesn’t then I don’t have any great options for you, other than:
-
Use BSD Sockets )-:
If you do file a bug, please post your bug number, just for the record.
If you are going to file a bug about this, it’s probably worthwhile spending a little time isolating the problem. If you pin requiredInterface
then:
-
Datagrams you send to the group should go out that interface.
-
Datagrams targeting that multicast address on that interface should be delivered to your group.
You can test these independently, and I think it’s worthwhile doing that. That is, determining whether the problem is with sending or receiving, or both.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"