Něco málo o http/3

27. srpna 2021

Nová verze http protokolu http/3 je v dnešní době podporována většinou prohlížečů. Tak pojďme zlehka nakouknout pod pokličku. 

Za protokol http/3 vděčíme vývojářům Google a jejich implementaci protokolu QUIC.  https://en.wikipedia.org/wiki/QUIC

Než se pustím do toho, proč je to tak úžasné a rychlé, pojďme se podívat jak funguje TLS 1.2 a TLS 1.3.

Obrázek jsem trochu zjednodušil, ale snad jsem v něm nevynechal nic zásadního. 

Pokud chcete se serverem navázat šifrované spojení pomocí TLS 1.2, musí se provést řada úkonů. Klient pošle ClientHello a server odpoví ServerHello při kterém si spolu domluví jak verzi TLS tak i použité šifry. Tahle operace nás stála 2x RTT (round-trip time), což je přibližně hodnota kterou vrací příkaz ping. V dalším kroku následuje výměna klíčů (velmi zjednodušeně řešeno) a sestavení šifrovaného kanálu. Pak už dál fungují normální http požadavky. Takže celkem 6x RTT než se začnou ze serveru přenášet data (například požadovaný web). 

TLS 1.3 to řeší poněkud elegantněji. V prvním kroku pošle ClientHello a rovnou s ním seznam podporovaných šifer a klíč. Server Vrátí ServerHello a klíč a zprávu o navázaném šifrovaném spojení. Takže data dostáváme o něco rychleji. No a v neposlední řadě tam funguje opětovně navázané spojení, kdy se využívá PSK (Pre-shared key) takže šifrované spojení je navázáno s nulovým RTT (Zero Round Trip Time, 0-RTT, early data).

No a jak to řeší QUIC?  QUIC používá autentizované šifrování s připojenými daty (authenticated encryption with associated data – AEAD). Takže spojení je šifrované už v okamžiku, kdy je navázáno spojení se serverem. Jinými slovy klient pošle http požadavek a v něm je rovnou i celé navázání spojení po TLS 1.3 a od serveru dostane odpověď po zašifrovaném kanálu. 

A tady se dostáváme k tomu nejdůležitějšímu – je tam 0-RTT už při navazování spojení se serverem. 

Takže můžeme se pomalu podívat o kousek dál. Proč http/3 používá UDP? Ta odpověď je v zásadě velmi jednoduchá. http/2 přineslo řadu zrychlení díky multiplexingu (v rámci jednoho spojení je přenášeno současně víc požadavků a odpovědí), komprimaci hlaviček, server push (server může poslat klientovi např. css nebo js soubory dřív, než si o ně klient požádá) ale nedokáže eliminovat problém blokování čela fronty (Head-of-line blocking). V praxi to znamená, že pokud se ztratí jeden paket v navázaném http/2 streamu, pak TCP nechá celý stream čekat, než dojde k opětovnému zaslání ztraceného paketu. No a přesně tohle dokáže UDP obejít. 

Dalším drobným problémem u TCP je něco co se jmenuje TCP congestion control (omlouvám se, nevím jak se to přesně překládá do češtiny), což je protokol zabraňující přetížení sítě. Ve zkratce funguje tak, že se začne na minimu a postupně se exponenciálně zvedá rychlost. Když dojde ke ztrátě paketu, zpomalí se, … no a algoritmů je celkem hodně – viz https://en.wikipedia.org/wiki/TCP_congestion_control

Protože UDP je už z principu ztrátový protokol, tuhle část za něj musí řešit QUIC. Díky tomu, že QUIC beží v user space (to je část paměti vyhrazená pro běh uživatelských programů), není potřeba při úpravách algoritmů čekat, než se stanou součástí jádra operačních systémů (na rozdíl od TCP). Aktuálně QUIC využívá NewReno – https://www.rfc-editor.org/rfc/rfc9002.html

Jinými slovy, pokud od http/3 někdo očekával raketový start při načítání obsahu, není tomu tak. Stále se začíná na nejnižší možné rychlosti a postupně se zrychluje. Jediné co pomocí UDP dokáže obejít je již zmiňovaný problém blokování čela fronty a to i na síťových prvcích na cestě mezi serverem a klientem.

No a jak je to s použitelností http/3 v prohlížečích? Na to nám opět odpoví https://caniuse.com/http3

Pokud si chcete http/3 vyzkoušet, tak doporučuji svůj předchozí článek: https://www.interval.cz/clanky/openlitespeed-webserver-jako-http-3-proxy/

 

Zdroje:

https://http3-explained.haxx.se/

https://datatracker.ietf.org/doc/html/rfc9000

Štítky: HTTP

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *