Quiche ist eine Implementierung des Quic -Transportprotokolls und des HTTP/3, wie vom IETF angegeben. Es bietet eine API auf niedriger Ebene für die Verarbeitung von Quic -Paketen und zur Bearbeitung des Verbindungszustands. Die Anwendung ist für die Bereitstellung von E/A (z. B. Handhabung von Sockets) sowie für eine Ereignisschleife mit Unterstützung für Timer verantwortlich.
Weitere Informationen darüber, wie Quiche entstanden ist, und einige Einblicke in das Design können Sie einen Beitrag im Blog von Cloudflare lesen, der auf einige Details geht.
Die HTTP/3 -Unterstützung von Quiche Powers Cloudflare Edge Network. Die Cloudflare-quic.com-Website kann zum Testen und Experimentieren verwendet werden.
Der DNS -Resolver von Android verwendet Quiche, um DNS über http/3 zu implementieren.
Quiche kann in Curl integriert werden, um HTTP/3 zu unterstützen.
Quiche kann mit einem inoffiziellen Patch in Nginx integriert werden, um HTTP/3 zu unterstützen.
Bevor Sie in die Quiche-API eintauchen, finden Sie hier einige Beispiele, wie die Quiche-Tools als Teil der Quiche-Apps-Kiste verwendet werden.
Nach dem Klonen des Projekts gemäß dem im Abschnitt Gebäude genannten Befehl kann der Kunde wie folgt ausgeführt werden:
$ Cargo Run--Bin Quiche-Client-https://cloudflare-quic.com/
Während der Server wie folgt ausgeführt werden kann:
$ Cargo Run--Bin Quiche-Server--Zehnungs-Apps/SRC/bin/cert.crt-Keey Apps/SRC/bin/cert.Key
(Beachten Sie, dass das bereitgestellte Zertifikat selbst signiert ist und nicht in der Produktion verwendet werden sollte.)
Verwenden Sie das Flag --help
-Befehlszeilenflag, um eine detailliertere Beschreibung der Optionen jedes Tools zu erhalten.
Der erste Schritt zum Erstellen einer Quic -Verbindung mithilfe von Quiche besteht darin, ein Config
zu erstellen:
Sei MUT config = quiche :: config :: new (quiche :: protocol_version) ?;; config.set_application_protos (& [b "example-proto"]; // zusätzliche Konfigurationspezifik für Anwendungs- und Anwendungsfall ...
Das Config
steuert wichtige Aspekte der Quic -Verbindung wie Quic -Version, ALPN -IDs, Durchflussregelung, Überlastungssteuerung, Leerlaufzeitüberschreitungen und anderen Eigenschaften oder Merkmalen.
Quic ist ein allgemeines Transportprotokoll, und es gibt mehrere Konfigurationseigenschaften, in denen es keinen vernünftigen Standardwert gibt. Beispielsweise hängt die zulässige Anzahl der gleichzeitigen Ströme eines bestimmten Typs von der Anwendung ab, die über Quic ausgeführt wird, und anderer Anwendungsfall-spezifischer Bedenken.
Quiche stellt mehrere Eigenschaften auf Null aus. Anträge müssen diese höchstwahrscheinlich auf etwas anderes einstellen, um ihre Anforderungen mit den folgenden Anforderungen zu erfüllen:
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
hält auch die TLS -Konfiguration. Dies kann von Mutatatoren auf dem vorhandenen Objekt oder durch das Erstellen eines TLS -Kontextes manuell und durch Erstellen einer Konfiguration mit with_boring_ssl_ctx_builder()
geändert werden.
Ein Konfigurationsobjekt kann unter mehreren Verbindungen geteilt werden.
Auf der Client-Seite kann die Funktion connect()
-Vernahmeregelung verwendet werden, um eine neue Verbindung zu erstellen, während accept()
für Server bestimmt ist:
// Client Connection.let conn = quiche :: connect (einige (& server_name), & scid, lokal, peer & mut config)?; // server Connection.let conn = quiche :: Accept (& scid, keine, lokal, peer, peer, & Mut config)?;
Mit der recv()
-Methode der Verbindung kann die Anwendung eingehende Pakete verarbeiten, die zu dieser Verbindung aus dem Netzwerk gehören:
Sei an = socket.local_addr (). uflap (); Loop {let (read, von) = socket.recv_from (& mut buf) .unwrap (); let recv_info = quiche :: recvinfo {from, an}; les Read = Match conn.Recv (& mut buf [.. read], recv_info) {ok (v) => v, err (e) => {// Es ist ein Fehler aufgetreten, damit umgehen. Break;},};}
Ausgehende Pakete werden stattdessen mit der send()
-Methode der Verbindung erzeugt:
Schleife {let (write, send_info) = übereinstimmen conn.send (& mut out) {OK (v) => v, err (quiche :: error :: done) => {// Done Writing.break;}, err (err ( e) => {// Es ist ein Fehler aufgetreten, damit umgehen. Break;},}; socket.send_to (& out [.. write], & send_info.to) .unwrap ();}
Wenn Pakete gesendet werden, ist die Anwendung dafür verantwortlich, einen Timer zu erhalten, um auf zeitbasierte Verbindungsereignisse zu reagieren. Die Timer -Ablauf kann mit der timeout()
-Methode der Verbindung erhalten werden.
let timeout = conn.timeout ();
Die Anwendung ist für die Bereitstellung einer Timer -Implementierung verantwortlich, die spezifisch für das verwendete Betriebssystem oder das verwendete Netzwerk -Framework sein kann. Wenn ein Timer abläuft, sollte die on_timeout()
-Methode der Verbindung aufgerufen werden. Danach müssen möglicherweise zusätzliche Pakete im Netzwerk gesendet werden:
// Timeout abgelaufen, behandeln Sie es. Err (quiche :: error :: done) => {// DEM WRITE. Break;}, err (e) => {// Es ist ein Fehler aufgetreten, Handle it.break;},}; socket.send_to (& out [.. write], & send_info.to) .unwrap ();}
Es wird empfohlen, dass die Anwendungen ausgehenden Paketen das Erstellen von Paket-Bursts vermeiden, die kurzfristige Überlastungen und Verluste im Netzwerk verursachen können.
Quiche enthält Tempo -Hinweise für ausgehende Pakete über das [ at
] -Feld der [ SendInfo
] -Struktur, die von der send()
-Methode zurückgegeben wird. Dieses Feld gibt die Zeit an, in der ein bestimmtes Paket in das Netzwerk gesendet werden soll.
Anwendungen können diese Hinweise verwenden SO_TXTIME
indem sie das Senden von Paketen durch plattformspezifische Mechanismen (z.
Nach einiger Hin- und Her -Verbindung wird die Verbindung ihren Handschlag abschließen und bereit sein, Anwendungsdaten zu senden oder zu empfangen.
Daten können in einem Stream mit der Methode stream_send()
gesendet werden:
Wenn conn.is_established () {// Handshake abgeschlossen ist, senden Sie einige Daten auf Stream 0.Conn.Stream_Send (0, B "Hallo", Richtig) ?;}
Die Anwendung kann prüfen, ob es lesbare Streams mithilfe der readable()
-Methode der Verbindung gibt, die einen Iterator über alle Streams zurückgibt, die über herausragende Daten gelesen werden.
Die Methode stream_recv()
kann dann verwendet werden, um die Anwendungsdaten aus dem lesbaren Stream abzurufen:
Wenn conn.is_established () {// über lesbare Streams.for Stream_id in conn.readable () {// Stream lesbar ist, lesen Sie, bis keine Daten mehr vorhanden sind. (Stream_id, & mut buf) {println! ("Got {} Bytes im Stream {}", read, stream_id);}}}
Das Quiche HTTP/3 -Modul bietet eine API auf hoher Ebene für das Senden und Empfangen von HTTP -Anforderungen und -Anantworten über dem Quic -Transportprotokoll.
Sehen Sie sich das Verzeichnis [Quiche/Beispiele/] an, um umfassendere Beispiele für die Verwendung der Quiche -API zu finden, einschließlich Beispiele zur Verwendung von Quiche in C/C ++ - Anwendungen (Weitere Informationen finden Sie weiter unten).
Quiche enthält eine dünne C -API über der Rost -API, mit der Quiche leichter in C/C ++ - Anwendungen integriert werden können (sowie in anderen Sprachen, die das Aufrufen von C -APIs über eine Form von FFI ermöglichen). Die C API folgt dem gleichen Design des Rostes, modulo die von der C -Sprache selbst auferlegten Einschränkungen.
Beim Laufen cargo build
wird eine statische Bibliothek namens libquiche.a
automatisch neben dem Rost -One erstellt. Dies ist vollständig eigenständig und kann direkt mit C/C ++-Anwendungen verknüpft werden.
Beachten Sie, dass die ffi
-Funktion für die FFI -API aktiviert werden muss (sie ist standardmäßig deaktiviert), indem Sie --features ffi
zu cargo
übergeben.
Quiche erfordert Rost 1.67 oder höher, um zu bauen. Die neueste stabile Rost -Version kann mit Rustup installiert werden.
Sobald die Rost -Build -Umgebung eingerichtet ist, kann der Quiche -Quellcode mit Git abgerufen werden:
$ git klone -recursive https://github.com/cloudflare/quiche
und dann mit Fracht gebaut:
$ Frachtbau -Beispiele
Fracht kann auch verwendet werden, um den Testsuite durchzuführen:
$ Frachttest
Beachten Sie, dass Boringssl, mit dem der kryptografische Handschlag von Quic anhand von TLS implementiert wird, erstellt und mit Quiche verknüpft werden muss. Dies geschieht automatisch beim Erstellen von Quiche mit Fracht, erfordert jedoch, dass der cmake
-Befehl während des Build -Vorgangs verfügbar ist. Unter Windows brauchen Sie auch Nasm. Die offizielle Boringssl -Dokumentation enthält mehr Details.
Alternativ können Sie Ihren eigenen benutzerdefinierten Build von Boringssl verwenden, indem Sie das Boringssl -Verzeichnis mit der Umgebungsvariablen QUICHE_BSSL_PATH
konfigurieren:
$ Quiche_bsl_path = "/path/to/boringssl" Frachtbau -Beispiele
Alternativ können Sie OpenSSL/Quictls verwenden. Damit Quiche diesen Anbieter verwenden kann, kann die openssl
-Funktion der --feature
-Liste hinzugefügt werden. Beachten Sie, dass 0-RTT
nicht unterstützt wird, wenn dieser Anbieter verwendet wird.
Bauen von Quiche für Android (NDK Version 19 oder höher, 21 empfohlen) können mit Fracht-NDK (v2.0 oder höher) durchgeführt werden.
Zunächst muss der Android NDK installiert werden, entweder mit Android Studio oder direkt und die Umgebungsvariable ANDROID_NDK_HOME
muss auf den NDK -Installationspfad, z. B.:
$ export android_ndk_home =/usr/local/share/android-ndk
Dann kann die Rost -Toolchain für die benötigten Android -Architekturen wie folgt installiert werden:
$ Rustup Ziel add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
Beachten Sie, dass die minimale API -Ebene für alle Zielarchitekturen 21 beträgt.
Fracht-NDK (v2.0 oder höher) muss ebenfalls installiert werden:
$ fracht installieren Sie Fracht-NDK
Schließlich kann die Quiche -Bibliothek mit dem folgenden Verfahren erstellt werden. Beachten Sie, dass die Optionen -t <architecture>
und -p <NDK version>
obligatorisch sind.
$ Cargo Ndk -t ARM64 -V8A -P 21 -Build -FEATURES FFI
Weitere Informationen finden Sie unter Build_android_ndk19.sh.
Um Quiche für iOS zu erstellen, brauchen Sie Folgendes:
Installieren Sie Xcode-Befehlszeilen-Tools. Sie können sie mit Xcode oder mit dem folgenden Befehl installieren:
$ XCODE-SELECT-Installieren Sie
Installieren Sie die Rust Toolchain für iOS -Architekturen:
$ Rustup Ziel fügen Sie aArarch64-apple-ios x86_64-apple-ios hinzu
cargo-lipo
einbauen:
$ fracht installieren Sie Fracht-Lipo
Führen Sie den folgenden Befehl aus, um Libquiche zu erstellen:
$ Cargo Lipo -FEATURES FFI
oder
$ Cargo Lipo -FEATURES FFI -RELEASE
Der iOS -Build wird in Xcode 10.1 und Xcode 11.2 getestet.
Um die Docker -Bilder zu erstellen, führen Sie einfach den folgenden Befehl aus:
$ Make Docker-Build
Die Quiche Docker -Bilder finden Sie in den folgenden Docker Hub -Repositories:
Cloudflare/Quiche
Cloudflare/Quiche-Qns
Das latest
Tag wird aktualisiert, wenn die Quiche Master -Filiale aktualisiert wird.
Cloudflare/Quiche
Bietet einen Server und Client, der in/usr/local/bin installiert ist.
Cloudflare/Quiche-Qns
Bietet das Skript zum Testen von Quiche im Quic-Interop-Runner.
Copyright (C) 2018-2019, Cloudflare, Inc.
Siehe Kopieren für die Lizenz.