class: center, middle # HTTP/2 and QUIC (HTTP/3) __CS291A__ Dr. Bryce Boe November 21, 2019 --- # Today's Agenda * HTTP Optimization Hacks * HTTP/2 * QUIC * HTTP/3 r--- class: center, middle, inverse # HTTP Optimization Hacks --- # Review: Connections per Page .center[  ] Many requests are required for today's web pages: * CSS * JavaScript * Images Source: http://httparchive.org --- # Review: TCP Phases .center[  ] Establishing many TCP connections to serve these resources is very slow. Source: High Performance Browser Networking --- # Review: TCP Round Trips .center[  ] TCP was designed for long-lived flows. HTTP is short and bursty. --- # Review: HTTP Keep-alive & Head-of-Line Blocking .left-column[  ] .right-column[ HTTP Keep-alive was introduced to help reuse TCP connections for HTTP, but there are issues. While we can reuse a TCP socket for multiple HTTP requests, one heavyweight request can starve all others. This is called __Head-of-line blocking__. ] --- # Review: HTTP Request Header .center[  ] --- # HTTP Request Header Repetition .center[  ] The highlighted sections show the differences from this request with the previous request. All other bytes are duplicates. --- # HTTP Request Header Repetition .center[  ] In this case the only thing that changed from the previous request were 14 new bytes out of 683. > How do we minimize this header overhead with HTTP/1.1? --- # Review: Asset Concatenation To minimize header overhead in HTTP/1.1 we concatenate files together (e.g., JavaScript, and CSS). In Rails, that is one of the purposes of the asset pipeline. This technique can also be applied to images. --- # Review: Image Spriting .center[  ] A sprite is an image that is comprised of many smaller images. CSS is used to extract the individual image based on its position and size in the sprite. Spriting is cumbersome to work with, and is a hack used to reduce page load times. --- # Review: Concurrent TCP Connections The browser will utilize up to 6 concurrent TCP connections to a single host in order to reduce the time to obtain a page's resources. For better performance domain sharding is utilized with HTTP/1.1. .center[  ] --- # Performance Goals We want fewer TCP connections, but * we don't want head-of-line blocking * we don't want to have to concatenate our CSS and JavaScript * we don't want to have to use image sprites * we don't want to have to split our resources across domains to trick the browser > What do we do? --- class: center middle inverse # HTTP/2 addresses all of these issues --- # HTTP/2 History * Google internally announced the SPDY protocol (Nov 2009). * Google released SPDY in Chrome for (Sept 2010). * Google deployed SPDY on all their servers (Jan 2011). * Twitter deployed SPDY on its servers (March 2012). * Apache added support for SPDY (April 2012) * NGINX added support for SPDY (June 2012) * Firefox added support for SPDY (June 2012) * First draft of HTTP/2.0 based on SPDY (Nov 2012) * RFC 7540: HTTP/2.0 published (May 2015) --- # HTTP/2 Features * Multiplexing application streams permits concurrent streams over a single TCP connection with the ability to prioritize streams. * Header compression minimizes request and response overhead. * Server push provides a way for the server to send responses prior to receiving a request for the associated resource. --- # HTTP/2 Binary Frames .center[  ] Note that the headers and data are in separate frames. --- # HTTP/2 Binary Framed Connection .center[  ] Note that different streams are interleaved over a single TCP connection (multiplexing). --- # Header Compression With binary framing, header compression becomes easy. Initially implemented using GZIP, but [CRIME attack](https://en.wikipedia.org/wiki/CRIME) revealed weaknesses. * If an attacker can inject data, compressed size can leak information. Now implemented using HPACK. --- # HPACK .center[  ] 1. HPACK allows the transmitted header fields to be encoded via a static Huffman code, which reduces their individual transfer size. 2. HPACK requires that both the client and server maintain and update an indexed list of previously seen header fields (i.e. establishes a shared compression context), which is then used as a reference to efficiently encode previously transmitted values. Source: High Performance Browser Networking --- # Binary Framing Benefits .left-column[  ] .right-column[ With binary framing the ordering of resources is flexible. * Handling of many small resources is efficient. * Headers are compressed, so they are lightweight. * _Resource-based_ head of line blocking no longer exists. ] --- # HTTP/2 Prioritization and Flow Control With resource ordering no longer an issue, we can implement resource prioritization. ## Request Priority Example 1. Requests that interact with the DOM 2. CSS 3. JavaScript 4. Images ## Flow Control A `WINDOW_UPDATE` flag exists to control the number of frames _in flight_. --- # HTTP/2 Saves the Day HTTP/2 obviates the HTTP/1.1 hacks used over the last twenty+ years. * Spriting and asset compilation are no longer needed since we can effectively handle many small resources without worrying about _resource-based_ head of line blocking. * Domain sharding is irrelevant since all content is delivered over a single connection. --- # HTTP/2 New Feature: Server Push .center[  ] When a resource is requested (e.g., `/`) the server can proactively send additional resources using `PUSH_PROMISE` (e.g., favicon.ico, style.css). The client can indicate that it does not want the additional content. This feature is useful if the client already has a cached copy. --- # HTTP/2 Results .center[  ] --- # HTTP/2 Low Latency Results .center[  ] --- # HTTP/2 High Latency Results .center[  ] --- class: center inverse middle # QUIC --- # QUIC HTTP/2 improves HTTP while still using TCP as the underlying protocol. __QUIC__ is is built on top of UDP in order to avoid TCP limitations, primarily the round trip necessary to establish connections.  --- # Review: TCP Connection Establishment .center[  ] TCP connections require a full round trip before any application data can be sent. --- # Review: TCP+TLS Establishment .center[  ] HTTPS (TCP+TLS) requires three full round trips (two with optimizations) before any application data can be sent. --- # HTTP/2 (SPDY) and Dropped Packets .center[  ] HTTP/2 provides excellent multiplexing support. However, any dropped packet blocks the entire connection. TCP cannot differentiate between packets dropped by different streams. --- # TCP Retransmissions .center[  ] Losing packets results in retransmissions. In high latency networks this process is painfully slow. --- # Physically Mobile Users .left-column[  ] .right-column[ A TCP connection is defined by its source IP address/port combination. If a connected user's device moves from their house's wifi to their cellular network or to another network's wifi, they will obtain a new IP address. This move requires the user to establish a new connection and once again incur any start-up costs. ] --- class: center inverse middle # Given the limitations of TCP, can we build a better HTTP/2 on top of UDP instead? --- # QUIC QUIC is an attempt to use UDP for HTTP. QUIC's primary goal is to reduce latency. In fact, you are already using QUIC if you use Google Chrome and access Google services. Inspect via: `chrome://net-internals/` --- # QUIC Initial Connection * Client sends random 64-bit CID (connection ID) * Server replies with certificate and cookie * Client responds with: * CID * cookie * proposed encrypted session key * encryption algorithm * Client can immediately send requests --- # QUIC Subsequent Connections .left-column[  ] .right-column[ * Client sends (assumes server certificate hasn't changed): * CID * cookie * proposed encrypted session key * encryption algorithm * Client can immediately send requests ] --- # QUIC and IP Spoofing TCP's three-way handshake makes it immune to IP spoofing related attacks. UDP by-default is vulnerable. QUIC is engineered to avoid such attacks through the use of the CID. --- # QUIC and Packet Loss .center[  ] Packet loss affects only the stream that lost the resource. No global head-of-line blocking. TCP handles packet loss through retransmissions. QUIC can handle packet loss without retransmission. > How? --- # Forward Error Correction .center[  ] With forward error correction we trade bandwidth (extra data) for latency (retransmissions). --- # QUIC and Physically Mobile Users .left-column[  ] .right-column[ Connections in QUIC are based on the CID rather than the its IP address/PORT combination. Thus clients can freely move between networks without having to reestablish their connections. ] --- # QUIC Results * 75% of requests avoid handshake * Google search observed a 3% reduction in mean page load time. * The slowest 1% of users experience a 1 second reduction in page load time. * YouTube users experience 30% fewer rebuffers. Overall the most significant results occur under poor network conditions. As of September 2017, QUIC accounts for approximately 7% of Internet traffic [[ref](https://blog.apnic.net/2018/05/15/how-much-of-the-internet-is-using-quic/)]. --- # HTTP/3 HTTP/3 is proposed as HTTP over QUIC. https://mailarchive.ietf.org/arch/msg/quic/RLRs4nB1lwFCZ_7k0iuz0ZBa35s Latest Draft (November 4, 2019) - https://tools.ietf.org/html/draft-ietf-quic-http-24 Abstract: > The QUIC transport protocol has several features that are desirable in a transport for HTTP, such as stream multiplexing, per-stream flow control, and low-latency connection establishment. This document describes a mapping of HTTP semantics over QUIC. This document also identifies HTTP/2 features that are subsumed by QUIC, and describes how HTTP/2 extensions can be ported to HTTP/3.