FreeBSD の「net.inet.tcp.always_keepalive」が RFC1122 に違反するのはなぜですか?

FreeBSD の「net.inet.tcp.always_keepalive」が RFC1122 に違反するのはなぜですか?

FreeBSD 上で実行され、TCP を使用するサーバー アプリケーションで作業しているときに、アプリケーションが TCP ソケットで SO_KEEPALIVE を明示的に無効にしているにもかかわらず、TCP キープアライブ プローブが送信されることに気付きました。

によるとRFC1122 セクション 4.2.3.6(TCP キープアライブ):

「キープアライブが含まれている場合、アプリケーションは TCP 接続ごとにキープアライブをオンまたはオフにできなければならず、デフォルトではオフに設定されている必要があります。」

調整可能なパラメータがネット.inet.tcp.always_keepalive有効(1 に設定)になっており、無効にするとキープアライブ プローブの送信が停止されることがわかりました。

FreeBSD にこの動作を組み込んだ理由は何ですか? 私の知る限り、Linux と Windows にはそのようなオプションはありませんが、FreeBSD と Mac OS X にはあるため、RFC に違反しています。

もっと具体的に言うと、どのような状況でアプリケーションの要望を無視するのが合理的でしょうか?

私の場合はオプションを無効にできるので、これは簡単な修正ですが、なぜオプションが存在するのかを理解したいと思います。

この質問Linux が RFC に従って動作することを示しています。

答え1

キープアライブをデフォルトでオンにする理由は、次のとおりです。https://svnweb.freebsd.org/base?view=revision&revision=47752

グローバル TCP キープアライブを制御するためのハンドルを追加し、デフォルトでオンにします。

名前に反して、TCP セッションを維持することはできず、相手側が AWOL になった場合にセッションを終了します。これは、NAT、動的 IP 割り当てを使用するクライアント、またはアップタ​​イムの上限が 2^32 * 10^-3 秒であるクライアントでよく発生します。

このため、ネットワーク トラフィックの増加は検出されません。ライブ TCP 接続では、2 時間ごとに 2 つの最小 TCP パケットが送信されます。

多くのサーバーでは、すでにキープアライブが有効になっています。

ホスト要件の RFC は 10 年前のものであり、今日のインターネットのクライアントの減少については考慮されていません。

いずれにしても、アプリケーションから要求された場合は、キープアライブをオフにする方がよいでしょう。たとえば、次のようになります (C の場合)。

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

しかし、これを修正するのは簡単ではありません。

答え2

調整可能なノブは存在すべきだと思いますが、デフォルトではオフにしておく方がよかったかもしれません。

私の考えは、アプリケーション開発者はこうした種類の決定を誤る可能性があり、最終的にはアプリケーション開発者ではなくシステム管理者がこうした種類のネットワーク ポリシーを制御する必要があるということです。

関連情報