Was ist QUIC

QUIC soll das Transmission-Control-Protocol (TCP) des Internetprotokolls optimieren. „Quick UDP Internet Connection (QUIC)“ ist ein relativ „neues“ Netzwerkprotokoll. Es wurde im Mai 2021 von der Internet Engineering Task Force (IETF) im RFC 9000 (Titel: QUIC: A UDP-Based Multiplexed and Secure Transport) standardisiert. Dieser Artikel gibt einen kurzen Überblick über QUIC und zeigt an einigen Beispielen, in welchem Umfang QUIC im heutigen Internet verwendet wird.

QUIC wurde von Google im Jahr 2012 entwickelt und die ersten öffentlichen Versionen dieses Protokolls wurde in Chromium Version 29 integriert. QUIC ist ein Versuch, die grundlegende Funktionsweise des Transmission-Control-Protocols (TCP) des Internetprotokolls zu verfeinern, und zwar nicht durch eine grundlegende Änderung der Flusskontrollverfahren und der Stream-Verwaltung, sondern durch eine Änderung des Ortes, an dem die Transportfunktion innerhalb des Endgeräts implementiert ist, und folglich auch durch eine Änderung der Kontrolle über diese Funktion.

Das TCP-Protokoll wurde als Betriebssystemfunktion implementiert, und Anwendungen interagieren mit TCP über eine Schnittstelle, die die grundlegenden I/O-Funktionen (Öffnen/Schließen und Lesen/Schreiben) bereitstellt. Die Einzelheiten zur Integrität der Datenströme und der Flusskontrolle sind für die Anwendung weitgehend verborgen. Das macht die Anwendungen zwar einfacher, aber diese Einfachheit bringt auch Probleme mit sich.

TCP hat einige Probleme in Bezug auf webbasierte Dienste. Heutzutage sind die meisten Webseiten keine einfachen monolithischen Objekte mehr. Sie enthalten in der Regel viele separate Komponenten, darunter Bilder, Skripte, angepasste Frames, Style-Sheets und Ähnliches. Jede dieser Komponenten bildet ein separates Objekt, und wenn man einen Browser verwendet, der mit der ursprünglichen HTTP-Implementierung ausgestattet ist, wird jedes Objekt in einer neuen TCP-Sitzung geladen, selbst wenn es von derselben IP-Adresse aus bedient wird. Der Aufwand für den Aufbau einer neuen TCP-Sitzung und einer neuen TLS-Sitzung (Transport Layer Security) für jedes einzelne Web-Objekt innerhalb einer zusammengesetzten Web-Ressource kann beträchtlich sein, und die Versuchung, eine bereits eingerichtete TLS-Sitzung für mehrere Abrufe vom selben Server wiederzuverwenden, ist nahezu unmöglich.

Aber auch dieser Ansatz des Multiplexens mehrerer Datenströme innerhalb einer einzigen TCP-Sitzung hat seine Tücken. Das Multiplexen mehrerer logischer Datenströme in einer einzigen Sitzung kann zu unerwünschten Abhängigkeiten zwischen den Maschinen, die den Datenstrom verarbeiten, führen. Dabei kann es zu einer sogenannten „Head of Line Blocking“-Situationen kommen, bei denen ein Stillstand bei der Übertragung des gerade aktiven Datenstroms alle in der Warteschlange befindlichen Abrufströme in derselben TCP-Sitzung blockiert. Obwohl es durchaus sinnvoll ist, eine einzige Ende-zu-Ende-Sicherheitsassoziation und einen einzigen ratengesteuerten Datenflusszustand über ein Netz hinweg für mehrere logische Datenflüsse gemeinsam zu nutzen, ist TCP ein eher schlechter Weg, um dieses Ziel zu erreichen. Die Schlussfolgerung ist, dass wir, wenn wir die Effizienz solcher zusammengesetzten Transaktionen durch die Einführung von parallelem Verhalten in das Protokoll verbessern wollen, über das derzeitige Verhalten von TCP hinausgehen müssen.

Das hört sich natürlich viel einfacher an, als es tatsächlich ist. Einige Klassen von Anwendungen (und Diensten) würden gerne einige Änderungen im Verhalten von TCP sehen, aber es liegt an den Betreibern der Betriebssystemplattformen, solche Änderungen zu implementieren. Eine Verbesserung kann jedoch nur dadurch erreicht werden, dass man der Anwendung die direkte Kontrolle darüber überlässt, wie das Verhalten des Transportdienstes gestaltet wir.

Im Gegensatz dazu setzt das User-Datagram-Protocol (UDP) die Anwendung ohne großartige Zusatzmechanismen direkt auf dem IP-Protokoll auf. Daher kann jede Anwendung ihr eigenes Ende-zu-Ende-Transportprotokoll implementieren und die Kontrollstrukturen dieses Transportprotokolls quasi als Nutzlast über UDP umsetzen. An diesem Punkt hat die Anwendung die vollständige Kontrolle über das Transportprotokoll und kann dessen Verhalten nach Belieben anpassen, ohne auf eine dritte Partei warten zu müssen.

 

Kurzer Überblick über QUIC

QUIC ist ein Ende-zu-Ende-Transportprotokolls, das als Overlay auf einem UDP-Datagrammfluss realisiert ist.

Vergleich von TCP und QUIC innerhalb der HTTP-Architektur.

QUIC kombiniert die Stream-Integrität und die Flow-Control-Funktionen von TCP mit den Verschlüsselungsfunktionen von Sessions von TLS, fügt eine flexiblere Behandlung von Multistream hinzu und bietet darüber hinaus eine bessere Unterstützung für die Adressflexibilität, um eine breite Palette von NAT-Adressübersetzungsfunktionen zu tolerieren.

QUIC-Verbindungsbezeichner

Für einen flexiblen Übergang über NATs verwendet QUIC das Konzept der Verbindungskennungen (connection IDs). Jeder Endpunkt generiert Verbindungs-IDs, die es ermöglichen, dass empfangene Pakete mit dieser Verbindungs-ID an den Prozess weitergeleitet werden, der diese Verbindungs-ID verwendet. Während der Aushandlung der QUIC-Version werden diese Verbindungs-IDs ausgetauscht, und danach enthält jedes gesendete QUIC-Paket die aktuelle Verbindungs-ID der Gegenstelle.

Diese Form der semantischen Unterscheidung zwischen der Identität einer Verbindung zu einem Endpunkt und der aktuellen IP-Adresse und Portnummer, die von QUIC verwendet wird, ähnelt dem Host-Identity-Protocol (HIP). Der konstante Endpunkt-Identifikator von QUIC ermöglicht es einer Sitzung, Änderungen der IP-Adressen und Ports des Endpunkts zu überstehen. Ein eingehendes QUIC-Paket kann als Teil eines bestehenden Streams erkannt werden, wenn es dieselbe Verbindungs-ID verwendet, auch wenn sich die Quell-IP-Adresse und die UDP-Port-Nummern geändert haben.

 

QUIC-Multistream-Unterstützung

Eine einzelne QUIC-Session kann mehrere Stream-Profile unterstützen. Bidirektionale Streams stellen die Client- und Server-Transaktionen in einen abgestimmten Kontext, wie er beispielsweise für die herkömmlichen Request/Response-Transaktionen von HTTP/1 erforderlich ist. Von einem Client wird erwartet, dass dieser einen bidirektionalen Stream mit einem Server öffnet und dann eine Anfrage in einem Stream stellt, die eine entsprechende Antwort des Servers erzeugt. Es ist möglich, dass ein Server einen bidirektionalen Push-Stream an einen Client initiiert, der eine Antwort ohne eine anfängliche Anfrage enthält. Kontrollinformationen werden durch unidirektionale Kontrollströme unterstützt, bei denen eine Seite eine Nachricht an die andere Seite weiterleiten kann, sobald diese dazu in der Lage ist. Eine zugrundeliegende unidirektionale Stream-Schnittstelle, die zur Unterstützung von Kontrollströmen verwendet wird, ist auch für die Anwendung zugänglich.

QUIC kann nicht nur eine Reihe von verschiedenen Stream-Profilen unterstützen, sondern auch verschiedene Stream-Profile innerhalb einer einzigen Ende-zu-Ende-Session. Dies ist natürlich kein neues Konzept, und das HTTP/2-Protokoll ist ein gutes Beispiel für ein Protokoll auf Anwendungsebene, das Multiplexing und Stream Framing einsetzt, um mehrere Datenströme über einen einzigen Transportdatenstrom zu übertragen. Bei einem einzelnen TCP-Transportstrom, wie dieser von HTTP/2 verwendet wird, kann es jedoch zu einem Head-of-Line-Blocking kommen, bei dem sich alle Overlay-Datenströme über eine einzige TCP-Sitzung verteilen. Wenn einer der Ströme blockiert, ist es möglich, dass alle Overlay-Datenströme davon betroffen sind und ebenfalls blockiert werden.

QUIC ermöglicht eine etwas andere Form des Multiplexing, bei der jeder Overlay-Datenstrom seinen eigenen Ende-zu-Ende-Flow-Status nutzen kann und eine Pause in einem Overlay-Datenstrom nicht bedeutet, dass ein anderer gleichzeitiger Datenstrom betroffen ist.

Ein Grund für das Multiplexing mehrerer Datenströme zwischen denselben zwei Endpunkten in HTTP/2 war die Verringerung des Aufwands für die Einrichtung einer TLS-Sicherheitsassoziation für jede TCP-Sitzung. Dies kann ein großes Problem darstellen, wenn die einzelnen Ströme jeweils ein kleines Objekt senden, und es ist möglich, dass die TCP- und TLS-Handshake-Komponente eines zusammengesetzten Web-Objektabrufs sowohl die Gesamt-Downloadzeit als auch das Datenvolumen dominiert.

QUIC verlagert die Sicherheitsassoziation in den Ende-zu-Ende-Zustand, der als UDP-Datenfluss implementiert ist, so dass einzelne Streams auf einfache Weise gestartet werden können, da sie im Wesentlichen den etablierten sicheren Sitzungszustand wiederverwenden.

 

QUIC-Verschlüsselung

QUIC nutzt eine Ende-zu-Ende-Verschlüsselung. Diese Verschlüsselung wird an der UDP-Nutzlast vorgenommen, so dass nach Abschluss des TLS-Handshakes nur sehr wenig des nachfolgenden QUIC-Paketaustauschs ungeschützt bleibt

Vergleich von TCP und TLS mit QUIC.

Bei QUIC bleiben nur die öffentlichen Flags ungeschützt. Dieser erste Teil eines QUIC-Pakets besteht aus der Verbindungs-ID, die es dem Empfänger ermöglicht, das Paket einem Endpunkt zuzuordnen, ohne das gesamte Paket zu entschlüsseln. Die QUIC-Version ist ebenfalls Teil der öffentlichen Flag-Informationen. Diese wird nur beim ersten Aufbau einer QUIC-Session genutzt und kann danach weggelassen werden.

Der Rest des QUIC-Pakets besteht aus nicht öffentlichen Flags und der Nutzlast. Diese werden verschlüsselt und sind für eine Analyse nicht direkt sichtbar. Dieser private Teil enthält die Sequenznummer des Pakets. Dieses Feld wird verwendet, um doppelte und fehlende Pakete zu erkennen. Es enthält auch alle Parameter der Flusskontrolle, einschließlich der Übertragungsfenster.

Genau hierin liegt der entscheidenden Unterschiede zwischen TCP und QUIC. Bei TCP sind die Kontrollbestandteile des Protokolls unverschlüsselt. Dadurch kann ein Netzelement (beispielsweise ein Proxy) die Portadressen (und den Anwendungstyp) sowie den Zustand der Verbindung problemlos überprüfen. Eine Verbindung ist somit nur eine Folge von TCP-Pakete, selbst wenn man nur die Pakete betrachtet werden, die innerhalb der Verbindung in eine Richtung fließen. Dadurch kann ein Netzelement problemlos auf die Umlaufzeit und die Datenübertragungsrate schließen. Auch kann ein Netzelement durch Manipulation des Empfangsfensters im ACK-Stream eine Verbindung drosseln und die Übertragungsrate auf eine Weise reduzieren. Dies wäre für die beiden an der Session beteiligten Endpunkte unsichtbar. Die Verschlüsselung dieser Kontrollinformationen innerhalb des QUIC-Pakets stellt sicher, dass kein Netzelement direkten Einblick in diese Informationen hat und kein Netzelement den Verbindungsfluss manipulieren kann.

 

QUIC und IP-Fragmentierung

Mathias Hein, Consultant, Buchautor, Journalist

In RFC 9000 wird die Fragmentierung von UDP-Datagrammen auf der IP-Schicht verboten. Darüber hinaus müssen die Clients sicherstellen, dass UDP-Datagramme, die Initialpakete enthalten, UDP-Nutzlasten von mindestens 1200 Byte aufweisen, wobei PADDING-Frames nach Bedarf hinzugefügt werden können. Dies wird dadurch erreicht, dass das QUIC-HELLO-Paket auf die maximale Paketgröße aufgefüllt wird und der anfängliche HELLO-Austausch nicht abgeschlossen wird, wenn das maximal große Paket fragmentiert ist. Den Endpunkten ist es gestattet, eine größere maximale Paketgröße zu verwenden, wenn sie die Machbarkeit dieser Einstellung über ein Verfahren zur Ermittlung der Pfad-MTU bestätigt haben. Ein anderer Lösungsansatz besteht darin, eine Paketgröße zu wählen, bei der relativ sicher ist, dass sie nicht fragmentiert wird.

Bei Messungen im Internet wurden in 46 Prozent aller Sessions eine Paketgröße von 1.200 Byte beobachtet. Die nächsthäufigsten Größen waren 1.250 Byte (18,5 Prozent der Sessions) und 1.252 Byte (16,4 Prozent der Sessions).

 

Welche Clients verwenden HTTP/3?

Durch die Verwendung des Browser-Strings, der bei jedem HTTP-Abruf übermittelt wird, und den Abgleich des Abrufs mit dem verwendeten Protokoll (HTTP/2 oder HTTP/3) kann ein Profil der Plattformen und Browser erstellen werden, die HTTP/3 für den Objektabruf verwenden.

 

BetriebssystemHTTP/3Nicht-HTTP/3
Android47,7%84,5%
iOS44,5%5,5%
Win10,0%5,5%
Mac OS X1,5%1,0%
Win7/81,0%1,0%
Linux0,3%0,4%

Tabelle: Plattformen und HTTP/3-Nutzung

 

Aus der Tabelle geht klar hervor, dass sich derzeit die größte Verschiebung bei der Verwendung von HTTP/3 in Apples iOS-Geräten (iPhones und iPads) stattfindet. Ähnliche sieht es bei den Browsern aus.

 

BrowserHTTP/3Nicht-HTTP/3
Chrome52,2%91,7%
Safari44,6%4,3%
Firefox2,2%0,8%
Edge0,6%0,7%
Opera0,3%0,2%

Tabelle: Browser und HTTP/3-Nutzung

Von Mathias Hein, Consultant, Autor, Journalist