Freebsd

(為什麼)FreeBSD ’net.inet.tcp.always_keepalive’ 違反 RFC1122?

  • April 17, 2016

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

根據RFC1122 第 4.2.3.6 節(TCP Keep-Alives):

“如果包含 keep-alives,應用程序必須能夠為每個 TCP 連接打開或關閉它們,並且它們必須預設為關閉。”

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

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

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

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

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

這裡給出了預設開啟 keep-alive 的理由:https ://svnweb.freebsd.org/base?view=revision&revision=47752

添加句柄以控制全域 TCP keepalives 並將其預設打開。

儘管他們的名字它不會讓 TCP 會話保持活動狀態,但如果另一端已經離開,它會殺死它們。對於使用 NAT、動態 IP 分配或正常執行時間上限為 2^32 * 10^-3 秒的客戶端,這種情況經常發生。

因此,網路流量沒有可檢測到的增加:對於實時 TCP 連接,每兩小時有兩個最小的 TCP 數據包。

許多伺服器已經自己啟用了keepalives。

主機需求 RFC 已有 10 年曆史,不了解當今 Internet 的客戶流失情況。

無論如何,如果應用程序要求,最好關閉保持活動,例如(在 C 中):

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

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

引用自:https://serverfault.com/questions/671710