Quicheは、IETFで指定されているQUIC輸送プロトコルとHTTP/3の実装です。 QUICパケットを処理し、接続状態を処理するための低レベルAPIを提供します。このアプリケーションは、タイマーをサポートしたイベントループと同様に、I/O(ソケット処理など)を提供する責任があります。
Quicheがどのように生まれたのか、そのデザインに関するいくつかの洞察の詳細については、CloudFlareのブログの投稿を読むことができます。
Quiche Powers CloudFlare Edge NetworkのHTTP/3サポート。 CloudFlare-Quic.comのWebサイトは、テストと実験に使用できます。
AndroidのDNS Resolverは、Quicheを使用してHTTP/3にDNSを実装しています。
QuicheをCurlに統合して、HTTP/3のサポートを提供できます。
Quicheは、非公式パッチを使用してNginxに統合して、HTTP/3のサポートを提供できます。
Quiche APIに飛び込む前に、Quiche-Apps Crateの一部として提供されるキッシュツールを使用する方法に関するいくつかの例を以下に示します。
建物セクションに記載されているコマンドに従ってプロジェクトをクローニングした後、クライアントは次のように実行できます。
$ cargo run-bin quiche-client-https://cloudflare-quic.com/
サーバーは次のように実行できますが、
$ cargo run -bin quiche-server- - Cert Apps/src/bin/cert.crt -Key Apps/src/bin/cert.key
(提供された証明書は自己署名であり、生産に使用すべきではないことに注意してください)
--help
コマンドラインフラグを使用して、各ツールのオプションのより詳細な説明を取得します。
Quicheを使用してQUIC接続を確立する最初のステップは、 Config
オブジェクトを作成することです。
mut config = quiche :: config :: new(quiche :: protocol_version)?; config.set_application_protos(&[b "embly-proto"]); //アプリケーションとユースケースに固有の追加構成...
Config
オブジェクトは、QUICバージョン、ALPN ID、フロー制御、混雑制御、アイドルタイムアウト、その他のプロパティまたは機能など、QUIC接続の重要な側面を制御します。
QUICは汎用輸送プロトコルであり、合理的なデフォルト値がない構成プロパティがいくつかあります。たとえば、特定のタイプの許可された数の同時ストリームの数は、QUICを超えて実行されているアプリケーションやその他のユースケースの特定の懸念に依存します。
Quicheはいくつかのプロパティをゼロにデフォルトします。アプリケーションは、以下を使用してニーズを満たすためにこれらを他の何かに設定する必要がある可能性が高いです。
set_initial_max_streams_bidi()
set_initial_max_streams_uni()
set_initial_max_data()
set_initial_max_stream_data_bidi_local()
set_initial_max_stream_data_bidi_remote()
set_initial_max_stream_data_uni()
Config
TLS構成も保持します。これは、既存のオブジェクト上のMutatorによって変更されるか、TLSコンテキストを手動で構築し、 with_boring_ssl_ctx_builder()
を使用して構成を作成することで変更できます。
構成オブジェクトは、複数の接続間で共有できます。
クライアント側では、 connect()
ユーティリティ関数を使用して新しい接続を作成できますが、 accept()
はサーバー用です。
// client connection.let conn = quiche :: connect(some(&server_name)、&scid、local、peer、&mut config)? &mut config)?;
接続のrecv()
メソッドを使用すると、アプリケーションはネットワークからその接続に属する着信パケットを処理できます。
to = socket.local_addr()。unwrap(); loop {let(read、from)= socket.recv_from(&mut buf).unwrap(); let recv_info = quiche :: recvinfo {from、}; match conn.recv(&mut buf [.. read]、recv_info){ok(v)=> v、err(e) => {//エラーが発生し、it.break;}、};}
発信パケットは、代わりに接続のsend()
メソッドを使用して生成されます。
loop {let(write、send_info)= match conn.send(&mut){ok(v)=> v、err(quiche :: error :: done)= {// done writing.break;}、err( e)=> {//エラーが発生し、it.break;}、}; socket.send_to(&out [.. write]、 &send_info.to).unwrap();}
パケットが送信されると、アプリケーションはタイマーを維持して時間ベースの接続イベントに対応する責任があります。 Connectionのtimeout()
メソッドを使用して、タイマーの有効期限を取得できます。
let timeout = conn.timeout();
このアプリケーションは、使用されるオペレーティングシステムまたはネットワークフレームワークに固有のタイマーの実装を提供する責任があります。タイマーの有効期限が切れると、接続のon_timeout()
メソッドを呼び出す必要があります。その後、ネットワークで追加のパケットを送信する必要がある場合があります。
//タイムアウトの有効期限は、it.conn.on_timeout(); // timeout.loop {let(write、send_info)= mate conn.send(&mut){ok(v)=> v、mated(write、send_info)= mate conn.send(write、send_info)= mate err(quiche :: error :: done)=> {// doned writing.break;}、err(e)=> {//エラーが発生し、ハンドルが発生しましたit.break;}、}; socket.send_to(&out [.. write]、&send_info.to).unwrap();}
ネットワークの短期的な混雑と損失を引き起こす可能性のあるパケットバーストの作成を避けるために、発信パケットのアプリケーションのペース送信をお勧めします。
Quicheはsend()
メソッドによって返される[ SendInfo
]構造の[at sendinfo]構造の[ at
]フィールドを介して、発信パケットのペーシングヒントを公開します。このフィールドは、特定のパケットをネットワークに送信する時間を表します。
アプリケーションは、プラットフォーム固有のメカニズム(Linux上のSO_TXTIME
ソケットオプションなど)を介してパケットの送信を人為的に遅延させることで、カスタムメソッド(ユーザースペースタイマーを使用するなど)を使用することにより、これらのヒントを使用できます。
やり取りの後、接続は握手を完了し、アプリケーションデータを送信または受信する準備が整います。
stream_send()
メソッドを使用して、データをストリームに送信できます。
conn.is_eStablished(){//ハンドシェイクが完了した場合、ストリームにいくつかのデータを送信します0.conn.stream_send(0、b "hello"、true)?;}
アプリケーションは、Connectionのreadable()
メソッドを使用して読み取り可能なストリームがあるかどうかを確認できます。
その後、 stream_recv()
メソッドを使用して、読み取り可能なストリームからアプリケーションデータを取得できます。
conn.is_eStablished(){//読み取り可能なストリームを反復します。 (stream_id、&mut buf){println!( "got {} bytes on stream {}"、read、stream_id);}}}}
Quiche HTTP/3モジュールは、QUIC輸送プロトコルに加えてHTTPリクエストと応答を送信および受信するための高レベルAPIを提供します。
[Quiche/Examples/]ディレクトリをご覧ください。C/C ++アプリケーションでキッシュの使用方法に関する例を含む、Quiche APIの使用方法に関するより完全な例をご覧ください(詳細については、以下を参照)。
Quicheは、rust APIの上に薄いC APIを公開します。これは、キッシュをより簡単にC/C ++アプリケーションに統合するために(およびFFIの形を介してC APIを呼び出すことを可能にする他の言語)に公開します。 c APIは、錆びたものと同じ設計に従います。これは、C言語自体によって課される制約を測定します。
cargo build
実行すると、 libquiche.a
という静的ライブラリが錆びたものと一緒に自動的に構築されます。これは完全にスタンドアロンであり、C/C ++アプリケーションに直接リンクできます。
FFI APIを有効にするには、 ffi
機能を有効にする必要があります(デフォルトでは無効になっています)、 --features ffi
cargo
に渡すことにより。
キッシュでは、錆びた1.67以降を構築する必要があります。 Rustupを使用して、最新の安定したRustリリースをインストールできます。
Rustビルド環境がセットアップされると、gitを使用してキッシュソースコードを取得できます。
$ git clone -Recursive https://github.com/cloudflare/quiche
そして、貨物を使用して構築しました:
$貨物ビルド-examples
貨物は、テストスイートの実行にも使用できます。
$貨物テスト
TLSに基づいてQuicの暗号化握手を実装するために使用されるBoringsSlは、Quicheに構築され、リンクする必要があることに注意してください。これは、貨物を使用してキッシュを構築するときに自動的に行われますが、ビルドプロセス中にcmake
コマンドを利用できるようにする必要があります。 Windowsでは、NASMも必要です。公式のBoringsSLドキュメントには詳細があります。
別の方法では、 QUICHE_BSSL_PATH
環境変数を使用してBoringsSLディレクトリを構成することにより、BoringsSLの独自のカスタムビルドを使用できます。
$ quiche_bssl_path = "/path/to/boringssl" cargo build -examples
または、OpenSSL/QUICTLSを使用できます。 Quicheがこのベンダーを使用できるようにするために、 openssl
機能を--feature
リストに追加できます。このベンダーが使用されている場合、 0-RTT
はサポートされていないことに注意してください。
Android用のビルディングキッシュ(NDKバージョン19以降、21を推奨)は、貨物NDK(v2.0以降)を使用して行うことができます。
最初に、Android Studioまたは直接的に使用してAndroid NDKをインストールする必要があり、 ANDROID_NDK_HOME
環境変数は、NDKインストールパスに設定する必要があります。
$ export android_ndk_home =/usr/local/share/android-ndk
次に、必要なAndroidアーキテクチャ用のRustツールチェーンを次のようにインストールできます。
$ Rustup Target Add Aarch64-Linux-Android ARMV7-LINUX-ANDROIDEABI I686-LINUX-ANDROID X86_64-LINUX-ANDROID
すべてのターゲットアーキテクチャの最小APIレベルは21であることに注意してください。
cargo-ndk(v2.0以降)もインストールする必要があります。
$貨物インストール貨物ndk
最後に、次の手順を使用してキッシュライブラリを構築できます。 -t <architecture>
および-p <NDK version>
オプションが必須であることに注意してください。
$ cargo ndk -t arm64 -v8a -p 21-ビルド - フィーチュアffi
詳細については、build_android_ndk19.shを参照してください。
iOSのキッシュを構築するには、次のことが必要です。
Xcodeコマンドラインツールをインストールします。 Xcodeまたは次のコマンドでそれらをインストールできます。
$ xcode-select - インストール
iOSアーキテクチャ用のRustツールチェーンをインストールします。
$ Rustup Target Add Aarch64-Apple-Ios X86_64-Apple-Ios
cargo-lipo
をインストールします:
$貨物インストール貨物LIPO
Libquicheを構築するには、次のコマンドを実行します。
$ cargo lipo - ffi
または
$ cargo lipo - features ffi - リリース
iOSビルドは、Xcode 10.1およびXcode 11.2でテストされています。
Docker画像を作成するには、次のコマンドを実行するだけです。
$ make docker-build
次のDocker Hubリポジトリで、Quiche Docker画像を見つけることができます。
CloudFlare/Quiche
cloudflare/quiche-qns
latest
タグは、キッシュマスターブランチの更新がいつでも更新されます。
CloudFlare/Quiche
/usr/local/binにインストールされているサーバーとクライアントを提供します。
cloudflare/quiche-qns
Quic-Interop-Runner内でキッシュをテストするスクリプトを提供します。
Copyright(c)2018-2019、CloudFlare、Inc。
ライセンスのコピーを参照してください。