EN JA
SOCKET(9)
SOCKET(9) FreeBSD Kernel Developer's Manual SOCKET(9)

名称

socketカーネルソケットインタフェース

書式

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

int
sobind( struct socket *so, struct sockaddr *nam, struct thread *td);

void
soclose( struct socket *so);

int
soconnect( struct socket *so, struct sockaddr *nam, struct thread *td);

int
socreate( int dom, struct socket **aso, int type, int proto, struct ucred *cred, struct thread *td);

int
sogetopt( struct socket *so, struct sockopt *sopt);

int
soreceive( struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp);

int
sosetopt( struct socket *so, struct sockopt *sopt);

int
sosend( struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td);

int
soshutdown( struct socket *so, int how);

解説

カーネル socket プログラミングインタフェースは、カーネル内の消費者が socket(2) ユーザ API を使用して許可されたものと同様の方法でローカルとネットワークソケットオブジェクトと情報をやりとりすることを許可します。これらのインタフェースは、分散ファイルシステムと他のネットワーク意識カーネルサービスによる使用に適しています。ユーザ API がファイル記述子で動作している間に、カーネルインタフェースは、 struct socket ポインタで直接動作します。

ほかに表示されるところを除いて、 socket 関数は、スリープ可能でないカーネルロックが保持されている間に、スリープするかもしれなくて、 ithread(9) コンテキストで使用のためには適切ではありません。

ソケットの作成と破壊

新しいソケットは、 socreate() を使用して作成されます。 socket(2) と同様に、引数は、 dom, typeproto を通して、要求されたドメイン、タイプとプロトコルを指定します。ソケットは、成功すれば、 aso を通して返されます。さらに、ソケットに関連している操作を承認するために使用される資格証明は、 credtd を通して操作を実行するスレッドを通して渡されます (そして、ソケットの生存期間のためにキャッシュされます)。 警告: ソケット作成操作の承認は、(生のソケットのような) いくつかのプロトコルに対してスレッドの資格証明を使用して実行されます。

ソケットは、 close(2) と同様のセマンティックがある、 soclose() を使用してクローズされ、解放されます。

接続とアドレス

sobind() 関数は、 bind(2) システムコールと同等で、アドレス nam にソケット so をバインドします。操作は、スレッド td で資格証明を使用して認定されます。

soconnect() 関数は、 connect(2) システムコールと同等であり、ソケット so でアドレス nam に接続を開始します。操作は、スレッド td で資格証明を使用して承認されます。ユーザシステムコールと違って、 soconnect() は、直ちに返ります。呼び出し側は、ソケットミューテックスを保持して、 SS_ISCONNECTING フラグをクリアするか、または、 so->so_error を 0 以外にするためにウェートしている間に so->so_timeomsleep(9) します。 soconnect() が失敗するなら、呼び出し側は、手動で SS_ISCONNECTING フラグをクリアしなければなりません。

soshutdown() 関数は、 shutdown(2) システムコールと同等であり、ソケットで部分または全ての接続を遮断します。

ソケットオプション

sogetopt() 関数は、 getsockopt(2) システムコールに同等であり、ソケット so でソケットオプションを検索します。 sosetopt() 関数は、 setsockopt(2) システムコールに同等であり、ソケット so でソケットオプションを設定します。

sogetopt() と sosetopt() の両方の 2 番目の引数は、ソケットオプション操作について説明する struct sopt への sopt ポインタです。呼び出し側で割り付けられた構造は、0 にクリアされなければならなくて、次に、ソケットオプション操作引数を指定するために初期化されたフィールドがありませす:

sopt_dir
これは、操作を取得するかまたは設定するかどうかによって SOPT_SET または SOPT_GET を設定します。
sopt_level
操作がターゲットとされるネットワークスタックでレベルを指定します。例えば、 SOL_SOCKET
sopt_name
設定するソケットオプションの名前を指定します。
sopt_val
ソケットオプションのための引数値へのカーネル空間ポインタ。
sopt_valsize
バイト単位の引数値のサイズ。

ソケット I/O

soreceive() 関数は、 recvmsg(2) システムコールと同等であり、ソケット so からバイトのデータを受信することを試み、なにも読み込む準備ができていないなら、オプションでデータに対してのウェートをブロックします。データは、データコピーを避けて、 uio 引数を通して、または mp0 を通して呼び出し側に返される mbuf チェーンとして、直接カーネルまたはユーザメモリで検索されます。 uio は、常に NULL 以外でなければなりません。 mp0NULL でないなら、 uiouio_resid だけが使用されます。呼び出し側は、 NULL でない psa 引数を通して記憶域を提供することによって、 PR_ADDR ケーパビリティでプロトコルのソケットアドレスをオプションで検索できます。呼び出し側は、 NULL でない controlp 引数を通して制御データ mbuf をオプションで検索できます。オプションのフラグは、 NULL でない flagsp 引数を通して soreceive() に渡され、 recvmsg(2) システムコールと同じフラグの名前空間を使用します。

sosend() 関数は、 sendmsg(2) システムコールと同等であり、ソケット so を通してバイトのデータを送信することを試み、直ちにデータを送信することができないなら、オプションでブロックします。データは、データコピーを避けて、 uio 引数を通して、または top を通して mbuf チェーンとして、カーネルまたはユーザメモリから直接送信されます。 uio または top ポインタの 1 つだけは、 NULL 以外になります。オプションの宛先アドレスは、プロトコルによってサポートされているなら、暗黙の接続となる、 NULL でない addr 引数を通して指定されます。呼び出し側は、 NULL でない control 引数を通して制御データ mbuf をオプションで送信します。フラグは、 flags 引数を使用して sosend() に渡され、 sendmsg(2) システムコールと同じフラグの名前空間を使用します。

ithread(9) コンテキスト、または保持されているミューテックスでで実行しているカーネルの呼び出し側は、ブロッキングしないソケットを使用して、これらの関数がスリープすることを防ぐために MSG_DONTWAIT フラグを渡したくなります。

歴史

socket(2) システムコールは 4.2BSD で登場しました。このマニュアルページは FreeBSD 7.0 で導入されました。

作者

このマニュアルページは Robert Watson によって書かれました。

バグ

明白に渡された資格証明、明白に渡されたスレッドにぶら下がる資格証明、 curthread における資格証明とソケット作成時からのキャッシュされた資格証明の使用は、矛盾していて、予期されない振る舞いを導くかもしれません。いくつかの td 引数は、 cred 引数であるべきか、または単に全く存在していないことが可能です。

呼び出し側は、 soconnect() がエラーを返すなら、手動で SS_ISCONNECTING をクリアする必要があります。

MSG_DONTWAIT フラグは、 sosend() のために実装されないで、0 コピーソケットが有効にされるとき、 soreceive() で常に動作するとは限りません。

このマニュアルページは、ブロッキング I/O を使用しないで読み易さ/書き易さのために、ソケットの upcall を登録するか、またはソケットをモニタする方法を説明していません。

soref() と sorele() 関数は、説明されていません、そして sorele() が、 soclose() の後で最後に呼び出されるとき、混乱して潜在的に不正確な相互作用のために、多くの場合、使用するべきではありません。

April 12, 2013 FreeBSD