(为什么)FreeBSD的“net.inet.tcp.always_keepalive”违反RFC1122?

在使用运行在FreeBSD上的服务器应用程序并使用TCP时,我注意到即使我的应用程序显式禁用TCP套接字上的SO_KEEPALIVE,TCP保持活动探测也会被发送。

根据RFC1122第4.2.3.6节 (TCP Keep-Alives):

“如果包含keepalive,应用程序必须能够打开或closures每个TCP连接,并且它们必须默认closures。”

我发现可调参数net.inet.tcp.always_keepalive已被启用(设置为1),禁用它将阻止keepalive探测发送。

在FreeBSD中包含这个行为的原因是什么? 据我所知,Linux和Windows没有这样的select,但是FreeBSD和Mac OS X都这样做,所以他们违反了RFC。

更具体地说,在什么情况下忽略申请的意愿是有意义的?

在我的情况下,这是一个简单的解决方法,因为我可以禁用该选项,但我想了解为什么它在那里。

这个问题表明Linux根据RFC运行。

默认情况下保持活动状态的理由如下: https : //svnweb.freebsd.org/base?view=revision&revision=47752

添加句柄来控制全局TCP keepalive,并将其作为默认开启。

尽pipe他们的名字不会让TCP会话保持活跃,但如果另一端已经离职,就会杀死它们。 对于使用NAT,dynamicIP分配或在正常运行时间上有2 ^ 32 * 10 ^ -3秒上限的客户端,会发生这种情况。

networkingstream量没有可检测到的增加,因为这个:每两个小时对于一个实时TCP连接两个最小的TCP分组。

许多服务器已经启用了Keepalive。

主机要求RFC是10岁,不知道今天InterNet的松动客户端。

无论如何,如果应用程序要求,最好closures保持活动状态,例如(在C中):

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

但解决这个问题并不容易。

我认为可调旋钮应该存在,但也许最好保持closures默认情况下。

我的推理是这样的,一个应用程序开发人员可以做出这种错误的决定,最终是一个系统pipe理员,应该控制这种networking策略而不是应用程序开发人员。