GETSOCKOPT(2)

名称
getsockopt, setsockopt - ソケットのオプションの取得と設定

ライブラリ
libc

書式
<sys/types.h> <sys/socket.h> int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)

解説
getsockopt() と setsockopt() システムコールは、ソケットに対応する オプション を操作します。 オプションは複数のプロトコルレベルに存在する可能性があります。 これらは必ず最上位の “ソケット” レベルに存在します。

ソケットオプションを操作する際は、オプションが常駐するレベル およびオプションの名前を指定する必要があります。 ソケットレベルでオプションを操作するには level を SOL_SOCKET として指定します。 他のレベルでオプションを操作するには、 オプションを制御している適切なプロトコルのプロトコル番号を指定します。 例えば、オプションが TCP プロトコルによって解釈されることを指示するには、 level を TCP のプロトコル番号に設定する必要があります。 getprotoent(3) を参照してください。

optval と optlen 引数は、 setsockopt() がオプション値にアクセスするために使用されます。 getsockopt() の場合、これらは要求されたオプションの値が返される バッファを識別します。 getsockopt() の場合、 optlen は値と結果の引数であり、初期には optval の指すバッファのサイズが入っており、戻り時に修正されて 返された値の実際のサイズを示すようになります。 オプション値を指定しないか、またはオプション値が返されない場合、 optval に NULL を指定してもかまいません。

optname 引数および指定のオプションは、解釈されずに、 解釈用の該当プロトコルモジュールに渡されます。 インクルードファイル <sys/socket.h> には後述するソケットレベルオプション用の定義が入っています。 他のプロトコルレベルのオプションは形式と名称がさまざまです。 マニュアルのセクション 4 の該当するエントリを参照してください。

ほとんどのソケットレベルのオプションは optval 用に int 引数を使用します。 setsockopt() の場合、ブール演算を有効にするためには引数は 0 でない必要があり、 オプションを無効にする場合は 0 である必要があります。 SO_LINGER は、 <sys/socket.h> で定義された struct linger 引数を使用します。 これは、目的の状態のオプションとリンガ間隔 (後述) を指定します。 SO_SNDTIMEO と SO_RCVTIMEO は、 <sys/time.h> で定義された struct timeval 引数を使用します。

以降のオプションがソケットレベルで認識されます。 別記した場合を除いて、各オプションが getsockopt() で調べられ、 setsockopt() で設定されます。
SO_DEBUG | デバッグ情報の記録を有効にします
SO_REUSEADDR | ローカルアドレスの再使用を有効にします
SO_REUSEPORT | 重複したアドレスとポートのバインドを有効にします
SO_KEEPALIVE | 接続を保持することを有効にします
SO_DONTROUTE | 発信メッセージについて経路設定バイパスを有効にします
SO_LINGER | データが存在する場合はクローズで遅延します
SO_BROADCAST | ブロードキャストメッセージを送信するパーミッションを有効にします
SO_OOBINLINE | バンド内でのバンド外データの受信を有効にします
SO_SNDBUF | 出力用のバッファサイズを設定します
SO_RCVBUF | 入力用のバッファサイズを設定します
SO_SNDLOWAT | 出力用の最小カウントを設定します
SO_RCVLOWAT | 入力用の最小カウントを設定します
SO_SNDTIMEO | 出力についてのタイムアウト値を設定します
SO_RCVTIMEO | 入力についてのタイムアウト値を設定します
SO_ACCEPTFILTER | 待ち受けソケットでの受け取り用フィルタを設定します
SO_TYPE | ソケットのタイプを取得します (取得のみ)
SO_ERROR | ソケットのエラーを取得してクリアします (取得のみ)

SO_DEBUG は下層のプロトコルモジュール内でデバッグを有効にします。 SO_REUSEADDR は、 bind(2) システムコールで指定されたアドレスを検証するのに使用する規則で、 ローカルアドレスの再利用が可能であることを示します。 SO_REUSEPORT は、ポートをバインドする前の複数のプロセスがすべて SO_REUSEPORT を設定している場合に、 複数のプロセスによる完全に重複したバインドが可能になるようにします。 このオプションは、プログラムの複数のインスタンスそれぞれが、 バインドされたポートを宛先とする UDP/IP マルチキャストまたは ブロードキャストのデータグラムを受信できるようにします。 SO_KEEPALIVE は接続されたソケット上でメッセージの周期的な送信を有効にします。 接続された一方がこれらのメッセージに応答できない場合は 接続が破壊されていると考えられ、ソケットを使用しているプロセスは データを送信しようとするときに SIGPIPE シグナルによって通知を受けます。 SO_DONTROUTE は発信メッセージが標準の経路設定機能をバイパスする必要があることを示します。 代わりに、メッセージは、宛先アドレスのネットワーク部分に従って 該当するネットワークインタフェースに転送されます。

SO_LINGER は送信されていないメッセージがソケットの待ち行列にあり、しかも close(2) が実行される時に行われる処置を制御します。 ソケットがデータの信頼できる配信を確約し、しかも SO_LINGER が設定されている場合、 データを送信できるまで または情報を配信できない (リンガ間隔と呼ばれるタイムアウト時間は、 SO_LINGER が要求されるときに setsockopt() システムコール内で秒単位で指定されます) と判定するまで、システムはプロセスを close(2) 上でブロックします。 SO_LINGER が無効の状態で close(2) が起動されると、システムは、プロセスが可能な限り迅速に処理を 継続できる方法でクローズ処理を行います。

オプション SO_BROADCAST は、ソケット上でブロードキャストデータグラムを送信するパーミッションを 要求します。 ブロードキャストは、システムの初期バージョンでは特権操作でした。 バンド外のデータをサポートするプロトコルで、 SO_OOBINLINE オプションは、バンド外のデータが受信された順番で通常の データ入力待ち行列に配置されることを要求します。 そして、これは MSG_OOB フラグなしに recv(2) 呼び出しまたは read(2) 呼び出しでアクセスできます。 常に このオプションが設定されているかのように動作する プロトコルもあります。 SO_SNDBUF と SO_RCVBUF は、それぞれ、出力および入力用に割り当てられる通常のバッファサイズを 調整するオプションです。 バッファのサイズは、高ボリューム接続のために増加することができますし、 着信データの可能なバックログを 制限するために減少させることもできます。 システムはこれらの値について 1 つの絶対最大値を設定します。 この最大値は sysctl(3) MIB 変数 “kern.ipc.maxsockbuf” によってアクセスできます。

SO_SNDLOWAT は出力操作に最小カウントを設定するオプションです。 ほとんどの出力操作は、送信用のプロトコルにデータを配信し、 フロー制御のためにブロックしながら呼び出しによって与えられた すべてのデータを処理します。 ノンブロッキング出力操作は、ブロックなしのフロー制御に従って 許容される限界までデータを処理しますが、フロー制御が 最低基準値または要求全体のいずれか小さい方を処理することを許容しない 場合はデータを処理しません。 ソケットへの書込み能力を試験する select(2) 操作が真で返るのは、最低基準値を処理できる場合だけです。 SO_SNDLOWAT のデフォルト値はネットワーク効率性のために 適切なサイズ (多くの場合は 1024) に設定されます。 SO_RCVLOWAT は入力操作の最小カウントを設定するオプションです。 一般に、受信呼び出しは、いくらかの (0 でない) データが 受信されるまでブロックしてから、利用できる量または 要求された量のいずれか少ない方とともに戻ります。 SO_RCVLOWAT のデフォルト値は 1 です。 SO_RCVLOWAT にもっと大きな値が設定されている場合、 受信呼び出しのブロックは通常、最低基準値または 要求された量のいずれか小さい方が受信されるまで待機します。 受信呼び出しは、エラーが発生したり、シグナルが捕らえられたり、 または受信待ち行列内の次のデータのタイプが返されたものと異なる場合は、 最低基準値より小さい値でも戻ることがあります。

SO_SNDTIMEO は出力操作についてタイムアウト値を設定するオプションです。 これは、出力操作完了の待機を制限するために使用される秒数、 マイクロ秒数を struct timeval 引数で指定します。 送信操作が指定された時間以上ブロックされた場合、部分的なカウントで戻るか、 またはデータが送信されていない場合はエラー EWOULDBLOCK で戻ります。 現在の実装では、このタイマは追加の各データがプロトコルに 配信されるたびに再起動され、これはサイズが出力用の最低基準値から 最高基準値の範囲に至る出力部分に適用されることを意味します。 SO_RCVTIMEO は入力操作についてタイムアウト値を設定するオプションです。 これは入力操作完了の待機を制限するために使用される秒数、マイクロ秒数を struct timeval 引数で指定します。 現在の実装では、このタイマは追加のデータがプロトコルによって 受信されるたびに再起動されるので、 制限は実際には休止期間のタイマとなります。 追加のデータを受信することなく受信操作がこれだけの時間について ブロックされた場合、短いカウントで戻るか、 またはデータが受信されていない場合はエラー EWOULDBLOCK で戻ります。

SO_ACCEPTFILTER は、ソケット上に accept_filter(9) を置きます。 これにより、待ち受けしているストリームソケットに入ってくる接続が accept(2) に渡される前にフィルタされることになります。 念のため繰り返します。 フィルタをソケット上にインストールする前に、ソケットに対して listen(2) 呼び出す必要があります。 そうしないと setsockopt() システムコールが失敗します。

    struct  accept_filter_arg {
            char    af_name[16];
            char    af_arg[256-16];
    };

optval 引数は struct accept_filter_arg を指さなくてはなりません。 この構造体が accept_filter(9) を選択、設定します。 af_name 引数は、アプリケーションが待ち受けソケット上に置きたいと思っている 受け取り用フィルタの名前で埋めなくてはなりません。 オプションの引数 af_arg は、 af_name で指定された受け取り用フィルタに渡すことができるものです。 これにより、ソケットに置かれる時にさらなる設定オプションを 提供します。 NULL を optval 中で渡すと、フィルタが削除されます。

最後に、 SO_TYPE と SO_ERROR は getsockopt() でだけ使用されるオプションです。 SO_TYPE では SOCK_STREAM のようなソケットのタイプが返ります。 これはスタートアップ時にソケットを継承するようなサーバに便利です。 SO_ERROR はソケット上で延期中のエラーを返し、エラー状態をクリアします。 これは接続されたデータグラムソケット上の非同期的エラーをチェックしたり、 その他の非同期エラーをチェックするのに使用できます。

戻り値

エラー
呼び出しは次の場合を除いて正常です:

[EBADF]
    引数 s が有効な記述子ではありません。

[ENOTSOCK]
    引数 s がソケットではなくファイルです。

[ENOPROTOOPT]
    指示されたレベルでオプションは存在しません。

[EFAULT]
    optval が指すアドレスがプロセスアドレス空間の有効な部分にありません。 getsockopt() では、 optlen がプロセスアドレス空間の有効な部分でない場合も、 このエラーが返される可能性があります。

[EINVAL]
    待ち受けていないソケットに対して accept_filter(9) のインストールを試みました。

関連項目
ioctl(2), socket(2), getprotoent(3), sysctl(3), protocols(5), sysctl(8), accept_filter(9)

バグ
ソケットオプションのいくつかはシステムの低いレベルで処理される必要があります。

歴史
getsockopt() システムコールは 4.2BSD ではじめて登場しました。