unix

Autres langues

Langue: ja

Version: 2004-05-27 (mandriva - 01/05/08)

Section: 7 (Divers)

名前

unix, PF_UNIX, AF_UNIX, PF_LOCAL, AF_LOCAL - ローカルな プロセス間通信用のソケット

書式

#include <sys/socket.h>
#include <sys/un.h>

unix_socket = socket(PF_UNIX, type, 0);
error = socketpair(PF_UNIX, type, 0, int *sv);

説明

PF_UNIX (PF_LOCALPF_FILE とも言われる) ソケットファミリーは、同じマシン上でプロセス同士が 効率的に通信するために用いられる。 Unix ソケットは、 (socketpair(2) で作成して) 名前なしにもできるし、ソケット型のファイルに 関連づけることもできる。 さらに Linux では、ファイルシステムに依存しない 抽象名前空間 (abstract namespace) もサポートしている。

有効なタイプは以下の通りである:

SOCK_STREAM
ストリーム指向のソケット
SOCK_DGRAM
メッセージ境界を保存するデータグラム指向のソケット (ほとんどの Unix の実装では、Unix ドメイン・データグラム・ソケットは 常に信頼でき、データグラムの並び替えは行わない)
SOCK_SEQPACKET
(カーネル 2.6.4 以降で利用できる) メッセージ境界を保存し、送信された順序でメッセージを届ける接続指向ソケット

Unix ソケットでは、補助データを使って ファイルディスクリプタやプロセスの信任状 (credential) を 送受信することもできる。

アドレスのフォーマット

Unix アドレスはファイルシステムではファイル名として定義され、 抽象名前空間では他と重ならない文字列として定義されている。 socketpair(2) で作られたソケットは名前がない。名前なしソケット以外のソケットでは、 接続先ターゲットのアドレスを connect(2) を使って設定できる。 ローカルアドレスは bind(2) を使って設定できる。 ローカルアドレスをまだ持っていないソケットが接続された場合、 自動的に抽象名前空間に他と重ならないアドレスが生成される。
 #define UNIX_PATH_MAX    108
 
 struct sockaddr_un {
     sa_family_t    sun_family;               /* AF_UNIX */
     char           sun_path[UNIX_PATH_MAX];  /* pathname */
 };
 

sun_family には必ず AF_UNIX が入っている。 sun_path には、ファイルシステム中のソケット名が、 NULL で終端された文字列として 格納されている。 sun_path が NULL バイト ('\0') で始まる場合、 これは Unix プロトコルモジュールで管理されている 抽象名前空間を参照する。 この名前空間におけるソケットのアドレスは、 sun_path の残りのバイトで表される。 抽象名前空間に置ける名前は NULL で終端されていないことに注意。

ソケットオプション

歴史的な理由により、これらのオプションは たとえ PF_UNIX 固有のオプションであっても SOL_SOCKET 型で指定する。 ソケットファミリーとして SOL_SOCKET を指定すると、 setsockopt(2) でオプションが設定でき、 getsockopt(2) で取得ができる。
SO_PASSCRED
送信プロセスの補助メッセージとして信任状を受信できるようにする。 このオプションがセットされていて、まだソケットが接続されていないと、 抽象名前空間に他と重ならない名前が自動的に生成される。 ブール整数値のフラグを取る。

サポートされている機能、されていない機能

この節では、Linux の Unix ドメイン・ソケットでの、 ドメイン固有の詳細仕様とソケット API でサポートされていない機能に ついて説明する。

Unix ドメイン・ソケットでは、帯域外データ (out-of-band data) の 送信 (send(2) と recv(2) の MSG_OOB フラグ) はサポートされていない。

send(2) MSG_MORE フラグは Unix ドメイン・ソケットではサポートされていない。

SO_SNDBUF ソケットオプションは Unix ドメイン・ソケットで効果を持つが、 SO_RCVBUF は効果がない。 データグラム・ソケットでは、 SO_SNDBUF の値が出力データグラムの上限サイズとなる。 実際の上限値は、 SO_SNDBUF オプションとして設定された値の 2倍 (socket(7) 参照) からオーバヘッドとして使用される 32 バイトを引いた値となる。

補助メッセージ

補助データを送受するには、 sendmsg(2) や recvmsg(2) を使用する。 歴史的な理由により、以下に示す補助メッセージの型は たとえ PF_UNIX 固有のものであっても SOL_SOCKET 型で指定する。 これらを送るには、構造体 cmsghdrcmsg_level フィールドに SOL_SOCKET をセットし、 cmsg_type フィールドにタイプをセットする。 詳細は cmsg(3) を見よ。
SCM_RIGHTS
他のプロセスでオープンされたファイルディスクリプタのセットを送受信する。 データ部分にファイルディスクリプタの整数配列が入っている。 渡されたファイルディスクリプタは、あたかも dup(2) で生成されたかのように振る舞う。
SCM_CREDENTIALS
Unix 信任状を送受信する。これは認証に用いることができる。 信任状は、 struct ucred の補助メッセージとして渡される。
 struct ucred {
     pid_t pid;    /* process ID of the sending process */
     uid_t uid;    /* user ID of the sending process */
     gid_t gid;    /* group ID of the sending process */
 };
 

送信側が指定した信任状は、カーネルがチェックする。 実効ユーザー ID が 0 のプロセスには、 自分自身以外の値を指定する事が許される。 送信側は以下の 3 つを指定しなければならない。 1) 自分自身のプロセス ID (CAP_SYS_ADMIN 権限を持っていない場合)、 2) 自分自身のユーザー ID あるいは実効ユーザー ID か保存 set-user-ID (CAP_SETUID 権限を持っていない場合)、 3) 自分自身のグループ ID あるいは実行グループ ID か保存 set-group-ID (CAP_SETGID を持っていない場合)。 struct ucred メッセージを受信するためには、ソケットに対し SO_PASSCRED オプションを有効にしなくてはならない。

エラー

ENOMEM
メモリが足りない。
ECONNREFUSED
listen 状態にないソケットオブジェクトに対して connect(2) が呼ばれた。リモートソケットが存在していなかった、 ファイル名がソケットではなかった、などのときに起こる。
EINVAL
渡した引数が不正。よくある原因は、 渡したアドレスの sun_type フィールドに AF_UNIX を設定しなかった、 行おうとした操作に対してソケットの状態が有効ではなかった、など。
EOPNOTSUPP
ストリーム指向でないソケットに対してストリーム操作が呼び出された。 または帯域外データオプションを用いようとした。
EPROTONOSUPPORT
渡されたプロトコルが PF_UNIX でない。
ESOCKTNOSUPPORT
未知のソケットタイプ。
EPROTOTYPE
リモートソケットとローカルソケットのタイプが一致していなかった (SOCK_DGRAM と SOCK_STREAM)。
EADDRINUSE
選択したソケットが既に用いられていた。または、 ファイルシステムのソケットオブジェクトが既に存在していた。
EISCONN
既に接続されているソケットに対して connect(2) が呼ばれた。または、指定したターゲットアドレスが 既に接続済みのソケットだった。
ENOTCONN
ソケット操作にターゲットアドレスが必要だが、 このソケットは接続されていない。
ECONNRESET
リモートソケットが予期しないかたちでクローズされた。
EPIPE
リモートソケットがストリームソケット上でクローズされた。 可能な場合は SIGPIPE も同時に送られる。これを避けるには MSG_NOSIGNAL フラグを sendmsg(2) や recvmsg(2) に渡す。
EFAULT
ユーザーメモリアドレスが不正。
EPERM
送信者が struct ucred に不正な信任状を渡した。

他にも汎用のソケット層でエラーが起こったり、 ファイルシステム上にソケットオブジェクトを作ろうとした場合に ファイルシステムのエラーが起こることがある。 それぞれの詳細は適切な man ページを参照すること。

バージョン

SCM_CREDENTIALS と抽象名前空間は、Linux 2.2 で導入された。 移植性が必要なプログラムでは使うべきではない。 (BSD 由来のシステムの中にも信任状の送受信をサポートしているものがあるが、 その実装の詳細はシステムによって異なる)

注意

Linux の実装では、ファイルシステム上から見えるソケットは、 それらが置かれているディレクトリのパーミッションに従う。 ソケットの所有者、グループ、パーミッションは変更できる。 新しいソケットを作るとき、作ろうとするディレクトリに対して プロセスが書き込みと検索 (実行) 権限を持っていなければ、作成に失敗する。 ソケットオブジェクトに接続するには、 read/write 権限が必要である。 この動作は、多くの BSD 由来のシステムとは異なっている (BSD では Unix ソケットに対してはパーミッションを無視する)。 移植性の必要なプログラムでは、 セキュリティをこの仕様に依存してはならない。

ファイル名を指定してソケットにバインドすると、 ファイルシステムにソケットが生成される。 これは必要なくなったときに呼びだしたユーザーが削除しなければならない (unlink(2) を用いる)。 Unix で通常使われる「背後で閉じる方式」が適用される。 ソケットはいつでも unlink することができ、最後の参照が クローズされたときにファイルシステムから削除される。

SOCK_STREAM 上でファイルディスクリプタや信任状を渡すためには、 同じ sendmsg(2) や recvmsg(2) コールで補助データ以外のデータを少なくとも 1 バイト送信/受信する必要がある。

Unix ドメインのストリーム・ソケットでは、 帯域外データの概念はサポートされない。

bind(2) 参照。

関連項目

recvmsg(2), sendmsg(2), socket(2), socketpair(2), cmsg(3), capabilities(7), socket(7)