Motywacja do zmian: ograniczenie transportowe
Przejście z HTTP/1.1 do HTTP/2 zwiększyło wydajność sieci. HTTP/2 wprowadził multipleksowanie, umożliwiając równoczesne wysyłanie wielu żądań i odpowiedzi przez jedno połączenie TCP, co ograniczyło blokowanie na czele kolejki na poziomie aplikacji. Wolne żądanie o duży obraz nie musiało już blokować pobierania pliku CSS. Pozostało jednak ograniczenie transportowe. Blokowanie na czele kolejki w warstwie transportowej jest związane z architekturą protokołu .
HTTP/2 przeplata ramki wielu strumieni, lecz TCP przekazuje je jako jeden uporządkowany strumień bajtów. Mechanizm odzyskiwania utraconych danych TCP nie rozróżnia więc strumienia HTTP, którego dane dotyczą.
TCP zapewnia niezawodne i uporządkowane dostarczanie danych. W ramach jednego połączenia traktuje je jako jeden uporządkowany strumień bajtów. Jeśli pakiet zostanie utracony, TCP wstrzyma dostarczanie kolejnych bajtów, także tych należących do innych, niezależnych strumieni HTTP/2, do czasu retransmisji i odebrania brakującego pakietu. Utrata pakietu z pobieranego obrazu może więc opóźnić renderowanie pliku JavaScript na tym samym połączeniu.
Blokowanie HOL na poziomie TCP jest szczególnie odczuwalne w niestabilnych lub opóźnionych sieciach, w tym komórkowych. Ograniczenie to wskazało potrzebę zmiany transportu używanego przez HTTP. Jedną z odpowiedzi na tę potrzebę stał się HTTP/3.
Transport QUIC nad UDP
HTTP/3 nie działa na protokole TCP. Wykorzystuje . QUIC jest nazwą protokołu. Rozwinięcie Quick UDP Internet Connections nie jest jego oficjalnym skrótem. QUIC włącza TLS 1.3 do ustanawiania połączenia, a HTTP/3 negocjuje identyfikator aplikacji h3 przez ALPN.
QUIC opiera się na protokole UDP. pozwala aplikacjom wysyłać datagramy bez ustanawiania połączenia i bez gwarancji dostarczenia lub kolejności. Datagramy mogą zostać utracone, zduplikowane albo dotrzeć w innej kolejności.
QUIC dodaje do UDP niezawodne strumienie, kontrolę przeciążenia i kontrolę przepływu. Te mechanizmy są rozdzielone dla poszczególnych strumieni, podczas gdy kontrola przeciążenia obejmuje całe połączenie. QUIC zapewnia też szyfrowanie pakietów oraz uwierzytelnienie punktów końcowych przez TLS.
Handshake QUIC ustala parametry transportu, w tym limity przepływu i liczbę obsługiwanych strumieni. HTTP/3 przekazuje własne ustawienia na strumieniu sterującym, a negocjacja h3 wskazuje protokół aplikacyjny.
Właściwość 1: brak blokowania HOL między strumieniami
QUIC usuwa blokowanie czoła kolejki pomiędzy niezależnymi strumieniami. Utrata pakietu zawierającego dane jednego strumienia nie zatrzymuje dostarczania danych z pozostałych strumieni. Brakujące bajty nadal wstrzymują jednak uporządkowane dostarczenie w obrębie tego samego strumienia.
W HTTP/2 nad TCP koncepcja strumieni istnieje tylko na poziomie aplikacji. Sam protokół TCP jest ich nieświadomy i widzi tylko pojedynczy, monolityczny strumień bajtów. W przeciwieństwie do tego, QUIC zarządza wieloma niezależnymi strumieniami logicznymi w ramach jednego połączenia. Ramki STREAM w pakietach QUIC zawierają identyfikator strumienia, do którego należą ich dane.
Jeśli pakiet zawierający dane dla strumienia 3 zostanie utracony, mechanizm niezawodności QUIC wstrzymuje dostarczanie danych tego strumienia do czasu ponownego przesłania brakujących danych. Strumienie 1 i 5, których pakiety zostały odebrane, mogą nadal trafiać do warstwy aplikacji. Rozdzielenie obsługi strumieni ogranicza wpływ utraty pakietów na pozostałe dane, szczególnie w sieciach mobilnych i o dużej stratności. QUIC przesyła utracone ramki w nowych pakietach, zachowując niezależność strumieni.
Właściwość 2: ustanawianie połączenia
HTTP/3 może skrócić ustanawianie połączenia, ponieważ QUIC łączy negocjację transportu z TLS 1.3. W HTTP/2 nad TCP ustanowienie bezpiecznego połączenia obejmuje dwa sekwencyjne uzgodnienia:
- Uzgadnianie TCP: Wymaga jednego pełnego obiegu (round-trip) między klientem a serwerem (SYN -> SYN-ACK -> ACK).
- Uzgadnianie TLS: Pełny handshake TLS 1.3 zwykle wymaga jednego dodatkowego obiegu. Starsze konfiguracje TLS 1.2 mogły wymagać dwóch.
W typowej konfiguracji TLS 1.3 pierwszy bajt danych aplikacji może zostać wysłany po około dwóch obiegach, a konfiguracje TLS 1.2 mogły wymagać trzech. W sieciach mobilnych opóźnienie początkowe zależy od czasu obiegu.
Uzgadnianie 1-RTT i 0-RTT w QUIC
QUIC łączy uzgadnianie transportowe i kryptograficzne w jedną procedurę. Nowe połączenie zwykle korzysta z uzgadniania 1-RTT, natomiast 0-RTT używa danych zapamiętanych przy wcześniejszym połączeniu i wymaga oceny ryzyka powtórzenia.
- Połączenie 1-RTT: Dla nowego połączenia klient wysyła komunikat
ClientHello, a serwer może odpowiedzieć komunikatem zawierającym swój certyfikat TLS i wszystkie niezbędne parametry do ustanowienia bezpiecznej sesji. Klient może to następnie zweryfikować i rozpocząć wysyłanie zaszyfrowanych danych. Cały proces zajmuje zazwyczaj jeden obieg (). - Wznowienie połączenia 0-RTT: klient znający serwer może wysłać wczesne dane aplikacji wraz z pierwszym komunikatem uzgadniającym. Dane 0-RTT nie mają ochrony przed powtórzeniem przez napastnika, dlatego serwer może je odrzucić, a klient powinien ograniczyć je do operacji bezpiecznych przy ponownym wykonaniu. Mechanizm skraca oczekiwanie na rozpoczęcie transmisji, ale nie usuwa opóźnienia sieci ani czasu przetwarzania żądania.
Dane 0-RTT mogą zostać zaakceptowane albo odrzucone przez serwer. Ponieważ mogą zostać powtórzone, aplikacja powinna ograniczać je do operacji, których wielokrotne wykonanie ma bezpieczny efekt, albo stosować ochronę przed powtórzeniem.
Właściwość 3: migracja połączenia
QUIC obsługuje zmiany adresu sieciowego za pomocą migracji połączenia. Tradycyjne połączenie TCP jest identyfikowane przez 4-krotkę: źródłowy adres IP, port źródłowy, docelowy adres IP i port docelowy. Zmiana jednej z tych wartości powoduje utratę identyfikacji dotychczasowego połączenia TCP.
Przy przejściu telefonu z Wi-Fi do sieci komórkowej zmienia się jego adres IP. Z perspektywy TCP oznacza to nową 4-krotkę, więc aplikacja musi zwykle ustanowić kolejne połączenie TCP i TLS oraz wznowić transmisję. Zmiana może spowodować buforowanie lub przerwę w odtwarzaniu.
QUIC używa zamiast polegać wyłącznie na adresach IP i portach. Po zmianie sieci klient może wysyłać pakiety z tym identyfikatorem z nowego adresu. Endpoint wykonuje walidację nowej ścieżki. Po jej pomyślnym zakończeniu połączenie może być kontynuowane. Identyfikatory mogą być zmieniane dla kolejnych ścieżek, aby ułatwić routing i ograniczyć śledzenie. Implementacja może wyłączyć aktywną migrację, natomiast nieudana walidacja wymaga powrotu do poprzedniej ścieżki.
Zmiana adresu może wynikać także z ponownego mapowania NAT. Endpoint musi zweryfikować nową ścieżkę, aby ograniczyć możliwość wysyłania danych do podstawionego adresu. Połączenie może wtedy używać jednej zweryfikowanej ścieżki naraz.
Warstwa Aplikacji w HTTP/3
HTTP/3 używa QUIC zamiast TCP, lecz zachowuje semantykę HTTP, w tym żądania i odpowiedzi, pola, metody (GET, POST, itp.) oraz kody statusu. Na poziomie HTTP/3 zdefiniowano Server Push. Podstawowy RFC 9114 nie definiuje sygnalizacji priorytetu. Rozszerzenie RFC 9218 określa pole Priority i ramkę PRIORITY_UPDATE dla HTTP/2 oraz HTTP/3. Część obsługi strumieni przejmuje QUIC.
Mapowanie HTTP na strumienie QUIC
Różnica dotyczy mapowania semantyki na transport. QUIC zapewnia abstrakcję strumienia, więc każda para żądanie-odpowiedź HTTP/3 jest mapowana na jeden dwukierunkowy strumień klienta. Odpowiedzi wypychane korzystają z jednokierunkowych strumieni serwera. W HTTP/2 podobną funkcję realizowała warstwa ramek nałożona na TCP.
QPACK: kompresja pól dla QUIC
Kompresja pól pozostaje istotną funkcją. HPACK z HTTP/2 korzystał z uporządkowanego dostarczania danych przez TCP, lecz strumienie QUIC mogą być dostarczane niezależnie. HTTP/3 używa QPACK, który korzysta z oddzielnych, jednokierunkowych strumieni do modyfikowania i śledzenia dynamicznych tabel pól. Ogranicza to blokowanie między strumieniami, lecz pojedynczy blok pól może czekać na brakujący wpis tabeli. Dekoder może przetworzyć blok od razu, gdy używa wyłącznie wpisów statycznych lub dostępnych wpisów dynamicznych.
Wdrożenie HTTP/3
HTTP/3 jest opublikowanym standardem z 2022 roku. Jest obsługiwany przez główne przeglądarki, serwery i sieci dostarczania treści, ale administrator nadal musi skonfigurować QUIC oraz ruch UDP do portu usługi.
QUIC może być blokowany przez zapory lub urządzenia pośredniczące, które nie dopuszczają ruchu UDP do portu . Klient wykrywa obsługę HTTP/3 między innymi na podstawie informacji Alt-Svc, rekordów HTTPS DNS, zapamiętanych danych o serwerze i własnej konfiguracji. Pierwsza wizyta nie zawsze zaczyna się więc próbą HTTP/3. Jeżeli QUIC jest niedostępny, klient może użyć HTTP/2 lub HTTP/1.1 przez TCP, zależnie od obsługi po obu stronach.
Pole Alt-Svc może wskazać nazwę hosta i port UDP usługi HTTP/3. Klient może sprawdzić tę usługę i zachować informację dla kolejnych żądań. Nieudane połączenie QUIC nie powinno uniemożliwiać użycia wersji HTTP działającej przez TCP.