De peste 20 de ani, vizionăm pagini web prin intermediul protocolului HTTP. Majoritatea utilizatorilor nu se gândesc deloc la ce înseamnă și cum funcționează. Alții știu că undeva sub HTTP se află TLS, iar sub acesta TCP, sub care se află IP și așa mai departe. Iar alții – eretici – consideră că TCP este ceva din trecut, dorind ceva mai rapid, mai fiabil și mai sigur. Dar în încercările lor de a inventa un protocol ideal nou, s-au întors la tehnologiile anilor '80 și încearcă să construiască pe acestea lumea lor nouă minunată.

Puțină istorie: HTTP/1.1
În 1997, protocolul de schimb de informații textuale HTTP versiunea 1.1 a obținut propriul său RFC. Pe atunci, protocolul era deja utilizat de browsere de câțiva ani, iar noul standard a rezistat încă cincisprezece. Protocolul funcționa doar pe principiul cerere-răspuns și era destinat în principal pentru transferul de informații textuale.
HTTP a fost proiectat să funcționeze deasupra protocolului TCP, care garantează livrarea fiabilă a pachetelor către destinatar. Funcționarea TCP se bazează pe stabilirea și menținerea unei conexiuni fiabile între punctele finale și pe fragmentarea traficului în segmente. Segmentele au un număr de ordine și un cod de sumare de control. Dacă, dintr-o dată, unul dintre segmente nu ajunge sau ajunge cu o sumă de control greșită, transferul se va opri până când segmentul pierdut este recuperat.
În HTTP/1.0, conexiunea TCP era închisă după fiecare cerere. Acest lucru era extrem de risipitor, deoarece stabilirea unei conexiuni TCP (3-Way-Handshake) nu este un proces rapid. În HTTP/1.1 a fost introdus mecanismul keep-alive, care permite reutilizarea unei conexiuni pentru mai multe cereri. Totuși, deoarece aceasta poate deveni ușor un punct de bottleneck, în diferitele implementări HTTP/1.1 este permisă deschiderea mai multor conexiuni TCP către același gazdă. De exemplu, în Chrome și în versiunile recente de Firefox sunt permise până la șase conexiuni.

Criptarea era de asemenea preconizată să fie lăsată în seama altor protocoale, iar pentru aceasta, deasupra TCP a fost utilizat protocolul TLS, care proteja datele destul de fiabil, dar care adăuga și mai mult timp necesar pentru stabilirea conexiunii. În cele din urmă, procesul de handshake a ajuns să arate astfel:

Ilustrarea Cloudflare
Astfel, HTTP/1.1 avea o serie de probleme:
- Instalare lentă a conexiunii.
- Datele sunt transmise în format text, ceea ce face ca transferul de imagini, videoclipuri și alte informații non-text să fie ineficient.
- O conexiune TCP este utilizată pentru o singură cerere, ceea ce înseamnă că celelalte cereri trebuie fie să își găsească o altă conexiune, fie să aștepte până când cererea curentă o eliberează.
- Este suportat doar modelul pull. Standardul nu conține nimic despre server-push.
- Anteturile sunt transmise în text.
Dacă server-push este implementat cu ajutorul protocolului WebSocket, atunci restul problemelor trebuie abordate mai radical.
Puțină modernitate: HTTP/2
În 2012, în cadrul Google a început lucrul la protocolul SPDY (se pronunță „spidi”). Protocolul a fost creat pentru a rezolva problemele principale ale HTTP/1.1 și, în același timp, trebuia să păstreze compatibilitatea înapoi. În 2015, grupul de lucru IETF a prezentat specificația HTTP/2, bazată pe protocolul SPDY. Iată care au fost diferențele în HTTP/2:
- Serializare binară.
- Multiplexarea mai multor cereri HTTP într-o singură conexiune TCP.
- Server-push din cutie (fără WebSocket).
Protocolul a fost un pas mare înainte. El câștigă semnificativ față de prima versiune în viteză Cu toate acestea, multiplexarea duce la o altă problemă crucială. Imaginați-vă că executăm în mod asincron 5 cereri către un singur server. Utilizând HTTP/2, toate aceste cereri vor fi executate în cadrul unei singure conexiuni TCP, ceea ce înseamnă că, dacă unul dintre segmentele oricărei cereri se pierde sau ajunge greșit, transferul tuturor cererilor și răspunsurilor se va opri până când segmentul pierdut este recuperat. Este evident că, cu cât calitatea conexiunii este mai proastă, cu atât HTTP/2 funcționează mai lent.
Conform evaluării lui Daniel Steinberg Această problemă se numește „head-of-line blocking” și, din păcate, rezolvarea ei utilizând TCP pare imposibilă.
Ilustrație Daniel Steinberg

Ilustrație Daniel Steinberg
În concluzie, dezvoltatorii standardului HTTP/2 au depus eforturi enorme și au realizat practic tot ce se putea face la nivelul aplicațiilor modelului OSI. A venit momentul să coborâm la nivelul de transport și să inventăm un nou protocol de transport.
Avem nevoie de un nou protocol: UDP vs TCP
Destul de repede s-a înțeles că implementarea unui protocol complet nou la nivel de transport este o sarcină imposibilă în realitatea de astăzi. Motivul este că dispozitivele hardware sau middle-box-urile (routere, firewalls, servere NAT…) cunosc doar nivelul de transport, iar a-i învăța ceva nou este o sarcină extrem de complicată. În plus, suportul pentru protocoalele de transport este încorporat în nucleele sistemelor de operare, iar nucleele nu se schimbă foarte ușor.
Și aici s-ar putea să ne pierdem speranța și să spunem „Cu siguranță, vom inventa noul HTTP/3 cu preferințe și curtezane, dar implementarea lui va dura 10-15 ani (aproximativ în acea perioadă majoritatea dispozitivelor vor fi înlocuite)”, dar există o altă variantă, nu atât de evidentă: utilizarea protocolului UDP. Da, exact acel protocol cu care ne-am aruncat fișierele prin rețea la sfârșitul anilor ’90 și începutul anilor 2000. Practic toate dispozitivele de astăzi pot lucra cu el.
Care sunt avantajele UDP în comparație cu TCP? În primul rând, nu avem o sesiune la nivel de transport, despre care știe hardware-ul. Acest lucru ne permite să definim singuri sesiunea la punctele finale și să gestionăm acolo conflictele care apar. Adică nu suntem limitați la una sau mai multe sesiuni (ca în cazul TCP), ci putem crea atât de multe câte avem nevoie. În al doilea rând, transferul de date prin UDP se face mai repede decât prin TCP. Astfel, teoretic, putem depăși limita actuală de viteză atinsă în HTTP/2.
Cu toate acestea, UDP nu garantează fiabilitatea transferului de date. De fapt, trimitem pur și simplu pachete, sperând că de cealaltă parte le vor primi. Nu le-au primit? Ei bine, nu a fost noroc... Acest lucru a fost suficient pentru a transmite video pentru adulți, dar pentru lucruri mai serioase este nevoie de fiabilitate, ceea ce înseamnă că va trebui să adăugăm ceva deasupra UDP-ului.
Așa cum s-a întâmplat și în cazul HTTP/2, lucrările pentru crearea unui nou protocol au început la Google în 2012, adică aproximativ în aceeași perioadă cu începutul lucrului la SPDY. În 2013, Jim Roskind a prezentat publicului larg , și deja în 2015 a fost inclus un Internet Draft pentru standardizare în IETF. Deja la acel moment, protocolul dezvoltat de Roskind la Google se deosebea semnificativ de standardul propus, așa că versiunea Google a început să fie numită gQUIC.
Ce este QUIC
În primul rând, așa cum s-a menționat, este un wrapper peste UDP. Peste UDP se construiește o conexiune QUIC, unde, similar cu HTTP/2, pot exista mai multe fluxuri. Aceste fluxuri există doar la punctele finale și sunt gestionate independent. Dacă un pachet se pierde într-un flux, celelalte nu sunt afectate.

Ilustrație Daniel Steinberg
În al doilea rând, criptarea este acum implementată nu ca un nivel separat, ci este integrată în protocol. Acest lucru permite stabilirea conexiunii și schimbul de chei publice într-o singură strângere de mână, precum și utilizarea unui mecanism ingenios de 0-RTT handshake, evitând astfel întârzierile la strângerea de mână. În plus, acum este posibil să se cripteze pachete de date separate. Acest lucru permite decriptarea pachetelor primite independent, fără a aștepta finalizarea primirii datelor din flux. Acest mod de operare era în general imposibil în TCP, deoarece TLS și TCP funcționau independent unul de celălalt, și TLS nu putea ști pe ce bucăți va tăia datele TCP. Prin urmare, nu putea pregăti segmentele sale astfel încât acestea să se aliniază segmentelor TCP unul câte unul și să poată fi decriptate independent. Toate aceste îmbunătățiri permit QUIC să reducă latența comparativ cu TCP.

În al treilea rând, conceptul de fluxuri ușoare permite debarasarea conexiunii de adresa IP a clientului. Acest lucru este important, de exemplu, atunci când clientul comută de la un acces Wi-Fi la altul, schimbându-și astfel IP-ul. În acest caz, utilizând TCP, are loc un proces lung, în care conexiunile TCP existente cad din cauza timeout-ului și se creează noi conexiuni cu noul IP. În cazul QUIC, clientul continuă pur și simplu să trimită pachete serverului de pe noul IP cu vechiul ID al fluxului. Deoarece ID-ul fluxului este acum unic și nu este reutilizat, serverul înțelege că clientul a schimbat IP-ul, retransmite pachetele pierdute și continuă comunicația pe noua adresă.
În al patrulea rând, QUIC este implementat la nivelul aplicației, nu al sistemului de operare. Acest lucru, pe de o parte, permite modificări mai rapide ale protocolului, deoarece pentru a obține o actualizare este suficient să actualizezi biblioteca, fără a aștepta o nouă versiune a sistemului de operare. Pe de altă parte, aceasta duce la o creștere semnificativă a consumului de procesor.
Și la final, să discutăm despre antete. Compresia antetelor se numără printre aspectele care diferă în QUIC și gQUIC. Nu văd sens în a dedica prea mult timp acestui subiect, voi menționa doar că în versiunea supusă standardizării, compresia antetelor a fost făcută cât mai asemănătoare cu compresia antetelor din HTTP/2. Mai multe detalii pot fi citite .
Cât de rapid este?
Aceasta este o întrebare complexă. Problema este că, deocamdată, nu avem un standard, așa că nu prea avem ce măsura. Probabil, singurele date statistice de care dispunem sunt cele de la Google, care folosește gQUIC din 2013 și în 2016 , că aproximativ 90% din traficul către serverele lor din browserul Chrome utilizează acum QUIC. În aceeași prezentare, ei anunță că prin gQUIC paginile se încarcă cu aproximativ 5% mai rapid, iar la redarea video sunt cu 30% mai puține blocaje comparativ cu TCP.
În 2017, un grup de cercetători condus de Arash Molavi Kakhki a publicat o cercetare asupra performanței gQUIC comparativ cu TCP.
Studiul a identificat câteva slăbiciuni ale gQUIC, cum ar fi instabilitatea la amestecarea pachetelor de rețea, egoismul în utilizarea lățimii de bandă și o transmitere mai lentă a obiectelor mici (de până la 10 kB). Acest din urmă aspect, însă, se compensează prin utilizarea 0-RTT. În toate celelalte cazuri studiate, gQUIC a demonstrat o creștere a vitezei comparativ cu TCP. Despre cifre concrete este dificil de vorbit. Cel mai bine este să citiți sau .
Aici trebuie menționat că aceste date se referă strict la gQUIC și nu sunt actuale pentru standardul în dezvoltare. Ce va fi pentru QUIC: deocamdată este un mister, dar există speranța că slăbiciunile identificate la gQUIC vor fi luate în considerare și corectate.
Puțin despre viitor: ce se întâmplă cu HTTP/3?
Și aici este totul clar: API-ul nu se va schimba. Totul va rămâne exact la fel ca în HTTP/2. Dacă API-ul rămâne același, trecerea la HTTP/3 va necesita utilizarea unei versiuni noi a bibliotecii pe backend, care suportă transportul prin QUIC. Totuși, va trebui să menținem un fallback pentru versiunile vechi de HTTP, deoarece internetul nu este pregătit pentru o tranziție completă la UDP.
Cine deja suportă
Iată implementărilor existente QUIC. Deși nu există un standard, lista nu este rea.
Niciun browser nu suportă în prezent QUIC în versiunea de producție. Recent, a existat informația că Chrome a activat suportul pentru HTTP/3, dar deocamdată doar în Canary.
Dintre backend-uri, HTTP/3 este suportat doar de și , dar deocamdată experimental. NGINX, la sfârșitul primăverii 2019, , a anunțat că lucrează la suportul pentru HTTP/3, dar deocamdată nu a finalizat.
Ce probleme există
Trăim într-o lume reală, în care nicio tehnologie mare nu poate ajunge la masă fără a întâlni rezistență, iar QUIC nu este o excepție.
Cel mai important, trebuie cumva să explicăm browserului că "https://" acum nu mai înseamnă neapărat că duce la portul TCP 443. S-ar putea să nu existe deloc TCP. Pentru aceasta se folosește antetul Alt-Svc. Acesta permite browserului să comunice că acest site web este de asemenea disponibil pe un alt protocol la o anumită adresă. În teorie, aceasta ar trebui să funcționeze perfect, dar în practică vom întâlni probleme, cum ar fi faptul că UDP ar putea fi, de exemplu, interzis pe firewall pentru a evita atacurile DDoS.
Dar chiar dacă UDP nu este interzis, clientul ar putea fi în spatele unui router NAT, care este configurat să mențină sesiunea TCP pe adresa IP, iar cum noi folosim UDP, care nu are sesiuni hardware, NAT nu va menține conexiunea, iar sesiunea QUIC .
Toate aceste probleme sunt legate de faptul că UDP nu a fost folosit anterior pentru transmiterea conținutului internetului, iar producătorii de echipamente nu au putut prevedea că așa ceva se va întâmpla vreodată. La fel, administratorii nu înțeleg încă foarte bine cum să își configureze rețelele pentru a funcționa cu QUIC. Această situație se va schimba treptat, și, în orice caz, astfel de schimbări vor dura mai puțin timp decât implementarea unui nou protocol de transport.
În plus, așa cum a fost deja descris, QUIC crește semnificativ utilizarea procesorului. Daniel Stenberg creșterea procesorului până la de trei ori.
Când va fi HTTP/3
Standard În mai 2020, având în vedere că, în prezent, documentele planificate pentru iulie 2019 rămân incomplete, se poate spune că data va fi, cel mai probabil, amânată.
Începând din 2013, Google folosește propria implementare gQUIC. Dacă ne uităm la cererea HTTP trimisă motorului de căutare Google, putem observa asta:

Conclusions
QUIC pare în prezent o tehnologie destul de neterminată, dar foarte promițătoare. Având în vedere că în ultimii 20 de ani toate optimizările protocoalelor de transport s-au concentrat în principal pe TCP, QUIC, câștigând în majoritatea cazurilor în performanță, arată deja foarte bine.
Cu toate acestea, încă există probleme nerezolvate cu care va trebui să facem față în următorii câțiva ani. Procesul poate dura mai mult din cauza hardware-ului, pe care nimeni nu îl iubește să-l actualizeze, dar toate problemele par a fi soluționabile, iar mai devreme sau mai târziu vom avea cu toții HTTP/3.
Viitorul nu este departe!
Sursa: habr.com
