Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Counting HTTP with QUIC & HTTP/3

Counting HTTP with QUIC & HTTP/3

Presenting 30 years of Internet through the lens of HTTP protocol versions
diff. HTTP/3 brings the most significant changes we've seen so far, so
let's review them alongside with reasoning and implications analysis.

Oleksii Kachaiev

April 27, 2021
Tweet

More Decks by Oleksii Kachaiev

Other Decks in Programming

Transcript

  1. C un in H TP 0.9 ... 3 O ek

    ii ac ai v, @k ch ye
  2. Year Protocol 1991 HTTP/0.9 1996 HTTP/1.0 1997 HTTP/1.1 Feb, 2010

    - Dec, 2011 WebSocket Jul, 2012 - Feb, 2015 SPDY Jun, 2014 revisioned HTTP/1.1 Aug, 2014 - May, 2015 HTTP/2.0 Jun, 2017 - nowadays HTTP/3.0
  3. $ telnet 127.0.0.1 8080 Trying 127.0.0.1... Connected to localhost. Escape

    character is '^]'. GET / HTTP/0.9 HTTP/0.9 200 OK Date: Sun, 08 Jul 2018 20:56:34 GMT content-length: 18 hello, world !
  4. H TP/0.9 → 1.0 • New methods • Content negotiation

    • Optional "Host" header • "Connection: keep-alive" • TCP handshake is slow • Even 20+ years ago it was a problem
  5. H TP/1.0 → 1.1 • Mandatory "Host" header • "100

    Continue" • Chunked & byte-range transfers • Compression • "Upgrade" header (TLS, websockets)
  6. H TP/1.1: R du e at nc • Defaults to

    "Connection: keep-alive" • Pipelining • Didn't work out
  7. $ curl -v http://localhost:8080 * Rebuilt URL to: http://localhost:8080/ *

    Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/plain < Server: Aleph/0.4.7 < Connection: Keep-Alive < Date: Sun, 08 Jul 2018 20:46:32 GMT < content-length: 18 < hello, world ! * Connection #0 to host localhost left intact
  8. W bS ck t • Full-duplex communication • RFC 6455

    "The WebSocket Protocol" • Handshaking using HTTP Upgrade header (compatibility) • Framing (text, binary, ping/pong, close, continuation)
  9. W bS ck t pg ad $ curl -v -H

    "Upgrade: websocket" \ -H "Connection: upgrade" \ -H "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==" \ -H "Sec-WebSocket-Protocol: chat" \ -H "Sec-WebSocket-Version: 13" \ http://echo.websocket.org * Rebuilt URL to: http://echo.websocket.org/ * Trying 174.129.224.73... * TCP_NODELAY set * Connected to echo.websocket.org (174.129.224.73) port 80 (#0) > GET / HTTP/1.1 > Host: echo.websocket.org > Upgrade: websocket > Connection: upgrade > Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== > Sec-WebSocket-Protocol: chat > Sec-WebSocket-Version: 13
  10. W bS ck t pg ad < < HTTP/1.1 101

    Web Socket Protocol Handshake < Connection: Upgrade < Date: Tue, 10 Jul 2018 09:11:33 GMT < Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= < Server: Kaazing Gateway < Upgrade: websocket <
  11. W bS ck t: P ot • Where things started

    getting dicey • Multiple levels of handshakes to get TCP-like functionality
  12. W bS ck t: I PL. • Fully supported in

    Netty & Aleph • After upgrade, you get a Manifold stream • Deep HTTP Dive Through Aleph & Netty (require '[manifold.stream :as s]) (defn echo-handler [req] (let [s @(http/websocket-connection req)] (s/connect s s)))
  13. W bS ck t: I PL. • Some of the

    hardest issues were about WS • Less common means less tested • HTTP/1.1 in Aleph has a "connectionless" API • This brings a few corner cases even for HTTP/1.1 • For WS the abstraction leaks heavily • Ring 2.0 spec in DRAFT
  14. W bS ck t s S ss on ay r

    ro oc l (c) p rs na s ic t ke
  15. A PN • Application-Layer Protocol Negotiation Extention, RFC 7301 •

    allows the application layer to negotiate which protocol should be performed • replaced NPN (Next Protocol Negotiation Extension) • emerged from SPDY development
  16. A PN $ curl -v https://github.com/ * Trying 192.30.253.112... *

    TCP_NODELAY set * Connected to github.com (192.30.253.112) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * TLSv1.2 (OUT), TLS handshake, Client hello (1): .... * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 * ALPN, server accepted to use http/1.1 * Server certificate: .... * SSL certificate verify ok. > GET / HTTP/1.1 > Host: github.com > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 200 OK
  17. H TP/2: W Y? • TCP handshake is still slow

    • Head-of-line blocking • Server to initiate the communication • TCP congestion control with tons of connections
  18. H TP/2: H W? • Binary, compression of HTTP headers

    (HPACK) • Framed transport (similar to WS) • Multiplexing over a single TCP connection • HTTP/2 Server Push • Settings management flow, priorities • ALPN, "Upgrade"
  19. H TP/2: I PL. • Fully supported in Netty, not

    support in Aleph • Again, most features are not part of Ring spec • Some of the hardest issues I worked with were about WS • ^ because we don't support HTTP/2 • To my best knowledge, heavy usage of HTTP/2: • HTTTP/2 → HTTP/1.1 proxies, including LBs • gRPC
  20. H TP/2 i r re y u il ze d

    re tl (c) p rs na s ic t ke
  21. W n T P? • Head of line blocking (still

    ! ) • Streams are not independent • 3 different handshakes: TCP, TLS, HTTP • Better with TLS1.3, but still • TCP relies on IP address • TCP is "hardcoded" into infrastructure (links, routers, kernel)
  22. Q IC: H W? • Merge multiple layers • UDP-based

    transport • Handshakes: 0-RTT, 1-RTT, early data • TLS1.3 encryption • ConnectionID instead of IP • Streams
  23. Q IC: U P??? • User-space reliability: • re-transmissions, congestion,

    pacing • faster improvements/experiments • error prone? • Supported everywhere (heh DNS) • Kernel implementations are highly optimized
  24. Q IC: S re ms • Bi- or uni- directional

    • Initiated by any party • Independent not only logically!
  25. H TP/3: I tr • Application level protocol • "Almost

    HTTP/2" • QPACK instead of HPACK • Upgrade: Alt-Svc
  26. P t UI i t e on ex • QUIC

    is not only HTTP • MQTT over QUIC • DNS over QUIC • And more • Not the first UDP-based attempt
  27. P ov ng ot in i I po si le

    • What do we get in comparison after 1.5 year? • less dark theme • Vim instead of Emacs
  28. F om xp ri en al o ra ti al

    • kachayev/quiche4j - QUIC & HTTP/3 in Java • utilizes cloudflare/quiche (Rust) • JNI layer using rust-jni (also in Rust) • Java API on top • Pluggable I/O scheduling • version with Netty Event Loop as an example
  29. F om xp ri en al o ra ti al

    • netty/netty-incubator-codec-quic • netty/netty-incubator-codec-http3 • Also built on top of cloudflare/quiche • Contributions are always very welcome!
  30. Q IC: I PL. • connect, accept • send, recv

    • send_stream, recv_stream • though devil in details
  31. Q IC: I PL. • Cryptography-first • BoringSSL provides API

    • OpenSSL does not (manually) • Framing is straightforward • Loss detection and congestion control are hard • cloudflare/quiche implements Reno & CUBIC • Connection migration between IPs is problematic
  32. H TP/3: I PL. • QPACK is similar to HPACK

    • Dynamic table is non-trivial • remember, no ordering guarantees • // TODO: implement dynamic table in quiche • QPACK to support dynamic table in Netty
  33. Q IC & H TP/3: U e as s •

    You need more than request-reply (e.g. streaming) • You have high throughput requirements • TCP is too expensive for you • Too many things happens within the same connection
  34. I y u on't no w y ou d ou

    ee i y u ro ab y on't (c) p rs na s ic t ke
  35. C nn ct it m : • Twitter, @kachayev •

    Github, @kachayev q&a le se