nine の暗号機能はそのまま動く実装ではなく、多少の開発を要する API 形式で提供している。 これには次のような理由がある。
ネットゲームの場合、通常の通信セキュリティ技術とは異なった脅威へ対処する必要がある。 一般的な通信セキュリティ技術では、第三者からの盗聴や改竄への耐性が求められる。 ネットゲームでは、これに加えて悪意あるユーザーによるクライアント実行環境での盗聴・改竄への耐性も求められる。
また、セキュリティ技術は進歩が著しい分野の一つである。 最先端の技術を取りこむことができるという付随的なメリットもある。
メッセージコントロールAPI は、メッセージ型通信の利用時に低レベルな操作方法を提供するためのものである。 暗号化や圧縮などの送受信データ操作や、ハンドシェイク処理を実現できる。
コントロールAPI の中核は Controller インターフェースクラスである。 この具象クラスを実装し、MessageServer::setController() で指定することで、コントロールを実現する。
コントローラにはいくつかのフック関数が定義されている。 これらは nine がメッセージの送受信を行う際の特定の段階で呼び出される。 この引数を介して、間接的なコントロールを行うことができる。
間接的な方法とは別に、直接コントロールする関数も定義されている。 コントロール関数は protected になっており、具象クラスから呼び出すことができる。 フック関数の中でコントロール関数を呼び出すことを想定している。
struct Context {
enum { SEQ_LEN = 8, };
uint8_t sequence[SEQ_LEN];
};
sequence は encode,decode 対象のデータの連番である。
ビッグエンディアンの 8byte整数になっている(メモリアドレスの小さい seqence[0] が一番大きい位になる)
暗号化のナンスに使うことを想定している。
後で説明するように、単一のデータに対しての encode/decode 処理は複数のフック関数を呼び出す。 これら一連のフック呼び出しでは、同一の Context オブジェクトを与えられる。 Context を利用して、フック関数間のデータ受け渡しなどを行うことができる。
任意のメッセージを「コントロールメッセージ」として送信する。 受信したコントロールメッセージは、handleControlMessage() フック関数で渡される。
メッセージを post() した時に、マーシャル処理の中でコントローラの送信フック関数が呼ばれる。 以下の順に、beginEncode() から endEncode() まで順番に呼ばれる。 まとめて encode処理と呼ぶ。
beginEncode() が呼ばれてから endEncode() から出るまでの間は、アプリケーションで post() されたメッセージが encode に周ってくることはない。
また、beginEncode() が呼ばれてから、endEncode() が呼ばれるまでの間は、直接的なコントロール関数は呼ぶべきでない。コントロール関数を呼ぶ必要があるならば、endEncode() の中で呼ぶこと。
コントロール関数の中でも、postControlMessage() はさらに注意を要する。
postControlMessage() もまた送信処理であり、encode 処理も呼ばれることになる。
void DhCtrl::endEncode(Context* pCtx)
{
if (pCtx->sequence[7] == 0) { //every 256 messages
MyMessage msg;
sendMessage(&msg);
}
}
メッセージ全体のデータグラムを受信して、メッセージオブジェクトへの解析処理の中でコントローラの受信フック関数が呼ばれる。
decode シーケンスは encode に似ている。
beginDecode() の始まりから endDecode() の終了までの間は、他の受信メッセージの decode 処理は走らないようになっている。 beginDecode() から decode() の中では、コントロール関数は呼ぶべきでない。
handleControlMessage() は decode に特有の処理で、解析したメッセージがコントロールメッセージの場合に呼ばれる。 この中では必要に応じてコントロール関数を呼んでよい。 例えばハンドシェイクを完了させるメッセージの場合、enableNormalMessage() を呼ぶことになるだろう。
コントローラでは新たな解析処理を発生させることは無いので、encode のように再入に気を付ける必要はない。