Summary

  • RFC 10055 records the socket calls and ancillary-data conventions used to make ECN over UDP work for Chromium on Apple, Linux and Windows; it is Informational, not a platform mandate.
  • A congestion codepoint becomes usable by an application only when enablement, packet-level receipt, platform-specific parsing and the transport's feedback logic all line up.

The packet can carry the right two bits and the network can mark congestion correctly. The application may still receive no usable signal.

That gap is the subject of RFC 10055. The IETF document records experiments that enabled Explicit Congestion Notification (ECN) over UDP for Chromium on Apple, Linux and Windows. It is a practical snapshot, not a standard that binds operating systems to an API. Its importance lies in making visible a boundary often hidden by protocol diagrams: a transport's feedback loop depends on what the kernel exposes through a socket.

ECN starts in the IP header. RFC 3168 defines the field as a way for network devices to indicate congestion without relying only on packet loss; RFC 9330 builds a low-latency architecture around more frequent explicit signals. A transport that uses those signals still needs to get them from the IP layer. QUIC, specified in RFC 9000, validates ECN counts along a path and disables ECN when validation fails. That validation is possible only if the implementation can observe the marks that arrived.

RFC 10055 breaks reception into two steps. First, enable reporting on the socket. Then read the mark attached to each datagram as ancillary data, commonly through recvmsg(). On Linux, Apple and FreeBSD, the documented option is IP_RECVTOS for IPv4 and IPV6_RECVTCLASS for IPv6. Linux adds a dual-stack wrinkle: an IPv6 socket that also receives IPv4 packets needs IP_RECVTOS as well. The corresponding Apple and FreeBSD path does not require that extra setting.

Windows presents a different branch. Its documentation recommends WSASetRecvIPEcn(), with the result returned as control data through WSARecvMsg. RFC 10055 describes exceptions for dual-stack sockets and for IPv4-mapped IPv6 addresses. A portable application therefore cannot treat “IPv6 enabled” as one predictable capability. It must test the actual socket family and configuration, then verify that the kernel returns the expected control message.

The bytes also mean different things across these interfaces. Linux and Apple/FreeBSD may return the complete DS-field byte, which contains both the six-bit Differentiated Services Code Point (DSCP) and the two ECN bits. Windows reports the ECN codepoint alone in IP_ECN or IPV6_ECN control data. A parser that extracts the low bits on one platform but assumes the same shape everywhere can quietly turn a valid observation into a wrong one.

Sending has its own interface choices. A stable marking can be configured at socket level on the Unix-like systems RFC 10055 covers; a shared socket serving connections with different ECN support may need a per-packet mark. Windows lacked per-socket marking in the RFC's snapshot. In addition, changing IP_TOS or IPV6_TCLASS can alter DSCP as well as ECN on some systems. Code that writes only for ECN may overwrite another component's service-class choice unless it preserves the existing field and coordinates concurrent updates.

These are not merely portability chores. They define who can see congestion, which connection receives the observation, and whether an application can distinguish a missing signal from a clear path. RFC 10055 also notes that uneven ECN support can help a peer identify an operating system, creating a privacy signal. It does not quantify how often that fingerprint is usable, and its platform guidance is expressly time-bounded.

The practical control is an observable capability matrix: socket family and dual-stack mode; reporting option accepted; ancillary type and data shape; ECN value recovered; DSCP preserved; and transport feedback validated. A green result for one row should not certify another operating system or address family. Nor does receipt of CE prove that the sender changed its congestion response. The socket is one link in a chain, not the end-to-end outcome.

The decision for transport maintainers is narrow but consequential: treat UDP ECN support as a tested interface contract, not as a property inherited automatically from the protocol or kernel. Keep the common requirement small—deliver the correct per-datagram codepoint without corrupting adjacent DSCP state—and allow operating systems to expose it through their local APIs. Then make that contract visible in continuous tests.

Sources