次の方法で共有


QUIC 構成オプション

System.Net.Quic ライブラリでは、オプション クラスを使用して、構築と初期化の前にプロトコル オブジェクト (QuicListenerQuicConnection) を構成します。 これを行うには、次の 3 つの異なるオプション クラスがあります。

すべてのオプション クラスを段階的に設定できます。つまり、コンストラクターを使用してプロパティを初期化する必要がなく、個別に設定できます。 ただし、新しいリスナーまたは接続の構成に使用された時点で、オプションが検証され、不足している必須値や正しく構成されていない値に対して適切な種類の ArgumentException がスローされます。 たとえば、必須の QuicConnectionOptions.DefaultStreamErrorCode が設定されていない場合に ConnectAsync(QuicClientConnectionOptions, CancellationToken) を呼び出すと、ArgumentOutOfRangeException がスローされます。

QuicListenerオプションズ

QuicListenerOptions は、新しい QuicListenerを開始するときに QuicListener.ListenAsync(QuicListenerOptions, CancellationToken) で使用されます。 個々の構成プロパティは次のとおりです。

アプリケーションプロトコル

サーバーで受け入れられるアプリケーション プロトコルを定義します (RFC 7301 - ALPN)。 関連付けられていない可能性がある異なるプロトコルに対して複数の値を含めることができます。 新しい接続を受け入れるプロセスでは、リスナーは受信接続ごとに 1 つの特定のプロトコルを絞り込んだり選択したりできます。QuicListenerOptions.ConnectionOptionsCallbackを参照してください。 このプロパティは必須であり、少なくとも 1 つの値を含める必要があります。

ConnectionOptionsCallback (接続オプションコールバック)

ConnectionOptionsCallback は、受信接続の QuicServerConnectionOptions を選択するデリゲートです。 この関数には、クライアントによって要求されたサーバー名 (RFC 6066 - SNI) を含む の部分的に初期化されたインスタンスが与えられます。 デリゲートは、受信接続ごとに呼び出されます。 指定されたクライアント情報に基づいて異なるオプションを返すか、毎回同じオプションのインスタンスを安全に返すことができます。 デリゲートの目的と形状は、意図的に SslStream.AuthenticateAsServerAsync(ServerOptionsSelectionCallback, Object, CancellationToken)で使用される ServerOptionsSelectionCallback に似ています。 このプロパティは必須です。

ListenBacklog

ListenBacklog は、追加の接続が拒否され始める前にリスナーが保持できる受信接続の数を決定します。 接続の確立の試行は、失敗した場合や、キューで待機中に接続がシャットダウンされた場合でもカウントされます。 新しい接続を確立するための進行中のプロセスも、この制限に含まれます。 接続または接続の試行回数は、QuicListener.AcceptConnectionAsync(CancellationToken) によって取得されるまでカウントされます。 バックログの制限の目的は、サーバーが処理できるよりも多くの着信接続に圧倒されないようにすることです。 このプロパティは省略可能で、既定値は 512 です。

ListenEndPoint

ListenEndPoint には、リスナーが新しい接続を受け入れる IP アドレスとポートが含まれています。 基になる実装により、MsQuicリスナーは、ここで指定した内容に関係なく、常にデュアルスタック ワイルドカード ソケットにバインドされます。 これは、特に HTTP/1.1 や HTTP/2 の場合のような通常の TCP ソケットと比較して、予期しない動作につながる可能性があります。 詳細については、QUIC トラブルシューティング ガイドを参照してください。 このプロパティは必須です。

QuicConnectionOptions

QuicConnectionOptions オプションは、QuicClientConnectionOptionsQuicServerConnectionOptionsの間で共有されます。 これは抽象基本クラスであり、単独では使用できません。 これには、次のプロパティが含まれています。

デフォルトクローズエラーコード

DefaultCloseErrorCode は、QuicConnection.CloseAsync(Int64, CancellationToken)を呼び出さずに接続が破棄されるときに使用されます。 QUIC プロトコルでは、接続を閉じるアプリケーション レベルの理由を指定する必要があります (RFC 9000- 接続を閉じる)。 QuicConnection 接続を破棄する前に、アプリケーション コードで CloseAsync(Int64, CancellationToken) を強制的に呼び出す方法はありません。 このような場合には、接続が使用すべきエラーコードを認識する必要があります。 このプロパティは必須です。

DefaultStreamErrorCode

DefaultStreamErrorCode は、すべてのデータが読み取る前にストリームが破棄されるときに使用されます。 QUIC ストリーム経由でデータを受信する場合、アプリケーションはすべてのデータを使用するか、そうでない場合は読み取り側を中止する必要があります。 また、接続の終了と同様に、QUIC プロトコルには、読み取り側を中止するアプリケーション レベルの理由が必要です (RFC 9000-の送信を停止します)。 このプロパティは必須です。

HandshakeTimeout

HandshakeTimeout 接続を完全に確立する必要がある時間制限を設定します。それ以外の場合は中止されます。 この値を InfiniteTimeSpan に設定することは可能ですが、お勧めしません。 接続試行は無期限にハングする可能性があり、QuicListenerを停止する以外にクリアする手段はありません。 このプロパティは省略可能で、既定値は 10 秒です。

IdleTimeout

指定した IdleTimeoutを超えて接続が非アクティブな場合、接続は切断されます。 このオプションは、QUIC プロトコル仕様 (RFC 9000 - アイドル タイムアウト) の一部であり、接続ハンドシェイク中にピアに送信されます。 接続は、このオプションとピアのアイドル タイムアウトのうち小さい方の値を使用します。 したがって、このオプションが設定されたよりも早く、アイドル タイムアウト時に接続が閉じられる可能性があります。 このプロパティは省略可能です。既定値は MsQuic (30 秒) に基づいています。

InitialReceiveWindowSizes

InitialReceiveWindowSizes は、接続やストリームで受信できるデータの量を制限する値のセットを指定します。 QUIC プロトコルは、個々のストリームを介して送信できるデータの量と、接続全体に対して累積的に送信できる量を制限するメカニズムを定義します (RFC 9000 - データ フロー制御)。 これらの制限は、アプリケーションがデータの使用を開始する前にのみ適用されます。 その後、MsQuic は、アプリケーションが読み取る速度に基づいて受信ウィンドウのサイズを継続的に調整します。 このプロパティは QuicReceiveWindowSizes 型であり、次のオプションが含まれています。

これらの値は、2 の累乗である負以外の整数である必要があります。これは MsQuicから継承された制限です。 これらの値のいずれかを 0 に設定すると、基本的に、特定のストリームまたは接続全体でデータが受信されることはありません。 このプロパティは省略可能で、既定値はストリームの場合は 64 KB、接続の場合は 64 MB です。

キープアライブインターバル (KeepAliveInterval)

KeepAliveInterval は、PING フレームを送信するかどうか、そしてそれを送信する頻度を決定し、接続をアクティブに保ってIdleTimeoutで閉じないようにします(RFC 9000 - PING フレーム)。 このプロパティを設定する場合は、RFC 9000 - アイドルタイムアウトの延期に関する推奨事項を考慮してください。 値を低く設定すると、パフォーマンスに悪影響を及ぼす可能性があります。 また、アイドル タイムアウトに近すぎるプロパティを設定しても、接続が終了する可能性があります。 このプロパティは省略可能です。既定値 InfiniteTimeSpan、PING は送信されません。

MaxInboundBidirectionalStreams

MaxInboundBidirectionalStreams は、接続が受け入れる同時にアクティブな双方向ストリームの最大数を決定します。 これは、QUIC 仕様でコンカレンシーの処理を定義する方法 (RFC 9000- コンカレンシーの制御) とは異なる点に注意してください。 QUIC プロトコルは、接続の有効期間中にストリームを累積的にカウントし、増加し続ける制限を使用して、既に閉じているストリーム (RFC 9000- MAX_STREAMS フレーム) を含む、接続で受け入れられるストリームの合計数を決定します。 このプロパティを使用すると、アプリケーションが同時ストリームの制限のみを指定し、MsQuic がこの制限を対応する MAX_STREAMS フレームに変換する処理を行えるように、これを簡略化します。 このプロパティは省略可能で、既定値はクライアント接続の場合は 0、サーバー接続では 100 です。

MaxInboundUnidirectionalStreams

MaxInboundUnidirectionalStreams は、接続が受け入れる同時にアクティブな単方向ストリームの最大数を決定します。 これは、QUIC 仕様でストリームコンカレンシーの処理を定義する方法とは異なうことに注意してください (RFC 9000- コンカレンシーの制御)。 QUIC プロトコルは、接続の有効期間中にストリームを累積的にカウントし、増加し続ける制限を使用して、既に閉じているストリーム (RFC 9000- MAX_STREAMS フレーム) を含む、接続で受け入れられるストリームの合計数を決定します。 このプロパティを使用すると、アプリケーションが同時ストリームの制限のみを指定し、MsQuic がこの制限を対応する MAX_STREAMS フレームに変換する処理を行えるように、これを簡略化します。 このプロパティは省略可能で、クライアント接続の場合は既定値は 0、サーバー接続の場合は 10 です。

StreamCapacityCallback(ストリーム容量コールバック)

StreamCapacityCallback は、ピアが MAX_STREAMS 経由で新しいストリーム容量を解放するたびに呼び出されるコールバックであり、その結果、現在の容量は 0 を超えています。 コールバック引数で指定される値は容量の増分です。つまり、コールバックからのすべての値の合計は、 (RFC 9000 - MAX_STREAMS フレーム) から受け取った最後の値と等しくなります。 このコールバックは、SocketsHttpHandler.EnableMultipleHttp3Connections 機能をサポートするように設計されており、いくつかの注意事項があります。

次の簡略化されたシナリオでは、ストリームの開始とコールバックの動作をキャプチャします。

  1. クライアントは、次の方法でサーバーへの接続を開始します。

    var client = await QuicConnection.ConnectAsync(new QuicClientConnectionOptions
    {
        ...
        StreamCapacityCallback = (connection, args) =>
            Console.WriteLine($"{connection} stream capacity increased by: unidi += {args.UnidirectionalIncrement}, bidi += {args.BidirectionalIncrement}")
    };
    
  2. サーバーは、一方向ストリームの場合はストリーム制限 2、双方向の場合は 0 を使用してクライアントに初期設定を送信します。

  3. クライアントの StreamCapacityCallback が呼び出され、出力されます。

    [conn][0x58575BF805B0] stream capacity increased by: unidi += 2, bidi += 0
    
  4. ConnectAsync へのクライアント呼び出しは、[conn][0x58575BF805B0] 接続で返されます。

  5. クライアントは、いくつかのストリームを開こうとします。

    var stream1 = await connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional);
    var stream2 = await connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional);
    // The following call will get suspended because the stream's limit has been reached.
    var taskStream3 = connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional);
    
  6. クライアントは、最初の 2 つのストリームを終了して閉じます。

    await stream1.WriteAsync(data, completeWrites: true);
    await stream1.DisposeAsync();
    await stream2.WriteAsync(data, completeWrites: true);
    await stream2.DisposeAsync();
    Console.WriteLine($"Stream 3 {(taskStream3.IsCompleted ? "opened" : "pending")}");
    
  7. クライアントは次の内容を出力します。

    Stream 3 pending
    
  8. サーバーは、最初の 2 つのストリームを処理した後、2 の追加容量を解放します。

  9. クライアントで 2 つのことが起こります。 最初に、3 つ目のストリームが開かれます。

    var stream3 = await taskStream3;
    

    その後、クライアントの StreamCapacityCallback が再度呼び出され、次の内容が表示されます。

    [conn][0x58575BF805B0] stream capacity increased by: unidi += 2, bidi += 0
    

このプロパティは省略可能です。

QuicServerConnectionOptions(クイックサーバー接続オプション)

QuicServerConnectionOptions オプションは、サーバー側接続に固有です。 QuicConnectionOptionsから継承されたプロパティとは別に、次のものが含まれます。

サーバー認証オプション

ServerAuthenticationOptions には、サーバー接続の TLS 設定が含まれています。 オプションは、SslStream.AuthenticateAsServer(SslServerAuthenticationOptions) および SslStream.AuthenticateAsServerAsync(SslServerAuthenticationOptions, CancellationToken)で使用されるのと同じです。 QUIC サーバーの場合、SslServerAuthenticationOptions は次の場合に有効です。

このプロパティは必須であり、一覧の条件を満たす必要があります。

QuicClientConnectionOptions

QuicClientConnectionOptions オプションは、クライアント側の接続に固有です。 QuicConnectionOptionsから継承されたプロパティとは別に、次のものが含まれます。

クライアント認証オプション (ClientAuthenticationOptions)

ClientAuthenticationOptions には、クライアント接続の TLS 設定が含まれています。 オプションは、SslStream.AuthenticateAsClient(SslClientAuthenticationOptions) および SslStream.AuthenticateAsClientAsync(SslClientAuthenticationOptions, CancellationToken)で使用されるのと同じです。 QUIC クライアントの場合、SslClientAuthenticationOptions は次の場合に有効です。

このプロパティは必須であり、一覧の条件を満たす必要があります。

ローカルエンドポイント

LocalEndPoint には、クライアント接続のバインド先となる IP アドレスとポートが含まれます。 指定しない場合、OS は IP アドレスとポートを割り当てます。 このプロパティは省略可能です。

リモートエンドポイント

RemoteEndPoint は、接続が確立されているピアの DnsEndPoint または IPEndPoint にすることができます。 DnsEndPointの場合は、Dns.GetHostAddressesAsync(String, CancellationToken) によって返される最初の IP アドレスが使用されます。 このプロパティは必須です。