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.

B9b7a5ffa24e2af6f877a7950461ba0f?s=128

Oleksii Kachaiev

April 27, 2021
Tweet

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. H TP:// T e de

  4. $ 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 !
  5. 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
  6. H TP/1.0 → 1.1 • Mandatory "Host" header • "100

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

    "Connection: keep-alive" • Pipelining • Didn't work out
  8. $ 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
  9. W :// T e de

  10. 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)
  11. 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
  12. 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 <
  13. W bS ck t: P ot • Where things started

    getting dicey • Multiple levels of handshakes to get TCP-like functionality
  14. 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)))
  15. 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
  16. W bS ck t s S ss on ay r

    ro oc l (c) p rs na s ic t ke
  17. T S, A PN

  18. 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
  19. 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
  20. H2:// T e de

  21. 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
  22. 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"
  23. 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
  24. P ov ng ot in i I po si le

  25. H TP/2 i r re y u il ze d

    re tl (c) p rs na s ic t ke
  26. H3:// T e de

  27. H TP/3 = H TP/2 o er UI *

  28. 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)
  29. 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
  30. 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
  31. Q IC: S re ms • Bi- or uni- directional

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

    HTTP/2" • QPACK instead of HPACK • Upgrade: Alt-Svc
  33. 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
  34. P ov ng ot in i I po si le

  35. P ov ng ot in i I po si le

  36. 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
  37. 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
  38. 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!
  39. Q IC: I PL. • connect, accept • send, recv

    • send_stream, recv_stream • though devil in details
  40. 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
  41. 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
  42. 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
  43. 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
  44. C nn ct it m : • Twitter, @kachayev •

    Github, @kachayev q&a le se