ソケットパスの長さが100文字に制限されているのはなぜですか?


18

Unixシステムでは、パス名には通常、長さの制限はほとんどありません(Linuxでは4096文字)...ソケットファイルのパスは100文字Linuxでは 107文字)に制限されています。

  • 最初の質問:なぜそんなに低い制限があるのか​​?

私はそれはいくつかのソケットが同じパスを使用して、すべてのファイルを現在の作業ディレクトリを変更し、さまざまなディレクトリに作成することによって、この制限を回避することが可能と思われることを確認しました./myfile.sockクライアントアプリケーションが正しく偶数かかわらず、期待されるサーバプロセスに接続するように見える:lsofショーのすべて同じソケットファイルパスでリッスンします。

  • この回避策は信頼性がありますか、それとも私は幸運でしたか?
  • この動作はLinux固有のものですか、またはこの回避策は他のUnixにも適用できますか?

制限は、現在のOpenBSDシステムまたはMac OS X 10.11ではさらに低くなっています(104)。
thrig

重要なことは、互換性のために108より低くなければならないことです:)

私の知る限り、Linuxでは108文字です。マシンの/usr/include/$arch-linux-gnu/sys/un.hを確認してください。
チャイバ

@schaiba:108バイト。これは、ヌルターミネータで終了する107文字の文字列を意味します。
-WhiteWinterWolf

回答:


18

使用している間、他のプラットフォーム、または古いものとの互換性との互換性は、オーバーランを避けるためにsnprintf()strncpy()

Michael Kerriskは、彼の本の1165ページ -章57、Sockets:Unix domain で説明しています。

SUSv3はsun_pathフィールドのサイズを指定しません。初期のBSD実装では108バイトと104バイトを使用し、現代的な実装(HP-UX 11)では92バイトを使用していました。ポータブルアプリケーションは、この低い値にコーディングし、snprintf()またはstrncpy()を使用して、このフィールドに書き込む際のバッファオーバーランを回避する必要があります。

一部のソケットは110文字の長さだったので、Dockerの男たちもそれをからかいました。

これが、LINUXが108文字のソケットを使用する理由です。これは変更できますか?もちろん。そして、これが、最初に古いオペレーティングシステムでこの制限が作成された理由です。

答えを引用する:

便利なカーネルデータ構造で利用可能なスペースを一致させることでした。

McKusickらによる「4.4BSDオペレーティングシステムの設計と実装」を引用 al。(369ページ):

メモリ管理機能は、mbufと​​呼ばれるデータ構造を中心に展開します。Mbufs、またはメモリバッファは128バイト長で、このスペースの100または108バイトがデータストレージ用に予約されています。

その他のOS(Unixドメインソケット):


1
SUSv3 XNETは、問題に関するコンセンサスがないため沈黙していました。
fpmurphy

あなたの視点を証明するリンクはありますか?

この答えをありがとう。それは、(例えば、名前のソケットファイルの作成別の作業ディレクトリからの相対同じ名前をもつ複数のソケットファイルを使用するために信頼性のある./my.socketディレクトリの下にA/も名前が付けられ、別のソケットファイル./my.socketディレクトリの下にB/)?lsof2つのソケットファイルを区別しませんが、まだ機能しているようですが、これは私が幸運だからだと思います。これは、既に許可されているサイズよりも長いパスの下にソケットファイルを作成するための適切な回避策です。
-WhiteWinterWolf

メールサーバーでUNIXソケットを検索すると、フルパス名が表示されるようです:(lsof -U| grep amavis改行)amavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock

はい、私はこれが異常であることを知っているので、ここで私の質問;)!私がテストしたものでは、相対名は機能しますが、それでも私には奇妙に思えます... 私のアプリケーションは、システム全体ではありませんので、ソケットファイルがどちらか強く好まれるユーザ制御の場所、でなく、潜在的に非常に長いパスを持つ他のすべてのアプリケーションデータを格納している、または私が乱雑にできる/tmp一意の名前の削除されていないディレクトリごとのトン単一のソケットファイルを含む(まったく見苦しいが、ポータブルで安全)。
-WhiteWinterWolf

5

理由については、nwildnerはすでに優れた答えを書いています

ここでは、どのように、どのように相対パスを使用するかに焦点を当てます。

内部的には、ソケットファイルは名前で検索することもできますが(私は推測します)、通常はiノードで検索されます。Linuxでは、この検索はnet / unix / af_unix.cでunix_find_socket_byinode()定義されている関数によって保証されます。

これは次のように簡単に確認できます。

  • 2つのディレクトリA /B /を作成します。
  • 各ディレクトリの下で、同じ名前のソケットファイルでプロセスをリッスンさせます。socatあなたのようなコマンドを使用します。
$ socat UNIX-LISTEN:./my.sock -
  • ここで、A / my.sockB /に、またはその逆に移動してソケットファイルを交換します。
  • これ以降、クライアントアプリケーションがA / my.sockに接続するとサーバーBに接続し、B / my.sockに接続するとサーバーAに接続します(ただし、通信が終了すると、サーバープロセスは独自のソケットファイルと思われるものを正当に削除します)。

少数のUnixシステム(Linux Debian、FreeBSD、およびOpenIndianaで多様性を得るため)でこの動作を確認したため、この動作は標準ではないにしても、少なくとも広く普及しているようです。

通常、クライアントプロセスはサーバーとの初期通信を確立する方法を知らない可能性があるため、絶対パスはクライアントプロセスとサーバープロセス間の規則として使用されます。

ただし、この最初の通信が問題にならない場合は、ソケットファイルの作成に相対パスを使用して、ソケットファイルの場所がサーバープロセスによって直接制御されていない場合のパスの長さの問題を回避できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.