Inability to seperate IPv4 and IPv6 Traffic on the Same Port Using Network Framework

Hi everyone,

I’m working on an app where I need to separate IPv4 and IPv6 traffic on a specific port, let's say "X", using the Network Framework. However, I’ve run into a problem: it appears that I'm only able to open a single NWListener for a given port number. I was under the impression that I should be able to create distinct IPv4 and IPv6 listeners for the same port "X".

Here’s the sample code I’ve written:

var params: NWParameters
var l1: NWListener
var l2: NWListener

params = NWParameters.udp

let protocolOptions = params.defaultProtocolStack.internetProtocol! as NWProtocolOptions
let ipOptions = protocolOptions as! NWProtocolIP.Options
ipOptions.version = .v6

l1 = try NWListener(using: params, on: NWEndpoint.Port(rawValue: 54192)!)
l1.stateUpdateHandler = InternalListenerStateHandler
l1.newConnectionHandler = InternalNewConnectionHandler
l1.start(queue: .global())

ipOptions.version = .v4

l2 = try NWListener(using: params, on: NWEndpoint.Port(rawValue: 54192)!)
l2.stateUpdateHandler = InternalListenerStateHandler
l2.newConnectionHandler = InternalNewConnectionHandler
l2.start(queue: .global())

I’m trying to figure out why this approach isn’t working. Is there a way to manage both IPv4 and IPv6 traffic on the same port using the Network Framework, or is there something I’m overlooking in my setup?

Additionally, when I switch to the BSD framework, I can successfully open two sockets on the same port by setting the "IPV6_ONLY" property on the IPv6 socket.

Any insights or advice would be greatly appreciated!

Thanks,

Harshal

I’m working on an app where I need to separate IPv4 and IPv6 traffic on a specific port … using the Network Framework.

I don’t think there’s a way to do that with Network framework.

Having said that, I’m curious why you need this separation. If you use a single listener, you can tell whether a connection is v4 or v6 by looking at its metadata.

Share and Enjoy

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

@DTS Engineer The question really here is when one opens two NWListeners with ipOptions.version = .v6 and .v4 respectively and we can confirm that underlying sockets created are of type udp4 and udp6 (and not udp46) respectively. Then if standard says, one should be able to bind a socket to same port if your transport & ip protocol are different, then why in this case, we cannot do the same?

Then if standard says

What standard are you talking about here? Network framework doesn’t claim to follow any API standard, and the TCP standard doesn’t say anything about APIs.

we cannot do the same?

I generally can’t answer why questions [1] but in this case I’ll speculate: This is just the way it’s currently implemented.

The reason I asked why you need to use separately listeners is that, with that information, I might be able to suggest a better way to resolve your issue. If, however, you don’t actually have an issue, and you just want Network framework to work in a specific way, then I can’t really help you with that. You are flee to file an enhancement request for that change, but I doubt that’ll get any traction unless you provide an explanation as to why this is important to you.

Share and Enjoy

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

[1] See Quinn’s Top Ten DevForums Tips.

Inability to seperate IPv4 and IPv6 Traffic on the Same Port Using Network Framework
 
 
Q