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

名称

mod_cc, DECLARE_CC_MODULE, CC_VARモジューラ輻輳制御

書式

#include < netinet/cc.h>
#include < netinet/cc/cc_module.h>

DECLARE_CC_MODULE( ccname, ccalgo);

CC_VAR( ccv, what);

解説

mod_cc フレームワークによって、輻輳制御アルゴリズムを kld(4) 機能を通して、動的にロード可能なカーネルモジュールとして実装できます。トランスポートプロトコルは、それぞれの接続 (connection-by-connection) ベース、またはシステムデフォルトを使用して、利用可能なアルゴリズムのリストから選択することができます (その他の詳細については、 mod_cc(4) を参照してください)。

mod_cc モジュールは、 ascii(7) の名前と次のメンバがある struct cc_algo でカプセル化されたフック関数のセットによって識別されます:

struct cc_algo { 
 char name[TCP_CA_NAME_MAX]; 
 int (*mod_init) (void); 
 int (*mod_destroy) (void); 
 int (*cb_init) (struct cc_var *ccv); 
 void (*cb_destroy) (struct cc_var *ccv); 
 void (*conn_init) (struct cc_var *ccv); 
 void (*ack_received) (struct cc_var *ccv, uint16_t type); 
 void (*cong_signal) (struct cc_var *ccv, uint32_t type); 
 void (*post_recovery) (struct cc_var *ccv); 
 void (*after_idle) (struct cc_var *ccv); 
};

name フィールドは、アルゴリズムのユニークな名前を識別し、 (互換性の理由で、 < netinet/tcp.h> にある TCP_CA_NAME_MAX 定義) TCP_CA_NAME_MAX-1 文字より長くない名前であるべきです。

mod_init 関数は、登録プロセスが完了する前にに、新しいモジュールがシステムにロードされるとき、呼び出されます。モジュールが、新しい接続によって使用のために利用可能となる前にいくつかのグローバルな状態をセットアップする必要があるなら、実装されるべきです。 mod_init から 0 以外の値を返すことで、モジュールのローディングは、失敗します。

mod_destroy 関数は、カーネルから既存のモジュールをアンロードする前に呼び出されます。モジュールが、カーネルから取り除く前に、任意のグローバルな状態をクリーンアップする必要があるなら、実装されるべきです。返り値は、現在、無視されます。

cb_init 関数は、TCP 制御ブロック struct tcpcb が作成されるとき、呼び出されます。モジュールが、プライベートな接続毎の状態を格納するためにメモリを割り付ける必要があるなら、実装されるべきです。 cb_init から 0 以外の値を返すことによって、セットアップされた接続を中止し、結果として接続を終了します。

cb_destroy 関数は、TCP 制御ブロック struct tcpcb が破壊されるとき、呼び出されます。モジュールが、 cb_init に割り付けられたメモリを解放する必要があるなら、実装されるべきです。

conn_init 関数は、新しい接続が確立され、変数が初期化されるとき、呼び出されます。新しく確立された接続のために輻輳制御アルゴリズム変数を初期化するために実装されるべきです。

ack_received 関数は、TCP 肯定応答 (ACK) パケットが受信されるとき、呼び出されます。モジュールは、輻輳管理アルゴリズムの入力として type 引数を使用します。現在、スタックによって報告されている ACK タイプは、CC_ACK と CC_DUPACK です。 CC_ACK は、前の肯定応答でないデータで受信された ACK 肯定応答を示します。 CC_DUPACK は、既に受信された ACK がある、受信された ACK 肯定応答データを示します。

cong_signal 関数は、輻輳イベントがが TCP スタックによって検出されるとき、呼び出されます。モジュールは、輻輳管理アルゴリズムへの入力として type 引数を使用します。現在、スタックによって報告される輻輳イベントタイプは、CC_ECN、CC_RTO、 CC_RTO_ERR と CC_NDUPACK です。 CC_ECN は、TCP スタックが明白な輻輳通知 (RFC3168) を受信するとき、報告されます。 CC_RTO は、再送タイムアウトタイマが起動されるとき、報告されます。 CC_RTO_ERR は、再送タイムアウトタイマがエラーで起動されたなら、報告されます。 CC_NDUPACK は、ACK を複写する N が、逆並列 (back-to-back) で受信されていたなら、報告されます、ここで N は、高速で再送される複写 ack 閾値です (現在、RFC5681 により N=3)。

post_recovery 関数は、TCP 接続が輻輳イベントから復旧された後に、呼び出されます。必要に応じて状態を調整するために実装されるべきです。

after_idle 関数は、データ転送がアイドル期間の後に再開するとき、呼び出されます。必要に応じて状態を調整するために実装されるべきです。

DECLARE_CC_MODULE() マクロは、 DECLARE_MODULE(9) マクロの周りの便利なラッパを提供し、 mod_cc フレームワークで mod_cc モジュールを登録するために使用されます。 ccname 引数は、モジュールの名前を指定します。 ccalgo 引数は、モジュールの struct cc_algo を指します。

mod_cc モジュールは、 struct cc_algo のインスタンスを作成しなければなりませんが、名前フィールドを設定するためと、オプションで関数ポインタのいずれかを必要とするだけです。スタックは、NULL である任意の関数ポインタへの呼び出しをスキップするので、関数ポインタのいずれかを実装する要件はありません。フィールドを設定する初期化子の機能に指定された C99 を使用することは、奨励されます。

輻輳制御状態を処理する各関数ポインタは、次のメンバがある struct cc_var へのポインタに渡されます:

struct cc_var { 
 void  *cc_data; 
 int  bytes_this_ack; 
 tcp_seq  curack; 
 uint32_t flags; 
 int  type; 
 union ccv_container { 
  struct tcpcb  *tcp; 
  struct sctp_nets *sctp; 
 } ccvc; 
};

struct cc_var は、輻輳制御関連変数を単一の組み込み可能な構造にグループ化し、転送プロトコル制御ブロックにアクセスする間接の層を追加します。最後のゴールは、すべての輻輳を気付いているトランスポートプロトコルの間で共有される mod_cc モジュールの単一セットを許可することですが、現在 tcp(4) だけがサポートされます。

このゴールに向かった最後の変移を支援するために、トランスポートプロトコルのデータ構造からの変数の直接使用は、強くお勧めできません。しかしながら、これらの変数のいくつかへのアクセスを必要とする現在の時間に不可避です、それで、 CC_VAR() マクロは、便利なアクセス機構として存在しています。 ccv 引数は、 mod_cc フレームワークによって関数に渡された struct cc_var を指します。 what 引数は、アクセスするための変数の名前を指定します。

typeccv_container フィールドは別として、 struct cc_var の残っているフィールドは、 mod_cc モジュールによって使用するためにのものです。

cc_data フィールドは、動的なメモリポインタをアタッチするため追加の接続毎の状態を必要とするアルゴリズムに利用可能です。メモリは、モジュールの cb_init フック関数で割り付けられ、アタッチされるべきです。

bytes_this_ack フィールドは、最も最近受信された ACK パケットによって肯定応答された新しいバイトの数を指定します。それは、 ack_received フック関数だけで有効です。

curack フィールドは、最も最近受信された ACK パケットのシーケンス番号を指定します。それは、 ack_received, cong_signalpost_recovery フック関数だけで有効です。

flags フィールドは、スタックから mod_cc モジュールまで役に立つ情報を渡すために使用されます。 CCF_ABC_SENTAWND フラグは、 ack_received に関連していて、カウントしている適切なバイト (RFC3465) が、送信されたウィンドウのバイトの価値をカウントしたとき、設定されます。シグナルを処理した後に、フラグをクリアするのはモジュールの責任です。 CCF_CWND_LIMITED フラグは、 ack_received に関連していて、データを送信する接続の能力が輻輳ウィンドウの値によって現在抑制されるとき、設定されます。アルゴリズムは、輻輳ウィンドウと送信ウィンドウの間の大きな違いを蓄積することを避けるために設定される、このフラグがないことを使用するべきです。

謝辞

このソフトウェアの開発とテストは、Community Foundation Silicon Valley において FreeBSD Foundation と Cisco University Research Program Fund からの助成金によって一部可能となりました。

今後の作業

sctp(4) と統合します。

歴史

モジューラ輻輳制御 (Congestion Control (CC)) フレームワークは、 FreeBSD 9.0 で登場しました。

このフレームワークは、 Community Foundation Silicon Valley において Cisco University Research Program Fund からの助成金によって一部可能となった、 Advanced Internet Architectures、Melbourne、Australia のために Swinburne University of Technology の Centre において NewTCP 研究プロジェクトに従事している間に、James Healy と Lawrence Stewart によって 2007 年に始めてリリースされました。その他の詳細は、次で利用可能です:

http://caia.swin.edu.au/urp/newtcp/

作者

mod_cc フレームワークは、 Lawrence Stewart <lstewart@FreeBSD.org>, James Healy <jimmy@deefa.com>と David Hayes <david.hayes@ieee.org>によって書かれました。

このマニュアルページは、 David Hayes <david.hayes@ieee.org>と Lawrence Stewart <lstewart@FreeBSD.org>によって書かれました。

September 15, 2011 FreeBSD