Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
If we can't fix head-of-line blocking within TCP, then in theory we should be able to make a new transport protocol next to UDP and TCP in the network stack. Or perhaps even use SCTP which is a transport protocol standardized by the IETF in RFC 4960 with several of the desired characteristics.
However, in recent years efforts to create new transport protocols have almost entirely been halted because of the difficulties in deploying them on the Internet. Deployment of new protocols is hampered by many firewalls, NATs, routers and other middle-boxes that only allow TCP or UDP are deployed between users and the servers they need to reach. Introducing another transport protocol makes N% of the connections fail because they are being blocked by boxes that see it not being UDP or TCP and thus evil or wrong somehow. The N% failure rate is often deemed too high to be worth the effort.
Additionally, changing things in the transport protocol layer of the network stack typically means protocols implemented by operating system kernels. Updating and deploying new operating system kernels is a slow process that requires significant effort. Many TCP improvements standardized by the IETF are not widely deployed or used because they are not broadly supported.
SCTP is a reliable transport protocol with streams, and for WebRTC there are even existing implementations using it over UDP.
This was not deemed good enough as a QUIC alternative due to several reasons, including:
SCTP does not fix the head-of-line-blocking problem for streams
SCTP requires the number of streams to be decided at connection setup
SCTP does not have a solid TLS/security story
SCTP has a 4-way handshake, QUIC offers 0-RTT
QUIC is a bytestream like TCP, SCTP is message-based
QUIC connections can migrate between IP addresses but SCTP cannot
For more details on the differences, see A Comparison between SCTP and QUIC.
This book effort was started in March 2018. The plan is to document HTTP/3 and its underlying protocol: QUIC. Why, how they work, protocol details, the implementations and more.
The book is entirely free and is meant to be a collaborative effort involving anyone and everyone who wants to help out.
A reader of this book is presumed to have a basic understanding of TCP/IP networking, the fundamentals of HTTP and the web. For further insights and specifics about HTTP/2 we recommend first reading up the details in http2 explained.
This book is created and the work is started by Daniel Stenberg. Daniel is the founder and lead developer of curl, the world's most widely used HTTP client software. Daniel has worked with and on HTTP and internet protocols for over two decades and is the author of http2 explained.
The home page for this book is found at daniel.haxx.se/http3-explained.
If you find mistakes, omissions, errors or blatant lies in this document, please send us a refreshed version of the affected paragraph and we will make amended versions. We will give proper credits to everyone who helps out. I hope to make this document better over time.
Preferably, you submit errors or pull requests on the book's GitHub page.
This document and all its contents are licensed under the Creative Commons Attribution 4.0 license.
HTTP/3 explained is a collaborative effort to document the HTTP/3 and the QUIC protocols. Join in and help!
Get the Web or PDF versions on http3-explained.haxx.se.
The contents get updated automatically on every commit to this git repository.
HTTP/2 is done over TCP and with much fewer TCP connections than when using earlier HTTP versions. TCP is a protocol for reliable transfers and you can basically think of it as an imaginary chain between two machines. What is being put out on the network in one end will end up in the other end, in the same order - eventually. (Or the connection breaks.)
With HTTP/2, typical browsers do tens or hundreds of parallel transfers over a single TCP connection.
If a single packet is dropped, or lost in the network somewhere between two endpoints that speak HTTP/2, it means the entire TCP connection is brought to a halt while the lost packet is re-transmitted and finds its way to the destination. Since TCP is this "chain", it means that if one link is suddenly missing, everything that would come after the lost link needs to wait.
An illustration using the chain metaphor when sending two streams over this connection. A red stream and a green stream:
It becomes a TCP-based head of line block!
As the packet loss rate increases, HTTP/2 performs less and less well. At 2% packet loss (which is a terrible network quality, mind you), tests have proven that HTTP/1 users are usually better off - because they typically have up to six TCP connections to distribute lost packets over. This means for every lost packet the other connections can still continue.
Fixing this issue is not easy, if at all possible, with TCP.
With QUIC there is still a connection setup between the two end-points that makes the connection secure and the data delivery reliable.
When setting up two different streams over this connection, they are treated independently so that if any link goes missing for one of the streams, only that stream, that particular chain, has to pause and wait for the missing link to get retransmitted.
Illustrated here with one yellow and one blue stream sent between two end-points.
The HTTP/2 specification RFC 7540 was published in May 2015 and the protocol has since then been implemented and deployed widely across the Internet and the World Wide Web.
In early 2018, almost 40% of the top-1000 web sites run HTTP/2, around 70% of all HTTPS requests Firefox issues get HTTP/2 responses back and all major browsers, servers and proxies support it.
HTTP/2 addresses a whole slew of shortcomings in HTTP/1 and with the introduction of the second version of HTTP users can stop using a bunch of work-arounds. Some of which are pretty burdensome on web developers.
One of the primary features of HTTP/2 is that it makes use of multiplexing, so that many logical streams are sent over the same physical TCP connection. This makes a lot of things better and faster. It makes congestion control work much better, it lets users use TCP much better and thus properly saturate the bandwidth, makes the TCP connections more long-lived - which is good so that they get up to full speed more frequently than before. Header compression makes it use less bandwidth.
With HTTP/2, browsers typically use one TCP connection to each host instead of the previous six. In fact, connection coalescing and "desharding" techniques used with HTTP/2 may actually even reduce the number of connections much more than so.
HTTP/2 fixed the HTTP head of line blocking problem, where clients had to wait for the first request in line to finish before the next one could go out.
QUIC is a name, not an acronym. It is pronounced exactly like the English word "quick".
QUIC is a new reliable and secure transport protocol that is suitable for a protocol like HTTP and that can address some of the known shortcomings of doing HTTP/2 over TCP and TLS. The logical next step in the web transport evolution.
QUIC is not limited to just transporting HTTP. The desire to make the web and data in general delivered faster to end users is probably the largest reason and push that initially triggered the creation of this new transport protocol.
So why create a new transport protocol and why do it on top of UDP?
The initial QUIC protocol was designed by Jim Roskind at Google and was initially implemented in 2012, announced publicly to the world in 2013 when Google's experimentation broadened.
Back then, QUIC was still claimed to be an acronym for "Quick UDP Internet Connections", but that has been dropped since then.
Google implemented the protocol and subsequently deployed it both in their widely used browser (Chrome) and in their widely used server-side services (Google search, gmail, youtube and more). They iterated protocol versions fairly quickly and over time they proved the concept to work reliably for a vast portion of users.
In June 2015, the first internet draft for QUIC was sent to the IETF for standardization, but it took until late 2016 for a QUIC working group to get approved and started. But then it took off immediately with a high degree of interest from many parties.
In 2017, numbers quoted by QUIC engineers at Google mentioned that around 7% of all Internet traffic were already using this protocol. The Google version of the protocol.
The QUIC working group that was established to standardize the protocol within the IETF quickly decided that the QUIC protocol should be able to transfer other protocols than "just" HTTP. Google-QUIC only ever transported HTTP - in practice it transported what was effectively HTTP/2 frames, using the HTTP/2 frame syntax.
It was also stated that IETF-QUIC should base its encryption and security on TLS 1.3 instead of the "custom" approach used by Google-QUIC.
In order to satisfy the send-more-than-HTTP demand, the IETF QUIC protocol architecture was split in two separate layers: the transport QUIC and the "HTTP over QUIC" layer - the latter of which was renamed to HTTP/3 in November 2018.
This layer split, while it may sound innocuous, has caused the IETF-QUIC to differ quite a lot from the original Google-QUIC.
The working group did however soon decide that in order to get the proper focus and ability to deliver QUIC version 1 on time, it would focus on delivering HTTP, leaving non-HTTP transports to later work.
In March 2018 when we started working on this book, the plan was to ship the final specification for QUIC version 1 in November 2018 but this has been postponed a number of times. The IETF QUIC protocol was standardized and published in May 2021 as RFC 9000.
While the work on IETF-QUIC has progressed, the Google team has incorporated details from the IETF version and has started to slowly progress their version of the protocol towards what the IETF version might become. Google has continued using their version of QUIC in their browser and services.
Most new implementations under development have decided to focus on the IETF version and are not compatible with the Google version.
The HTTP/2 specification RFC 7540 was published in May 2015, just a month before QUIC was brought to IETF for the first time.
With HTTP/2, the foundation for changing HTTP over the wire was laid out and the working group that created HTTP/2 was already of the mindset that this would help iterating to new HTTP versions much faster than it had taken to go to version 2 from version 1 (about 16 years).
With HTTP/2, users and software stacks got used to the idea that HTTP can no longer be assumed to be done with a text-based protocol in a serial manner.
HTTP-over-QUIC (HTTP/3) builds upon HTTP/2 and follows many of the same concepts but moves some of the specifics from the HTTP layer as they are covered by QUIC.
The QUIC protocol from a high level.
Illustrated below is the HTTP/2 network stack on the left and the QUIC network stack on the right, when used as HTTP transport.
Similar to SCTP, SSH and HTTP/2, QUIC features separate logical streams within the physical connections. A number of parallel streams that can transfer data simultaneously over a single connection without affecting the other streams.
A connection is a negotiated setup between two end-points similar to how a TCP connection works. A QUIC connection is made to a UDP port and IP address, but once established the connection is associated by its "connection ID".
Over an established connection, either side can create streams and send data to the other end. Streams are delivered in-order and they are reliable, but different streams may be delivered out-of-order.
QUIC offers flow control on both connection and streams.
See further details in connections and streams sections
The internet is a network of networks. There is equipment set up on the Internet in many different places along the way to make sure this network of networks works as it is supposed to. These devices, the boxes that are distributed out in the network, are what we sometimes refer to as middle-boxes. Boxes that sit somewhere between the two end-points that are the primary parties involved in a traditional network data transfer.
These boxes serve many different specific purposes but I think we can say that universally they are put there because someone thinks they must be there to make things work.
Middle-boxes route IP packets between networks, they block malicious traffic, they do NAT (Network Address Translation), they improve performance, some try to spy on the passing traffic and more.
In order to perform their duties these boxes must know about networking and the protocols that are monitored or modified by them. They run software for this purpose. Software that is not always upgraded frequently.
While they are glue components that keep the Internet together they are also often not keeping up with the latest technology. The middle of the network typically does not move as fast as the edges, as the clients and the servers of the world.
The network protocols that these boxes might want to inspect, and have ideas about what is okay and what is not then have this problem: these boxes were deployed some time ago when the protocols had a feature set of that time. Introducing new features or changes in behavior that were not known before risks ending up considered bad or illegal by such boxes. Such traffic may well just be dropped or delayed to the degree that users really do not want to use those features.
This is called "protocol ossification".
Changes to TCP also suffer from ossification: some boxes between a client and the remote server will spot unknown new TCP options and block such connections since they do not know what the options are. If allowed to detect protocol details, systems learn how protocols typically behave and over time it becomes impossible to change them.
The only truly effective way to "combat" ossification is to encrypt as much of the communication as possible in order to prevent middle-boxes from seeing much of the protocol passing through.
QUIC offers both 0-RTT and 1-RTT handshakes that reduce the time it takes to negotiate and setup a new connection. Compare with the 3-way handshake of TCP.
In addition to that, QUIC offers "early data" support from the get-go which is done to allow more data and it is used more easily than TCP Fast Open.
With the stream concept, another logical connection to the same host can be done at once without having to wait for the existing one to end first.
TCP Fast Open was published as RFC 7413 in December 2014 and that specification describes how applications can pass data to the server to be delivered already in the first TCP SYN packet.
Actual support for this feature in the wild has taken time and is riddled with problems even today in 2018. The TCP stack implementors have had issues and so have applications trying to take advantage of this feature - both in knowing in which OS version to try to activate it but also in figuring out how to gracefully back down and deal when problems arise. Several networks have been identified to interfere with TFO traffic and they have thus actively ruined such TCP handshakes.
QUIC is always secure. There is no clear-text version of the protocol so to negotiate a QUIC connection means doing cryptography and security with TLS 1.3. As mentioned above, this prevents ossification as well as other sorts of blocks and special treatments, as well as making sure QUIC has all the secure properties of HTTPS that web users have come to expect and want.
There are only a few initial handshake packets that are sent in the clear before the encryption protocols have been negotiated.
The work on sending protocols other than HTTP over QUIC has been postponed until after QUIC version 1 has shipped.
QUIC offers both 0-RTT and 1-RTT connection setups, meaning that at best QUIC needs no extra round-trips at all when setting up a new connection. The faster of those two, the 0-RTT handshake, only works if there has been a previous connection established to a host and a secret from that connection has been cached.
QUIC allows a client to include data already in the 0-RTT handshake. This feature allows a client to deliver data to the peer as fast as it possibly can, and that then of course allows the server to respond and send data back even sooner.
The HTTP layer, called HTTP/3, does HTTP-style transports, including HTTP header compression using QPACK - which is similar to the HTTP/2 compression named HPACK.
The HPACK algorithm depends on an ordered delivery of streams so it was not possible to reuse it for HTTP/3 without modifications since QUIC offers streams that can be delivered out of order. QPACK can be seen as the QUIC-adapted version of HPACK.
QUIC is a transfer protocol implemented on top of UDP. If you watch your network traffic casually, you will see QUIC appear as UDP packets.
Based on UDP it also then uses UDP port numbers to identify specific network services on a given IP address.
All known QUIC implementations are currently in user-space, which allows for more rapid evolution than kernel-space implementations typically allow.
There are enterprises and other network setups that block UDP traffic on other ports than 53 (used for DNS). Others throttle such data in ways that makes QUIC perform worse than TCP based protocols. There is no end to what some operators may do.
For the foreseeable future, all use of QUIC-based transports will probably have to be able to gracefully fall-back to another (TCP-based) alternative. Google engineers have previously mentioned measured failure rates in the low single-digit percentages.
Chances are that if QUIC proves to be a valuable addition to the Internet world, people will want to use it and they will want it to function in their networks and then companies may start to reconsider their obstacles. During the years the development of QUIC has progressed, the success rate for establishing and using QUIC connections across the Internet has increased.
The QUIC working group has worked fiercely since late 2016 on specifying the protocols and is approaching final stages at the time of writing (June 2020).
During 2019 and 2020 there has been an increasing number of interoperability tests with HTTP/3 and CDNs and Browsers have started launching initial support - though often behind flags.
There are a number of different QUIC implementations listed in the QUIC working groups' wiki pages.
Implementing QUIC is not easy and the protocol has kept moving and changing even up to this date.
NGINX support for QUIC and HTTP/3 is under development and a preview version has been announced.
There have been no public statement in terms of support for QUIC from Apache.
None of the larger browser vendors have yet shipped any version, at any state, that can run the IETF version of QUIC or HTTP/3.
Google Chrome has shipped with a working implementation of Google's own QUIC version since many years and has recently started supporting the IETF version behind a flag. Firefox similarly supports this behind a flag.
curl shipped the first experimental HTTP/3 support (draft-22) in the 7.66.0 release on September 11, 2019. curl uses either the Quiche library from Cloudflare or the ngtcp2 family of libraries to get the work done.
QUIC decided to use TLS 1.3 as the foundation for the crypto and security layer to avoid inventing something new and instead lean on a trustworthy and existing protocol. However, while doing this, the working group also decided that to really streamline the use of TLS in QUIC, it should only use "TLS messages" and not "TLS records" for the protocol.
This might sound like an innocuous change, but this has actually caused a significant hurdle for many QUIC stack implementors. Existing TLS libraries that support TLS 1.3 simply do not have APIs enough to expose this functionality and allow QUIC to access it. While several QUIC implementors come from larger organizations who work on their own TLS stack in parallel, this is not true for everyone.
The dominant open source heavyweight OpenSSL for example, does not have any API for this. The plan to address this seems to happen in their PR 8797 that aims to introduce an API that is very similar to the one of BoringSSL.
This will eventually also lead to deployment obstacles since QUIC stacks will need to either base themselves on other TLS libraries, use a separate patched OpenSSL build or require an update to a future OpenSSL version.
Both Google and Facebook have mentioned that their wide scale deployments of QUIC require roughly twice the amount of CPU than the same traffic load does when serving HTTP/2 over TLS.
Some explanations for this include
the UDP parts in primarily Linux is not at all as optimized as the TCP stack is, since it has not traditionally been used for high speed transfers like this.
TCP and TLS offloading to hardware exist, but that is much rarer for UDP and basically non-existing for QUIC.
There are reasons to believe that performance and CPU requirements will improve over time.
The IETF QUIC protocol is a transport protocol, on top of which other application protocols can be used. The initial application layer protocol is HTTP/3 (h3).
The transport layer supports connections and streams.
The legacy Google version of QUIC had transport and HTTP glued together into one single do-it-all and was a more special-purpose send-http/2-frames-over-udp protocol.
The transport security used in QUIC is using TLS 1.3 (RFC 8446) and there are never any unencrypted QUIC connections.
TLS 1.3 has several advantages compared to older TLS versions but a primary reason for using it in QUIC is that 1.3 changed the handshake to require fewer roundtrips. It reduces protocol latency.
The Google legacy version of QUIC used a custom crypto.
While UDP is not a reliable transport, QUIC adds a layer on top of UDP that introduces reliability. It offers re-transmissions of packets, congestion control, pacing and the other features otherwise present in TCP.
Data sent over QUIC from one end-point will appear in the other end sooner or later, as long as the connection is maintained.
Without explaining the exact bits and bytes on the wire, this section describes how the fundamental building blocks of the QUIC transport protocol work. If you want to implement your own QUIC stack, this description should give you a general understanding, but for all the details, refer to the actual IETF Internet Drafts and RFCs.
Set up a connection
... that includes TLS security
Then use streams
A QUIC connection is a single conversation between two QUIC endpoints. QUIC's connection establishment combines version negotiation with the cryptographic and transport handshakes to reduce connection establishment latency.
To actually send data over such a connection, one or more streams have to be created and used.
Each connection possesses a set of connection identifiers, or connection IDs, each of which can be used to identify the connection. Connection IDs are independently selected by endpoints; each endpoint selects the connection IDs that its peer uses.
The primary function of these connection IDs is to ensure that changes in addressing at lower protocol layers (UDP, IP, and below) do not cause packets for a QUIC connection to be delivered to the wrong endpoint.
By taking advantage of the connection ID, connections can thus migrate between IP addresses and network interfaces in ways TCP never could. For instance, migration allows an in-progress download to move from a cellular network connection to a faster wifi connection when the user moves their device into a location offering wifi. Similarly, the download can proceed over the cellular connection if wifi becomes unavailable.
QUIC is built atop UDP, so a 16 bit port number field is used to differentiate incoming connections.
A QUIC connection request originating from a client will tell the server which QUIC protocol version it wants to speak, and the server will respond with a list of supported versions for the client to select from.
Streams in QUIC provide a lightweight, ordered byte-stream abstraction.
There are two basic types of stream in QUIC:
Unidirectional streams carry data in one direction: from the initiator of the stream to its peer.
Bidirectional streams allow for data to be sent in both directions.
Either type of stream can be created by either endpoint, can concurrently send data interleaved with other streams, and can be canceled.
To send data over a QUIC connection, one or more streams are used.
Streams are individually flow controlled, allowing an endpoint to limit memory commitment and to apply back pressure. The creation of streams is also flow controlled, with each peer declaring the maximum stream ID it is willing to accept at a given time.
Streams are identified by an unsigned 62-bit integer, referred to as the Stream ID. The least significant two bits of the Stream ID are used to identify the type of stream (unidirectional or bidirectional) and the initiator of the stream.
The least significant bit (0x1) of the Stream ID identifies the initiator of the stream. Clients initiate even-numbered streams (those with the least significant bit set to 0); servers initiate odd-numbered streams (with the bit set to 1).
The second least significant bit (0x2) of the Stream ID differentiates between unidirectional streams and bidirectional streams. Unidirectional streams always have this bit set to 1 and bidirectional streams have this bit set to 0.
QUIC allows for an arbitrary number of streams to operate concurrently. An endpoint limits the number of concurrently active incoming streams by limiting the maximum stream ID.
The maximum stream ID is specific to each endpoint and applies only to the peer that receives the setting.
Endpoints use streams to send and receive data. That is after all their ultimate purpose. Streams are an ordered byte-stream abstraction. Separate streams are however not necessarily delivered in the original order.
Stream multiplexing has a significant effect on application performance if resources allocated to streams are correctly prioritized. Experience with other multiplexed protocols, such as HTTP/2, shows that effective prioritization strategies have a significant positive impact on performance.
QUIC itself does not provide signals for exchanging prioritization information. Instead it relies on receiving priority information from the application that uses QUIC. Protocols that use QUIC are able to define any prioritization scheme that suits their application semantics.
The Extensible Prioritization Scheme for HTTP (RFC 9218) can be used for HTTP/3. It defines signals and provides scheduling guidance. This scheme is simpler than the original one defined for HTTP/2.
Immediately after the initial packet setting up a connection, the initiator sends a crypto frame that starts setting up the secure layer handshake. The security layer uses TLS 1.3 security.
There is no way to opt-out or avoid using TLS for a QUIC connection. The protocol is designed to be hard for middle-boxes to tamper with, in order to help prevent ossification of the protocol.
QUIC guarantees in-order delivery of streams, but not between streams. This means that each stream will send data and maintain data order, but each stream may reach the destination in a different order than the application sent it!
For example: stream A and B are transferred from a server to a client. Stream A is started first and then stream B. In QUIC, a lost packet only affects the stream to which the lost packet belongs. If stream A loses a packet but stream B does not, stream B may continue its transfers and complete while stream A's lost packet is re-transmitted. This was not possible with HTTP/2.
Illustrated here with one yellow and one blue stream sent between two QUIC end-points over a single connection. They are independent and may arrive in a different order, but each stream is reliably delivered to the application in order.
To reduce the time required to establish a new connection, a client that has previously connected to a server may cache certain parameters from that connection and subsequently set up a 0-RTT connection with the server. This allows the client to send data immediately, without waiting for a handshake to complete.
One of the perhaps longest design discussions within the QUIC working group that has been the subject of several hundred mails and hours of discussions concerns a single bit: the Spin Bit.
The proponents of this bit insist that there is a need for operators and people on the path between two QUIC endpoints to be able to measure latency.
The opponents to this feature do not like the potential information leak.
Both endpoints, the client and the server, maintain a spin value, 0 or 1, for each QUIC connection, and they set the spin bit on packets it sends for that connection to the appropriate value.
Both sides then send out packets with that spin bit set to the same value for as long as one round trip lasts and then it toggles the value. The effect is then a pulse of ones and zeroes in that bitfield that observers can monitor.
This measuring only works when the sender is neither application nor flow control limited and packet reordering over the network can also make the data noisy.
One of the success factors for regular TCP and programs using that, is the standardized socket API. It has well defined functionality and using this API you can move programs between many different operating systems as TCP works the same.
QUIC is not there. There is no standard API for QUIC.
With QUIC, you need to pick one of the existing library implementations and stick with its API. It makes applications "locked in" to a single library to some extent. Changing to another library means another API and that might involve a lot of work.
Also, since QUIC is typically implemented in user-space, it can't easily just extend the socket API or appear similar to how existing TCP and UDP functionality do. Using QUIC will mean using another API than the socket API.
As mentioned previously, the first and primary protocol to transport over QUIC is HTTP.
Much like HTTP/2 was once introduced to transport HTTP over the wire in a completely new way, HTTP/3 is yet again introducing a new way to send HTTP over the network.
HTTP still maintains the same paradigms and concepts like before. There are headers and a body, there is a request and a response. There are verbs, cookies and caching. What primarily changes with HTTP/3 is how the bits get sent over to the other side of the communication.
In order to do HTTP over QUIC, changes were required and the results of this is what we now call HTTP/3. These changes were required because of the different nature that QUIC provides as opposed to TCP. These changes include:
In QUIC the streams are provided by the transport itself, while in HTTP/2 the streams were done within the HTTP layer.
Due to the streams being independent of each other, the header compression protocol used for HTTP/2 could not be used without it causing a head of block situation.
QUIC streams are slightly different than HTTP/2 streams. The HTTP/3 section will detail this somewhat.
HTTP/3 is made for QUIC so it takes full advantage of QUIC's streams, where HTTP/2 had to design its entire stream and multiplexing concept of its own on top of TCP.
HTTP requests done over HTTP/3 use a specific set of streams.
HTTP/3 means setting up QUIC streams and sending over a set of frames to the other end. There's but a small fixed number (actually nine on December 18th, 2018!) of known frames in HTTP/3. The most important ones are probably:
HEADERS, that sends compressed HTTP headers
DATA, sends binary data contents
GOAWAY, please shutdown this connection
The client sends its HTTP request on a client-initiated bidirectional QUIC stream.
A request consists of a single HEADERS frame and might optionally be followed by one or two other frames: a series of DATA frames and possibly a final HEADERS frame for trailers.
After sending a request, a client closes the stream for sending.
The server sends back its HTTP response on the bidirectional stream. A HEADERS frame, a series of DATA frames and possibly a trailing HEADERS frame.
The HEADERS frames contain HTTP headers compressed using the QPACK algorithm. QPACK is similar in style to the HTTP/2 compression called HPACK (RFC 7541), but modified to work with streams delivered out of order.
QPACK itself uses two additional unidirectional QUIC streams between the two end-points. They are used to carry dynamic table information in either direction.
The alternate service (Alt-svc:) header and its corresponding ALT-SVC
HTTP/2 frame are not specifically created for QUIC or HTTP/3. They are part of an already designed and created mechanism for a server to tell a client: "look, I run the same service on THIS HOST using THIS PROTOCOL on THIS PORT". See details in RFC 7838.
A client that receives such an Alt-svc response is then advised to, if it supports and wants to, connect to that given other host in parallel in the background - using the specified protocol - and if it is successful switch its operations over to that instead of the initial connection.
If the initial connection uses HTTP/2 or even HTTP/1, the server can respond and tell the client that it can connect back and try HTTP/3. It could be to the same host or to another one that knows how to serve that origin. The information given in such an Alt-svc response has an expiry timer, making clients able to direct subsequent connections and requests directly to the alternative host using the suggested alternative protocol, for a certain period of time.
An HTTP server includes an Alt-Svc:
header in its response:
This indicates that HTTP/3 is available on UDP port 50781 at the same host name that was used to get this response.
A client can then attempt to setup a QUIC connection to that destination and if successful, continue communicating with the origin like that instead of the initial HTTP version.
HTTP/3 will be performed using HTTPS://
URLs. The world is full of these URLs and it has been deemed impractical and downright unreasonable to introduce another URL scheme for the new protocol. Much like HTTP/2 did not need a new scheme, neither will HTTP/3.
The added complexity in the HTTP/3 situation is however that where HTTP/2 was a completely new way of transporting HTTP over the wire, it was still based on TLS and TCP like HTTP/1 was. The fact that HTTP/3 is done over QUIC changes things in a few important aspects.
Legacy, clear-text, HTTP://
URLs will be left as-is and as we proceed further into a future with more secure transfers they will probably become less and less frequently used. Requests to such URLs will simply not be upgraded to use HTTP/3. In reality they rarely upgrade to HTTP/2 either, but for other reasons.
The first connection to a fresh, not previously visited host for a HTTPS:// URL probably has to be done over TCP (possibly in addition to a parallel attempt to connect via QUIC). The host might be a legacy server without QUIC support or there might be a middle box in between setting up obstacles preventing a QUIC connection from succeeding.
A modern client and server would presumably negotiate HTTP/2 in the first handshake. When the connection has been setup and the server responds to a client HTTP request, the server can tell the client about its support of and preference for HTTP/3.
Implementing a transport protocol in user-space helps enable quick iteration of the protocol, as it is comparatively easy to evolve the protocol without necessitating that clients and servers update their operating system kernel to deploy new versions.
Nothing inherent in QUIC prevents it from being implemented and offered by operating system kernels in the future, should someone find that a good idea.
One obvious effect of implementing a new transport protocol in user-space is that we can expect to see many independent implementations.
Different applications are likely to include (or layer atop) different HTTP/3 and QUIC implementations for the foreseeable future.
HTTP/3 server push is similar to what is described in HTTP/2 (RFC 7540), but uses different mechanisms.
A server push is effectively the response to a request that the client never sent!
Server pushes are only allowed to happen if the client side has agreed to them. In HTTP/3 the client even sets a limit for how many pushes it accepts by informing the server what the max push stream ID is. Going over that limit will cause a connection error.
If the server deems it likely that the client wants an extra resource that it hasn't asked for but ought to have anyway, it can send a PUSH_PROMISE
frame (over the request stream) showing what the request looks like that the push is a response to, and then send that actual response over a new stream.
Even when pushes have been said to be acceptable by the client before-hand, each individual pushed stream can still be canceled at any time if the client deems that suitable. It then sends a CANCEL_PUSH
frame to the server.
Ever since this feature was first discussed in the HTTP/2 development and later after the protocol shipped and has been deployed over the Internet, this feature has been discussed, disliked and pounded up in countless different ways in order to get it to become useful.
Pushing is never "free", since while it saves a half round-trip it still uses bandwidth. It is often hard or impossible for the server-side to actually know with a high level of certainty if a resource should be pushed or not.
The base HTTP/3 specification doesn't define prioritization itself. The HTTP/2 approach to prioritization has been deemed too complicated and is deprecated by the latest revision of the HTTP/2 specification RFC 9113. A simpler alternative, the Extensible Prioritization Scheme for HTTP (RFC 9218), has been published separately, which can be used in both HTTP/2 and HTTP/3.
In HTTP/3, priority signals are sent in the form of the Priority header field and/or the PRIORITY_UPDATE frame sent on the HTTP/3 Control Stream. Servers can act on these signals to schedule sending of HTTP response content. RFC 9218 provides scheduling guidance that is intended to improve client web application performance.
HTTP/3 is designed for QUIC, which is a transport protocol that handles streams by itself.
HTTP/2 is designed for TCP, and therefore handles streams in the HTTP layer.
The two protocols offer clients virtually identical feature sets.
Both protocols offer server push support
Both protocols have header compression, and QPACK and HPACK are similar in design.
Both protocols offer multiplexing over a single connection using streams
The differences are in the details and primarily there thanks to HTTP/3's use of QUIC:
HTTP/3 has better and more likely to work early data support thanks to QUIC's 0-RTT handshakes, while TCP Fast Open and TLS usually sends less data and often faces problems.
HTTP/3 has much faster handshakes thanks to QUIC vs TCP + TLS.
HTTP/3 does not exist in an insecure or unencrypted version. HTTP/2 can be implemented and used without HTTPS - even if this is rare on the Internet.
HTTP/2 can be negotiated directly in a TLS handshake with the ALPN extension, while HTTP/3 is over QUIC so it needs an Alt-Svc:
header response first to inform the client about this fact.
The base HTTP/3 specification doesn't define prioritization itself. The HTTP/2 approach to prioritization has been deemed too complicated and is deprecated by the latest revision of the HTTP/2 specification RFC 9113. A simpler alternative, the Extensible Prioritization Scheme for HTTP (RFC 9218), has been published separately, which can be used in both HTTP/2 and HTTP/3.
A lot of enterprises, operators and organizations block or rate-limit UDP traffic outside of port 53 (used for DNS) since it has in recent days mostly been abused for attacks. In particular, some of the existing UDP protocols and popular server implementations for them have been vulnerable for amplification attacks where one attacker can make a huge amount of outgoing traffic to target innocent victims.
QUIC has built-in mitigation against amplification attacks by requiring that the initial packet must be at least 1200 bytes and by restriction in the protocol that says that a server must not send more than three times the size of the request in response without receiving a packet from the client in response.
This seems to be the truth, at least initially. We can of course not tell how this will develop and how much of this is simply the result of UDP transfer performance not having been in developers' focus for many years.
For most clients, this "slowness" is probably never even noticeable.
Similar to the "UDP is slow" remark above, this is partly because the TCP and TLS usage of the world has had a longer time to mature, improve and get hardware assistance.
There are reasons to expect this to improve over time, and already we are seeing some improvements in this space. The question is how much this extra CPU usage will hurt deployers.
No it is not. Google brought the initial spec to the IETF after having proved, on a large Internet-wide scale, that deploying this style of protocol over UDP actually works and performs well.
Since then, individuals from a large number of companies and organizations have worked in the vendor-neutral organization IETF to put together a standard transport protocol out of it. In that work, Google employees have of course been participating, but so have employees from a large number of other companies that are interested in furthering the state of transport protocols on the Internet, including Mozilla, Fastly, Cloudflare, Akamai, Microsoft, Facebook and Apple.
That is not really a critique but an opinion. Maybe it is, and maybe it is too little of an improvement so close in time since HTTP/2 was shipped.
HTTP/3 is likely to perform much better in packet loss-ridden networks, it offers faster handshakes so it will improve latency both as perceived and actual. But is that enough of benefits to motivate people to deploy HTTP/3 support on their servers and for their services? Time and future performance measurements will surely tell!
In order to get the most focus possible on the core QUIC protocol and be able to ship it on time, several features that were originally planned to be part of the core protocol have been postponed and are now planned to instead get done in a subsequent QUIC version.
The author of this document does however have a rather faulty crystal ball so we can not tell for sure exactly what features will or will not appear in such a future version. We can however mention some of the features and things that explicitly have been removed from the v1 work to be "worked on later" and that then possibly might appear in a future version.
Forward error correction (FEC) is a method of obtaining error control in data transmission in which the transmitter sends redundant data and the receiver recognizes only the portion of the data that contains no apparent errors.
Google experimented with this in their original QUIC work but it was subsequently removed again since the experiments did not turn out well. This feature is subject for discussion for QUIC but probably takes for someone to prove that it actually can be a useful addition without too much penalty.
Multipath means that the transport can by itself use multiple network paths to maximize resource usage and increase redundancy.
The SCTP proponents of the world like to mention that SCTP already features multipath and so does modern TCP.
It has been discussed to offer "unreliable" streams as an option, that would then allow QUIC to also replace UDP-style applications.
DNS over QUIC was one of the early mentioned non-HTTP protocols that just might get some attention once QUIC v1 and HTTP/3 ship. But with a new transport like this having been brought on to the world I cannot imagine that it will stop there.
Here is a collection of the RFCs for the various parts and components of QUIC and HTTP/3.
Compatible Version Negotiation for QUIC
QUIC: A UDP-Based Multiplexed and Secure Transport
QUIC Loss Detection and Congestion Control
Hypertext Transfer Protocol Version 3 (HTTP/3)
Este libro fue lanzado en Marzo del 2018. El plan consiste en documentar HTTP/3 y su protocolo subyacente: QUIC. Por qué, cómo funcionan, los detalles del protocolo, las implementaciones y más.
Este libro es completamente gratis y se pretende ser un esfuerzo colaboración en el que participen todas las personas que quieran ayudar.
Se supone que el lector de este libro tiene un conocimiento básico de redes TCP/IP, los fundamentos de HTTP y la web. Para más información y especificidades sobre HTTP/2, recomendamos leer primero los detalles en http2 explained (español).
Este libro es creado y el trabajo es iniciado por Daniel Stenberg. Daniel es el fundador y desarrollador principal de curl, el software cliente HTTP más utilizado del mundo. Daniel ha trabajado con y sobre HTTP y los protocolos de Internet durante más de dos décadas y es autor de http2 explained (español).
La página de inicio de este libro se encuentra en daniel.haxx.se/http3-explained/es.
Si encuentra errores, omisiones, equivocaciones o mentiras flagrantes en este documento, envÃenos una versión actualizada del párrafo afectado y haremos versiones modificadas. Daremos el debido crédito a todos los que nos ayuden. Espero que este documento mejore con el tiempo.
De preferencia, envÃe los errores o pull requests mediante la página de GitHub del libro.
Este documento y todo su contenido estan bajo la licencia Creative Commons Attribution 4.0 license.
QUIC es un nombre, no un acrónimo. Se pronuncia exactamente como la palabra "quick" en inglés.
QUIC es un nuevo protocolo de transporte fiable y seguro que es adecuado para un protocolo como HTTP y que puede solucionar algunas de las deficiencias conocidas de hacer HTTP/2 sobre TCP y TLS. Es el siguiente paso lógico en la evolución del transporte web.
QUIC no se limita a transportar HTTP. El deseo de hacer que la web y los datos en general lleguen más rápido a los usuarios finales es probablemente la mayor razón y el impulso que desencadenó inicialmente la creación de este nuevo protocolo de transporte.
Entonces, ¿por qué crear un nuevo protocolo de transporte y por qué hacerlo sobre UDP?
HTTP/2 se realiza sobre TCP y con muchas menos conexiones TCP que cuando se utilizan versiones anteriores de HTTP. TCP es un protocolo para transferencias fiables y básicamente se puede pensar en él como una cadena imaginaria entre dos máquinas. Lo que se pone en la red en un extremo terminará en el otro, en el mismo orden - eventualmente. (O la conexión se rompe).
Con HTTP/2, los navegadores tÃpicos realizan decenas o cientos de transferencias paralelas a través de una única conexión TCP.
Si un solo paquete se cae, o se pierde en la red en algún lugar entre dos puntos finales que hablan HTTP/2, significa que toda la conexión TCP se detiene mientras el paquete perdido se retransmite y encuentra su camino hacia el destino. Dado que TCP es esta "cadena", significa que si un eslabón se pierde de repente, todo lo que vendrÃa después del eslabón perdido tiene que esperar.
Una ilustración utilizando la metáfora de la cadena al enviar dos flujos a través de esta conexión. Un flujo rojo y un flujo verde:
¡Se convierte en un bloqueo de cabeza de lÃnea TCP!
A medida que aumenta la tasa de pérdida de paquetes, HTTP/2 rinde cada vez menos. Con un 2% de pérdida de paquetes (que es una calidad de red terrible, ojo), las pruebas han demostrado que los usuarios de HTTP/1 suelen estar mejor, porque suelen tener hasta seis conexiones TCP entre las que distribuir los paquetes perdidos. Esto significa que por cada paquete perdido, las otras conexiones pueden continuar.
Arreglar este problema no es fácil, si acaso es posible, con TCP.
Con QUIC todavÃa hay una configuración de conexión entre los dos puntos finales que hace que la conexión sea segura y la entrega de datos fiable.
Cuando se establecen dos flujos diferentes sobre esta conexión, se tratan de forma independiente, de manera que si se pierde algún enlace para uno de los flujos, sólo ese flujo, esa cadena en particular, tiene que hacer una pausa y esperar a que el enlace perdido se retransmita.
Ilustrado aquà con un flujo amarillo y otro azul enviados entre dos puntos finales.
La especificación de HTTP/2 RFC 7540 fue publicado en mayo de 2015 y desde entonces el protocolo se ha implementado y desplegado ampliamente en Internet y en la World Wide Web.
A principios de 2018, casi el 40% de los principales 1000 sitios web ejecutan HTTP/2, alrededor del 70% de todas las solicitudes HTTPS que emite Firefox obtienen respuestas HTTP/2 y todos los principales navegadores, servidores y proxies lo soportan.
HTTP/2 aborda toda una serie de deficiencias de HTTP/1 y con la introducción de la segunda version de HTTP los usuarios pueden dejar de utilizar un montón de métodos alternativos. Algunos de las cuales son bastante agobiante para los desarrolladores web.
Una de las principales caracterÃsticas de HTTP/2 es que hace uso de la multiplexación, de modo que que muchos flujos lógicos (streams) se envÃan a través de la misma conexión TCP fÃsica. Esto hace que muchas cosas sean mejores y más rápidas. Hace que el control de la congestión funcione mucho mejor, permite a los usuarios usar TCP mucho mejor y asà saturar adecuadamente el ancho de banda, hace que las conexiones TCP sean más duraderas, lo que es bueno para que para que puedan alcanzar su máxima velocidad con más frecuencia que antes. La compresión de cabeceras hace que se utilice menos ancho de banda.
Con HTTP/2, los navegadores suelen utilizar una conexión TCP a cada host en lugar de de las seis anteriores. De hecho, las técnicas de coalescencia de la conexión y de "desharding" utilizadas con HTTP/2 pueden incluso reducir el número de conexiones mucho más que eso.
HTTP/2 solucionó el problema de bloqueo de la cabecera de la lÃnea HTTP (HTTP head of line blocking), donde los clientes tenÃan que esperar a que terminara la primera petición (request) para que pudiera salir la siguiente.
Si no podemos arreglar el bloqueo de cabecera en TCP, entonces en teorÃa deberÃamos ser capaces de hacer un nuevo protocolo de transporte junto a UDP y TCP en la pila de la red. O quizás incluso utilizar SCTP que es un protocolo de transporte estandarizado por el IETF en RFC 4960 con varias de las caracterÃsticas deseadas.
Sin embargo, en los últimos años los esfuerzos para crear nuevos protocolos de transporte se han detenido casi por completo debido a las dificultades para desplegarlos en Internet. El despliegue de nuevos protocolos se ve obstaculizado por muchos cortafuegos, NATs, routers y otras cajas intermedias que sólo permiten TCP o UDP se despliegan entre los usuarios y los servidores que necesitan alcanzar. Introducir otro protocolo de transporte hace que el N% de las conexiones fallen porque están siendo bloqueadas por cajas que ven que no es UDP o TCP y que, por tanto, es malo o erróneo de alguna manera. La tasa de fallos del N% se considera a menudo demasiado alta para que merezca la pena el esfuerzo.
Además, cambiar cosas en la capa de protocolo de transporte de la pila de red suele significar protocolos implementados por los kernels del sistema operativo. Actualizar y desplegar nuevos kernels de los sistemas operativos es un proceso lento que requiere un esfuerzo considerable. Muchas de las mejoras de TCP estandarizadas por el IETF no están ampliamente desplegadas o utilizadas porque no están ampliamente soportadas.
SCTP es un protocolo de transporte fiable con flujos, y para WebRTC hay incluso implementaciones existentes que lo utilizan sobre UDP.
Esto no se consideró lo suficientemente bueno como una alternativa a QUIC debido a varias razones, incluyendo:
SCTP no soluciona el problema del bloqueo de la cabeza de lÃnea para los flujos
SCTP requiere que el número de flujos se decida al establecer la conexión
SCTP no tiene una historia sólida de TLS/seguridad
SCTP tiene un handshake de 4 vÃas, QUIC ofrece 0-RTT
QUIC es un bytestream como TCP, SCTP está basado en mensajes
Las conexiones QUIC pueden migrar entre direcciones IP, pero SCTP no
Para más detalles sobre las diferencias, véase A Comparison between SCTP and QUIC.
QUIC es siempre seguro. No hay una versión texto claro del protocolo, por lo que negociar una conexión QUIC significa hacer criptografÃa y seguridad con TLS 1.3. Como se mencionó anteriormente, esto evita la osificación, asà como otros tipos de bloqueos y tratamientos especiales, además de asegurar que QUIC tiene todas las propiedades seguras de HTTPS que los usuarios de la web han llegado a esperar y desear.
Sólo hay unos pocos paquetes iniciales de intercambio de información que se envÃan en claro antes de que los protocolos de encriptación hayan sido negociados.
El protocolo QUIC inicial fue diseñado por Jim Roskind en Google y se implementó inicialmente en 2012, anunciándose públicamente al mundo en 2013 cuando se amplió la experimentación de Google.
Por aquel entonces, QUIC seguÃa siendo un acrónimo de "Quick UDP Internet Connections" (conexiones rápidas a Internet), pero desde entonces se ha eliminado.
Google implementó el protocolo y, posteriormente, lo desplegó tanto en su ampliamente utilizado navegador (Chrome) como en sus ampliamente utilizados servicios (búsqueda de Google, Gmail, YouTube y más). Han iterado versiones del protocolo con bastante rapidez y, con el tiempo, han demostrado que el concepto funciona de forma fiable para una gran parte de los usuarios.
En junio de 2015, el primer borrador de Internet para QUIC se envió al IETF para su estandarización, pero hubo que esperar hasta finales de 2016 para que se aprobara y se pusiera en marcha un grupo de trabajo sobre QUIC. Pero luego despegó de inmediato con un alto grado de interés de muchas partes.
En 2017, las cifras citadas por los ingenieros de QUIC en Google mencionaban que alrededor del 7% de todo el tráfico de Internet ya utilizaba este protocolo. La versión de Google del protocolo.
QUIC ofrece handshakes de 0-RTT y 1-RTT que reducen el tiempo de negociación y establecimiento de una nueva conexión. Compárese con el handshake de 3 vÃas de TCP.
Además de eso, QUIC ofrece soporte de "datos tempranos" desde el principio que se hace para permitir más datos y se utiliza más fácilmente que TCP Fast Open.
Con el concepto de flujo, se puede hacer otra conexión lógica al mismo host a la vez sin tener que esperar a que la existente termine primero.
TCP Fast Open se publicó como RFC 7413 en diciembre de 2014 y esa especificación describe cómo las aplicaciones pueden pasar datos al servidor para que se entreguen ya en el primer paquete TCP SYN.
El soporte real de esta caracterÃstica en la naturaleza ha tomado tiempo y está plagado de problemas incluso hoy en 2018. Los implementadores de la pila TCP han tenido problemas y también lo han tenido las aplicaciones que intentan aprovechar esta caracterÃstica, tanto para saber en qué versión del sistema operativo intentar activarla como para averiguar cómo retroceder con gracia y lidiar cuando surgen problemas. Se han identificado varias redes que interfieren con el tráfico TFO y, por tanto, han arruinado activamente estos handshakes TCP.
El grupo de trabajo de QUIC que se creó para estandarizar el protocolo dentro de la IETF decidió rápidamente que el protocolo QUIC debÃa ser capaz de transferir otros protocolos además de "sólo" HTTP. Google-QUIC sólo transportaba HTTP - en la práctica transportaba lo que era efectivamente tramas HTTP/2, utilizando la sintaxis de tramas HTTP/2.
También se afirmó que el IETF-QUIC deberÃa basar su cifrado y seguridad en TLS 1.3 en lugar del enfoque "personalizado" utilizado por Google-QUIC.
Con el fin de satisfacer la demanda de enviar-más-que-sólo-HTTP, la arquitectura del protocolo IETF-QUIC se dividió en dos capas separadas: el transporte QUIC y la capa "HTTP sobre QUIC" - esta última fue renombrada como HTTP/3 en noviembre de 2018.
Esta división de capas, aunque pueda parecer inocua, ha hecho que el IETF-QUIC difiera bastante del Google-QUIC original.
Sin embargo, el grupo de trabajo pronto decidió que para conseguir el enfoque adecuado y la capacidad de entregar la versión 1 de QUIC a tiempo, se centrarÃa en entregar HTTP, dejando los transportes no HTTP para un trabajo posterior.
En marzo de 2018, cuando comenzamos a trabajar en este libro, el plan era enviar la especificación final para la versión 1 de QUIC en noviembre de 2018, pero esto se ha pospuesto varias veces y, en el momento de escribir este artÃculo (junio de 2020), está entrando en las etapas finales.
Mientras el trabajo en IETF-QUIC ha progresado, el equipo de Google ha incorporado detalles de la versión del IETF y ha comenzado a progresar lentamente su versión del protocolo hacia lo que la versión del IETF podrÃa llegar a ser. Google ha seguido utilizando su versión de QUIC en su navegador y sus servicios.
La mayorÃa de las nuevas implementaciones en desarrollo han decidido centrarse en la versión del IETF y no son compatibles con la versión de Google.
La especificación RFC 7540 de HTTP/2 fue publicada en mayo de 2015, justo un mes antes que QUIC fuera llevado a la IETF por primera vez.
Con HTTP/2, se sentaron las bases para cambiar HTTP sobre la red y el grupo de trabajo que creó HTTP/2 ya tenÃa la idea de que esto ayudarÃa a iterar a nuevas versiones de HTTP mucho más rápido de lo que se habÃa tardado en pasar a la versión 2 desde la versión 1 (unos 16 años).
Con HTTP/2, los usuarios y los stack de software se acostumbraron a la idea de que HTTP ya no puede suponerse un protocolo basado en texto de forma serial.
HTTP-over-QUIC (HTTP/3) se basa en HTTP/2 y sigue muchos de los mismos conceptos pero traslada algunos de los aspectos especÃficos de la capa HTTP, ya que están cubiertos por QUIC.
El protocolo QUIC desde un alto nivel.
A continuación se ilustra la pila de red HTTP/2 a la izquierda y la pila de red QUIC a la derecha, cuando se utiliza como transporte HTTP.
Internet es una red de redes. Hay equipos instalados en Internet en muchos lugares diferentes a lo largo del camino para asegurarse de que esta red de redes funciona como se supone que debe hacerlo. Estos dispositivos, las cajas que están distribuidas en la red, son lo que a veces llamamos cajas intermedias. Cajas que se sitúan en algún lugar entre los dos puntos finales que son las partes principales implicadas en una transferencia de datos de red tradicional.
Estas cajas sirven para muchos propósitos especÃficos diferentes, pero creo que podemos decir que universalmente se ponen ahà porque alguien piensa que deben estar ahà para que las cosas funcionen.
Las cajas intermedias enrutan los paquetes IP entre las redes, bloquean el tráfico malicioso, hacen NAT (traducción de direcciones de red), mejoran el rendimiento, algunas intentan espiar el tráfico que pasa y mucho más.
Para desempeñar sus funciones, estas cajas deben conocer las redes y los protocolos que supervisan o modifican. Para ello ejecutan un software. Un software que no siempre se actualiza con frecuencia.
Aunque son componentes de pegamento que mantienen unida a Internet, a menudo no se mantienen al dÃa con la última tecnologÃa. El centro de la red no suele moverse tan rápido como los bordes, como los clientes y los servidores del mundo.
Los protocolos de red que estas cajas podrÃan querer inspeccionar, y tener ideas sobre lo que está bien y lo que no, tienen entonces este problema: estas cajas se desplegaron hace algún tiempo cuando los protocolos tenÃan un conjunto de caracterÃsticas de esa época. Al introducir nuevas caracterÃsticas o cambios en el comportamiento que no se conocÃan antes, se corre el riesgo de que dichas cajas lo consideren malo o ilegal. Es muy posible que ese tráfico se elimine o se retrase hasta el punto de que los usuarios no quieran utilizar esas funciones.
Esto se llama "osificación del protocolo".
Los cambios en TCP también sufren de osificación: algunas cajas entre un cliente y el servidor remoto detectarán nuevas opciones TCP desconocidas y bloquearán dichas conexiones ya que no saben cuáles son las opciones. Si se permite detectar los detalles del protocolo, los sistemas aprenden cómo se comportan normalmente los protocolos y con el tiempo resulta imposible cambiarlos.
La única forma realmente eficaz de "combatir" la osificación es cifrar la mayor parte posible de la comunicación para evitar que las cajas intermedias vean gran parte del protocolo que pasa.
El grupo de trabajo de QUIC ha trabajado intensamente desde finales de 2016 en la especificación de los protocolos y se está acercando a las etapas finales en el momento de escribir este artÃculo (junio de 2020).
Durante 2019 y 2020 ha habido un número creciente de pruebas de interoperabilidad con HTTP/3 y las CDN y los navegadores han comenzado a lanzar el soporte inicial - aunque a menudo detrás de flags.
Hay un número de diferentes implementaciones de QUIC listadas en las páginas wiki de los grupos de trabajo de QUIC.
Implementar QUIC no es fácil y el protocolo ha seguido moviéndose y cambiando incluso hasta la fecha.
El soporte de NGINX para QUIC y HTTP/3 está en desarrollo y se ha anunciado una versión preliminar.
No ha habido ninguna declaración pública en términos de soporte para QUIC por parte de Apache.
Ninguno de los grandes proveedores de navegadores ha lanzado aún ninguna versión, en ningún estado, que pueda ejecutar la versión IETF de QUIC o HTTP/3.
Google Chrome ha sido distribuido con una implementación funcional de la propia versión de QUIC de Google desde hace muchos años y recientemente ha comenzado a soportar la versión del IETF detrás de un flag. Firefox también lo soporta con una flag.
curl envió el primer soporte experimental de HTTP/3 (draft-22) en la versión 7.66.0 el 11 de septiembre de 2019. curl utiliza la biblioteca Quiche de Cloudflare o la familia de bibliotecas ngtcp2 para realizar el trabajo.
QUIC decidió utilizar TLS 1.3 como base para la capa de criptografÃa y seguridad para evitar inventar algo nuevo y en su lugar apoyarse en un protocolo existente y de confianza. Sin embargo, al hacer esto, el grupo de trabajo también decidió que para realmente racionalizar el uso de TLS en QUIC, sólo deberÃa utilizar "mensajes TLS" y no "registros TLS" para el protocolo.
Esto puede parecer un cambio inocuo, pero en realidad ha causado un obstáculo importante para muchos implementadores de la pila QUIC. Las librerÃas TLS existentes que soportan TLS 1.3 simplemente no tienen APIs suficientes para exponer esta funcionalidad y permitir a QUIC acceder a ella. Aunque varios implementadores de QUIC provienen de organizaciones más grandes que trabajan en su propia pila TLS en paralelo, esto no es cierto para todos.
El dominante peso pesado de código abierto, OpenSSL, por ejemplo, no tiene ninguna API para esto. El plan para abordar esto parece ocurrir en su PR 8797 que pretende introducir una API muy similar a la de BoringSSL.
Esto eventualmente también conducirá a obstáculos en el despliegue, ya que las pilas QUIC tendrán que basarse en otras bibliotecas TLS, utilizar una construcción separada de OpenSSL parcheada o requerir una actualización a una futura versión de OpenSSL.
Tanto Google como Facebook han mencionado que sus despliegues a gran escala de QUIC requieren aproximadamente el doble de CPU que la misma carga de tráfico cuando se sirve HTTP/2 sobre TLS.
Algunas explicaciones para esto incluyen
las partes UDP principalmente en Linux no están tan optimizadas como la pila TCP, ya que no se ha utilizado tradicionalmente para transferencias de alta velocidad como esta.
la descarga de TCP y TLS al hardware existe, pero eso es mucho más raro para UDP y básicamente inexistente para QUIC.
Hay razones para creer que el rendimiento y los requisitos de la CPU mejorarán con el tiempo.
Al igual que SCTP, SSH y HTTP/2, QUIC presenta flujos lógicos separados dentro de las conexiones fÃsicas. Una serie de flujos paralelos que pueden transferir datos simultáneamente a través de una única conexión sin afectar a los otros flujos.
Una conexión es una configuración negociada entre dos end-points, similar a cómo funciona una conexión TCP. Una conexión QUIC se realiza con un puerto UDP y una dirección IP, pero una vez establecida la conexión se asocia por su "ID de conexión".
A través de una conexión establecida, cualquiera de las partes puede crear flujos y enviar datos al otro extremo. Los flujos se entregan en orden y son fiables, pero diferentes flujos pueden entregarse fuera de orden.
QUIC ofrece control de flujo tanto en la conexión como en los flujos.
Ver más detalles en las secciones conexiones y flujos
Aunque UDP no es un transporte fiable, QUIC añade una capa sobre UDP que que introduce la fiabilidad. Ofrece retransmisiones de paquetes, control de congestión control de la congestión, ritmo y otras caracterÃsticas presentes en TCP.
Los datos enviados a través de QUIC desde un end-point aparecerán en el otro extremo tarde o temprano, siempre que se mantenga la conexión.
QUIC es un protocolo de transferencia implementado sobre UDP. Si observas casualmente el tráfico de tu red, verás que QUIC aparece como paquetes UDP.
Basado en UDP también utiliza números de puerto UDP para identificar servicios de red especÃficos en una dirección IP determinada.
Todas las implementaciones conocidas de QUIC están actualmente en el espacio de usuario, lo que permite una evolución más rápida de lo que suelen permitir las implementaciones en el espacio del núcleo.
Hay empresas y otras configuraciones de red que bloquean el tráfico UDP en otros puertos que no sean el 53 (utilizado para el DNS). Otros estrangulan tales datos de manera que hace que QUIC funcione peor que los protocolos basados en TCP. No hay fin a lo que algunos operadores pueden hacer.
En un futuro previsible, todo uso de transportes basados en QUIC probablemente tendrá que ser capaz de retroceder con gracia a otra alternativa (basada en TCP). Los ingenieros de Google han mencionado anteriormente tasas de fallo medidas en porcentajes de un solo dÃgito.
Lo más probable es que si QUIC demuestra ser una valiosa adición al mundo de Internet, la gente querrá utilizarlo y querrá que funcione en sus redes y entonces las empresas podrÃan empezar a reconsiderar sus obstáculos. Durante los años en que ha progresado el desarrollo de QUIC, el Ãndice de éxito para establecer y utilizar conexiones QUIC en Internet ha aumentado.
QUIC garantiza la entrega en orden de los flujos, pero no entre flujos. Esto significa que cada flujo enviará datos y mantendrá el orden de los mismos, ¡pero cada flujo puede llegar al destino en un orden diferente al que la aplicación lo envió!
Por ejemplo: los flujos A y B son transferidos desde un servidor a un cliente. El flujo A se inicia primero y luego el flujo B. En QUIC, un paquete perdido sólo afecta al flujo al que pertenece el paquete perdido. Si el flujo A pierde un paquete pero el flujo B no, el flujo B puede continuar sus transferencias y completarlas mientras el paquete perdido del flujo A es retransmitido. Esto no era posible con HTTP/2.
Ilustrado aquà con un flujo amarillo y otro azul enviados entre dos end-points de QUIC a través de una única conexión. Son independientes y pueden llegar en un orden diferente, pero cada flujo se entrega de forma fiable a la aplicación en orden.
La seguridad de transporte utilizada en QUIC usa TLS 1.3 (RFC 8446) y nunca hay conexiones QUIC sin cifrar.
TLS 1.3 tiene varias ventajas en comparación con las versiones anteriores de TLS, pero una de las principales razones para usarlo en QUIC es que 1.3 cambió el handshake para requerir menos viajes de ida y vuelta. Esto reduce la latencia del protocolo.
La versión heredada de Google de QUIC utilizaba una criptografÃa personalizada.
QUIC ofrece configuraciones de conexión 0-RTT y 1-RTT, lo que significa que, en el mejor de los casos, QUIC no necesita ningún viaje de ida y vuelta adicional al establecer una nueva conexión. El más rápido de los dos, el handshake 0-RTT, sólo funciona si se ha establecido una conexión previa con un host y se ha almacenado en caché un secreto de esa conexión.
QUIC permite a un cliente incluir datos ya en el handshake 0-RTT. Esta caracterÃstica permite a un cliente entregar datos al peer tan rápido como sea posible, y eso entonces, por supuesto, permite al servidor responder y enviar datos de vuelta incluso antes.
El trabajo sobre el envÃo de protocolos distintos de HTTP sobre QUIC se ha pospuesto hasta después de que la versión 1 de QUIC haya sido enviada.
El protocolo IETF QUIC es un protocolo de transporte, sobre el que se pueden utilizar otros protocolos de aplicación pueden ser utilizados. El protocolo inicial de la capa de aplicación es HTTP/3 (h3).
La capa de transporte soporta conexiones y flujos.
La versión heredada de Google de QUIC tenÃa el transporte y HTTP pegados en una sola y era un protocolo enviar-tramas-http/2-sobre-udp de propósito mas espécifico.
La capa HTTP, llamada HTTP/3, realiza transportes de estilo HTTP, incluyendo la compresión de cabeceras HTTP usando QPACK - que es similar a la compresión HTTP/2 llamada HPACK.
El algoritmo HPACK depende de una entrega ordenada de flujos, por lo que no fue posible reutilizarlo para HTTP/3 sin modificaciones, ya que QUIC ofrece flujos que pueden ser entregados fuera de orden. QPACK puede verse como la versión adaptada a QUIC de HPACK.
Sin explicar los bits y bytes exactos en el cable, esta sección describe cómo funcionan los bloques fundamentales del protocolo de transporte QUIC. Si quieres implementar tu propio stack QUIC, esta descripción deberÃa darte una comprensión general, pero para todos los detalles, consulta los actuales borradores de Internet del IETF y las RFC.
Configura una conexión
... que incluya seguridad TLS
Luego utiliza flujos
Una conexión QUIC es una conversación única entre dos end-points QUIC. El establecimiento de la conexión de QUIC combina la negociación de la versión con los handshakes criptográficos y de transporte para reducir la latencia del establecimiento de la conexión.
Para enviar realmente datos a través de una conexión de este tipo, hay que crear y utilizar uno o más flujos.
Cada conexión posee un conjunto de identificadores de conexión, o IDs de conexión, cada uno de los cuales puede ser utilizado para identificar la conexión. Los IDs de conexión son seleccionados de forma independiente por los end-points; cada punto final selecciona los IDs de conexión que utiliza su compañero.
La función principal de estos IDs de conexión es asegurar que los cambios en el direccionamiento en las capas inferiores del protocolo (UDP, IP, y por debajo) no causen que los paquetes de una conexión QUIC sean entregados al end-point equivocado.
Aprovechando el ID de conexión, las conexiones pueden migrar entre direcciones IP e interfaces de red de una manera que TCP nunca podrÃa. Por ejemplo, la migración permite que una descarga en curso pase de una conexión de red celular a una conexión wifi más rápida cuando el usuario traslada su dispositivo a un lugar que ofrece wifi. Del mismo modo, la descarga puede continuar a través de la conexión celular si el wifi no está disponible.
QUIC está construido sobre UDP, por lo que se utiliza un campo de número de puerto de 16 bits para diferenciar las conexiones entrantes.
Una petición de conexión QUIC originada por un cliente le dirá al servidor qué versión del protocolo QUIC quiere hablar, y el servidor responderá con una lista de versiones soportadas para que el cliente las seleccione.
Inmediatamente después del paquete inicial que establece una conexión, el iniciador envÃa una trama criptográfica que comienza a configurar el handshake de la capa segura. La capa de seguridad capa de seguridad utiliza la seguridad TLS 1.3.
No hay forma de optar por no utilizar TLS en una conexión QUIC. El protocolo está diseñado para que sea difÃcil de manipular por las cajas intermedias, con el fin de para ayudar a prevenir la osificación del protocolo.
Los flujos en QUIC proporcionan una abstracción ligera y ordenada de flujos de bytes.
Hay dos tipos básicos de flujos en QUIC:
Los flujos unidireccionales transportan datos en una dirección: desde el iniciador del flujo a su par.
Los flujos bidireccionales permiten el envÃo de datos en ambas direcciones.
Cualquier tipo de flujo puede ser creado por cualquier end-point, puede enviar datos simultáneamente intercalados con otros flujos, y puede ser cancelado.
Para enviar datos a través de una conexión QUIC, se utilizan uno o más flujos.
Los flujos se controlan individualmente, lo que permite a un end-point limitar el compromiso de memoria y aplicar presión de retorno. La creación de flujos también está controlada por el flujo, con cada par declarando el máximo ID de flujo que está dispuesto a aceptar en un momento dado.
Los flujos se identifican mediante un número entero sin signo de 62 bits, denominado ID del flujo. Los dos bits menos significativos del ID de flujo se utilizan para identificar el tipo de flujo (unidireccional o bidireccional) y el iniciador del flujo.
El bit menos significativo (0x1) del ID de flujo identifica al iniciador del flujo. Los clientes inician los flujos pares (los que tienen el bit menos significativo en 0); los servidores inician los flujos impares (con el bit en 1).
El segundo bit menos significativo (0x2) del ID del flujo diferencia entre los flujos unidireccionales y los bidireccionales. Los flujos unidireccionales siempre tienen este bit a 1 y los bidireccionales a 0.
QUIC permite que un número arbitrario de flujos operen simultáneamente. Un end-point limita el número de flujos entrantes concurrentemente activos limitando el ID máximo del flujo.
El ID de flujo máximo es especÃfico para cada end-point y se aplica sólo al peer que recibe la configuración.
Los end-points utilizan flujos para enviar y recibir datos. Ese es, después de todo, su propósito final. Los flujos son una abstracción ordenada de flujos de bytes. Sin embargo, los flujos separados no se entregan necesariamente en el orden original.
La multiplexación de flujos tiene un efecto significativo en el rendimiento de la aplicación si los recursos asignados a los flujos se priorizan correctamente. La experiencia con otros protocolos multiplexados, como HTTP/2, muestra que las estrategias de priorización eficaces tienen un impacto positivo significativo en el rendimiento.
El propio QUIC no proporciona tramas para intercambiar información de priorización. En su lugar, depende de la recepción de información de prioridad de la aplicación que utiliza QUIC. Los protocolos que utilizan QUIC pueden definir cualquier esquema de priorización que se adapte a la semántica de su aplicación.
Se ha criticado el modelo de priorización de HTTP/2, y se teme que sea demasiado complejo y que no sea utilizado ni implementado por muchos servidores HTTP/2. Por ahora, la priorización en HTTP/3 se ha eliminado de la especificación principal de HTTP/3 y se está trabajando en ella como una [especificación separada] (https://tools.ietf.org/html/draft-ietf-httpbis-priority).
Una de las discusiones de diseño quizás más largas dentro del grupo de trabajo de QUIC que ha sido objeto de varios cientos de correos y horas de discusiones se refiere a un solo bit: el Spin Bit.
Los defensores de este bit insisten en la necesidad de que los operadores y las personas que se encuentran en la ruta entre dos puntos finales de QUIC puedan medir la latencia.
A los que se oponen a esta caracterÃstica no les gusta la posible fuga de información.
Ambos end-points, el cliente y el servidor, mantienen un valor de giro, 0 o 1, para cada conexión QUIC, y establecen el spin bit en los paquetes que envÃan para esa conexión al valor apropiado.
A continuación, ambos lados envÃan paquetes con ese bit de giro fijado al mismo valor durante el tiempo que dura un viaje de ida y vuelta y luego se alterna el valor. El efecto es entonces un pulso de unos y ceros en ese campo de bits que los observadores pueden monitorizar.
Esta medición sólo funciona cuando el emisor no está limitado por la aplicación ni por el control de flujo, y la reordenación de los paquetes en la red también puede hacer que los datos sean ruidosos.
Para reducir el tiempo necesario para establecer una nueva conexión, un cliente que se ha conectado previamente a un servidor puede almacenar en caché ciertos parámetros de esa conexión y posteriormente establecer una conexión 0-RTT con el servidor. Esto permite al cliente enviar datos inmediatamente sin esperar a que se complete el handshake.
Implementar un protocolo de transporte en el espacio de usuario ayuda a permitir una rápida iteración del protocolo, ya que es comparativamente fácil evolucionar el protocolo sin necesidad de que los clientes y servidores actualicen el núcleo de su sistema operativo para desplegar nuevas versiones.
Nada inherente a QUIC impide que sea implementado y ofrecido por los kernels de los sistemas operativos en el futuro, si a alguien le parece una buena idea.
Un efecto obvio de implementar un nuevo protocolo de transporte en el espacio de usuario es que podemos esperar ver muchas implementaciones independientes.
Es probable que diferentes aplicaciones incluyan (o se superpongan) diferentes implementaciones de HTTP/3 y QUIC en un futuro previsible.
Uno de los factores de éxito de TCP regular y de los programas que lo utilizan, es la API de sockets estandarizada. Tiene una funcionalidad bien definida y usando esta API puedes mover programas entre muchos sistemas operativos diferentes ya que TCP funciona el mismo.
QUIC no está ahÃ. No hay una API estándar para QUIC.
Con QUIC, tienes que elegir una de las implementaciones de bibliotecas existentes y y seguir su API. Esto hace que las aplicaciones estén "encerradas" en una sola biblioteca hasta una sola biblioteca. Cambiar a otra biblioteca significa otra API y eso podrÃa implicar mucho trabajo.
Además, como QUIC se implementa normalmente en el espacio de usuario, no puede fácilmente extender la API del socket o aparecer de forma similar a la funcionalidad existente de TCP y UDP. existentes. Usar QUIC significará usar otra API además de la API de sockets.
Como se ha mencionado anteriormente, el primer y principal protocolo que se transporta a través de QUIC es HTTP.
Al igual que HTTP/2 se introdujo en su dÃa para transportar HTTP por el cable de una forma completamente nueva, HTTP/3 vuelve a introducir una nueva forma de enviar HTTP por la red.
HTTP sigue manteniendo los mismos paradigmas y conceptos que antes. Hay cabeceras y un cuerpo, hay una petición y una respuesta. Hay verbos, cookies y caché. Lo que cambia principalmente con HTTP/3 es cómo se envÃan los bits al otro lado de la comunicación.
Para hacer HTTP sobre QUIC, fueron necesarios cambios y el resultado de esto es lo que ahora llamamos HTTP/3. Estos cambios fueron necesarios debido a la diferente naturaleza que QUIC proporciona en comparación con TCP. Estos cambios incluyen:
En QUIC los flujos son proporcionados por el propio transporte, mientras que en HTTP/2 los flujos se hacÃan dentro de la capa HTTP.
Debido a que los flujos son independientes unos de otros, el protocolo de compresión de cabecera utilizado para HTTP/2 no podÃa ser utilizado sin que causara una situación de cabeza de bloque.
Los flujos QUIC son ligeramente diferentes a los flujos HTTP/2. La sección de HTTP/3 lo detallará un poco.
La cabecera de servicio alternativo (Alt-svc:) y su correspondiente trama ALT-SVC
HTTP/2 no han sido creadas especÃficamente para QUIC o HTTP/3. Son parte de un mecanismo ya diseñado y creado para que un servidor le diga a un cliente: "mira, ejecuto el mismo servicio en ESTE HOST usando ESTE PROTOCOLO en ESTE PUERTO ". Vea los detalles en RFC 7838.
Un cliente que reciba tal respuesta Alt-svc es entonces aconsejado para, si lo soporta y lo desea, conectarse a ese otro host en paralelo en segundo plano - usando el protocolo especificado - y si tiene éxito cambiar sus operaciones a eso en lugar de la conexión inicial.
Si la conexión inicial utiliza HTTP/2 o incluso HTTP/1, el servidor puede responder e indicar al cliente que puede volver a conectarse e intentar HTTP/3. Puede ser al mismo host o a otro que sepa servir ese origen. La información dada en una respuesta Alt-svc de este tipo tiene un temporizador de caducidad, lo que hace que los clientes puedan dirigir las siguientes conexiones y peticiones directamente al host alternativo utilizando el protocolo alternativo sugerido, durante un determinado periodo de tiempo.
Un servidor HTTP incluye una cabecera Alt-Svc:
en su respuesta:
Esto indica que HTTP/3 está disponible en el puerto UDP 50781 en el mismo nombre de host que se utilizó para obtener esta respuesta.
Un cliente puede entonces intentar establecer una conexión QUIC con ese destino y, si tiene éxito, seguir comunicándose con el origen asà en lugar de con la versión HTTP inicial.
HTTP/3 se realizará utilizando URLs HTTPS://
. El mundo está lleno de estas URLs y se ha considerado poco práctico y francamente irrazonable introducir otro esquema de URL para el nuevo protocolo. Al igual que HTTP/2 no necesitaba un nuevo esquema, tampoco lo necesitará HTTP/3.
La complejidad añadida en la situación de HTTP/3 es, sin embargo, que mientras HTTP/2 era una forma completamente nueva de transportar HTTP a través del cable, seguÃa basándose en TLS y TCP como lo hacÃa HTTP/1. El hecho de que HTTP/3 se realice sobre QUIC cambia las cosas en algunos aspectos importantes.
Las URLs heredadas, de texto claro, HTTP://
se dejarán como están y, a medida que avancemos hacia un futuro con transferencias más seguras, probablemente se utilizarán cada vez con menos frecuencia. Las peticiones a estas URLs simplemente no se actualizarán para utilizar HTTP/3. En realidad tampoco se actualizan a HTTP/2, pero por otras razones.
La primera conexión a un host nuevo, no visitado previamente, para una URL HTTPS:// probablemente tenga que hacerse sobre TCP (posiblemente además de un intento paralelo de conexión vÃa QUIC). El host puede ser un servidor heredado sin soporte para QUIC o puede haber una caja intermedia que ponga obstáculos que impidan el éxito de una conexión QUIC.
Un cliente y un servidor modernos presumiblemente negociarÃan HTTP/2 en el primer apretón de manos. Cuando la conexión se haya establecido y el servidor responda a una petición HTTP del cliente, el servidor puede informar al cliente sobre su soporte y preferencia por HTTP/3.
Como se ha mencionado anteriormente, la priorización entre flujos se ha eliminado de la especificación principal de HTTP/3 para trabajar en ella por separado.
Esto se debe a lo aprendido del modelo de priorización de HTTP/2 y su implementación (o falta de ella) en el mundo real.
Se ha propuesto un [modelo de priorización más sencillo que el de HTTP/2] (https://tools.ietf.org/html/draft-ietf-httpbis-priority) que utiliza campos de cabecera HTTP con un número limitado de ajustes de prioridad. Se trata de un cambio clave con respecto a los indicadores de dependencia y peso en los marcos de cabecera de HTTP/2 y permite una mejor comprensión en la capa de aplicación.
La repriorización, y la posibilidad de apoyarla, todavÃa se está debatiendo. HTTP/2 tenÃa marcos de priorización para manejar esto, pero los verdaderos flujos independientes en QUIC y HTTP/3 hacen que esto sea más complicado, por lo que todavÃa se están debatiendo los beneficios frente a la complejidad.
Cuando se acuerde (¡o si se acuerda!) un mejor modelo de priorización para HTTP/3, se espera poder trasladarlo también a HTTP/2, para resolver la complejidad y los problemas de implementación.
HTTP/3 está hecho para QUIC, por lo que aprovecha al máximo los flujos de QUIC, mientras que HTTP/2 tuvo que diseñar su propio concepto de flujo y multiplexación sobre TCP.
Las peticiones HTTP realizadas sobre HTTP/3 utilizan un conjunto especÃfico de flujos.
HTTP/3 implica la creación de flujos QUIC y el envÃo de un conjunto de tramas al otro extremo. Sólo hay un pequeño número fijo (¡en realidad nueve al 18 de diciembre de 2018!) de tramas conocidas en HTTP/3. Las más importantes son probablemente
HEADERS, que envÃa cabeceras HTTP comprimidas
DATA, envÃa contenidos de datos binarios
GOAWAY, que cierra esta conexión
El cliente envÃa su petición HTTP en un flujo QUIC bidireccional iniciado por el cliente.
Una petición consiste en una única trama HEADERS y, opcionalmente, puede ir seguida de una o dos tramas más: una serie de tramas DATA y posiblemente una última trama HEADERS para los trailers.
Después de enviar una petición, un cliente cierra el flujo para su envÃo.
El servidor devuelve su respuesta HTTP en el flujo bidireccional. Una trama HEADERS, una serie de tramas DATA y posiblemente una trama HEADERS final.
Las tramas HEADERS contienen cabeceras HTTP comprimidas mediante el algoritmo QPACK. QPACK es similar en estilo a la compresión HTTP/2 llamada HPACK ( RFC 7541), pero modificada para trabajar con flujos entregados fuera de orden.
QPACK utiliza dos flujos QUIC unidireccionales adicionales entre los dos puntos finales. Se utilizan para transportar información de la tabla dinámica en cualquier dirección.
HTTP/3 server push es similar a lo descrito en HTTP/2 ([RFC 7540] (https://httpwg.org/specs/rfc7540.html)), pero utiliza mecanismos diferentes.
Un push de servidor es efectivamente la respuesta a una petición que el cliente nunca envió.
Los push del servidor sólo se permiten si la parte del cliente los ha aceptado. En HTTP/3 el cliente incluso establece un lÃmite para el número de pushes que acepta, informando al servidor de cuál es el ID máximo del flujo de push. Sobrepasar ese lÃmite provocará un error de conexión.
Si el servidor considera probable que el cliente quiera un recurso extra que no ha pedido pero que deberÃa tener de todas formas, puede enviar una trama PUSH_PROMISE
(sobre el flujo de petición) mostrando cómo es la petición a la que el push es una respuesta, y luego enviar esa respuesta real sobre un nuevo flujo.
Aunque el cliente haya dicho que los envÃos son aceptables de antemano, cada flujo individual enviado puede ser cancelado en cualquier momento si el cliente lo considera conveniente. Entonces envÃa una trama CANCEL_PUSH
al servidor.
Desde que esta caracterÃstica se discutió por primera vez en el desarrollo de HTTP/2 y más tarde después de que el protocolo se enviara y se desplegara en Internet, esta caracterÃstica se ha discutido, no ha gustado y se ha machacado de innumerables maneras diferentes con el fin de conseguir que sea útil.
El push nunca es "gratuito", ya que, aunque ahorra medio viaje de ida y vuelta, sigue utilizando ancho de banda. A menudo es difÃcil o imposible para el servidor saber con un alto nivel de certeza si un recurso debe ser enviado por push o no.
HTTP/3 está diseñado para QUIC, que es un protocolo de transporte que maneja flujos por sà mismo.
HTTP/2 está diseñado para TCP, y por lo tanto maneja flujos en la capa HTTP.
Los dos protocolos ofrecen a los clientes conjuntos de caracterÃsticas prácticamente idénticos.
Ambos protocolos ofrecen soporte para el push del servidor
Ambos protocolos tienen compresión de cabecera, y QPACK y HPACK tienen un diseño similar.
Ambos protocolos ofrecen multiplexación a través de una única conexión utilizando streams
Las diferencias están en los detalles y principalmente están ahà gracias al uso de QUIC por parte de HTTP/3:
HTTP/3 tiene un mejor y más probable soporte de datos tempranos gracias a los handshakes 0-RTT de QUIC, mientras que TCP Fast Open y TLS suelen enviar menos datos y a menudo tienen problemas.
HTTP/3 tiene handshakes mucho más rápidos gracias a QUIC frente a TCP + TLS.
HTTP/3 no existe en una versión insegura o sin cifrar. HTTP/2 puede ser implementado y utilizado sin HTTPS - aunque esto es raro en Internet.
HTTP/2 puede ser negociado directamente en un handshake TLS con la extensión ALPN, mientras que HTTP/3 es sobre QUIC por lo que necesita una respuesta de cabecera Alt-Svc:
primero para informar al cliente sobre este hecho.
HTTP/3 no tiene priorización. El enfoque de HTTP/2 para la priorización se ha considerado demasiado complicado, o incluso un fracaso, y se está trabajando en la creación de una toma más simple. Este esquema más simple planeado también está planeado para poder ser retroportado para correr sobre HTTP/2 usando el mecanismo de extensión de HTTP/2.
Aquà hay una colección de los últimos borradores oficiales para las distintas partes y componentes de QUIC y HTTP/3.
Propiedades independientes de la versión de QUIC
QUIC: A UDP-Based Multiplexed and Secure Transport
Detección de Pérdidas y Control de Congestión de QUIC
Protocolo de Transferencia de Hipertexto Versión 3 (HTTP/3)
Muchas empresas, operadores y organizaciones bloquean o limitan el tráfico UDP fuera del puerto 53 (utilizado para DNS) ya que en los últimos dÃas se ha abusado de él para realizar ataques. En particular, algunos de los protocolos UDP existentes y las implementaciones de servidores populares para ellos han sido vulnerables a los ataques de amplificación en los que un atacante puede hacer una gran cantidad de tráfico saliente para atacar a vÃctimas inocentes.
QUIC tiene una mitigación incorporada contra los ataques de amplificación al requerir que el paquete inicial sea de al menos 1200 bytes y mediante una restricción en el protocolo que dice que un servidor no debe enviar más de tres veces el tamaño de la solicitud en respuesta sin recibir un paquete del cliente en respuesta.
Esto parece ser la verdad, al menos inicialmente. Por supuesto, no podemos saber cómo evolucionará esto y cuánto de esto es simplemente el resultado de que el rendimiento de la transferencia UDP no ha estado en el foco de los desarrolladores durante muchos años.
Para la mayorÃa de los clientes, es probable que esta "lentitud" ni siquiera se note.
Al igual que la observación anterior de que "UDP es lento", esto se debe en parte a que el uso de TCP y TLS en el mundo ha tenido más tiempo para madurar, mejorar y obtener asistencia de hardware.
Hay razones para esperar que esto mejore con el tiempo, y ya [estamos viendo algunas mejoras en este espacio] (https://www.fastly.com/blog/measuring-quic-vs-tcp-computational-efficiency). La cuestión es hasta qué punto este uso adicional de la CPU perjudicará a los implantadores.
No, no lo es. Google llevó la especificación inicial al IETF después de haber demostrado, a gran escala en Internet, que el despliegue de este estilo de protocolo sobre UDP realmente funciona y tiene un buen rendimiento.
Desde entonces, personas de un gran número de empresas y organizaciones han trabajado en la organización neutral de proveedores IETF para elaborar un protocolo de transporte estándar a partir de él. En ese trabajo, los empleados de Google han participado, por supuesto, pero también lo han hecho los empleados de un gran número de otras empresas que están interesadas en promover el estado de los protocolos de transporte en Internet, como Mozilla, Fastly, Cloudflare, Akamai, Microsoft, Facebook y Apple.
Esto no es realmente una crÃtica, sino una opinión. Tal vez lo sea, y tal vez sea una mejora demasiado pequeña desde que se lanzó HTTP/2.
Es probable que HTTP/3 funcione mucho mejor en redes con pérdida de paquetes, ofrece handshakes más rápidos, por lo que mejorará la latencia tanto percibida como real. Pero, ¿es esto suficiente para motivar a la gente a desplegar el soporte de HTTP/3 en sus servidores y servicios? El tiempo y las futuras mediciones de rendimiento seguramente lo dirán.
Con el fin de conseguir el mayor enfoque posible en el núcleo del protocolo QUIC y ser capaz de enviarlo a tiempo, varias caracterÃsticas que fueron originalmente planificadas para ser parte del núcleo del protocolo se han pospuesto y ahora están previstas para ser realizadas en una versión posterior de QUIC. QUIC versión 2 o posterior.
Sin embargo, el autor de este documento tiene una bola de cristal bastante defectuosa, por lo que no podemos decir con seguridad qué caracterÃsticas aparecerán o no en la versión 2. Sin embargo, podemos mencionar algunas de las caracterÃsticas y cosas que explÃcitamente han sido eliminadas del trabajo de la v1 para ser "trabajadas más tarde" y que entonces posiblemente podrÃan aparecer en una versión 2.
La corrección de errores hacia adelante (FEC) es un método para obtener el control de errores en la transmisión de datos en el que el transmisor envÃa datos redundantes y el receptor reconoce sólo la parte de los datos que no contiene errores aparentes.
Google experimentó con esto en su trabajo original de QUIC, pero posteriormente se eliminó de nuevo ya que los experimentos no salieron bien. Esta caracterÃstica es objeto de discusión para QUIC v2 pero probablemente se necesita que alguien demuestre que realmente puede ser una adición útil sin demasiada penalización.
Multipath significa que el transporte puede por sà mismo utilizar múltiples rutas de red para maximizar el uso de recursos y aumentar la redundancia.
A los defensores de SCTP del mundo les gusta mencionar que SCTP ya cuenta con multipath y también lo hace el TCP moderno.
Se ha discutido la posibilidad de ofrecer flujos "no fiables" como opción, lo que permitirÃa a QUIC sustituir también a las aplicaciones de tipo UDP.
DNS sobre QUIC fue uno de los primeros protocolos no-HTTP mencionados que podrÃa recibir algo de atención una vez que QUIC v1 y HTTP/3 sean lanzados. Pero con un nuevo transporte como este que se ha traÃdo al mundo no puedo imaginar que se detenga ahÃ.
QUIC ist ein Name, kein Akronym. Es wird genauso wie das englische Wort "quick" ausgesprochen.
Aus vielen verschiedenen Blickwinkeln kann QUIC als Lösung verstanden werden, wie ein neues, zuverlässiges und sicheres Transportprotokoll umgesetzt wird, das für ein Protokoll wie HTTP adäquat ist und die durch die Umsetzung von HTTP/2 über TCP und TLS entstandenen Mängel behebt. Der logische nächste Schritt in der Web-Transport Evolution.
QUIC ist nicht nur auf den Transport von HTTP limitiert. Der Wunsch nach einer schnelleren Auslieferung von Daten zum Endnutzer über das Web ist wahrscheinlich der größte Grund, der die Erschaffung dieses neuen Transportprotokolls angestoßen hat.
Warum also ein neues Transportprotokoll erschaffen und warum aufbauend auf UDP?
Die HTTP/2 Spezifikation RFC 7540 wurde im Mai 2015 veröffentlicht und seitdem flächendeckend im Internet und World Wide Web implementiert sowie ausgeliefert.
Anfang 2018 wurden fast 40% der Top 1000 Websites mit HTTP/2 ausgeliefert. Ungefähr 70% aller HTTPS Anfragen, die über Firefox verschickt wurden, bekamen eine HTTP/2 Antwort zurück. Die meistgenutzten Browser, Server und Proxies unterstützen die Spezifikation.
HTTP/2 behebt eine Fülle an Mängel von HTTP/1, weshalb HTTP-Nutzer nicht mehr zu Übergangslösungen greifen müssen - welche gerade Web Entwickler oft belastet haben.
Eines der Hauptmerkmale von HTTP/2 ist Multiplexing, die Möglichkeit viele logische Streams über die gleiche physische TCP Verbindung zu schicken. Das macht viele Dinge besser und schneller; es verbessert die Überlastungskontrolle wesentlich, es lässt User TCP besser nutzen um die Bandbreite besser auszunutzen, die TCP Verbindungen sind langlebiger - was gut ist, weil Verbindungen öfter die volle Geschwindigkeit aufbauen können. Header-Komprimierung nutzt dabei weniger Bandbreite.
Mit HTTP/2 nutzen Browser typischerweise eine TCP Verbindung zu jedem Host, anstatt der vorherigen sechs. Tatsächlich verringert sich die Anzahl der Verbindungen wegen der Verbindungsvereinigung und "Desharding" Techniken von HTTP/2 noch viel wesentlicher.
HTTP/2 löst das Problem des sogenannten HTTP Head-of-line blockings, bei dem Clients so lange warten müssen, bis eine gestellte Anfrage fertig ist, bevor die nächste gestellt werden kann.
Die Arbeit an diesem Buch wurde im März 2018 gestartet. Es dient der Dokumentation von HTTP/3 und dessen zugrundeliegendem Protokoll: QUIC. Warum, wie sie funktionieren, Protokolldetails, die Implementierung und mehr.
Dieses Buch ist zur Gänze frei zugänglich und wird als kollaborative Angstrengung von jedem getragen, der aushelfen will.
Einer Leserin oder Leser wird ein Grundverständnis von TCP/IP, den Grundlagen von HTTP und dem Web vorausgesetzt. Für weitere Einblicke und Details über HTTP/2 empfehlen wir: http2 explained.
Dieses Buch wurde geschrieben von Daniel Stenberg. Daniel ist der Gründer und Lead Developer von curl, der meistgenutzten HTTP Client Software der Welt. Daniel hat über zwei Jahrzehnte lang mit und an HTTP sowie Internetprotokollen gearbeitet und ist der Autor von http2 explained.
Die Website von diesem Buch kann hier gefunden werden: daniel.haxx.se/http3-explained.
Solltest du Irrtümer, fehlende Details, Fehler oder offensichtliche Lügen in diesem Dokument finden, dann sende uns bitte eine ausgebesserte Version des betroffenen Paragrafen und wir werden diese als neue Version veröffentlichen. Natürlich führen wir alle an, die aushelfen. Ich hoffe, dass wir das Dokument im Laufe der Zeit verbessern können.
Fehler sollten als Issues oder als Pull Requests auf der GitHub Seite des Buches übermittelt werden.
Dieses Buch und alle darin enthaltenen Inhalte sind als Creative Commons Attribution 4.0 license lizenziert.
QUIC ist immer sicher. Es gibt keine Klartext-Version des Protokolls, daher involviert der Verbindungsaufbau einer QUIC Verbindung Kryptographie und Sicherheit mit TLS 1.3. Wie vorhergehend angemerkt, verhindert dies eine Ossifikation sowie andere Blockierungen und spezielle Handhabung - und sorgt dafür, dass QUIC alle sicheren Eigenschaften von HTTPS hat, die User des Webs erwarten und sich wünschen.
Es gibt nur wenige initiale Handshake-Pakete, die im Klaren geschickt werden, bevor die Verschlüsselungsprotokolle verhandelt wurden.
Wenn wir Head-of-line blocking innerhalb von TCP nicht reparieren können, dann sollten wir theoretisch ein neues Transportprotokoll neben UDP und TCP im Netzwerkstack erstellen können. Oder vielleicht sogar SCTP nutzen; ein Transportprotokoll mit etlichen der von uns gewünschten Charakteristiken, welches von IETF in RFC 4960 standardisiert wurde.
Jedoch ist die Entwicklung von neuen Transportprotokollen in den letzten Jahren nahezu vollständig eingestellt worden, weil diese nur unter schwierigen Umständen im Internet eingesetzt werden können. Der Einsatz neuer Protokolle wird durch viele Firewalls, NATs, Router und andere Netzwerk-Appliances verhindert, welche lediglich TCP oder UDP in der Kommunikation zwischen User und Server zulassen. Ein weiteres Transportprotokoll einzuführen hat die Auswirkung, dass N% der Verbindungen fehlschlagen, weil diese durch Appliances geblockt werden, welche die Verbindungen wegen der Nutzung eines anderen Protokolls als UDP oder TCP als böswillig einstufen. Die N% Fehlerrate wird oft als zu hoch erachtet, um den Aufwand zu rechtfertigen.
Werden Änderungen auf der Ebene des Transportprotokolls im Netzwerkstack vorgenommen, bedeutet das, dass Protokolle über den Kernel des Betriebssystems implementiert werden. Kernel des Betriebssystems zu aktualisieren und auszuliefern ist ein langsamer Prozess, der signifikanten Aufwand mit sich bringt. Viele Verbesserungen von TCP, welche durch IETF standardisiert wurden, sind nicht flächendeckend eingesetzt, weil sie nicht umfassend unterstützt werden.
SCTP ist ein zuverlässiges Transportprotokoll mit Streams. Für WebRTC gibt es sogar existierende Implementierungen von SCTP über UDP.
Aus folgenden Gründen wurde SCTP-over-UDP als nicht gut genug befunden, um QUIC zu ersetzen:
SCTP löst das Head-of-line-blocking Problem für Streams nicht
SCTP hat keine solide TLS/Security Geschichte
SCTP hat einen 4-way handshake, QUIC bietet 0-RTT
QUIC ist ein Bytestream wie TCP, SCTP basiert auf Nachrichten
QUIC Verbindungen können zwischen IP Adressen migrieren, was SCTP nicht kann
Für weitere Details zu den Unterschieden empfiehlt sich folgende Übersicht: A Comparison between SCTP and QUIC.
Das Internet ist ein Netzwerk der Netzwerke. Um sicherzustellen, dass dieses Netzwerk der Netzwerke so funktioniert, wie es soll, gibt es Infrastruktur an vielen verschiedenen Plätzen. Diese Geräte - jene Boxen, die über das Netzwerk verteilt sind - bezeichnen wir manchmal als "Middle-Boxes". Boxen, die irgendwo zwischen den beiden Endpunkten sitzen und die primären Beteiligten in einem traditionellen Netzwerk-Datentransfer sind.
Diese Boxen dienen vielen verschiedenen spezifischen Zwecken - aber ich glaube sagen zu können, dass sie dort genutzt werden, weil jemand glaubt, dass diese dort sein müssen, damit alles funktioniert.
Middle-Boxes leiten IP-Pakete zwischen Netzwerken, sie blockieren böswilligen Traffic, führen die NAT (Network Address Translation, zu Deutsch "Netzwerkadressübersetzung") durch, verbessern die Leistung, manche versuchen den Traffic auszuspionieren und vieles mehr.
Um ihren Pflichten gerecht zu werden, müssen diese Boxen Networking und jene Protokolle kennen, die sie überwachen oder modifizieren. Dazu nutzen sie Software - die aber nicht oft aufgerüstet wird.
Auch wenn sie wie Klebstoff das Internet zusammenhalten, halten sie oft nicht mit der neuesten Technologie mit. Die Mitte eines Netzwerks verändert sich nicht so schnell wie die Enden, wie die Clients und Server dieser Welt.
Die Netzwerkprotokolle, die diese Boxen inspizieren wollen und kennen, haben dann folgendes Problem: die Boxen wurden vor einiger Zeit ausgeliefert, als die Protokolle gewisse Features hatten. Neue Features oder Veränderungen in der Verhaltensweise riskieren, dass Boxen diese als schlecht oder illegal interpretieren. Solcher Traffic könnte fallen gelassen oder verzögert werden - bis hin zu einem Ausmaß, dass User diese Features nicht nutzen wollen.
Das wird "Protokoll-Ossifikation" genannt.
Änderung an TCP leiden auch an Ossifikation: einige Boxen zwischen einem Client und einem entfernten Server erkennen neue TCP Optionen und blockieren solche Verbindungen, weil diese die Optionen nicht kennen. Wenn sie Protokolldetails erkennen dürfen, werden Systeme lernen, wie sich Protokolle normalerweise verhalten und im Laufe der Zeit wird es unmöglich sie zu ändern.
Der einzig effektive Weg um Ossifikation zu bekämpfen, ist die Verschlüsselung von so viel Kommunikation wie möglich. Damit werden Middle-Boxes daran gehindert, von durchgeleiteten Protokollen viel einsehen zu können.
QUIC bietet 0-RTT und 1-RTT Handshakes, welche die Zeit des Verhandelns sowie den Aufbau einer neuen Verbindung verkürzen. Vergleiche diesen Prozess mit dem 3-Schritt Handshake von TCP.
Zusätzlich bietet QUIC "Daten im Voraus" Support, welcher größeren Datenfluss erlaubt und im Vergleich zu TCP Fast Open benutzerfreundlicher ist.
Mit dem Stream-Konzept kann sofort eine weitere logische Verbindung zum gleichen Host aufgebaut werden, ohne auf das Ende einer bereits bestehenden Verbindung warten zu müssen.
TCP Fast Open wurde als RFC 7413 im Dezember 2014 veröffentlicht. Diese Spezifikation beschreibt, wie Applikationen Daten zum Server bereits im ersten TCP SYN Paket übermitteln können.
Der tatsächliche Support für dieses Feature hat lange gedauert und ist bis ins heutige Jahr 2018 mit Problemen gespickt. Diejenigen, die den TCP-Stack implementiert haben, hatten Probleme und somit auch Applikationen, die die Vorteile dieses Features nutzen wollten. Dies gilt sowohl für das Verständnis der zu aktivierenden Betriebssystemversionen als auch für das Lösen von Problemen im Zusammenhang mit der mangelnden Clientseitigen Unterstützung (backdown). Viele Netzwerke konnten identifiziert werden, die TFO-Traffic stören und daher den reibungslosen Ablauf von TCP-Handshakes beeinträchtigen.
Das ursprüngliche QUIC Protokoll wurde von Jim Roskind bei Google entworfen, im Jahr 2012 erstmals implementiert und der Welt 2013 vorgestellt, als Googles Experiment erweitert wurde.
Damals galt QUIC noch als Akronym für "Quick UDP Internet Connections", aber das wurde seitdem eingestellt.
Google implementierte das Protokoll und nutzte es anschließend sowohl in seinem weit verbreiteten Browser (Chrome) als auch in seinen weit verbreiteten serverseitigen Diensten (Google-Suche, Gmail, YouTube und mehr). Sie haben ziemlich schnell zwischen Protokollversionen iteriert und im Laufe der Zeit bewiesen, dass das Konzept für einen großen Teil der Nutzer zuverlässig funktioniert.
Im Juni 2015 wurde der erste Internetentwurf von QUIC zur Standardisierung an die IETF übermittelt. Es dauerte jedoch bis Ende 2016, bis eine QUIC-Arbeitsgruppe genehmigt und gestartet wurde. Aber dann ist es mit großem Interesse von vielen Parteien sofort losgegangen.
Im Jahr 2017 gaben die QUIC-Ingenieuren bei Google an, dass rund 7% des gesamten Internetverkehrs bereits das Protokoll verwenden. Die Google-Version des Protokolls.
HTTP/2 nutzt TCP, wenngleich es im Gegensatz zu früheren HTTP Versionen weniger TCP Verbindungen benötigt. TCP ist ein Protokoll für eine zuverlässige Übertragung und kann als imaginäre Kette zwischen zwei Computern gesehen werden. Was vom ersten Computer über das Netzwerk übermittelt wird, wird schließlich beim zweiten Computer in der gleichen Reihenfolge ankommen (oder die Verbindung ist unterbrochen).
Mit HTTP/2 machen Browser zehn oder hunderte Übertragungen gleichzeitig über eine einzige TCP Verbindung.
Wenn ein einziges Paket fallen gelassen wird oder im Netzwerk irgendwo zwischen den beiden Endpunkten - welche über HTTP/2 kommunizieren - verloren geht, dann wird die gesamte TCP Verbindung solange gestoppt, bis das verlorene Paket wieder übertragen wurde und ihren Weg zum Ziel gefunden hat. Weil TCP diese "Kette" darstellt, muss alles - sollte eine Verbindung plötzlich fehlen - was nach der verlorenen Verbindung kommen würde, warten.
Eine Illustration der Ketten-Metapher, wenn zwei Streams über diese Verbindung versendet werden. Ein roter und ein grüner Stream:
Es resultiert ein TCP basierender Head-of-line block!
Steigt die Verlustrate von Paketen, liefert HTTP/2 eine immer schlechtere Performance. Bei einer 2%-igen Verlustrate (was wohlgemerkt eine schlechte Netzwerkqualität ist) haben Tests gezeigt, dass HTTP/1 User normalerweise besser aussteigen - weil diese bis zu sechs TCP-Verbindungen haben, auf welche verlorene Pakete aufgeteilt werden können. Das bedeutet, dass für jedes verlorene Paket eine andere Verbindung weiterarbeiten kann.
Dieses Problem zu beheben ist nicht einfach - wenn überhaupt mit TCP möglich.
Mit QUIC gibt es noch immer einen Verbindungsaufbau zwischen den beiden Endpunkten, welcher die Verbindung sicher und den Datentransport zuverlässig macht.
Wenn zwei unterschiedliche Streams über diese Verbindung aufgebaut werden, werden diese unabhängig voneinander behandelt, sodass - sollte eine Verbindung für einen der Streams verloren gehen - nur der eine Stream, diese eine Kette pausieren und darauf warten muss, dass die fehlende Verbindung wieder versendet wird.
Hier wird dies mit einem gelben und einem blauen Stream illustriert, die zwischen zwei Endpunkten versendet werden.
Die zur Standardisierung des Protokolls innerhalb der IETF eingerichteten QUIC-Arbeitsgruppe entschied bald, dass das QUIC-Protokoll auch andere Protokolle als "nur" HTTP übertragen können soll. Google-QUIC hatte lediglich HTTP transportiert - in der Praxis wurden HTTP/2 Frames mithilfe des HTTP/2 Frame Syntax transportiert.
Es wurde auch angegeben, dass IETF-QUIC seine Verschlüsselung und Sicherheit auf TLS 1.3 anstelle des für Google-QUIC eigens entwickelten Ansatzes stützen sollte.
Um die Anforderung zu erfüllen, mehr als nur HTTP zu transportieren, wurde die IETF-QUIC-Protokollarchitektur in zwei separate Schichten aufgeteilt: die Transport-QUIC-Schicht und die "HTTP-over-QUIC"-Schicht (letztere wird manchmal als "hq" bezeichnet).
Diese Teilung in Schichten - auch wenn sie harmlos klingt - hat dazu geführt, dass sich IETF-QUIC erheblich vom ursprünglichen Google-QUIC unterscheidet.
Die Arbeitsgruppe hat jedoch bald entschieden, dass sie sich auf die Bereitstellung von HTTP konzentriert, um eine rechtzeitige Auslieferung der ersten QUIC Version gewährleisten zu können. Damit wurde die Implementierung des Nicht-HTTP-Transports auf später verschoben.
Als wir im März 2018 mit der Arbeit an diesem Buch begonnen haben, war geplant, die endgültige Spezifikation für die erste QUIC Version im November 2018 auszuliefern. Dies wurde später auf Juli 2019 verschoben.
Während die Arbeit an IETF-QUIC vorangeschritten ist, hat das Google-Team Details aus der IETF-Version übernommen und langsam damit begonnen, ihre Version des Protokolls dahingehend weiterzuentwickeln, dass diese wie die IETF-Version aussieht. Google hat die eigene QUIC-Version weiterhin in ihrem Browser und ihren Diensten im Einsatz.
[Die meisten neuen Implementierungen, die sich aktuell in Entwicklung befinden,] (https://github.com/quicwg/base-drafts/wiki/Implementations) haben beschlossen, sich auf die IETF-Version zu konzentrieren und sind nicht mit der Google-Version kompatibel.
Die HTTP/2 Spezifikation RFC 7540 wurde im Mai 2015 veröffentlicht, nur einen Monat bevor QUIC zum ersten Mal bei der IETF eingebracht wurde.
Mit HTTP/2 wurde die Grundlage für zukünftige Änderungen von HTTP gelegt. Die Arbeitsgruppe, die HTTP/2 kreiert hatte, war der Ansicht, dass diese Grundlage Iterationen zu neuen HTTP Versionen beschleunigen wird - viel schneller als der Wechsel von Version 1 zu Version 2 (ca. 16 Jahre).
Mit HTTP/2 haben Nutzer und Software-Stacks erkannt, dass es nicht mehr zeitgemäß ist, HTTP mit einem textbasierten Protokoll seriell abzuwickeln.
HTTP-over-QUIC wurde im November 2018 in HTTP/3 umbenannt.
QUIC ist ein Transportprotokoll, das basierend auf UDP implementiert wurde. Wenn Sie Ihren Netzwerkverkehr gelegentlich beobachten, wird QUIC als UDP-Pakete angezeigt.
Basierend auf UDP werden dann auch UDP-Portnummern verwendet, um bestimmte Netzwerkdienste unter einer bestimmten IP-Adresse zu identifizieren.
Alle bekannten QUIC-Implementierungen befinden sich derzeit im User-Space, was eine schnellere Entwicklung ermöglicht, als dies bei Kernel-Space-Implementierungen normalerweise möglich ist.
Es gibt Unternehmen und andere Netzwerkkonfigurationen, die den UDP-Verkehr an anderen Ports als 53 blockieren (für DNS verwendet). Andere drosseln solche Daten auf eine Weise, die die Leistung von QUIC schlechter macht als jene von TCP-basierten Protokollen. Es gibt kein Ende für das, was manche Betreiber tun könnten.
Auf absehbare Zeit muss jeder Einsatz von QUIC-basierten Transporten möglicherweise auf eine andere (TCP-basierte) Alternative zurückgreifen können. Google-Ingenieure haben zuvor gemessene Fehlerraten im niedrigen einstelligen Prozentbereich angegeben.
Wenn sich QUIC als eine wertvolle Bereicherung für das Internet herausstellt, möchten Leute es nutzen und das es in ihren Netzwerken funktioniert - dann können Unternehmen damit beginnen, ihre Hindernisse zu überdenken. Im Laufe der Jahre hat die Entwicklung von QUIC Fortschritte gemacht und die Erfolgsquote beim Aufbau sowie Nutzung von QUIC-Verbindungen über das Internet ist gestiegen.
Ähnlich wie SCTP, SSH und HTTP/2 verfügt QUIC über separate logische Streams innerhalb von physischen Verbindungen. Eine Anzahl paralleler Streams, die Daten gleichzeitig über eine einzelne Verbindung übertragen können, ohne die anderen Streams zu beeinträchtigen.
Eine Verbindung ist ein ausgehandelter Aufbau zwischen zwei Endpunkten, die ähnlich wie eine TCP-Verbindung funktioniert. Eine QUIC-Verbindung wird zu einem UDP-Port und einer IP-Adresse hergestellt, aber sobald die Verbindung hergestellt ist, wird sie durch ihre "Verbindungs-ID" verknüpft.
Über eine bestehende Verbindung kann jede Seite Streams erstellen und Daten an das andere Ende senden. Streams werden in richtiger Reihenfolge (in-order) und zuverlässig geliefert - andere Streams können aber in nicht richtiger Reihenfolge (out-of-order) geliefert werden.
QUIC bietet eine Datenflusssteuerung sowohl für Verbindungen als auch für Streams.
Weitere Details findest du in den Bereichen Verbindungen und Streams.
Das QUIC-Protokoll aus der Ferne betrachtet.
Folgend ist der HTTP/2-Netzwerkstack links und der QUIC-Netzwerkstack rechts dargestellt, wenn als HTTP-Transport verwendet.
Die QUIC-Arbeitsgruppe hat seit Ende 2016 intensiv an der Festlegung der Protokolle gearbeitet. Es ist geplant, die Spezifikation bis Juli 2019 zu finalisieren.
Bis November 2018 gab es noch keine größeren Interoperabilitätstests mit HTTP/3 - nur mit den beiden vorhandenen Implementierungen, nicht aber mit einem Browser oder einer beliebten Open-Server Lösungen.
In den Wiki-Seiten der QUIC-Arbeitsgruppe werden rund fünfzehn verschiedene QUIC Implementierungen aufgelistet - jedoch sind bei weitem nicht alle dieser Implementierungen mit den letzten Änderungen der Entwurfsspezifikation kompatibel.
QUIC zu implementieren ist nicht einfach. Das Protokoll hat sich bis zu diesem Zeitpunkt ständig weiterentwickelt und verändert.
Es wurden keine öffentlichen Erklärungen hinsichtlich der Unterstützung von QUIC durch Apache oder Nginx abgegeben.
Keiner der größeren Browser-Anbieter hat bisher eine Version ausgeliefert, mit der die IETF-Version von QUIC oder HTTP/3 ausgeführt werden kann.
Google Chrome wird seit vielen Jahren mit einer funktionsfähigen Implementierung von Googles eigener QUIC-Version ausgeliefert, die jedoch nicht mit dem IETF-QUIC-Protokoll kompatibel ist und deren HTTP-Implementierung sich von HTTP/3 unterscheidet.
QUIC hat sich dazu entschlossen, auf TLS 1.3 als Grundlage der Krypto- und Sicherheitsebene zu setzen, um sich auf ein zuverlässiges und bestehendes Protokoll stützen zu können. Jedoch hat sich die Arbeitsgruppe auch dazu entschieden, TLS in QUIC wirkungsvoller zu gestalten: es sollen lediglich "TLS messages" und nicht "TLS records" genutzt werden.
Dies mag nach einer harmlosen Änderung klingen, hat jedoch für viele QUIC-Stack-Implementierer eine erhebliche Hürde bedeutet. Bestehende TLS-Bibliotheken, die TLS 1.3 unterstützen, verfügen einfach nicht über ausreichende APIs, um diese Funktionalität verfügbar zu machen und QUIC den Zugriff darauf zu ermöglichen. Während mehrere QUIC-Implementierer von größeren Organisationen stammen, die parallel an ihrem eigenen TLS-Stack arbeiten, gilt dies nicht für alle.
Das dominierende Open-Source-Schwergewicht OpenSSL zum Beispiel, hat keine API dafür - und hat bisher auch keinen Wunsch geäußert, eine solche bald zur Verfügung zu stellen (Stand November 2018).
Dies wird letztendlich auch zu Hindernissen bei der Bereitstellung führen, da sich QUIC-Stacks entweder auf andere TLS-Bibliotheken stützen müssen, einen separat gepatchten OpenSSL-Build verwenden müssen oder ein Update auf eine zukünftige OpenSSL-Version benötigen.
Sowohl Google als auch Facebook haben angemerkt, dass die Bereitstellung von QUIC in großem Umfang ungefähr die doppelte Menge an CPU-Rechenleistung erfordert als wenn die gleiche Traffic-Last via HTTP/2 über TLS abgewickelt würde.
Einige Erklärungen hierfür sind:
Teile von UDP sind vor allem unter Linux nicht so optimiert wie der TCP-Stack, da UDP traditionell nicht für solche Hochgeschwindigkeitsübertragungen verwendet wurde.
TCP- und TLS-Offloading auf Hardware ist vorhanden, bei UDP jedoch viel seltener und bei QUIC im Grunde nicht vorhanden.
Daher gibt es Gründe zur Annahme, dass sich die Leistung und die CPU-Anforderungen im Laufe der Zeit verbessern werden.
Während UDP kein zuverlässiger Transport ist, fügt QUIC über UDP eine Schicht hinzu, die Zuverlässigkeit einführt. Es bietet Neuübertragungen von Paketen, Überlastungskontrolle, Pacing und andere Funktionen, die sonst in TCP vorhanden sind.
Daten, die von einem Endpunkt über QUIC gesendet werden, erscheinen früher oder später am anderen Ende - solange die Verbindung besteht.
QUIC garantiert die richtige Reihenfolge (in-order) der Zustellung von Streams, jedoch nicht zwischen Streams. Dies bedeutet, dass jeder Stream Daten sendet und die Datenreihenfolge beibehält, aber die Streams das Ziel möglicherweise in einer anderen Reihenfolge erreichen, als wie die Anwendung diese gesendet hat.
Beispiel: Stream A und B werden von einem Server zu einem Client übertragen. Zuerst wird Stream A und dann Stream B gestartet. In QUIC wirkt sich ein verlorenes Paket nur auf jenen Stream aus, zu dem das verlorene Paket gehört. Wenn Stream A ein Paket verliert, Stream B jedoch nicht, setzt Stream B die Übertragung möglicherweise fort und wird abgeschlossen, während das verlorene Paket von Stream A erneut übertragen wird. Dies war unter HTTP/2 nicht möglich.
Hier dargestellt mit einem gelben und einem blauen Stream, die über eine einzige Verbindung zwischen zwei QUIC-Endpunkten gesendet werden. Sie sind unabhängig und können in einer anderen Reihenfolge eintreffen, aber jeder Stream wird zuverlässig und in der richtigen Reihenfolge (in-order) an die Anwendung geliefert.
QUIC verwendete TLS 1.3 (RFC 8446) zur Transportsicherheit und es gibt unter keinen Umständen unverschlüsselte QUIC-Verbindungen.
TLS 1.3 hat einige Vorteile gegenüber älteren TLS-Versionen - ein Hauptgrund für die Verwendung in QUIC ist, dass 1.3 den Handshake so geändert hat, dass weniger Roundtrips erforderlich sind. Dieses Vorgehen reduziert die Protokolllatenz.
In der Google-Version von QUIC wurde eine eigens entwickelte Lösung verwendet.
QUIC bietet einen Verbindungsaufbau sowohl mit 0-RTT als auch 1-RTT. Das bedeutet, dass QUIC beim Aufbau einer neuen Verbindung bestenfalls keine zusätzlichen Roundtrips benötigt. Der Schnellere von beiden, der 0-RTT-Handshake, funktioniert nur, wenn zuvor eine Verbindung zu einem Host hergestellt und ein Geheimnis dieser Verbindung zwischengespeichert wurde.
Mit QUIC kann ein Client Daten bereits zu 0-RTT-Handshakes hinzufügen. Diese Funktion ermöglicht es einem Client, Daten so schnell wie möglich an den Peer zu übermitteln. Auf diese Weise kann der Server natürlich noch früher antworten und Daten zurücksenden.