unix - 約束事その他の説明 - Linux コマンド集 一覧表
名前
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_LOCAL
や
PF_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 型で指定する。 これらを送るには、構造体 cmsghdr の cmsg_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 オプションを有効にしなくてはならない。
バージョン
SCM_CREDENTIALS と抽象名前空間は、Linux 2.2 で導入された。 移植性が必要なプログラムでは使うべきではない。 (BSD 由来のシステムの中にも信任状の送受信をサポートしているものがあるが、 その実装の詳細はシステムによって異なる)
注意
Linux の実装では、ファイルシステム上から見えるソケットは、
それらが置かれているディレクトリのパーミッションに従う。
ソケットの所有者、グループ、パーミッションは変更できる。
新しいソケットを作るとき、作ろうとするディレクトリに対して
プロセスが書き込みと検索 (実行) 権限を持っていなければ、作成に失敗する。
ソケットオブジェクトに接続するには、 read/write 権限が必要である。
この動作は、多くの BSD 由来のシステムとは異なっている
(BSD では Unix ソケットに対してはパーミッションを無視する)。
移植性の必要なプログラムでは、
セキュリティをこの仕様に依存してはならない。
ファイル名を指定してソケットにバインドすると、
ファイルシステムにソケットが生成される。
これは必要なくなったときに呼びだしたユーザーが削除しなければならない
(
unlink
(2)を用いる)。
Unix で通常使われる「背後で閉じる方式」が適用される。
ソケットはいつでも unlink することができ、最後の参照が
クローズされたときにファイルシステムから削除される。
SOCK_STREAM 上でファイルディスクリプタや信任状を渡すためには、
同じ
sendmsg
()や
recvmsg
()コールで補助データ以外のデータを少なくとも
1 バイト送信/受信する必要がある。
エラー
- 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 ページを参照すること。
関連項目
recvmsg
(2),
sendmsg
(2),
socket
(2),
socketpair
(2),
cmsg
(3),
capabilities
(7),
socket
(7)