Freebsd – (Why) does FreeBSD ‘net.inet.tcp.always_keepalive’ violate RFC1122

freebsdkeepalivetcp

While working on a server application that runs on FreeBSD and uses TCP, I noticed that TCP keepalive probes get
sent even though my application explicitly disables SO_KEEPALIVE on TCP sockets.

According to RFC1122 Section 4.2.3.6 (TCP Keep-Alives):

"If keep-alives are included, the application MUST be able to turn
them on or off for each TCP connection, and they MUST default to off."

I found that the tuneable parameter net.inet.tcp.always_keepalive had been enabled (set to 1), and that disabling it would stop the keepalive probes from being sent.

What is the reasoning behind the inclusion of this behaviour in FreeBSD? From what I can tell, Linux and Windows do not have such an option, but FreeBSD and Mac OS X do, so they violate the RFC.

To be more specific, under what circumstance would it make sense to ignore the application's wishes?

This is a straightforward fix in my case as I can disable the option, but I'd like to understand why it's there.

This question shows that Linux behaves according to the RFC.

Best Answer

Rationale for turning keep-alive on by default was given here: https://svnweb.freebsd.org/base?view=revision&revision=47752

Add handle to control global TCP keepalives and turn them on as default.

Despite their name it doesn't keep TCP sessions alive, it kills them if the other end has gone AWOL. This happens a lot with clients which use NAT, dynamic IP assignment or which has a 2^32 * 10^-3 seconds upper bound on their uptime.

There is no detectable increase in network trafic because of this: two minimal TCP packets every two hours for a live TCP connection.

Many servers already enable keepalives themselves.

The host requirements RFC is 10 years old, and doesn't know about the loosing clients of todays InterNet.

Anyway it is better to turn keep-alive off if requested by application, for example (in C):

int val = 0;
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));

but it is not easy to fix this.