Does Multicast networking work with IPV6 addresses ?

I followed the instructions scrupulously ( https://developer.apple.com/news/?id=0oi77447 ) :

Code Block swift
guard let multicast = try? NWMulticastGroup(for:[ .hostPort(host: "ff02::1", port: 60000) ]) else { NSLog("ERROR - Multicast"); return }
let group = NWConnectionGroup(with: multicast, using: .udp)
group.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: true) { (message, content, isComplete) in
NSLog("Received message from \(String(describing: message.remoteEndpoint))")
let sendContent = Data("ack".utf8)
message.reply(content: sendContent)
}
group.stateUpdateHandler = { (newState) in
NSLog("Group entered state \(String(describing: newState))")
}
group.start(queue: .main)
let groupSendContent = Data("helloAll".utf8)
group.send(content: groupSendContent) { error in
NSLog("Send complete with error \(String(describing: error))")
}
group.cancel()


However, it returns me this error :

[] nwlistenersocketinboxcreatesocket IPV6LEAVE_GROUP ff02::1.60000 failed [49: Can't assign requested address]

My question is, does IOS Multicast networking work with IPV6 addresses ?

EDIT : I copied and pasted the example as it stands in the official documentation (with the 224.0.0.251 address and the 5353 port) and it did not change anything... Has anyone ever managed to make this library work ?

Does Multicast networking work with IPv6 addresses ?

What platform are you testing this on?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
The above code is executed on an iPhone SE 2020 (real device), with IOS 14. And my IDE is Xcode 12.

I have the com.apple.developer.networking.multicast restricted entitlement. It has been added to my provisioning profile, and I'm using it on Xcode.
I also added the row com.apple.developer.networking.multicast to my Info.plist file with a value of 1 (true).

However, when I run the following command in the terminal :

% codesign -d --entitlements :- /Users/nymesis/Library/Developer/Xcode/DerivedData/alacarte-eyzouhvinbrlqjgqwuldhcczaafi/Build/Products/Debug-iphoneos/myapp.app | grep -A 1 "com.apple.developer.networking.multicast"

it returns an empty array :


Executable=/Users/nymesis/Library/Developer/Xcode/DerivedData/alacarte-eyzouhvinbrlqjgqwuldhcczaafi/Build/Products/Debug-iphoneos/alacarte.app/alacarte



Still in Terminal, if I run the following command :

% security cms -D -i /Users/nymesis/Library/Developer/Xcode/DerivedData/alacarte-eyzouhvinbrlqjgqwuldhcczaafi/Build/Products/Debug-iphoneos/myapp.app/embedded.mobileprovision | grep -A 1 "com.apple.developer.networking.multicast"

it confirms that my profile allows use of the entitlement :

<key>com.apple.developer.networking.multicast</key> <true/>


with iOS 14

iOS 14.0? Or something later?

This matters because there’s been a raft of fixes related to local network privacy in the iOS 14.x cycle.

I also added the row com.apple.developer.networking.multicast to my
Info.plist file with a value of 1 (true).

This is an entitlement, not an Info.plist key. If you’re building with Xcode you need to add it to your target’s .entitlements file.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thank you for your answer.

iOS 14.0? Or something later?

iOS 14.1


If you’re building with Xcode you need to add it to your target’s .entitlements file.

My project does not have any .entitlements file. How can I create one and link it with the project ?

EDIT : In the target build settings, there is no "Code Signing Entitlements" property.
I managed to create the .entitlements file and I tested with iOS 14.2, but still have the same problem.

Can't assign requested address

I get the same error with the iOS simulator too.
Here is a summary of the problem :

I followed the Apple instructions carefully.
Code Block
guard let multicast = try? NWMulticastGroup(for:[ .hostPort(host: "224.0.0.251", port: 5353) ]) else { NSLog("ERROR"); return }
let group = NWConnectionGroup(with: multicast, using: .udp)
group.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: true) { (message, content, isComplete) in
NSLog("Received message from \(String(describing: message.remoteEndpoint))")
}
group.start(queue: .main)


However when I run this code I get the following error :

[49: Can't assign requested address]

The platform is iOS 14.2 and the problem persists if I run the program on a real device or through the simulator.

I have the com.apple.developer.networking.multicast entitlement and it is correctly configured.

I tried with various IP addresses (IPV4 and IPV6) and various ports, without any results.

Shouldn't I specify the "en0" interface?

For the moment you should test on the simulator. That rules out any entitlement issues (and, honestly, it sounds like you have serious issues on that front), allowing us to concentrate on your code.

This is how I set up my multicast receiver in my local network privacy test project:

Code Block
let description = try NWMulticastGroup(for: [inputs.groupAddress])
let group = NWConnectionGroup(with: description, using: .udp)
group.setReceiveHandler(maximumMessageSize: 64 * 1024, handler: self.didReceive(message:data:isComplete:))
group.stateUpdateHandler = self.didUpdateState(to:)
group.start(queue: .main)


In this context inputs.groupAddress is built from ff02::114, an address reserved for experimentation by RFC 4727, and port number 12345. I recommend that you start with a port number that’s not 5353 because risks a collision with mDNSResponder.

The only other gotcha is that you have to hold on to a persistent reference to group. If you release that then everything is going to shut down.

If you run this code in the sim, can you receive IPv6 multicasts to that address? That is, is the didReceive(message:data:isComplete:) method called?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thank you for your answer, eskimo.

Following your advice, I created a new clean project to allow us to concentrate on the code. Here is the entire code of this project :

Code Block
import SwiftUI
import Network
struct ContentView: View {
    var body: some View {
        Button(action: {
            NSLog("Test - Start")
            guard let description = try? NWMulticastGroup(for:[ .hostPort(host: "ff02::114", port: 12345) ]) else { NSLog("ERROR"); return }
            let group = NWConnectionGroup(with: description, using: .udp)
            group.setReceiveHandler(maximumMessageSize: 64 * 1024, rejectOversizedMessages: true) { (message, content, isComplete) in
                NSLog("Received message from \(String(describing: message.remoteEndpoint))")
            }
            group.stateUpdateHandler = { (newState) in
                NSLog("Group entered state \(String(describing: newState))")
                if newState == NWConnectionGroup.State.ready {
                    NSLog("Test - Send Message")
                    let groupSendContent = Data("helloAll".utf8)
                    group.send(content: groupSendContent) { error in
                        NSLog("Send complete with error \(String(describing: error))")
                    }
                }
            }
            group.start(queue: .main)
        }) {Text("Hello, world!")
            .padding()
        }
    }
}

And here are all the logs I received, when I ran it on the "iPhone SE (2nd generation)" simulator, :

2020-11-18 11:32:35.054906+0100 test[1178:41190] Test - Start

2020-11-18 11:32:35.188673+0100 test[1178:41412] [] nwlistenersocketinboxcreatesocket setsockopt SONECP_LISTENUUID failed [2: No such file or directory]

2020-11-18 11:32:35.188856+0100 test[1178:41412] [] nwlistenersocketinboxcreatesocket IPV6LEAVE_GROUP ff02::114.12345 failed [49: Can't assign requested address]

2020-11-18 11:32:35.190372+0100 test[1178:41190] Group entered state waiting(POSIXErrorCode: Network is down)

2020-11-18 11:32:35.190541+0100 test[1178:41190] Group entered state ready

2020-11-18 11:32:35.190662+0100 test[1178:41190] Test - Send Message

2020-11-18 11:32:35.206509+0100 test[1178:41412] [] nwprotocolgetquicimageblockinvoke dlopen libquic failed

2020-11-18 11:32:35.218750+0100 test[1178:41412] [connection] nwsocketservicewritesblock_invoke [C1:1] sendmsg(fd 8, 8 bytes) [65: No route to host]

2020-11-18 11:32:35.218930+0100 test[1178:41412] [] nwflowprepareoutputframes Failing the write requests [65: No route to host]

2020-11-18 11:32:35.219823+0100 test[1178:41412] [connection] nwwriterequest_report [C1] Send failed with error "No route to host"

2020-11-18 11:32:35.225903+0100 test[1178:41190] Send complete with error Optional(POSIXErrorCode: No route to host)

I checked with Wireshark, no packets were sent on the 12345 UDP port.
The code was compiled by Xcode 12.2 (12B45b) and the iOS deployment target is 14.2 (iPhone & iPad)
So, there are problems with the code you posted (1) but, even after fixing those, I can’t get this to work. And the test project I had for this is also giving me trouble (which is weird ’cause I swear it used to work).

Unfortunately I don’t have enough time to dig into this here on DevForums. My advice is that you open a DTS tech support incident, which will allow me (or Matt) to allocate more time to this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

(1) Putting networking code directly in SwiftUI buttons handlers is problematic because of object lifetime issues.
Does Multicast networking work with IPV6 addresses ?
 
 
Q