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
調整可能なノブは存在すべきだと思いますが、デフォルトではオフにしておく方がよかったかもしれません。
私の考えは、アプリケーション開発者はこうした種類の決定を誤る可能性があり、最終的にはアプリケーション開発者ではなくシステム管理者がこうした種類のネットワーク ポリシーを制御する必要があるということです。