Adding support for this to existing name server implementations is relatively easy, but does require source code modifications. It is also controlled via various kernel parameter parameters documented below.
Client side code changes
- The server must simply set the TCP_FASTOPEN flag using setsockopt() on the listening socket (note on OS X the socket MUST be listening already for this flag to be set, and the qlen MUST be 1). On linux this can be done after bind() is called.
The kernel parameter net.ipv4.tcp_fastopen controls TFO and since 4.1 has been set to 1 by default. This enables client mode but not server mode. To act in pure server mode set the integer value to 2. To enable both client and server mode, set it to 3, for example:
sysctl -w net.ipv4.tcp_fastopen=2
The analogous kernel parameter is net.inet.tcp.fastopen but is set to 3 by default. The fastopen backlog and fallback minimum can also be set via kernel parameter.
The parameter net.inet.tcp.clear_tfocache can be used to reset the TFO back-off when problems are encountered (this can be helpful when testing).
- 6 kernel parameters are available, TFO is controlled by net.inet.tcp.fastopen.enabled which is 0 by default and must be 1 to enable TFO.
The implementations have slightly different behaviour on the wire. Observations from testing include:
- The current Linux client implementation (4.4 at the time of writing) does not currently support receiving data in the SYN-ACK (although it should to be compliant with the spec). But a patch for this has been submitted. This can cause interop problems because the server must re-transmit the data. OS X does support this (no FreeBSD client implemented yet).
- The back-off algorithms also appear different. For example, the OS X implementation will fallback to normal TCP for a long period of time if it detects problems during cookie or TFO data exchange.
- Prior to 4.1 Linux used the experimental option code and format for TFO, in 4.1 the default is to use the official option code and format but fallback to the experimental code is still supported.