ECN and ToS of UDP Packet in SwiftNIO


Is it possible to read the Explicit Congestion Notification (ECN) flag of a UDP/IP Packet?
Also, is it possible to set the Type of Service (ToS) or Service Class of a UDP/IP Packet?

I know these flags are accessible through Network.framework but I don't know if there exits an eqivalent API for traditional sockets.
It looks like the WIP implementation of UDP support in swift-nio-transport-services does currently not include support for these flags.


Currently those flags are not exposed anywhere. In principle we can extend AddressedEnvelope to have a place to store metadata that is of interest to users. Users would have to request that we persist that information on messages because doing so presents a cost, but that's not unreasonable.

To begin with, we can design this out for swift-nio-transport-services, where we know this information is available. I can dive quickly into whether this information is exposed on raw sockets, but it is quite possible that it is not.

Yup, we can do this on sockets as well if we want. The socket options (IPPROTO_IP, IP_RECVTOS) and (IPPROTO_IP6, IPPROTO_RECVTCLASS) would do the trick.

What this needs:

  1. An enhancement to AddressedEnvelope to store arbitrary metadata. This likely ends up being a mapping of some kind.
  2. A change to move the current usage of recvfrom onto recvmsg so that we can extract control message data. I have most of this already.
  3. A change to provide support for extracting control message data into appropriately shaped boxes on the metadata of AddressedEnvelope. This shouldn't be too hard, though it requires some C helpers to enable iteration over the control message data.


Nice, that would cover the receiver side.

What about sending a packet with a ToS/Service Class?
I think if we use AddressedEnvelope here too, we could run into problems in the swift-nio-transport-services implementation because of the included remoteAddress .
As far as I can tell, NWConnection can only send packets to one fixed address and not dynamically on every send as traditional sockets.

As AddressedEnvelope is used in both inbound and outbound directions the pipeline side of that is covered.

I don't think it's an issue: we can arrange it so you can still choose to send an AddressedEnvelope instead of a ByteBuffer, and we'd just validate that you're using the right address for the remote peer. That will let you attach the appropriate metadata.