為什麼套接字路徑長度限制為一百個字元?

為什麼套接字路徑長度限制為一百個字元?

在 Unix 系統上,路徑名通常沒有長度限制(Linux 上是 4096 個字元)...除了套接字檔案路徑,其長度限制為約100個字符(107 個字符Linux)。

  • 第一個問題:為什麼限制這麼低?

我已經檢查過,似乎可以透過更改當前工作目錄並在各個目錄中創建多個使用相同路徑的套接字檔案來解決此限制./myfile.sock:客戶端應用程式似乎正確連接到預期的伺服器進程,儘管lsof顯示了所有它們監聽同一個套接字檔案路徑。

  • 這個解決方法可靠還是我只是幸運?
  • 此行為是 Linux 特有的還是此解決方法也適用於其他 Unix?

答案1

與其他平台的兼容性,或與舊版本的兼容性,以避免使用snprintf()和時出現溢出strncpy()

邁克爾·克里克 (Michael Kerrisk) 解釋道他的書第 1165 頁- 第 57 章,套接字:Unix 網域:

SUSv3 未指定 sun_path 欄位的大小。早期的 BSD 實作使用 108 和 104 字節,而一種現代實作 (HP-UX 11) 使用 92 位元組。便攜式應用程式應編碼為這個較低的值,並使用 snprintf() 或 strncpy() 以避免寫入此欄位時緩衝區溢位。

Docker 的人甚至取笑它,因為有些套接字的長度是 110 個字元:

這就是 LINUX 使用 108 字元套接字的原因。這可以改變嗎?當然。這就是為什麼首先在舊作業系統上建立此限制的原因:

引用一下答案:

它是為了匹配方便的核心資料結構中的可用空間。

引用 McKusick 等人的《4.4BSD 作業系統的設計與實現》。等人。 (第 369 頁):

記憶體管理設施圍繞著稱為 mbuf 的資料結構。 Mbufs(即記憶體緩衝區)長 128 字節,其中 100 或 108 位元組的空間保留用於資料儲存。

其他作業系統(unix 域套接字):

答案2

關於原因,nwildner 已經寫了一篇很好的答案

這裡我只關注如何使用以及相對路徑的使用。

在內部,雖然套接字檔案也可以透過名稱找到(我猜),但它們通常是透過索引節點來尋找的。在 Linux 中,此查找由unix_find_socket_byinode()定義在網/unix/af_unix.c

這可以很容易地檢查如下:

  • 建立兩個目錄A/乙/
  • 在每個目錄下,讓一個程序偵聽具有相同名稱的套接字檔案。和socat您可以使用以下命令:
$ socat UNIX-LISTEN:./my.sock -
  • 現在透過移動來交換套接字文件A/my.sock乙/反之亦然。
  • 從現在開始,如果客戶端應用程式連接到A/my.sock它將聯繫伺服器,如果它連接到B/my.sock它將聯繫伺服器A(但請注意,當通訊結束時,伺服器進程可以合法地刪除它認為是自己的套接字檔案的內容)。

我在一些 Unix 系統(Linux Debian、FreeBSD 和 OpenIndiana 以獲得一些多樣性)上檢查了這種行為,因此這種行為即使不是標準的,至少也是廣泛傳播的。

絕對路徑通常用作客戶端和伺服器進程之間的約定,因為客戶端進程可能不知道如何與伺服器建立初始通訊。

但是,如果這種初始通訊不是問題,那麼使用相對路徑建立套接字檔案似乎是安全的,這樣可以在套接字檔案位置不直接由伺服器進程控制時避免路徑長度問題。

相關內容