Packet Manipulator
概要
Packet Manipulator は Diarkis が扱う通信パケットに対して特定の操作を適用する仕組みです。 Diarkis Runtime 内に設定された Apply Point と呼ばれる処理の適用タイミングに対して Packet Filter を設定することでパケットに対する操作を適用します。 パケットに対する操作は C++ のコードとして実装することができ、Apply Point 毎に異なる通信パケットに関する情報を参照し、パケットを無視したり、通信量を計算したり、パケットを保存したり、特定のパケットに対してカスタムな処理をさせたりすることが可能です。 また、一般的に利用されることが想定されるパケットに遅延やパケロスを発生させる Packet Filter はプリセットとして提供されており、Packet Filter 自体のコードを書かなくても利用できるようになっています。 なお、Packet Manipulator はデバッグ用の機能となりますので Release ビルドでは使用することはできません。
注意点
Packet Manipulator はデバッグ用の機能となります。 リリースビルドなど、DIARKIS_DEBUG_FEATURES が定義されていない環境では事故防止のためにインターフェイスが見えなくなりますのでご注意ください。
本機能は experimental feature となります。 将来仕様や動作が変更される可能性がある点をご了承ください。
Namespace
Packet Manipulator の全機能は Diarkis::System::PacketManipulator namespace 内に存在します。 以降、本ドキュメントで使用するクラス名等では namespace は省略して記載しますのでご留意ください。
Packet Manipulator
Packet Manipulator の機能にアクセスするには IPacketManipulator のインスタンスを使用します。 IPacketManipulator のインスタンスは DiarkisGetPacketManipulator を呼び出して取得することができます。
Packet Manipulator の更新処理
IPacketManipulator には Packet Filter の状態を含む内部状態を更新する IPacketManipulator::Update があります。 このメソッドの呼び出し頻度が Packet Filter 毎の更新頻度につながるため Packet Filter の処理が必要としている頻度で実行する必要があります。
例えばプリセットのパケット遅延フィルタでは実際にパケットを受け取ったタイミングから、遅延してパケットを処理するため時間を計測しています。 この計測処理が Packet Filter の更新処理内で実行されているため、IPacketManipulator::Update が 100 ms 間隔で実行されていると遅延させる時間の計測も 100 ms 間隔となり想定している遅延時間よりも大きくずれる可能性があります。 Packet Manipulator の機能に必要な更新頻度を考慮して IPacketManipulator::Update を実行するようにしてください。
Apply Point
Packet Manipulator では Packet Filter を適用するタイミングを Apply Point と呼びます。Apply Point へ Packet Filter を設定することでパケットに対して特定の処理が反映されるようになります。 Apply Point には以下の種類が存在します。
RawUdpReceive
UDP ソケットでパケット受信時
P2P 含めて Diarkis が使用するすべての UDP パケットに対して適用されます
RawUdpSend
UDP ソケットでパケット送信時
P2P 含めて Diarkis が使用するすべての UDP パケットに対して適用されます
RoomPushAndResponseReceive
Room の Push/Response パケット受信時
Room の Push/Response として受信したパケットにのみ適用されます
P2PMessageReceive
P2P パケット受信時
P2P メッセージとして受信したパケットにのみ適用されます
Packet Filter Set
Packet Manipulator ではひとつの Apply Point に対して複数の Packet Filter を適用する仕組みとして Packet Filter Set が用意されています。 Packet Filter Set は Apply Point に関連付けられていて、IPacketManipulator::GetOrAllocFilterSet(FilterApplyPoint applyPoint) を使用することで Apply Point に対する IPacketFilterSet を取得することができます。 パケットに対して何か処理を適用するにはこの IPacketFilterSet に対して Packet Filter を追加していくことになります。
Packet Filter の追加
Packet Filter を追加するには前述の IPacketFilterSet を使用します。IPacketFilterSet にはプリセットの Packet Filter を追加する IPacketFilterSet::AddPacketDelayFilter のようなメソッドと任意の型の Packet Filter を追加する IPacketFilterSet::AddFilter メソッドが存在します。
Packet Filter と Apply Point の互換性
Packet Filter には Apply Point との互換性が存在します。これはある Packet Filter の機能が特定の Apply Point で機能するかどうかという設定で Packet Filter 側の実装状況や Apply Point での対応状況によります。 互換性がない Apply Point に Packet Filter を設定した場合、IPacketFilterSet::Add...Filter 系のメソッドが nullptr を返しますので返り値は必ずチェックするようにしてください。 Apply Point と Packet Filter の互換性には IPacketFilter::CheckIfAvailableApplyPointが使用されており、Custom Filter を実装する際はこのメソッドで判定を行うことで互換性の設定を行うことができます。
Preset Packet Filters
Packet Manipulator にはプリセットでいくつかの Packet Filter が用意されています。 Packet Manipulator Simple サンプル に使用した実装例がありますので参照してください。
Packet Delay Filter
IPacketFilterSet::AddPacketDelayFilter で追加することができます。
probability
パケット遅延の発生確率
minDelay
最低遅延時間(ms)
maxDelay
最高遅延時間(ms)
seed
疑似乱数のシード
作成時に指定された確率である一定範囲のパケット遅延が発生するようになります。 確率判定には疑似乱数が使用されているためフィルタが適用されるパケットや遅延時間はある程度同じになるようになっていますが、最終的には実行時にパケットが到達した順番に依存して変わる可能性があります。
Packet Loss Filter
IPacketFilterSet::AddPacketLossFilter で追加することができます。
probability
パケットロスの発生確率
seed
疑似乱数のシード
作成時に指定された確率である一定範囲のパケット遅延が発生するようになります。 確率判定には疑似乱数が使用されているためフィルタが適用されるパケットはある程度同じになるようになっていますが、最終的には実行時にパケットが到達した順番に依存して変わる可能性があります。
User Custom Filter
ユーザーが独自の処理をパケットに適用可能な Custom Filter を実装することができます。 Packet Manipulator Custom Filter サンプル に使用した実装例がありますので参照してください。
Custom Filter を実装するには IPacketFilter とそのサブクラスを継承します。IPacketFilter が一番低レベルな Packet Filter インターフェイスを持っているクラスとなり、Packet Manipulator から渡されるフィルタ適用メソッドの引数の型は IPacketFilterArgument となります。 しかし、IPacketFilterArgument では低レベルなパケットの情報にしかアクセスできないため、実際は各 Apply Point に応じた Filter Base を継承してカスタムフィルタを実装することをおすすめします。 例えば P2PMessageReceive Apply Point で利用可能な IP2PMessageReceiveFilterBase を継承してカスタムフィルタを実装すると、IP2PMessageReceiveFilterArgument 型でパケットに関する情報を取得することができます。IP2PMessageReceiveFilterArgument では送信元の UID や IP アドレス、ポートなど IPacketFilterArgument ではアクセスできない P2P 固有の情報にアクセスすることが出来るようになります。
フィルタ適用メソッド
IPacketFilter とそのサブクラスには Apply メソッドが存在し、Packet Filter 適用のタイミングでパケット情報を渡して実行されます。 ユーザーはこのメソッド内でフィルタ適用時に任意の処理を実装することができます。
また、Apply メソッドの返り値でその後のパケットの扱いをコントロールすることができます。FilterPostProcess::Skip を返すことでその後、Diarkis Runtime 内ではそのパケットが無かったものとして扱われます。FilterPostProcess::ApplyNextFilter を返すと通常通りの処理を継続します。
更新メソッド
IPacketFilter とそのサブクラスには Update メソッド存在し、Packet Filter に対して定期的に実行したい処理を実装することができます。 Update メソッドには引数として、設定されている Apply Point で Diarkis Runtime がパケットを処理するための関数が渡されます。この関数に必要な情報を渡すことで、パケット受信時以外のタイミングでパケットを処理することができます。 このメソッドは IPacketManipulator::Update から呼び出されます。
Apply Point 互換性判定メソッド
IPacketFilter とそのサブクラスには CheckIfAvailableApplyPoint メソッドが存在し、Packet Manipulator はこのメソッドを使用して Apply Point と Packet Filter に互換性があるかどうか判断します。
Custom Filter 実装時の注意点
Custom Filter の Apply メソッドは Apply Point によってさまざまなスレッドから実行される可能性があります。Custom Filter 内で扱うデータの排他制御には十分ご注意ください。
最終更新
役に立ちましたか?

