UNIX(7) | Linux Programmer's Manual | UNIX(7) |
名前
unix -ローカルなプロセス間通信用のソケット書式
#include <sys/socket.h>説明
AF_UNIX ( AF_LOCAL とも言われる) ソケットファミリーは、同じマシン上でプロセス同士が効率的に通信するために用いられる。伝統的に、UNIX ドメインソケットは、名前なしにもできるし、 (ソケット型であると印のついた) ファイルシステムのパス名に結び付けることもできる。さらに Linux では、ファイルシステムに依存しない抽象名前空間 (abstract namespace) もサポートしている。アドレスのフォーマット
UNIX ドメインソケットのアドレスは以下の構造体で表現される。
#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 が入っている。
この構造体では 3 種類のアドレスが区別される。
- *
- pathname (パス名): bind(2) を使って、UNIX ドメインソケットを NULL 終端されたファイルシステム上のパス名に結び付けることができる。 getsockname(2), getpeername(2), accept(2) がソケットのアドレスを返す際には、その長さは offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1 であり、 sun_path に NULL 終端されたパス名が格納される。
- *
- unnamed (名前なし): bind(2) を使ってパス名に結び付けることができないストリーム型のソケットは名前を持たない。同様に、 socketpair(2) で作成される 2 つのソケットも名前を持たない。 getsockname(2), getpeername(2), accept(2) が名前なしのソケットのアドレスを返す際には、その長さは sizeof(sa_family_t) であり、 sun_path は検査すべきではない。
- *
- abstract (抽象): 抽象ソケットアドレスは、 sun_path[0] が NULL バイト ('\0') であることで区別される。この名前空間におけるソケットのアドレスは、 sun_path の残りのバイトの、アドレス構造体の指定された長さの範囲で表される (名前中の NULL バイトには特別な意味はない)。この名前はファイルシステムのパス名とは何の関係もない。 getsockname(2), getpeername(2), accept(2) が抽象ソケットのアドレスを返す際には、返される addrlen は sizeof(sa_family_t) より大きく (つまり 2 より大きく)、ソケットの名前は sun_path の最初の (addrlen - sizeof(sa_family_t)) バイトに格納される。ソケットの抽象名前空間は Linux による拡張であり、移植性はない。
ソケットオプション
歴史的な理由により、これらのオプションはたとえ AF_UNIX 固有のオプションであっても SOL_SOCKET 型で指定する。ソケットファミリーとして SOL_SOCKET を指定すると、 setsockopt(2) でオプションが設定でき、 getsockopt(2) で取得ができる。- SO_PASSCRED
- 送信プロセスの補助メッセージで信任状を受信できるようにする。このオプションがセットされていて、まだソケットが接続されていないと、抽象名前空間に他と重ならない名前が自動的に生成される。ブール整数値のフラグを取る。
自動バインド (autobind) 機能
bind(2) 呼び出しで sizeof(sa_family_t) として addrlen を指定するか、アドレスに明示的にバインドされていないソケットに対して SO_PASSCRED ソケットオプションが指定されていた場合、そのソケットは抽象アドレスに自動的にバインドされる。このアドレスは、1 個の NULL バイトの後に、文字集合 [0-9a-f] のバイトが 5 個続く形式である。したがって、自動的にバインドされるアドレス数には 2^20 個という上限が存在する。 (Linux 2.1.15 以降で、自動バインド機能が追加されたときには、 8 バイトが使われており、自動バインドアドレス数の上限は 2^32 であった。 Linux 2.3.15 で 5 バイトに変更された。)ソケット API
この節では、Linux の UNIX ドメインソケットでの、ドメイン固有の詳細仕様とソケット API でサポートされていない機能について説明する。補助メッセージ
補助データを送受するには、 sendmsg(2) や recvmsg(2) を使用する。歴史的な理由により、以下に示す補助メッセージの型はたとえ AF_UNIX 固有のものであっても SOL_SOCKET 型で指定する。これらを送るには、構造体 cmsghdr の cmsg_level フィールドに SOL_SOCKET をセットし、 cmsg_type フィールドにタイプをセットする。詳細は cmsg(3) を見よ。- SCM_RIGHTS
- 他のプロセスでオープンされたファイルディスクリプタのセットを送受信する。データ部分にファイルディスクリプタの整数配列が入っている。渡されたファイルディスクリプタは、あたかも dup(2) で生成されたかのように振る舞う。
- SCM_CREDENTIALS
-
UNIX 信任状を送受信する。これは認証に用いることができる。信任状は
struct ucred の補助メッセージとして渡される。この構造体は
<sys/socket.h> で以下のように定義されている。
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 */
};
ioctl
以下の ioctl(2) 呼び出しは value に情報を入れて返す。正しい書式は以下の通り。
int value ;
error = ioctl( unix_socket , ioctl_type , & value );
ioctl_type には以下を指定できる:
- SIOCINQ
- 受信バッファのキューにある、まだ読んでいないデータの量を返す。ソケットは LISTEN 状態にあってはならず、さもないとエラー ( EINVAL) が返る。 SIOCINQ は <linux/sockios.h> で定義されている。代わりに、 <sys/ioctl.h> で定義されている、同義語の FIONREAD を使うこともできる。
エラー
- EADDRINUSE
- 指定したローカルアドレスが既に使用されているか、ファイルシステムのソケットオブジェクトが既に存在している。
- ECONNREFUSED
- connect(2) により指定されたリモートアドレスが接続待ちソケットではなかった。ターゲットアドレスがソケットではない場合にもこのエラーが発生する。
- ECONNRESET
- リモートソケットが予期しないかたちでクローズされた。
- EFAULT
- ユーザーメモリアドレスが不正。
- EINVAL
- 渡した引数が不正。よくある原因としては、渡したアドレスの sun_type フィールドに AF_UNIX が指定されていなかった、行おうとした操作に対してソケットが有効な状態ではなかった、など。
- EISCONN
- 既に接続されているソケットに対して connect(2) が呼ばれた。または、指定したターゲットアドレスが既に接続済みのソケットだった。
- ENOENT
- connect(2) に指定されたリモートアドレスのパス名が存在しなかった。
- ENOMEM
- メモリが足りない。
- ENOTCONN
- ソケット操作にターゲットアドレスが必要だが、このソケットは接続されていない。
- EOPNOTSUPP
- ストリーム指向でないソケットに対してストリーム操作が呼び出された。または帯域外データオプションを用いようとした。
- EPERM
- 送信者が struct ucred に不正な信任状を渡した。
- EPIPE
- リモートソケットがストリームソケット上でクローズされた。可能な場合は SIGPIPE も同時に送られる。これを避けるには MSG_NOSIGNAL フラグを sendmsg(2) や recvmsg(2) に渡す。
- EPROTONOSUPPORT
- 渡されたプロトコルが AF_UNIX でない。
- EPROTOTYPE
- リモートソケットとローカルソケットのタイプが一致していなかった ( SOCK_DGRAM と SOCK_STREAM)。
- ESOCKTNOSUPPORT
- 未知のソケットタイプ。
他にも汎用のソケット層でエラーが起こったり、ファイルシステム上にソケットオブジェクトを作ろうとした場合にファイルシステムのエラーが起こることがある。それぞれの詳細は適切な man ページを参照すること。
バージョン
SCM_CREDENTIALS と抽象名前空間は、Linux 2.2 で導入された。移植性が必要なプログラムでは使うべきではない。 (BSD 由来のシステムの中にも信任状の送受信をサポートしているものがあるが、その実装の詳細はシステムによって異なる)注意
Linux の実装では、ファイルシステム上から見えるソケットは、それらが置かれているディレクトリのパーミッションに従う。ソケットの所有者、グループ、パーミッションは変更できる。新しいソケットを作るとき、作ろうとするディレクトリに対してプロセスが書き込みと検索 (実行) 権限を持っていなければ、作成に失敗する。ソケットオブジェクトに接続するには、 read/write 権限が必要である。この動作は、多くの BSD 由来のシステムとは異なっている (BSD では UNIX ドメインソケットに対してはパーミッションを無視する)。移植性の必要なプログラムでは、セキュリティをこの仕様に依存してはならない。例
bind(2) 参照。関連項目
recvmsg(2), sendmsg(2), socket(2), socketpair(2), cmsg(3), capabilities(7), credentials(7), socket(7)この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2012-05-10 | Linux |