El Capitan: does it deal with network congestion at last?

The Internet is becoming increasingly congested. This is even more noticeable when you have a high-bandwidth connection to your ISP, but sometimes connections are so slow that they might as well be running over lengths of wet string.

A good idea

Nearly fifteen years ago, an extension was made to the TCP and IP protocols which are fundamental to networking and the Internet, to support Explicit Congestion Notification (ECN), a method which is designed to cope better with network congestion. Traditionally, when a network becomes congested, the way that this is signalled is by dropping packets: in other words, when connections start to slow up, the method of indicating that makes the connection even less efficient, and may make it noticeably slower too.

ECN allows compatible devices to mark packets to indicate that there is congestion; the recipient then informs the sender that there is congestion, without any deliberate data loss.

The snag is that not all routers and other devices on the Internet support ECN. Because it uses bit flags in the packets being transmitted, some servers will actually refuse to accepted connections using ECN, and some network equipment may also barf over such packets. Although latest information is that this affects less than 1% of web servers, it would be extremely frustrating to users if they consistently failed to connect with those few sites.

Support

OS X has had support for ECN built into its kernel since version 10.5, but it has remained disabled by default. Back in June 2015, Apple boldly announced that ECN would be turned on by default in OS X 10.11 El Capitan, and in iOS 9.0. With the hundreds of millions of devices which would then be expecting to use ECN, it was hoped that would encourage the remaining few incompatible servers and devices to get fixed quick.

As far as I can tell here, though, my copy of OS X 10.11.2 is still not running ECN.

Investigating

Because ECN is handled low down in the kernel, it is not easy to explore. However, if you want to discover whether your Mac has it turned on, open Terminal and type the command
sysctl net.inet.tcp
to display a long list of TCP settings. Within those, you will see the following:
net.inet.tcp.ecn_timeout: 60
net.inet.tcp.ecn_initiate_out: 0
net.inet.tcp.ecn_negotiate_in: 0

The first simply gives the timeout setting, but the other two should be set to 1 for ECN to come into use.

You can enable ECN yourself, again in Terminal’s command line, using the two commands
sysctl -w net.inet.tcp.ecn_negotiate_in=1
sysctl -w net.inet.tcp.ecn_initiate_out=1

However, those changes do not persist through a restart or shutdown. To make them permanent, you would need to put them into a file named sysctl.conf in the hidden /etc folder, which is actually in /private/etc. Interestingly, that file does not even exist on this Mac running OS X 10.11.2. If yours does (or you wish to create your own), then the lines which are required are:
net.inet.tcp.ecn_initiate_out=1
net.inet.tcp.ecn_negotiate_in=1

Unfortunately you may well trip over SIP‘s protection for system files, and have to turn that off before you can make any such change.

If your Mac does have ECN turned on, you can inspect its use by typing the following command in Terminal
netstat -sp tcp

This will return a long list of statistics for TCP connections, within which you should see entries for ECN. Mine are all empty, reading
0 client connection attempted to negotiate ECN
0 client connection successfully negotiated ECN
0 time graceful fallback to Non-ECN connection
0 time lost ECN negotiating SYN, followed by retransmission
0 server connection attempted to negotiate ECN
0 server connection successfully negotiated ECN
0 time lost ECN negotiating SYN-ACK, followed by retransmission
0 time received congestion experienced (CE) notification
0 time CWR was sent in response to ECE
0 time sent ECE notification
0 connection received CE atleast once
0 connection received ECE atleast once
0 connection using ECN have seen packet loss but no CE
0 connection using ECN have seen packet loss and CE
0 connection using ECN received CE but no packet loss

So do Macs and iOS devices now by default use ECN? Not as far as I can see. I wonder why not?