(為什麼)FreeBSD“net.inet.tcp.always_keepalive”違反了 RFC1122?

(為什麼)FreeBSD“net.inet.tcp.always_keepalive”違反了 RFC1122?

在開發在 FreeBSD 上運行並使用 TCP 的伺服器應用程式時,我注意到即使我的應用程式在 TCP 套接字上明確禁用 SO_KEEPALIVE,也會發送 TCP keepalive 探測。

根據RFC1122 第 4.2.3.6 節(TCP 保持活動):

“如果包含保持活動,應用程式必須能夠為每個 TCP 連線開啟或關閉它們,並且它們必須預設為關閉。”

我發現可調參數net.inet.tcp.always_keepalive已啟用(設定為 1),停用它會阻止發送 keepalive 探測。

將這種行為包含在 FreeBSD 中的原因是什麼?據我所知,Linux 和 Windows 沒有這樣的選項,但 FreeBSD 和 Mac OS X 有,因此它們違反了 RFC。

更具體地說,在什麼情況下忽略應用程式的願望才有意義?

在我的情況下,這是一個簡單的修復,因為我可以停用該選項,但我想了解它的原因。

這個問題表示 Linux 的行為符合 RFC。

答案1

預設開啟保持活動的基本原則如下:https://svnweb.freebsd.org/base?view=revision&revision=47752

新增句柄來控制全域 TCP keepalive 並將其預設為開啟。

儘管名稱如此,但它並不能保持 TCP 會話處於活動狀態,但如果另一端擅離職守,它就會殺死它們。對於使用 NAT、動態 IP 分配或正常運行時間上限為 2^32 * 10^-3 秒的用戶端,這種情況經常發生。

由於以下原因,網路流量沒有可偵測到的增加:對於即時 TCP 連接,每兩小時有兩個最小 TCP 封包。

許多伺服器本身已經啟用了保活。

主機要求 RFC 已經有 10 年歷史了,而且不知道當今互聯網的客戶流失情況。

無論如何,如果應用程式請求,最好關閉以保持活動狀態,例如(在 C 中):

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

但解決這個問題並不容易。

答案2

我認為可調旋鈕應該存在,但也許默認情況下將其關閉更好。

我的理由是,應用程式開發人員可能會做出錯誤的此類決策,最終系統管理員應該控制此類網路策略,而不是應用程式開發人員。

相關內容