> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MsQuic

> MsQuic

この記事では、Microsoft Game Development Kit (GDK) で [MsQuic](https://github.com/microsoft/msquic) を使用する方法について説明します。MsQuic は [IETF QUIC](https://datatracker.ietf.org/wg/quic/about/) プロトコルの Microsoft による実装です。クロス プラットフォームで、C で記述されており、汎用の QUIC ライブラリとして設計されています。

QUIC は元々、HTTP のような「TLS over TCP」を使用するシナリオを置き換えるために設計されました。開発者は、これを、リアルタイムの信頼性のないデータグラム メッセージと信頼性のある TCP のようなストリームを 1 つの接続上で多重化するのに適した、汎用の UDP データ トランスポート レイヤーに拡張しました。この設計により、クライアント/サーバー トランスポート レイヤーおよびリアルタイム ゲーム トラフィック データ フローの基盤として特に魅力的なものとなっています。

MsQuic は GDK タイトル向けに調整されており、Windows Server、Linux デスクトップとサーバー、iOS、Android、macOS など、さまざまなプラットフォームでも利用可能です。

[MsQuic API ドキュメント](https://github.com/microsoft/msquic/blob/main/docs/API.md) には、多くの重要な MsQuic の概念が記載されており、MsQuic API サーフェスに対してコードを書く方法が示されています。

## QUIC の機能

* すべてのパケットは暗号化され、ハンドシェイクは TLS 1.3 を使用して認証されます。
* 信頼性のあるアプリケーション データと信頼性のないアプリケーション データの並列ストリーム。
* 最初のラウンド トリップ (0-RTT) でのアプリケーション データの交換。
* 輻輳制御と損失回復の改善。
* クライアントの IP アドレスやポートの変更に耐えます。
* ステートレスなロード バランシング。
* 新機能や拡張のために容易に拡張可能。

## MsQuic の実装

GDK タイトルでの使用向けに調整されていることに加え、MsQuic には他の QUIC 実装とは異なるいくつかの特徴があります。

* クライアントとサーバー向けに最適化されています。
* 最大スループットと最小レイテンシに最適化されています。
* 非同期 IO。
* Receive Side Scaling (RSS) のサポート。
* UDP の送受信の結合 (coalescing) のサポート。

MsQuic は次の QUIC RFC を実装しています。

* [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)
* [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001)
* [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)

MsQuic は次の QUIC ドラフト拡張機能を実装しています。

* [Datagram](https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram)
* [Version Negotiation](https://datatracker.ietf.org/doc/html/draft-ietf-quic-version-negotiation)
* [Load Balancing](https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers)
* [ACK Frequency](https://datatracker.ietf.org/doc/html/draft-ietf-quic-ack-frequency)
* [Perf Testing](https://datatracker.ietf.org/doc/html/draft-banks-quic-performance)

## MsQuic の取得

Microsoft は MsQuic をオープン ソースの GitHub リポジトリでホストしています。MsQuic は、[こちら](https://github.com/microsoft/msquic/blob/main/docs/Release.md) にある公式リリースの 1 つを通じて取得してください。XBOX Series X|S コンソールのサポートは prerelease/1.9 で追加されましたが、GDK タイトルには可能な限り最新の公式リリース バージョンを使用することをお勧めします。

特定のリリース用にビルド済みの MsQuic バイナリは、特定のリリースの [Assets](https://github.com/microsoft/msquic/releases) セクションの下で見つけることができます。特定のバージョンの MsQuic のすべてのビルド フレーバーは、互いに完全に互換性があります。MsQuic はまた、リリース間の後方互換性の維持も試みていますが、異なるバージョン間での互換性の期待については、MsQuic のドキュメントとリリース ノートを参照してください。

### GDK ベースの PC タイトル

GDK ベースの PC タイトルには、`msquic_windows_x64_Release_openssl` ビルド済みバイナリを使用してください。

PC の GDK タイトルはネイティブ x64 Win32 アプリケーションとして実行されます。x64 プラットフォーム向けにビルドされた MsQuic バージョンを使用してください。PC では、GDK がサポートするすべての OS バージョンをサポートしている OpenSSL でビルドされた MsQuic バージョンを使用してください。Schannel を使用するバージョンは Windows 11 OS 以降のみをサポートしています。

### GDK ベースのコンソール タイトル

GDK ベースのコンソール タイトルには、`msquic_gamecore_console_x64_Release_schannel` ビルド済みバイナリを使用してください。

MsQuic は、XBOX コンソール上の GDK ベースのタイトル向けの特別なビルド フレーバーを提供しています。このフレーバーは MsQuic を `WINAPI_PARTITION_GAMES` 下の API に制限し、MsQuic が `XGamePlatform.lib` に対してリンクされるようにします。このビルド フレーバーを使用するには、2021 年 10 月リリース以降の XGDK をインストールする必要があります。MsQuic は、GDK ベースのコンソール タイトル向けにビルドする場合、Schannel を使用します。

<a id="ClientServerAuthentication" />

## クライアントとサーバーの認証

MsQuic は、サーバーを認証するために HTTPS Web リクエストに使用されるものと同じ認証および検証パスを自動的に利用します。クライアント認証は、[安全なクライアント/サーバー通信のベスト プラクティス (NDA トピック)](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/game-principles/security/communication-security/communication-security-impl/gc-secure-game-mesh-impl#ClientAuthentication) で概説されているベスト プラクティスに従うべきです。

MsQuic では、クライアントとサーバーの両方で、証明書を構成するために [ConfigurationLoadCredential](https://github.com/microsoft/msquic/blob/main/docs/api/ConfigurationLoadCredential.md) API を適切な [QUIC\_CREDENTIAL\_CONFIG](https://github.com/microsoft/msquic/blob/main/docs/api/QUIC_CREDENTIAL_CONFIG.md) と共に使用する必要があります。MsQuic に既定で含まれるすべての暗号スイートは安全であると考えられていますが、安全で認証された通信チャネルが確立されることを確実にするために、クライアントとサーバーの両方で MsQuic が証明書を検証する方法を適切に設定することが重要です。

サーバー側では、XSTS トークン クライアント認証を使用するには、`QUIC_CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION`、`QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED`、および `QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION` フラグを指定する必要があります。`QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION` フラグを指定する場合、[安全なクライアント/サーバー通信のベスト プラクティス (NDA トピック)](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/game-principles/security/communication-security/communication-security-impl/gc-secure-game-mesh-impl#ClientAuthentication) セクションで説明されているように、[QUIC\_CONNECTION\_EVENT\_PEER\_CERTIFICATE\_RECEIVED](https://github.com/microsoft/msquic/blob/main/docs/api/QUIC_CONNECTION_EVENT.md#quic_connection_event_peer_certificate_received) イベント コールバック内でクライアント証明書を自分自身で検証する必要があります。

さらにサーバー側では、HTTPS Web サーバーと同様に、クライアントがサーバーを認証できるように、適切にルート付けされた証明書を提供する必要があります。

クライアント側では、`QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION` フラグを *絶対に* 指定しないでください。サーバー認証に対する既定の MsQuic の動作が、ID を検証する最も簡単で最も安全な方法だからです。代わりに、XSTS トークン クライアント認証には、[安全なクライアント/サーバー通信のベスト プラクティス (NDA トピック)](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/game-principles/security/communication-security/communication-security-impl/gc-secure-game-mesh-impl#ClientAuthentication) セクションで説明されているように、`QUIC_CREDENTIAL_FLAG_CLIENT` フラグを、サーバーで生成された証明書と共に指定する必要があります。`QUIC_CREDENTIAL_TYPE_CERTIFICATE_CONTEXT` モードを指定し、[CertCreateContext](https://learn.microsoft.com/windows/win32/api/wincrypt/nf-wincrypt-certcreatecontext) などの API を使用して Web リクエストの応答データから直接コンテキストを生成する方法で、クライアント証明書を提供することをお勧めします。

## ネットワーク初期化

MsQuic は、GDK タイトルの [ネットワーク初期化](/build/console-features/networking/initialization-connectivity-networking) を自動的に処理しません。タイトルが起動された後、および各再開の後、[MsQuicOpenVersion](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicOpenVersion.md) または [MsQuicOpen](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicOpen.md) を使用して MsQuic を初期化する前に、ネットワークが初期化されるのを待ってください。

<a id="SuspendResume" />

## サスペンドと再開

`RegisterAppStateChangeNotification` を使用してサスペンドおよび再開イベントを登録します。サスペンド時には、開いているすべてのストリームを閉じ、MsQuic を閉じます。その後、再開時には、ネットワーク初期化を待ってから MsQuic を再度開きます。

サスペンド タイムアウト内ですべての MsQuic ストリームを迅速に閉じるには、開いている各ストリームに対して、`QUIC_STREAM_SHUTDOWN_FLAG_ABORT` と `QUIC_STREAM_SHUTDOWN_FLAG_IMMEDIATE` フラグを付けて [StreamShutdown](https://github.com/microsoft/msquic/blob/main/docs/api/StreamShutdown.md) を呼び出します。この呼び出しは、直ちに `QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE` イベントをトリガーします。この時点で、[StreamClose](https://github.com/microsoft/msquic/blob/main/docs/api/StreamClose.md) を呼び出してストリームを閉じるのが安全です。特定の接続に対するすべてのストリームが閉じられたら、`QUIC_CONNECTION_SHUTDOWN_FLAG_SILENT` フラグを付けて [ConnectionShutdown](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionShutdown.md) を呼び出し、続いて [ConnectionClose](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionClose.md) を呼び出します。すべての接続を閉じた後、未解決の登録および構成に対して [RegistrationClose](https://github.com/microsoft/msquic/blob/main/docs/api/RegistrationClose.md) および [ConfigurationClose](https://github.com/microsoft/msquic/blob/main/docs/api/ConfigurationClose.md) を呼び出し、続いて [MsQuicClose](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicClose.md) を呼び出します。

## 優先ポート

GDK タイトルのメイン ゲーム トラフィックには、[優先ローカル UDP マルチプレイヤー ポート](/build/console-features/networking/game-mesh/preferred-local-udp-multiplayer-port-networking) を使用してください。MsQuic では、[ConnectionStart](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionStart.md) を呼び出す前に、接続オブジェクト ハンドル上で `QUIC_PARAM_CONN_LOCAL_ADDRESS` 設定と共に [SetParam](https://github.com/microsoft/msquic/blob/main/docs/api/SetParam.md) 関数を使用して、このポートを設定します。

`QUIC_PARAM_CONN_LOCAL_ADDRESS` を設定するときは、デュアル スタック IPv4 および IPv6 ソケットを許可するために `AF_UNSPEC` ファミリを指定します。次の例は、`MsQuicCallTable` が [MsQuicOpen](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicOpen.md) から返され、`MsQuicConnectionHandle` が [ConnectionOpen](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionOpen.md) から返された場合に、優先ポートを設定する方法を示します。

```text theme={null}
uint16_t preferredPort;
if (SUCCEEDED(XNetworkingQueryPreferredLocalUdpMultiplayerPort(&preferredPort)))
{
    QUIC_ADDR localAddress = {};
    localAddress.si_family = AF_UNSPEC;
    localAddress.Ipv4.sin_port = htons(preferredPort);

    QUIC_STATUS status = MsQuicCallTable->SetParam(
        MsQuicConnectionHandle,
        QUIC_PARAM_LEVEL_CONNECTION,
        QUIC_PARAM_CONN_LOCAL_ADDRESS,
        sizeof(localAddress),
        &localAddress);
}
```

## メモリに関する考慮事項

MsQuic のパフォーマンスに優れた実装により、GDK タイトルとの間で高帯域幅の送受信が可能です。[WinSock メモリの考慮事項](/build/console-features/networking/game-mesh/winsock-intro-networking#SocketMemory) の拡張として、MsQuic を使用する場合は、カーネルによるメモリ消費を最小限に抑えるために、次のベスト プラクティスに従ってください。

GDK タイトルは、コールバック内での実行時間を最小限に抑える必要があります。MsQuic は、プロトコルの実行およびアプリへのアップコールに別のスレッドを使用しません。したがって、コールバック内で大きな遅延が発生すると、プロトコルが遅延し、カーネルによって必要とされるメモリ消費が増加します。タイトルによって完了する必要のある大きな時間や作業は、独自のスレッド上で発生させる必要があります。

GDK タイトルは、カーネル メモリの使用を減らすために、送信バッファーを効率的に管理する必要があります。詳細については、[MsQuic での送信バッファリング](https://github.com/microsoft/msquic/blob/main/docs/Streams.md#send-buffering) を参照して、MsQuic がタイトルにこの動作を制御させる方法を学習してください。

MsQuic では、受信したデータがユーザー モード バッファーに効率的に転送されることを確実にするために、非同期受信の使用を強くお勧めします。[MsQuic での受信](https://github.com/microsoft/msquic/blob/main/docs/Streams.md#receiving) には、非同期受信の処理方法に関する追加の詳細があります。さらに、消費されるカーネル メモリの量を最小限に抑えるために、MsQuic GDK クライアントで部分データ受け入れ機能を使用しないでください。

## 関連情報

[MsQuic](https://github.com/microsoft/msquic)

[MsQuic API ドキュメント](https://github.com/microsoft/msquic/blob/main/docs/API.md)

[MsQuic リリース](https://github.com/microsoft/msquic/blob/main/docs/Release.md)

[MsQuic ドキュメントのビルド](https://github.com/microsoft/msquic/blob/main/docs/BUILD.md)

[MsQuic Echo PlayFab サーバー サンプル](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Live/MsQuicEcho)


## Related topics

- [XBOX タイトル向けのゲーム メッシュ ネットワーク](/ja-jp/build/console-features/networking/game-mesh/index.md)
- [GDK による XBOX コンソールでのネットワーク](/ja-jp/build/console-features/networking/index.md)
- [Microsoft Game Development Kit ネットワークの概要](/ja-jp/build/console-features/networking/introduction-networking.md)
- [Game Mesh](/ja-jp/build/console-features/networking/game-mesh/game-mesh-toc.md)
- [Dynamic Power States (DPS)](/ja-jp/build/game-principles/sustainability/dynamic-power-states.md)
