From 9cc70a405c7ed9857d0bbfc3fcc0419f396ec20d Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 14 Sep 2022 01:36:09 -0400 Subject: [PATCH 01/18] add init quic content --- content/concepts/transport.md | 117 ++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index b54039e2..3df8a117 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -115,3 +115,120 @@ and some places in the codebase still use the "swarm" terminology. {{% /notice %}} [definition_switch]: /reference/glossary/#switch + +## QUIC + +Transport protocols continue to improve transport methods in an attempt to alleviate +the shortcomings of the transport layer. + +{{% notice "note" %}} + +Recalling the purpose of transports + +The IP service model provides logical communication between hosts (or nodes) but +is considered a best-effort delivery service, as segment delivery is not guaranteed. +The primary responsibility of transport protocols is to extend the IP +delivery service between two end systems. TCP connects the unreliable service of IP +between end systems into a reliable transport service between processes (i.e., the +processes running on the end systems). The purpose of newer transport protocols is not +only to improve current transport methods but also to allow for efficient connections +that distributed and peer-to-peer network stacks can utilize, like libp2p. + +{{% /notice %}} + +We need a transport protocol that: + +- Understands streams +- Is not byte-ordered +- Overcomes HOL blocking (Head-of-line blocking) +- Overcomes the latency of connection setup +- Overcomes the ossification risks of TCP + +and, ideally, with the guarantees of TCP. + +In 2014, a new transport protocol +called QUIC (which, at the time, stood for Quick UDP Internet Connections, but now +is only referred to as QUIC and does not use the original acronym) was launched as an +experiment on Google Chrome. It has since been refined and maintained by an official +working group under the IETF (Internet Engineering Task Force). + +QUIC is a UDP-based multiplexed and secure transport. +The official standard is defined in [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000). + +Being UDP-based, QUIC optimizes for speedy transmission, as opposed to the latency +that exists in HTTP leveraging TLS over TCP. + +A web browser connection typically entails the following (TCP+TLS+HTTP/2): + +1. IP layer: the connection will run on the IP layer, which is responsible for + packet routing. +2. Transport layer: TCP then runs on top of the IP layer to provide a reliable + byte stream. +3. Secure communication layer: Secure communication (i.e., TLS) runs on TCP to + encrypt the bytes. + - Negotiation (SYN-ACK) of encryption parameters for TLS. Standard TLS over + TCP requires 3 RTT. +4. Application layer: HTTP runs on a secure transport connection to transfer + information. + - Data starts to flow. + +Secure TCP-based connections offer a multi-layered approach for secure communication +over IP, whereas QUIC, by design, is an optimized transport consolidation of layers. +QUIC has to deal with TCP-like congestion control, loss recovery, and encryption. +Part of the application layer is also built directly into QUIC; when you +run HTTP on top of QUIC; only a small shim layer exists that maps +[HTTP semantics](https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html) +onto QUIC streams. + +To establish a connection, QUIC assumes that the node sends the right address over +the packet. QUIC saves one round-trip by doing this. If there is suspicion of an +attack, QUIC has a defense mechanism that can require a three-way handshake, but only +under particular conditions. A minimum packet size rule exists for the first packet to +ensure that small malicious packets like SYN packets cannot be sent and consume excessive +resources, as can be done with TCP. + +QUIC saves another round-trip in using TLS 1.3 by optimistically providing keyshares. +If you have established a connection before, the host can send you a session ticket +that can be used to establish a new secure connection instantly, without any round-trips. + +> Over the last several years, the IETF has been working on a new version of TLS, TLS 1.3. +> Learn more about TLS 1.3 and how it is used in libp2p on the secure communication concept guide. + + + +libp2p only supports bidirectional streams and uses TLS 1.3 by default (but can use other +cryptography methods). The streams in libp2p map cleanly to QUIC packets. + +When a connection starts, peers will take their host key and create a self-signed CA +certificate. They then sign an intermediate chain using their self-signed CA and put it +as a certificate chain in the TLS handshake. + +At the end of the handshake, each peer knows the certificate of the other. The peer can +verify if the connection was established with the correct peer by looking up the first +CA certificate on the certificate chain, retreive the public key, and using it to calculate +the opposing peer ID. QUIC acts like a record layer with TLS 1.3 as the backend as TLS is +responsible for all the cryptography. + +{{% notice "info" %}} + +To be clear, there is no additional security handshake and stream muxer need as QUIC provides +all of this by default. + +{{% /notice %}} + +Following the multiaddress format described earlier, a standard QUIC connection will +look like: + +``` +/ip4/127.0.0.1/udp/65432/quic/ +``` + +In this section, we offered an overview of QUIC and how QUIC works in libp2p. + +{{% notice "tip" %}} + +For more details on QUIC, including its limitations +check out the following resources: + + +{{% /notice %}} From 907edbef360369c363cc34f8465d18daaa483e4c Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Fri, 16 Sep 2022 05:05:40 -0400 Subject: [PATCH 02/18] add init content for webtransport --- content/concepts/transport.md | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 3df8a117..582a16a1 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -230,5 +230,74 @@ In this section, we offered an overview of QUIC and how QUIC works in libp2p. For more details on QUIC, including its limitations check out the following resources: +{{% /notice %}} + +## WebTransport + +Another transport protocol under development at the IETF is WebTransport. +WebTransport is a new specification that uses QUIC to offer an alternative to +WebSockets. Instead, it can be considered WebSockets over QUIC by allowing +browsers to establish a stream-multiplexed and bidirectional +connection to servers. + +The specification can depend on and reuse the QUIC infrastructure in place +to offer WebSockets that take the benefits of UDP and offer sockets without head-of-line +blocking. + +Recall that WebSockets are bidirectional, full-duplex communication between two +points over a single-socket connection. WebTransports, as a result, can be used +like WebSockets, but with the support of multistreams. + +WebTransport streams can be arbitrary in size and independent when possible. +They are reliable but can be canceled when possible. The datagrams in a +WebTransport connections are MTU-sized and can be unreliable when possible. + +{{% caution "note" %}} + +There is a functioning WebTransport implementation in go-libp2p that is part +of the v0.23 release. + +The implementation should be used experimentally and is not recommended for +production environments. {{% /notice %}} + +For network stacks like libp2p, WebTransport is a pluggable +protocol that fits well with a modular network design. + +For a standard WebSocket connection: + +- 1 RTT for DNS resolution +- 1 RTT for TCP handshake +- 1 RTT for TLS handshake +- 1 RTT for WebSocket handshake +- 1 RTT for Multistream Security handshake +- 1 RTT for libp2p handshake + +Plenty of handshakes and roundtrips: 6 RTTs: 5 handshakes + 1 DNS resolution + +WebTransport running over QUIC only requires 4 RTTs, as: + +- 1 RTT for QUIC handshake +- 1 RTT for WebTransport handshake +- 2 RTT for libp2p handshake; one for multistream and one for the secure + communication (TLS 1.3 or Noise) + +> With protocol select, the WebTransport handshake and the libp2p handshake +> can run in parallel, bringing down the total round trips to 2. + +WebTransport multiaddresses are composed of a QUIC multiaddr, followed +by `/webtransport` and a list of multihashes of the node certificates that the server uses. + +For instance, for multiaddress `/ip4/127.0.0.1/udp/123/quic/webtransport/certhash/`, +a standard local QUIC connection is defined up until and including `/quic.` +Then, `/webtransport/` runs over QUIC and the self-signed certificate hash that the +server will use to verify the connection. + +WebTransport requires an HTTPS URL to establish a WebTransport session - +e.g., `https://docs.libp2p.com/webtransport` and the multiaddresses use an HTTP URL +instead. Since multiaddrs don't allow the encoding of URLs, the HTTP endpoint of a libp2p +WebTransport servers must be located at `/.well-known/libp2p-webtransport`. + +For instance, the WebTransport URL of a WebTransport server advertising +`/ip4/1.2.3.4/udp/1234/quic/webtransport/` would be `https://1.2.3.4:1234/.well-known/libp2p-webtransport?type=tls`. From 2dddf02af865d78b0bf33d6577f2fad9e106f80d Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Fri, 16 Sep 2022 05:08:19 -0400 Subject: [PATCH 03/18] fix notice --- content/concepts/transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 582a16a1..8e7970c5 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -252,7 +252,7 @@ WebTransport streams can be arbitrary in size and independent when possible. They are reliable but can be canceled when possible. The datagrams in a WebTransport connections are MTU-sized and can be unreliable when possible. -{{% caution "note" %}} +{{% notice "caution" %}} There is a functioning WebTransport implementation in go-libp2p that is part of the v0.23 release. From bb4b4464f055c73a9283e10e9e544456c3e2d0fb Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 00:25:04 -0400 Subject: [PATCH 04/18] Apply suggestions from code review Co-authored-by: Marco Munizaga --- content/concepts/transport.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 8e7970c5..ba230c6f 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -144,7 +144,7 @@ We need a transport protocol that: - Overcomes the latency of connection setup - Overcomes the ossification risks of TCP -and, ideally, with the guarantees of TCP. +and, ideally, keeps the guarantees of TCP. In 2014, a new transport protocol called QUIC (which, at the time, stood for Quick UDP Internet Connections, but now @@ -197,7 +197,7 @@ that can be used to establish a new secure connection instantly, without any rou libp2p only supports bidirectional streams and uses TLS 1.3 by default (but can use other -cryptography methods). The streams in libp2p map cleanly to QUIC packets. +cryptography methods). The streams in libp2p map cleanly to QUIC streams. When a connection starts, peers will take their host key and create a self-signed CA certificate. They then sign an intermediate chain using their self-signed CA and put it @@ -211,7 +211,7 @@ responsible for all the cryptography. {{% notice "info" %}} -To be clear, there is no additional security handshake and stream muxer need as QUIC provides +To be clear, there is no additional security handshake and stream muxer needed as QUIC provides all of this by default. {{% /notice %}} @@ -236,17 +236,17 @@ check out the following resources: Another transport protocol under development at the IETF is WebTransport. WebTransport is a new specification that uses QUIC to offer an alternative to -WebSockets. Instead, it can be considered WebSockets over QUIC by allowing +WebSockets. It can be considered WebSockets over QUIC by allowing browsers to establish a stream-multiplexed and bidirectional connection to servers. The specification can depend on and reuse the QUIC infrastructure in place -to offer WebSockets that take the benefits of UDP and offer sockets without head-of-line +to offer WebSockets that take the benefits of UDP and offer streams without head-of-line blocking. Recall that WebSockets are bidirectional, full-duplex communication between two -points over a single-socket connection. WebTransports, as a result, can be used -like WebSockets, but with the support of multistreams. +points over a single-socket connection. WebTransport can be used +like WebSockets, but with the support of multiple streams. WebTransport streams can be arbitrary in size and independent when possible. They are reliable but can be canceled when possible. The datagrams in a @@ -254,7 +254,7 @@ WebTransport connections are MTU-sized and can be unreliable when possible. {{% notice "caution" %}} -There is a functioning WebTransport implementation in go-libp2p that is part +There is an experimental WebTransport transport in go-libp2p that is part of the v0.23 release. The implementation should be used experimentally and is not recommended for From 259d4a5b7690484725172ae4411f46dc3f5e5d3d Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 00:46:57 -0400 Subject: [PATCH 05/18] address PR feedback; edits and clarify claims --- content/concepts/transport.md | 51 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index ba230c6f..a4e84a51 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -201,12 +201,13 @@ cryptography methods). The streams in libp2p map cleanly to QUIC streams. When a connection starts, peers will take their host key and create a self-signed CA certificate. They then sign an intermediate chain using their self-signed CA and put it -as a certificate chain in the TLS handshake. +as a certificate chain in the TLS handshake. View the full TLS specification +[here](https://github.com/libp2p/specs/blob/master/tls/tls.md). At the end of the handshake, each peer knows the certificate of the other. The peer can verify if the connection was established with the correct peer by looking up the first CA certificate on the certificate chain, retreive the public key, and using it to calculate -the opposing peer ID. QUIC acts like a record layer with TLS 1.3 as the backend as TLS is +the opposing peer ID. QUIC acts like a record layer with TLS 1.3 as the backend as TLS is responsible for all the cryptography. {{% notice "info" %}} @@ -230,6 +231,8 @@ In this section, we offered an overview of QUIC and how QUIC works in libp2p. For more details on QUIC, including its limitations check out the following resources: + + {{% /notice %}} ## WebTransport @@ -248,41 +251,38 @@ Recall that WebSockets are bidirectional, full-duplex communication between two points over a single-socket connection. WebTransport can be used like WebSockets, but with the support of multiple streams. -WebTransport streams can be arbitrary in size and independent when possible. -They are reliable but can be canceled when possible. The datagrams in a -WebTransport connections are MTU-sized and can be unreliable when possible. +WebTransport supports reliable streams that can be arbitrary in size. They can be +independent and canceled if needed. The datagrams in a +WebTransport connections are MTU-sized. {{% notice "caution" %}} There is an experimental WebTransport transport in go-libp2p that is part -of the v0.23 release. - -The implementation should be used experimentally and is not recommended for -production environments. +of the v0.23 release. The implementation should be used experimentally and is not +recommended for production environments. {{% /notice %}} For network stacks like libp2p, WebTransport is a pluggable protocol that fits well with a modular network design. -For a standard WebSocket connection: +For a standard WebSocket connection, the roundtrips required are as follows: -- 1 RTT for DNS resolution -- 1 RTT for TCP handshake -- 1 RTT for TLS handshake -- 1 RTT for WebSocket handshake -- 1 RTT for Multistream Security handshake -- 1 RTT for libp2p handshake +- 1-RTT for DNS resolution +- 1-RTT for TCP handshake +- 1-RTT for TLS handshake +- 1-RTT for WebSocket handshake +- 1-RTT for Multistream Security handshake +- 1-RTT for libp2p handshake -Plenty of handshakes and roundtrips: 6 RTTs: 5 handshakes + 1 DNS resolution +In total, 6-RTTs: 5 handshakes + 1 DNS resolution. WebTransport running over QUIC only requires 4 RTTs, as: -- 1 RTT for QUIC handshake -- 1 RTT for WebTransport handshake -- 2 RTT for libp2p handshake; one for multistream and one for the secure - communication (TLS 1.3 or Noise) - +- 1-RTT for QUIC handshake +- 1-RTT for WebTransport handshake +- 2-RTT for libp2p handshake; one for multistream and one for authentication + (with a Noise handshake) > With protocol select, the WebTransport handshake and the libp2p handshake > can run in parallel, bringing down the total round trips to 2. @@ -296,8 +296,9 @@ server will use to verify the connection. WebTransport requires an HTTPS URL to establish a WebTransport session - e.g., `https://docs.libp2p.com/webtransport` and the multiaddresses use an HTTP URL -instead. Since multiaddrs don't allow the encoding of URLs, the HTTP endpoint of a libp2p -WebTransport servers must be located at `/.well-known/libp2p-webtransport`. +instead. The HTTP endpoint of a libp2p WebTransport servers must be located at +`/.well-known/libp2p-webtransport`. For instance, the WebTransport URL of a WebTransport server advertising -`/ip4/1.2.3.4/udp/1234/quic/webtransport/` would be `https://1.2.3.4:1234/.well-known/libp2p-webtransport?type=tls`. +`/ip4/1.2.3.4/udp/1234/quic/webtransport/` that is authenticated would be +`https://1.2.3.4:1234/.well-known/libp2p-webtransport?type=noise`. From 34f4a8f0f9cc8c3d47b605b87b8d473b2c6763ba Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 02:26:46 -0400 Subject: [PATCH 06/18] address PR feedback; remove ambiguity --- content/concepts/transport.md | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index a4e84a51..2c197641 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -139,7 +139,6 @@ that distributed and peer-to-peer network stacks can utilize, like libp2p. We need a transport protocol that: - Understands streams -- Is not byte-ordered - Overcomes HOL blocking (Head-of-line blocking) - Overcomes the latency of connection setup - Overcomes the ossification risks of TCP @@ -207,8 +206,7 @@ as a certificate chain in the TLS handshake. View the full TLS specification At the end of the handshake, each peer knows the certificate of the other. The peer can verify if the connection was established with the correct peer by looking up the first CA certificate on the certificate chain, retreive the public key, and using it to calculate -the opposing peer ID. QUIC acts like a record layer with TLS 1.3 as the backend as TLS is -responsible for all the cryptography. +the opposing peer ID. QUIC acts like the TLS record layer, where TLS 1.3 handles the handshake. {{% notice "info" %}} @@ -218,23 +216,10 @@ all of this by default. {{% /notice %}} Following the multiaddress format described earlier, a standard QUIC connection will -look like: - -``` -/ip4/127.0.0.1/udp/65432/quic/ -``` +look like: `/ip4/127.0.0.1/udp/65432/quic/`. In this section, we offered an overview of QUIC and how QUIC works in libp2p. -{{% notice "tip" %}} - -For more details on QUIC, including its limitations -check out the following resources: - - - -{{% /notice %}} - ## WebTransport Another transport protocol under development at the IETF is WebTransport. @@ -268,14 +253,14 @@ protocol that fits well with a modular network design. For a standard WebSocket connection, the roundtrips required are as follows: -- 1-RTT for DNS resolution - 1-RTT for TCP handshake -- 1-RTT for TLS handshake -- 1-RTT for WebSocket handshake -- 1-RTT for Multistream Security handshake -- 1-RTT for libp2p handshake +- 1-RTT for TLS 1.3 handshake +- 1-RTT for WebSocket upgrade +- 1-RTT for multistream security negotiation (Noise or TLS 1.3) +- 1-RTT for security handshake (Noise or TLS 1.3) +- 1-RTT for multistream muxer negotiation (mplex or yamux) -In total, 6-RTTs: 5 handshakes + 1 DNS resolution. +In total, 6-RTTs. WebTransport running over QUIC only requires 4 RTTs, as: @@ -302,3 +287,6 @@ instead. The HTTP endpoint of a libp2p WebTransport servers must be located at For instance, the WebTransport URL of a WebTransport server advertising `/ip4/1.2.3.4/udp/1234/quic/webtransport/` that is authenticated would be `https://1.2.3.4:1234/.well-known/libp2p-webtransport?type=noise`. + +In this section, we offered an overview of WebTransport and how WebTransport works +in libp2p. From ed6cc437e52b9a97c6c1fad1d0af18887a01db04 Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 03:48:31 -0400 Subject: [PATCH 07/18] address PR feedback for quic; concise, simplify + edits --- content/concepts/transport.md | 119 ++++++++++++++++------------------ 1 file changed, 55 insertions(+), 64 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 2c197641..bcb48883 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -118,23 +118,36 @@ and some places in the codebase still use the "swarm" terminology. ## QUIC -Transport protocols continue to improve transport methods in an attempt to alleviate -the shortcomings of the transport layer. +QUIC is a new transport protocol that provides an always-encrypted, stream-multiplexed +connection built on top of UDP. It started as an experiment by Google on Google Chrome +in 2014, and was later standardized by the IETF in +[RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000). -{{% notice "note" %}} +### Key challenges with TCP -Recalling the purpose of transports +1. Head-of-line blocking (HoL blocking): TCP is a single byte stream exposed by the kernel, + so streams layered on top of TCP experience HoL blocking. -The IP service model provides logical communication between hosts (or nodes) but -is considered a best-effort delivery service, as segment delivery is not guaranteed. -The primary responsibility of transport protocols is to extend the IP -delivery service between two end systems. TCP connects the unreliable service of IP -between end systems into a reliable transport service between processes (i.e., the -processes running on the end systems). The purpose of newer transport protocols is not -only to improve current transport methods but also to allow for efficient connections -that distributed and peer-to-peer network stacks can utilize, like libp2p. + {{% notice "info" %}} + HoL blocking occurs when a the head packet holds up the other packets in the transmission + queue. + {{% /notice %}} -{{% /notice %}} +2. Ossification: Because TCP is unencrypted, middleboxes can inspect and modify + TCP header fields and may break unexpectedly when they encounter anything they don’t like. + + {{% notice "info" %}} + Middleboxes are intermediary networking devices that can perform special functions to + inspect, transform, and even manipulate network traffic. Examples of middleboxes are + firewalls, NATs, proxies, and load balancers. + {{% /notice %}} + +3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1-RTT on verifying + the client’s address. + + {{% notice "info" %}} + TCP requires a 3-way handshake to establish a reliable, bidirectional connection as it intends to. + {{% /notice %}} We need a transport protocol that: @@ -145,73 +158,51 @@ We need a transport protocol that: and, ideally, keeps the guarantees of TCP. -In 2014, a new transport protocol -called QUIC (which, at the time, stood for Quick UDP Internet Connections, but now -is only referred to as QUIC and does not use the original acronym) was launched as an -experiment on Google Chrome. It has since been refined and maintained by an official -working group under the IETF (Internet Engineering Task Force). - -QUIC is a UDP-based multiplexed and secure transport. -The official standard is defined in [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000). - -Being UDP-based, QUIC optimizes for speedy transmission, as opposed to the latency -that exists in HTTP leveraging TLS over TCP. - A web browser connection typically entails the following (TCP+TLS+HTTP/2): -1. IP layer: the connection will run on the IP layer, which is responsible for - packet routing. -2. Transport layer: TCP then runs on top of the IP layer to provide a reliable +1. Transport layer: TCP runs on top of the IP layer to provide a reliable byte stream. -3. Secure communication layer: Secure communication (i.e., TLS) runs on TCP to - encrypt the bytes. - - Negotiation (SYN-ACK) of encryption parameters for TLS. Standard TLS over - TCP requires 3 RTT. -4. Application layer: HTTP runs on a secure transport connection to transfer - information. - - Data starts to flow. - -Secure TCP-based connections offer a multi-layered approach for secure communication -over IP, whereas QUIC, by design, is an optimized transport consolidation of layers. -QUIC has to deal with TCP-like congestion control, loss recovery, and encryption. -Part of the application layer is also built directly into QUIC; when you -run HTTP on top of QUIC; only a small shim layer exists that maps + - TCP provides a reliable, bidirectional connection between two end systems. +2. Secure communication layer: A TLS handshake runs on top of TCP to, + establishing an encrypted and authenticated connection. + - Standard TLS over TCP requires 3-RTT. A typical TLS 1.3 handshake takes 1-RTT. +3. Application layer: HTTP runs on a secure transport connection to transfer + information and applies a stream muxer to serve multiple requests. + - Application data starts to flow. + + + +### What is QUIC? + +QUIC combines the functionality of these layers: it sends UDP packets. Therefore, +it is responsible for loss detection and repair itself. By using encryption, +QUIC avoid middleboxes. The TLS 1.3 handshake is performed in the first flight, +removing the 1-RTT cost of verifying the client’s address. QUIC also exposes multiple +streams, so no stream multiplexer is needed at the application layer. Part of the application +layer is also built directly into QUIC; when you run HTTP on top of QUIC; only a small shim +layer exists that maps [HTTP semantics](https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html) onto QUIC streams. -To establish a connection, QUIC assumes that the node sends the right address over -the packet. QUIC saves one round-trip by doing this. If there is suspicion of an -attack, QUIC has a defense mechanism that can require a three-way handshake, but only -under particular conditions. A minimum packet size rule exists for the first packet to -ensure that small malicious packets like SYN packets cannot be sent and consume excessive -resources, as can be done with TCP. - -QUIC saves another round-trip in using TLS 1.3 by optimistically providing keyshares. -If you have established a connection before, the host can send you a session ticket -that can be used to establish a new secure connection instantly, without any round-trips. +QUIC supports the resumption of connections (0-RTT connections), allowing a +client to send application data right away, even before the QUIC handshake has finished. -> Over the last several years, the IETF has been working on a new version of TLS, TLS 1.3. -> Learn more about TLS 1.3 and how it is used in libp2p on the secure communication concept guide. + - +### QUIC in libp2p -libp2p only supports bidirectional streams and uses TLS 1.3 by default (but can use other -cryptography methods). The streams in libp2p map cleanly to QUIC streams. +libp2p only supports bidirectional streams and uses TLS 1.3 by default. +The streams in libp2p map cleanly to QUIC streams. When a connection starts, peers will take their host key and create a self-signed CA certificate. They then sign an intermediate chain using their self-signed CA and put it as a certificate chain in the TLS handshake. View the full TLS specification [here](https://github.com/libp2p/specs/blob/master/tls/tls.md). -At the end of the handshake, each peer knows the certificate of the other. The peer can -verify if the connection was established with the correct peer by looking up the first -CA certificate on the certificate chain, retreive the public key, and using it to calculate -the opposing peer ID. QUIC acts like the TLS record layer, where TLS 1.3 handles the handshake. - -{{% notice "info" %}} +{{% notice "note" %}} -To be clear, there is no additional security handshake and stream muxer needed as QUIC provides -all of this by default. +To be clear, there is no additional security handshake and stream muxer needed as QUIC +provides all of this by default. {{% /notice %}} From 4b182d39cac97d23c70d2d9dcc7d248f7d911f2c Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 03:55:35 -0400 Subject: [PATCH 08/18] limit PR to QUIC --- content/concepts/transport.md | 71 ----------------------------------- 1 file changed, 71 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index bcb48883..fd1e6197 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -210,74 +210,3 @@ Following the multiaddress format described earlier, a standard QUIC connection look like: `/ip4/127.0.0.1/udp/65432/quic/`. In this section, we offered an overview of QUIC and how QUIC works in libp2p. - -## WebTransport - -Another transport protocol under development at the IETF is WebTransport. -WebTransport is a new specification that uses QUIC to offer an alternative to -WebSockets. It can be considered WebSockets over QUIC by allowing -browsers to establish a stream-multiplexed and bidirectional -connection to servers. - -The specification can depend on and reuse the QUIC infrastructure in place -to offer WebSockets that take the benefits of UDP and offer streams without head-of-line -blocking. - -Recall that WebSockets are bidirectional, full-duplex communication between two -points over a single-socket connection. WebTransport can be used -like WebSockets, but with the support of multiple streams. - -WebTransport supports reliable streams that can be arbitrary in size. They can be -independent and canceled if needed. The datagrams in a -WebTransport connections are MTU-sized. - -{{% notice "caution" %}} - -There is an experimental WebTransport transport in go-libp2p that is part -of the v0.23 release. The implementation should be used experimentally and is not -recommended for production environments. - -{{% /notice %}} - -For network stacks like libp2p, WebTransport is a pluggable -protocol that fits well with a modular network design. - -For a standard WebSocket connection, the roundtrips required are as follows: - -- 1-RTT for TCP handshake -- 1-RTT for TLS 1.3 handshake -- 1-RTT for WebSocket upgrade -- 1-RTT for multistream security negotiation (Noise or TLS 1.3) -- 1-RTT for security handshake (Noise or TLS 1.3) -- 1-RTT for multistream muxer negotiation (mplex or yamux) - -In total, 6-RTTs. - -WebTransport running over QUIC only requires 4 RTTs, as: - -- 1-RTT for QUIC handshake -- 1-RTT for WebTransport handshake -- 2-RTT for libp2p handshake; one for multistream and one for authentication - (with a Noise handshake) -> With protocol select, the WebTransport handshake and the libp2p handshake -> can run in parallel, bringing down the total round trips to 2. - -WebTransport multiaddresses are composed of a QUIC multiaddr, followed -by `/webtransport` and a list of multihashes of the node certificates that the server uses. - -For instance, for multiaddress `/ip4/127.0.0.1/udp/123/quic/webtransport/certhash/`, -a standard local QUIC connection is defined up until and including `/quic.` -Then, `/webtransport/` runs over QUIC and the self-signed certificate hash that the -server will use to verify the connection. - -WebTransport requires an HTTPS URL to establish a WebTransport session - -e.g., `https://docs.libp2p.com/webtransport` and the multiaddresses use an HTTP URL -instead. The HTTP endpoint of a libp2p WebTransport servers must be located at -`/.well-known/libp2p-webtransport`. - -For instance, the WebTransport URL of a WebTransport server advertising -`/ip4/1.2.3.4/udp/1234/quic/webtransport/` that is authenticated would be -`https://1.2.3.4:1234/.well-known/libp2p-webtransport?type=noise`. - -In this section, we offered an overview of WebTransport and how WebTransport works -in libp2p. From b76e2b3db2dbccd06510ee38e9ccab87c1f1507d Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 11:22:33 -0400 Subject: [PATCH 09/18] Apply suggestions from code review Co-authored-by: Elena Frank --- content/concepts/transport.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index fd1e6197..7fd3343b 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -129,7 +129,7 @@ in 2014, and was later standardized by the IETF in so streams layered on top of TCP experience HoL blocking. {{% notice "info" %}} - HoL blocking occurs when a the head packet holds up the other packets in the transmission + HoL blocking occurs when a lost, or out-of-order delivered head packet holds up the other packets in the transmission queue. {{% /notice %}} @@ -174,9 +174,9 @@ A web browser connection typically entails the following (TCP+TLS+HTTP/2): ### What is QUIC? -QUIC combines the functionality of these layers: it sends UDP packets. Therefore, +QUIC combines the functionality of these layers. It sends UDP packets and therefore it is responsible for loss detection and repair itself. By using encryption, -QUIC avoid middleboxes. The TLS 1.3 handshake is performed in the first flight, +QUIC avoids ossified middleboxes. The TLS 1.3 handshake is performed in the first flight, removing the 1-RTT cost of verifying the client’s address. QUIC also exposes multiple streams, so no stream multiplexer is needed at the application layer. Part of the application layer is also built directly into QUIC; when you run HTTP on top of QUIC; only a small shim From 552dd998cfae2d00d140d83d2b5184d1490f0e92 Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 11:24:20 -0400 Subject: [PATCH 10/18] Update content/concepts/transport.md Co-authored-by: Elena Frank --- content/concepts/transport.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 7fd3343b..d1d1d9f4 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -163,8 +163,8 @@ A web browser connection typically entails the following (TCP+TLS+HTTP/2): 1. Transport layer: TCP runs on top of the IP layer to provide a reliable byte stream. - TCP provides a reliable, bidirectional connection between two end systems. -2. Secure communication layer: A TLS handshake runs on top of TCP to, - establishing an encrypted and authenticated connection. +2. Secure communication layer: A TLS handshake runs on top of TCP to + establish an encrypted and authenticated connection. - Standard TLS over TCP requires 3-RTT. A typical TLS 1.3 handshake takes 1-RTT. 3. Application layer: HTTP runs on a secure transport connection to transfer information and applies a stream muxer to serve multiple requests. From b375ec2392dc8c7e63e4827935e5b18875f2c0cc Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Wed, 21 Sep 2022 11:38:54 -0400 Subject: [PATCH 11/18] address PR feedback; rmv notices --- content/concepts/transport.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index d1d1d9f4..6d20ab36 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -136,19 +136,9 @@ in 2014, and was later standardized by the IETF in 2. Ossification: Because TCP is unencrypted, middleboxes can inspect and modify TCP header fields and may break unexpectedly when they encounter anything they don’t like. - {{% notice "info" %}} - Middleboxes are intermediary networking devices that can perform special functions to - inspect, transform, and even manipulate network traffic. Examples of middleboxes are - firewalls, NATs, proxies, and load balancers. - {{% /notice %}} - 3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1-RTT on verifying the client’s address. - {{% notice "info" %}} - TCP requires a 3-way handshake to establish a reliable, bidirectional connection as it intends to. - {{% /notice %}} - We need a transport protocol that: - Understands streams @@ -194,9 +184,9 @@ client to send application data right away, even before the QUIC handshake has f libp2p only supports bidirectional streams and uses TLS 1.3 by default. The streams in libp2p map cleanly to QUIC streams. -When a connection starts, peers will take their host key and create a self-signed CA -certificate. They then sign an intermediate chain using their self-signed CA and put it -as a certificate chain in the TLS handshake. View the full TLS specification +When a connection starts, peers will take their host key and create a self-signed +CA certificate. They then sign an intermediate chain using their self-signed CA certificate +and put it as a certificate chain in the TLS handshake. View the full TLS specification [here](https://github.com/libp2p/specs/blob/master/tls/tls.md). {{% notice "note" %}} From 0c1c8e00ad189908ad00a9556758d7edeb8db8ad Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Fri, 23 Sep 2022 10:28:12 -0400 Subject: [PATCH 12/18] Apply suggestions from code review Co-authored-by: Marten Seemann --- content/concepts/transport.md | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 6d20ab36..7aeea135 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -126,27 +126,25 @@ in 2014, and was later standardized by the IETF in ### Key challenges with TCP 1. Head-of-line blocking (HoL blocking): TCP is a single byte stream exposed by the kernel, - so streams layered on top of TCP experience HoL blocking. + so streams layered on top of TCP experience head-of-line (HoL) blocking. {{% notice "info" %}} - HoL blocking occurs when a lost, or out-of-order delivered head packet holds up the other packets in the transmission - queue. + In TCP, head-of-line blocking occurs when a single packet is lost, and packets delivered after that need to wait in the kernel buffer until a retransmission for the lost packet is received. {{% /notice %}} -2. Ossification: Because TCP is unencrypted, middleboxes can inspect and modify - TCP header fields and may break unexpectedly when they encounter anything they don’t like. +2. Ossification: Because the header of TCP packet is unencrypted, middleboxes can inspect and modify + TCP header fields and may break unexpectedly when they encounter anything they don’t understand. + This makes it practically impossible to deploy any changes to the TCP protocol that change the wire format. 3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1-RTT on verifying the client’s address. -We need a transport protocol that: +QUIC was designed with the following goals in mind: -- Understands streams -- Overcomes HOL blocking (Head-of-line blocking) -- Overcomes the latency of connection setup -- Overcomes the ossification risks of TCP +- Streams at the transport layer, thereby overcoming HoL blocking +- Reducing the latency of connection establishment to a single RTT for new connections, and to allow sending of 0-RTT application data for resumed connections +- Encrypting as much as possible. This eliminates the ossification risk, as middleboxes aren't able to read any encrypted fields, and allows future evolution of the protocol -and, ideally, keeps the guarantees of TCP. A web browser connection typically entails the following (TCP+TLS+HTTP/2): @@ -182,21 +180,19 @@ client to send application data right away, even before the QUIC handshake has f ### QUIC in libp2p libp2p only supports bidirectional streams and uses TLS 1.3 by default. -The streams in libp2p map cleanly to QUIC streams. +libp2p directly uses QUIC streams, without any additional framing. -When a connection starts, peers will take their host key and create a self-signed -CA certificate. They then sign an intermediate chain using their self-signed CA certificate -and put it as a certificate chain in the TLS handshake. View the full TLS specification -[here](https://github.com/libp2p/specs/blob/master/tls/tls.md). +To authenticate each others' peer IDs, peers encode their peer ID into a self-signed certificate, +which they sign using their host's private key. This is the same way peer IDs are authenticated in +the [libp2p TLS handshake](https://github.com/libp2p/specs/blob/master/tls/tls.md). {{% notice "note" %}} To be clear, there is no additional security handshake and stream muxer needed as QUIC -provides all of this by default. +provides all of this by default. This also means that establishing a libp2p connection between +two nodes using QUIC only takes a single RTT. {{% /notice %}} Following the multiaddress format described earlier, a standard QUIC connection will look like: `/ip4/127.0.0.1/udp/65432/quic/`. - -In this section, we offered an overview of QUIC and how QUIC works in libp2p. From 512d93c2e84aa385f9230985d65afbcd76d75ab7 Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Fri, 23 Sep 2022 12:17:10 -0400 Subject: [PATCH 13/18] refine http section + edits --- content/concepts/transport.md | 36 +++++++++++++++++----- content/concepts/transports/http3-osi.png | Bin 0 -> 46314 bytes 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 content/concepts/transports/http3-osi.png diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 7aeea135..6d21f077 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -129,12 +129,15 @@ in 2014, and was later standardized by the IETF in so streams layered on top of TCP experience head-of-line (HoL) blocking. {{% notice "info" %}} - In TCP, head-of-line blocking occurs when a single packet is lost, and packets delivered after that need to wait in the kernel buffer until a retransmission for the lost packet is received. + In TCP, head-of-line blocking occurs when a single packet is lost, and packets delivered + after that need to wait in the kernel buffer until a retransmission for the lost packet + is received. {{% /notice %}} 2. Ossification: Because the header of TCP packet is unencrypted, middleboxes can inspect and modify TCP header fields and may break unexpectedly when they encounter anything they don’t understand. - This makes it practically impossible to deploy any changes to the TCP protocol that change the wire format. + This makes it practically impossible to deploy any changes to the TCP protocol that change the + wire format. 3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1-RTT on verifying the client’s address. @@ -142,23 +145,38 @@ in 2014, and was later standardized by the IETF in QUIC was designed with the following goals in mind: - Streams at the transport layer, thereby overcoming HoL blocking -- Reducing the latency of connection establishment to a single RTT for new connections, and to allow sending of 0-RTT application data for resumed connections -- Encrypting as much as possible. This eliminates the ossification risk, as middleboxes aren't able to read any encrypted fields, and allows future evolution of the protocol +- Reducing the latency of connection establishment to a single RTT for new connections, and to + allow sending of 0-RTT application data for resumed connections +- Encrypting as much as possible. This eliminates the ossification risk, as middleboxes aren't + able to read any encrypted fields, and allows future evolution of the protocol +### Comparing HTTP/2 and HTTP/3 -A web browser connection typically entails the following (TCP+TLS+HTTP/2): +The IETF introduced a new hypertext transfer protocol standard in late 2018, +which turned into a proposed standard for HTTP/3 in +[RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114). HTTP/3 combines the advantages +of the existing transfer protocols HTTP/2 and HTTP over QUIC in one standard for faster and +more stable data transmission. + +The following diagram illustrates the OSI model for HTTP/2 and HTTP/3 [1]: + +![HTTP/2 & HTTP/3 OSI model](transports/http3-osi.png) + +A web browser connection typically entails the following **(TCP+TLS+HTTP/2)**: 1. Transport layer: TCP runs on top of the IP layer to provide a reliable byte stream. - TCP provides a reliable, bidirectional connection between two end systems. -2. Secure communication layer: A TLS handshake runs on top of TCP to +2. Security layer: A TLS handshake runs on top of TCP to establish an encrypted and authenticated connection. - Standard TLS over TCP requires 3-RTT. A typical TLS 1.3 handshake takes 1-RTT. 3. Application layer: HTTP runs on a secure transport connection to transfer information and applies a stream muxer to serve multiple requests. - Application data starts to flow. - +In contrast, HTTP/3 runs over [QUIC](##what-is-quic), where QUIC is similar to +TCP+TLS+HTTP/2 and runs over UDP. Building on UDP allows HTTP/3 to bypass the challenges +found in TCP and use all the advantages of HTTP/2 and HTTP over QUIC. ### What is QUIC? @@ -196,3 +214,7 @@ two nodes using QUIC only takes a single RTT. Following the multiaddress format described earlier, a standard QUIC connection will look like: `/ip4/127.0.0.1/udp/65432/quic/`. + +### References + +[1] [Cloudspoint: What is HTTP/3?](https://cloudspoint.xyz/what-is-http3/) diff --git a/content/concepts/transports/http3-osi.png b/content/concepts/transports/http3-osi.png new file mode 100644 index 0000000000000000000000000000000000000000..addd2e38562929d5805ab33a9a3a35bfe1768501 GIT binary patch literal 46314 zcmeFZWmHvL-!}|fP{IHu1eI2B!;>F$!)pmZbM@J{rcbDjGh z@B8ij@H}H&j^SXtSZnRM=9=sO|J5=;T2kl<5;hVH49pV|VSZT{m2-jB@F_4gep#Yx|U>?Fggn4kk3k=vF_W56*VZmo?82I1Y zVPF(tU;Xo06PD~h`}-Ng!2Pw40r+|UM;QDCNB{NnK^p9T&X@-Id+!J9X%GJX3{ks3 z?4oCo0sKI;5>~N=fkA$8{}&b}@yknaDagk1%67^U;;g!s=F}hbEOqp$oy@K7kAh)$ zVg(<~_3b|3IhmVT*s?lt5d7YQ6@0$mOhbV8dlx%X4gzHfX*@nl8+|+`>UY%d2sn}O z@bK7e^bA;K`33(v9Q=!ez{t+dij{`O(b19Gk)GPp#*l`Vg@uLY9UToF9TnJv%GTM! z?t>GRg)QNqll*-ietlbA8)GXwV@nIX`}2O#v9!12ARxH^qJRGU8K<4G!GFHV!uGGr z0vAYg{~H=w>UT8%oEsdMrL3Kqt8oOJBJcmCg-|MP8sj*_x5)(7Lg zKa7+1uS5R5?SJpjXK8L_qi<__zdz$&`~Q2}|K4BP$kNUd%(acNu84)5z706|uW$Q% zfdAin{B)==0uu6+9HF2;f4|6=aF}U-AR7bh$e7a zy=v2|lHoO&BSsHZf__()njFaCwj5G?&y0)j|5B4HF68$p|) zpRU>SmvQdnS##s`M+26gX7-Nulli%G&6cU0_7ubEe14%n9>F4T!$45HVBqjzU=iTr zxmCT)+Zq17jr#`;B+p^*!N0e`CBqbOY$zdI-5>P#@m?nDIDehz_a^QU#I)Iu9=>0n z{d0b>9h~YvhunYVe@_Lb=f89HXZ`(mG5mKi{8NnnyBPkv82-B${@YUjiy3}D1^?IM zD?O1P(^{U%Y>pPOek^~0BO8uF928=QU9@7oJIVKb@JaFdol|AQTG4X50#EByp__($tU z=uPD8U=p+A+4sXI%=2lNVsX?}u33#$LaYmWGUDhM>UHc6^!J60R1T(YKPtGHCksuk=rV*_4Q>}};aQDHN9)7PN!Q4~ z>3}yu_~em#o0we8O2nv;5?0ZE_N8{Aws62X_e>ZqN>3mRDxFHi2Tv2!mmDsY57qN! ziRpL1s>tOJc>adXVPY*DpD&c_)+uN?PRm0^WdXav5Ap|6`f)1`+xFTGik7#AEO&*x zVztZDnGZsz#CW}21_zlz;jS`#;Kz4B`qk=Z8-YMzt;6g0R^On(wd}TQ1K{G-axG`d zSLZBSCf&x{e34&q)jKrbUT%XmGnmTN(#PR){IzK#to3M^tJJdS$t$Kxw!bDT6wc=t zyAlOthPJJ$j!^)!LKs z-E%l@ML3@$_EOEJOOCVo%#H4|1=sy~+hGM>h`ah=pV=uN-g`Ld-PSq`Qb~^MiihNm@y(~R5`UeG;r?6@-O9uT&$}zF&UT}&i9mG9%D%{~>x=bNT!#L# zN05Z)U>ODaCVS&)lU%uq_a-ry8cIE8W}LLYK0i<;ovbGB4(?OcP~d8i^Cg$dNt@Nc zi^d1ntH+0jFl?KUJMlqP;0mlEr6D16Cex{%y7d%#XM}Rv6h0IL1aEd#J3PD`?T2tn zlHAB?CaV)u#cELmBzx142loV=pARo-{bCQ=P?eKHLLR|Ng5CCIn+sOH;cj3P6|9Rt z+#cMwpQzeQCQglcPyWro?*L1`F_aAZ*M2AnVW1kbYfgOr=TH(&)@Im0t44Z=wE(J5W$7SpC>0jgKb^_!6d62>M z@8MjNdYPQ1vT*SJNBiK$V~6CO{&JFe_3tUWeZgIIHT(tV-{VHXft7dtKWQ4h?d}?~ zx|LCTqDZBR5;NW)=!yOqN#{%0GbDw>L$QUhkLiX+KjeU;;~cY}o-Ebk(rR`Cjl^U$ zLm*c&nL?>#hb3t62TD)W!SjdR@89;Oc-`u5yAQk0O#dW4^Z{sb#l%?&<6IDDTze7VzX<`xYTEe=l3SD#X{e z1GJe!VI^ucCGUhAxNgsv0f-Q+eYBgyUG-=;Q2W_GxAs>O_e{Bd%lT3esMSfKEtgw` zp#5B!!`G9> z-kr-}B4aUmlk3@(okD{MeluLp^-ECPo_gz%qy@u)X-}ay90Gk%u|!>^T(9@x6KwfH z#bViP(Zh`mQ!~0}DP_c{-ddhFC&OHK>P;?H7R$cKn76lA`+)>`056&f_@KsUF`%G=sVdiXHgXWN;0bN!#@y ziH$PSkOTgnjyqY=DdG9YuiyU~6Qh~LepIYlRev-riTq$ZU>#%bM^MyL`%b*S7sN`6LzVB zQM&jELg_5wh|o7|v(|T~bC&c517DNSmOvB05jqz#o3A}caouCN+{l#TyjTGp+I@2@ z8{nsx%og(iq_u4^9W=f>enajplPOqbKBp+##bCAIyiShHQ)jbEU>sG0fPQT`!}(Z^oO{s{4(jy8WcW zlz4V+^IrXS^yTdRmwX~jD;3$?ykkB&XxMKStHmeEZoTFS8P;zC@GjeuK}iZKR_=M& zOA2l%y$c5?=0{Cker{8pQjLZwCWqw^=2$YBHVauV?&mM0{WAw`ia$^=6-lLXy3t82 zQKlU8Q34DB0NT#G6I78=ScfRyMo=`Dxiy#8ydU9weY0)t*$R*O9W**&X$Y?8b(v}1 z)TAvlIUimCBIx9*JiB`^jINeD-^=!J`cQ=5LK2M(pG*a9NO9fhF_U)$fvRkID2g>z zW2rS)xR%n_Z^2B?jmLv%w%F``x-&E7Bw-*s3)>(93lWh@v)`Udp$&b_GFIUyfk1@f zO(Kz4J9T^5PqRm|S_@FvRfq;^cwdmAYfNVHx0hlcd6%A#JeFt1;pW-puO!`@>^MX~ zAaiV3F9OxY`SdHIHypu8o($o%>YiboU}ImNgH|sk`~pCK#tmiwv5Al-gE4aBStF7i zC7U+dR5m0<N&L?0k3uLFDK54(&5Hd7|0qR7NG|j|qBi z=}Jt)>}l?|_@{4Jf6uHDB(X4h(JU&0fUQq$%`;9pMz&AImHgdG|oV?cJ2Xy)Ibbmpb3hM zMwTX?$9W>b{7>h{6Ndm?X+QkETtBEmWab`Lq{f$OwJhxR9!>Ug@c)mm?{4a8`(WKd zuxVX`C-B(n%`Udh&o*Bh!xrjdYsyXi80EMl7?rvi{k+#IRC^yzg>iszQtPs|wqp%6(6q zvzeh?PoYC}8kM~j`i7~z@qrZH*5@OP<@)G{YlGVsBo@whw>Lt#?v;nh?zb1~05u1D z;KgY;%yb02s8SBVZv54TtiXBD@q*CEVXoR7uuC)0$yfVg>|LUZogbf{Ol!p?o|ZK1 zVZYP%T1QDzK^>_eE9Bd8MEoV}Xbji5BeM&LGg57GQKyyofqK>b!t-Y#Li8b)S!W(#2CIXUkh9GI8~3sx#?HT z%aJ>;gUhmj-qXkWqyRM>TAhwWMpM1JSC);aFDAk8zj?Rp8A=?nuEpyT-0m=edJEWv z8z|S9T5i_I#m>|ttsfs1C#Ue483=sKw3Hv@%qeFjW;{bi4m;+rI|l8>Q3BfJTJz7^ z*@rev?;=j_jrr%O*Uyh$rW${ki?x^CeUg+SQ`EtQ@p)vl=qWmxvNFXY_E)#jozewQ zyM-ca*{=<^EruxB}L7l)_PyqH8&l=692 z;GVSriU|4ul~Rd%(P!H(EW?3RF0T0E&c1?ZlkO;UKHbF%(j!ZEa$n;4)<O5XQZ zKGa zY$Z8>60wY%^K}*I$A`yS)}81s$f8nG(^u_-%!@^Sy$_zTTLC(`-NCk3%co&zCh?ik zbV~d)z?*l~a~2hzrk0HdT>wLDK3O?m4jYc6No~{C`%H`1;kioYzEjq1GFd=O`bE%j zO2v>$vr&2dUi1M1i{q;ZUtYaa_PgsN&_us*zWw4bYrNldmNG-mPba%wO=cpTIVBe1 z>e3d2F0yJZ?vg`KJntX*O&e!ZMw5S7o?5>>sGLVKED}%}QLprrJ(=C~6hRJ8#3Iex ztJVisL1oK!EgAaQjBM>%na?w8fQVD~IR%JHdj>wS z*)%6gTLAKyPZq>rC_4e-yvvwAQm@WDf#_ma30fN+H+)T1v-{QU)#BZh>F0q$<+7#aFfNb1y7hukkHEsw zv@9q(3Jo%GExN&rsmJtKX-d8T56SLRVQScoIxf09-keMq>NnwBpS9do)p%<%0b=X! z3$q!%w0yE)Ga)0?n%wrHk+WqIvPQ@_8mta(qf+%h-XX3$E(N)eswF2M* zz_Dx6Z-gA8Yk8++uwB=71bRB53`Y;qNfR$%Pd{^OZ|78%vd^{`JN=S2bJ~M8$sN2i zxd4xCq0)8PO4ugFbe^rxt@%{Jc&K^O+TgYIz_01b{JbQJ?$?exh`XV0uclYHJg8we z`G)GnpV;c54DK6X;J0i0a1Ht|e-<>nW})n0K4GsRfF~1vg>rhyKwe{J(lhQ`wEj zh=A&=0rpmGN~(33OZ;?hJIs;$VwIn{Ny~PSk?-^4QK1J% zYhS_WKD2*Mn5GDkq2%svGUJXY^hA!m_w$oi3>d!YuefRyb_35wz74*sf_%)nNOoLcaokg{ z5L&Q!MPq%nTO(F+`>Xv~LV*MPFpzLmAk)GQ$<+4LzQz8?RMrG4>KXiqbz{WlfUP0F zIT62RgwA+&hrG%~3Jff3+K%Ba&}e!!S@Q1H6*2!Jie1L_;_2~g1m4+Qrt0X*7){R3s-E43|mLXV*lw;kA)&yt?cIZqa5X7SR z%1z(b`v-E$YU0r|+*}RN4-5B^4z8H7m5?E`k7dHWEFG8GJs_~W5~xx`L-P?!laA2I zO?J;VO|@z3;IG1@^2l0CN{j`3SE(qAuKX^!T-rwypSB>4Km0Ov4Cn2av!jht&5MH; z%PEVAz9Z;J6;*a0;DV7Q3Pt`{RRl?Zl$qI}lCVB{@$6{nXX=|EAB7bbrn1+83D%R! zfR)Qjl<3Q;{M7?sAPuao<5I6uwDdBZj-#p|g(?NsCI^^2_}0;r8~jSJxq!sJ@euDGVyr zEYFjLC1aJ{cn&13M!tNc7dNX~Sb(!!CPpEs%xiWH-2b%O&|fq>vMdMDWC zqIhnpNpUQ!?n9lE-Itr}8=o~@Fa8YrP|0^wXa7}}YA*dqnd?iS z73-JOAGFS~ar?Rzg3Zicg(kPUPM<(f9L3{W<*h7U}92I zFu#jLa`5)up0Q|B4(2pda^7|}!g+8^J2W#5vnjr}g?hb-pjyA8ZO@!APTeM;GT%qf zPE5GZ6sh!SLL8j)hUe9~l=sORzi-bRMr2xAVg4P%ai1Zn9$@X$E|137;iX8*h+dk( z_<@3_M1xeop>*(h?0o?Tn&^ZG3&b}NjYhU;Vrel~w7KEqVzd3nX!o)uPfGeT>A+~N zi)+>aEk4j?CiG)sTI3};D&!*bs_NYocWMmS{ zp-gJ1($Yg?mMzufsOUBj9nD!1JT7e$Fw?I|yM7lr>to!)DRyMPF~Y;5fVP*x6=kDp z%2W_9)=l}G{EF*Kprg{VMg1!|rYooiAsMBSrjAD06>w0-a~}pcX}HgY>g=K4&^*Q7 zpD|1|FV|x-9^*&P`kt*bD3uvCRijl{RJc$bwE-U@oKA;b&dFxv;REqgEY&Qop&5LP z!P@j>YnO7gJKpN_NLZ>?>~m|vb39%Wxwku?zM+zS8B;luj^SIY#aNG~R&w4?(P$aQ zuCeKzSAC*tf|U~uPo$F5_z6fR(b|)aceyDpq5*PXItD7&Fe&mlSbBsL#S|%;0@z*$ zNE&MqJIJet&y?bG9gpxK2}OKV;UT>If!9*YLS#>di9i>nWoC|_31?yNUEWM~AiGRnz;n(mG=YAy;hcclb5NYJmrq99nX*mO zH=Hlp7@HJuAFW{SFSdBbP$*;(nkS zO*kPg4eY`1iYvj*l6kLx$qW1Xo_L11)ZBen zN%~V{(*{$NO-%dT2EFTcqR)j=frbn%&^TnZgH@&JgvO&aUlDmuhI+7SRLHNkD!5>< zRKzsNU=%cajP+TVvI+<>wsMDT=#ZN?<_H@^DUE(HrK*AN%-J?%Rv1Y`qsh9+42&98 z8QV)tFLVpNOdyYU86RN_Ch$2f{+5!bguN;=8j_BJ>aH9&h_H~67FLHiJJ}wt zFZHq!x5Vv=Ntq{o|GxLQCXG~n-}P3rlxW^IAC~}Df*0CsKYm)gjg0nIwo$(B`1l$> zB_3{4^W_L*^!i7iq!^ufK~XXcbtKNr1qle=9?A-4+^|}+)e|k}ZeoSvr%^d^Y8rLl z(Ffl?sPtrvhECr|Z%99aI3H%AQ_85`JrGcY zBNACfjKv-Oq%YRfx4iez&Cp)QW@q}>Nx$9Ou>+v>4INA8uo2Hjb8{@?!}}+_w0;w* zJX|T+RWZ?!)J>x6>whL()UX`srX(ku=OQ385Ui=ofQzTQjFdGxzZ!fMWfoRGZ7M;D z=*UJbz}$2^Cg!qS?n>4X0W{+GZMoYUi0@u8x_qvL@s=k|^MBeIsEnkFBkVooK+lLQ zvM+P0J_V1AVMJ2m<3==dg0#+(NRX7+T2wb%qNijPP2zz!Be(KUJ07LS9CAKuoAhp% z504muENx~jZ^{e(`I-upqnC^f(vjnK@K^#LDta1;kfhsaMHCmxCiy4#I!K z&KBh%cVr#&j&##6;RYs#xJ!-)QI^B?`@OAzLJLcvM<58aaIbH7sK1JCGZ7Q-9D|?3 z$$ELoT2YiQzRA;EV8EP#^4-f5+zdce8XZ|yN8tWp2}v~FD3`|JbBv;ci%jvd*>vhs zZgjF9#$md57x?*ruK9#x2#oNSdsO z^PA!QV61hI7n-W9Fk%Y?J59ahA zt012nC|u(Tr{}ZdV|e>7oa+z#xEC6op`q-|jsH@VP*J$q1YxKm<=6>GfU6Nv*~Wr` zK;fMs5LBPD`@O6kn)TQljmXQ91fGVK?=yD^@afhm7Vb>1fir$rW8HyzuM*rVo}-As z&+mNG2JqIr1Q0u2Ag*V7C&6VvoloH~yLS!zKLZAd?egJEgXJP;jRR1Zp!Yl4L4bKk zrBPq`rZd&^w$9_m<&WU04Ip9)tzw>Z>%HI!=6n>0oI-pw!M0~RGs{z_pI+4Zk@4Z7 zA{zOe03^Gw%IUD9{CjC6eH+Ub<9J{;kr!e3Ea`qu{w!I|m+O1;b>qeED-lBV_i82_ zoJHL#hNI*bGEHMR+(#V*6oiOxpAcWLGtSjm?$5OUUN1&qy=10icGac4Tg(h)r3jA7 zNAl*!8%g8&2>alnvY1d9&dsP0?##UktOEfD;xd`VvvJ?7TU~DEHn{$_mi_-G&&?m& zAJ&)vl=^#)oIck8}r zauIs&hY;9j-azy@$j?nFXNzH7Yk$TCh;TNP5BB~U69-qQ>qEOP2vDsaWiKp{Io|xf z2ZCupZn&2U#(LcDMRcg$IB-tc9QTU6ya9m*3a#Dk^~Iy7uZ7F;>Ay@6eFYK(usTlm zpmR@K08|6Kz2%1w@(#{#Cs;?|$NsaKGLujTI^s0qSdW_%CD)Dbx?%cE1=&3KDu~f! zG8z3pQ?b&3xL;+;Y(AT1M2qOsR0~!VlS=ncZDf*HIr23C9f7xFuK6P4njl{RsH74S z@Uz0C_R8p4f&Co{cjz>=6P!sdGJo=g#daP|TeJ!&eNy~fnm#0%hQi1*FMeEvbKr*N zAb8JI7y`3j)jRZ(O1;(!7(~Qku|?{2Ho#5Vo-U=y)+|x4+mQJs9F~Glr6+|qFH~=F z1M(d3sM9ZJ z(JkX-XaS_-id*^xZoVUk2<^|+++$vat{6baDI&gTJ_|%6w*gAbqbE9wr#-h~G);B~ zOPx7wAOUf&?WgD#E+;2SEVV4i#O=t_mq`|TN_~kz~wi|H8&z{)(zv&dOqS2_AFT?FalK-mB zLzTP48na5yb#pvUtQ<3{csZw6qfucX0ff4io6|WV9B2L)3|dY<;iq+0?Wb}Y(8K^> zO>tgJpdV(Jd+Kpxx2GG%k#jPJ&YL;EzW&8_2*?)(YT+APtI={3nTm$dw4(W@&qA>1 zbAZspDxV{cg;fNvHGoeg2(2(2&J5#Jy`rh#AgEz(a746x7cn$in!Gb|N8Pxd^0tTmrk)^rlRdqP z-Ll_&WinNie^ybZ+ih}}B@%VGK3vKH>WClWrlMKRscC5bP>k193oEPH_jff1faz~( z%6w$qUQhLm6?Y87hL*lS-|+y}m#BGRPOO~_wuZtLAhnfgm5>9=+Ml1<_8aAl?Lh4< z^wqF4n#hyc+}va(Vyn6iVsM`s`^m%SOLg-14fT)x0*n9EdRfqz>MCjk$^QenX%{MfD7)(4l9vG22Phz{ zL=RRvm3TtpZ-D3+lwp0`rp?rTsRW&=Y?j>(Y?~&4|4_yKC+>FNPl2UvV=DS)CejTPEY2#rZph}`iNM4)ZsQ_+pjG6YKQd$qVGN+)|6DBb3gGAqGfZjfG2uT3gx6)#Md zOWuJ;N4zMs@dTI+iR{jYzL=V1cl9h{7(M&SkGRq%!4Pa9Sk}y6u%w8=|C97UL4h1<*T>dc_wRZ1HKQUh`UMkc z(rHp{YGawSrEp&DRDh(JSaF|Fi9edYm-A+JoWss{{0OR=8jrp3tb)Ou42$`j>bL7n zk`rplv8arc0e!_DGx~AHk_Dftu$2aNLs`0}lz5iDZlU_c;bxXS_BEjjBr$?pP zQwa>G^*8{=R6=j2#Ya@X^dN=l5{Vs;CK~w4>@R*zkbsVZ|kV)?kMZoy#bj;ayU^|g+24SuG0D~3i>C z4Okl>Okj+iw^mT#W6-yy)w%V(A}iNk-kw4}@2mM-H7cRtcRmV!7DPVUvqaOvl0i%_ z&{0f%b^wAvqggq9F2NF(6Y!c9O#=A~viAZ!1bTmdbG=-6 zuwFf4os4!EnghTW$93PnyqakVY@But60Emb6|G9M^6Xp}u65;P5tusHGJL~2fjx=C z!Z|eH{Vl%zZg5RHpdCf{2}E^CHI(S4c=Sj;;o0$plBfI1!RX@qo1Y`Ns4QOPmq8d5 z_&A&Ckr|pqa0ISdlxxnQ1m$o=VH3?>u|J<J1j%)x4FwmCh#b%jWy^E~eAAOZePsHrrCh}(!RW>cberfQ+^F8P`O)Nx5#Dx3A~hxhhG z72S4WX>($TFFwwgs}F|X7`M24)3(_tUP9>SY`S)F^e=zFXI`7_3m)yOf9}@Da^}!&3p$r zEh*wbju<3nRJucDE!W*D8?KGKr@gzylj6kXlg*L!?7$TX)Q&ihg;P>RU$u#7;FVz> z8+^WzfQ>iZoT0t~sex|F`NS6=NESIT}$l`@eCu)RCHDTrRZ(mv=E|^c|8|a=`e!JjFqFHRxGmCK1KDLi$j{GW7!5QYi}X9 zj*a)UXpjhwB|hT>Ruo}62vXxjDiIqQ{D)@XW*y#s=SW9$%JSn4U`2i5zZ2mBFf=7r z+OGVPD78|9NUI?vU9d;FBFm0GP{USU>NUA8W#}$>j?4`}!`I{t@(F|DSw?188H@<$BHuDw#q)epACAO{;W1szLNUk%N9FprY zp8iIo+&<5x8}qJiRLUX(?})nI@|2Pos6hg`tM$?6UphK+foK|0mWk3+4EPb#5F*c) z0*gUzcfd8O*)>`#LA)w+CHr$4-WSr3b9+V2gwnq}N<7fN&y%1c$`{D@GO9tkKvIC- z`;+{x4zNB9Fp7p73HF9Gpdumh#-*q=U4OVN3In8At>!eI!DdDHp67=v!?9cUh%Uw{ zpOPk21r*G_*rRjWbJcGVsm0fR_xtKWBy>5LJjtFasp37HH{Oe1=dWWRL_Jd^P39o~ zKwY-p4|CQeHNW`~P#-U?-+7izimMnA_84UO;`%I4Psd!Q8C`Gg_6%u!2sZK4QvOY* z=b|%3oW`b!m9q{}KErTrL)RM>?jqyKzm6H z@qr44YnrrKcbyWm7z?Qe$9)Gt@oy5eR zhG7zMCXtMH>c3S%{a#@hW@BVz4}W0*^7om($P8th8vx~QZ=v380)qRGhmtVU( z^bO#j3n0wF;BkEpjNvV7&s~s62A%>S(dF&@<-laRpAxtPZWkAqIBJb(`SzC=z)&aC zOw(@l;i+a(F~9PA@LuH+);DY8vTYbuUlA1lly3l67hN|4&j7kHnn^sPFe3Wx8OL!r zWD*k0-vM_Gfv_F=L&+lnfQh>6w=#)qliE&duNKlf*-hdTV64yPw zCs%6s0M--nzN!Onq!$Po#`R5rYOSP@D;CAKD2}}P^JGSP%~JzUzJ>~fHQ$jeilI|& zio_OBlSqEaOIreCns>l#Z#&)`NBD;b?q*`h%RP*yt-$?XRv=!i}#J%Om7kxQ|e`iIDo zl)_;Rf;>GGaJU-~`{Mw354;iK4AR?`89tiNZ~(^)j`>*kXcA{&+eZOKm>uGhvu$j; z+YDgQMTefT^gSvLAAws*XaRHC2@ms;wALicW@Ep1_FMAVSsz=7$uj=J@y>9TENG(fQOF=Ej9>NDsD0NTnoOj>tT5>b zr!_WCxV3akpfmX(dUF{C3PWZ712%_&hOGib{XTIZYHSWBNxfCFP`o;Ah@&2?ET3_< zT5RsEGA+H%O`RHwka9rf55{XJJkiW<_pF3GOngjnu#Gn5QK+9tjM`FrGoJ10h zLf#0xQge5E)-uSp1=0x&$#!c433ad%BA*Ng;zxm&LY50;Jfbv>SxXQJOUyVC!*!*%*ympC~HKui`T(l1s%3vjIVTUq1K zJIU1vrJ*GN3iklBn?w%yvTEQn_3LN5-*ekJjf2HJP-l zd;L?^o4dD@tS>(YBY*_isPb#olTN36EP%GQW zffyS2!io@H?lpY7lnUgMt@upgg_bEEh+DGQVbfaseqKmUWej36%eza!StW@xDRpXp z0{@J%cxUkaSJ$)4(q;<#wS+1ym)?oDi&fjfF_bmIxGlO@K6rE*Zeox^B;xqh`z+GG;;vm*fTA7jZ}-_rLO0`_x*Bgi)2 z4X@|$-xOgC1Rf%}$UF|#M2s#M9DR$#f6vcXi0J6^=X>Q@JB?h>(Na?Kp8y>rAdoZe zPLpeLbPNj8j|pp8qRNHVyE1U0t|dCUSrt`6P5qtsin9@C;euLp#h84Qe_Y`LhuGr$ zz$H;&$V{bi6k6k4nq6Z9mPG3JXhve+&i6lWQ5ksvpJDxKmj|>>C%`@_&We})K<3Q@9y+ZF;QVic=Duz0* zCnI^u?1MMcMosU@oK8W4l{Ea=_lo1G^i|yxPCT|kg~Bz}ymCdyaz;Y3v{^#0F7jT! zA3tty*w%*^>8zJZI)k3Qc^}UHK$pk^^?S8>k`61n3HhU7E%z}gE5wbY+V1x^H>W$j zCiI_6MvCf%Yi}-qx}{#Tw}$Hx4~oWi%Y~q=EaRsoD%GA7O#lmrtz)T+AL zJ9=%y-2cUK!T9Pdj(rtvS03&<^7iJL*`j8S9BIwd)gpv=m3RXY84(BP*84PI5yg6K z3*hOOIK+PSYH~c3v+R4d%UNNJneq`!i3j<37|tCr7=r05&-)S$3UW&rYM%FOgzlu0#> z@3h#|_S>sb?pAu6l|n-M+?DuCBkkacO%NHskdxxjZwO5T#vlxKE}XAdBVmH1B^?`c z2u@S27FSHo&HkHN-LnEE%>?=EzUbL1!!K@!E7*(-uH*u1M9%NOVqwA7sjWCh@NEFC zFV0WlAXJr2Ix3vNl&Yv=#bHbfvRpB`_|-}YbDDL5Rf9gSZ7Uj>w$e_8<$|@0F-npj zYC*#O1FF$^C#FCW!_2RfX`L^(V+bRX? z1+RDeXq?9-n8{P?*IZ0+a-Vk^-Ef}dy~s{dP_gWEiI8>>7^JmVvK*YC$Tn8;3gp$P z{NisAM4|2e%?q{v1FusNl98BRgsa6vp4e53JN;nPjT(tQJ)GRoe}qRAcQ zU3u*$y5YPwknJ6C_02G{6MhCO@Y8gtgD9{j|P`nm=2B=`&Qc zNgrXnVymCns_sW4_*l8pos%CQ#hFZ($j?=GO|`Hy=yt_tVijv$9dvuDd%Bmc4VrSC zsjEg1BngJ79(BEH(XXTDinK-9c?!HN1Wvf)I6@O=c36eQ{Af%Is$wP6oNjB z_cED}iA8^Z=XPEn#-%A=VGsiQAj6pId|i;mS_kOiqAq#4epvY(c@Y((kJX!PJ97%( z5c*6;r|9-Y8TqUcJFj9+yZYpWC-R9x^WIWZP-13Xlc*=$($gCMeHx~w;Sq5 z`b-Fgz9#Q2IhDZNl6){)SViEL)ncDHb&XgT^oOMg)N0(emR zxdT(kA9s}GgUh87pPAZpQJM%(9@C{^K9JCz>~CZ`IpKb@Y0kgu?^$=1ORQ7z9u)#Y z2K{lRedaX@iAi0-5hh&a8V#A2b;QxO*|X?y&O8377oqI3Ct_dha)pz=ArL3nW$&}aK0$b$VzI|iq4Q|30_^M&cfR#U7x%-7yF6H_Y>J8 zB6m#W>iKbJP9ABBq!IJ$jEMy@WFY1sX~|S4EDa`ZdMfPKi}BC}?bitvxc9oBO}bv~ z8ol2rE4@>wI~qzb{8FYfl2&jwA628>YJ@GmXIu5I;CjR$SXFAG!b_$@cUn%K=QEP^ z=)8n8K@nFQLtfU-SfA(ZMJ~h`jl{whNz9ybx85VrQpPLLop@?X_*9NNhoo1bl-Z=o zJC994IxB<}L6e8=GM>Dqel~)&CS-#@Il~__`!j?0iR_V!?K}OOX{tw!I>)Prj(pc@ zl}73Baj{DCUIjSKse(k#@BBc3gm!8Qr}JU$Q9@|_8n!+<849oJ#||8pscs*yHJr`< z{4tNZ5DsAe9d>+APN0V7US3`i#l^_RY)VDnKK~vsNp<=`T{K6+U2HO%CTdnZ{e2D8 zA!(ioNV}7%NK~V_e1RdOLdyAklhZl3IeihCKANwJ6j%#55;679R+M|}Zny@Q4&B_R zgv?p8#ZAGhAdU0F*rDtn0Ao#=$@fwUk^DG$X4Hu~({jdw9S(<1M82XyPd^M^U!ta( z$S9?)uf43Gy8D6=)cgK{RA%THdLrCB-O~>z;rK5^;}#BE;5-Y$HH(x7c|IOu&@^)d zjdTZxIGw)5Wf0Cc*g2Ndc&i^KGmAx>eJ~+jK4?TD*+ZOuy^7(VqRoUdzZaZ?mrdzi z7^ilGIBG76Dcq-={!_8MLFfdpDiR7!byx8|bYb0Gj{rGIi70#Gh8Y^IW}Wd6@o60Q zqe^}AKFOvBwUN+jl73x+nMu3?sBCt)D%`QT{5H0f<&4ebkJg4~Qi8o|dEw8!6)qR) zjPrdzj(!&5rVl?>;-^#XhubR5Tgxhdy_t;IhU%fpJY0;D;#Bd#%cdHCBOUK8#hi~=Det#sM9W2f2=cOhwwZi=Iytpc zHy5Mibb=)LLc4Kfl_6wHa^$FHmmeCq3VqDNxwUGo(r+m!=jGN-Zn!S8kMY$$q&Yxh z>5B3(qjtm#uAB9j&`Kv1?GiljVpSyt(OvRSD97%;) zC)YqG1?ux*dxl*ZB!V<%+ZWtAMjKqtUpsuk%lFo;lDP+@X<_NE;5~z*wIt8iDcG`U zCX-{kbN$nrSspj%ul(QxxVc3htOzLn`si`k+LK+J)d}7Tm!;EAC>0i}uuGj`Sd=2p zXN(f@P?Rv1{hCuCGA`!ZAE3`mT7gx=Ng#$&n6px9KP(pA|A;2Fgnj<-c*BmR5KXi6 z`{S7Gq-@NXuLH09a;#l@itciamB;pG^WPfV9Bpgx-ch(L=(&x1V5R+1tczm2It5W~ zdA;0&_RUuZ_ud(dTm-GT$=Af|EfV@_cVc&*RLtmGUSWImYMc~~e46Khp$fuYI(c-G z9{ycm6~8;PoXs-M+2cOMAeYT|+?O>>t~zZxJGESJn@~_9&mJg&M~)?zJ8%7n{oIxXqO(l&f#Y@%bqLr?iXa9zGNzQ%Jf96`!EP18W#ISBC5S=xSzCEMhA_k>Vz zqy2boG*hYRy8L?2UdxlCi0dI|!mD!&_ViCPQiw>`M!a;=BHb%uiZ6p3e~2RG>~zZI zh|BP5QO)KK=crIYbLB*%$Q29BQ?1GK)1RB46WbRukeB~c9rgGcuvl}kJwQ#Q~^6!=Y!X0QP^BGRyhj5jcnwW{-_vTG8+$VGz zcTz$poN0|uM48FaOO()zrFR+V>nAcz3;G-)cn=OJ;ym18NV*V>ExNfrQdKcNTk4cOy`WT}P_8mLO$}R#v~+)86K_6J zA(Y>hcz2paV18;oON5#li!JwwFy;LR-t)Hu<5FDESn_jmuUdyx?{N)0gdL35>itf)A=Ckh^9LD%P#>y}jHz>%%N;V)N zchWd`r>Z+FF4JeX$%*JLklnzI#+m*V%Q1|+A!yh5|Do$GpsH%Ouu<7=5DZ$8ltv|# zkS^(NkWx@OMUW5#K|w+3Zj|os66sFqkQStoM&Qnk-*?XW|9kHk49EG-SbME^t#_^W zo%5N`^GrpJqEvnc^QkocrIg}n)u=&6GWmpt7c=U!>{7{i&1@`CmCi<@AY0EVZ z8uk3Z+MDG-5UY|b16HKI`iU`dSzfDM= zOSZY)`)LZwzLxX{t9PQr%r09f4~Y|SGB<=8$^Ft=TRNf28Ymh1993-2*viPnoLi9= z&6JhyTJbCFOiXgYOm)ameAhJDT!Uvid9q83SG;ZRI$<($Pa9h)%8r9a-JmD3wrekV z0zD^no><@ix39qNs3#~@Zzn#k_>wK{%u{A``Cp?2yAWY*`h)-tiYF#^EC z`;6h4Oc3Mp7s877v4j1tDh-)=-&ZdSKYH*gXFg6nxvJf^{chMi>4!JLlPYWN>>(L3 zL#rHT<`0Izqv&zC>5UBKHQR!$7c~rqwXcQbnr zcbsDlZzNd)Ur%?JTx$fuh9d)o2QlAG-vx0`2Jan5O~st`7x`ncw92E^3D; z&hi-udz&l^UJ=Xaec%DHYrMBfQ>Ur<^Uyqj%e=!!Z)`uhkd)P!sP+N4bHTQ|wnBZ27FTl3F?N|*=;JX+yI(2v(rxBkzRhM4ANp=GwjLm#Yv~= zl2-qrfuN$HazBEn$btf8EaDP`1E-Y{fZtYXUws)QDm;Pf`FrQa7HG7h%lCZOewIs$ z=zXFdHQ&CmlGed|uW8<~u7uuT8lQ3+rnCZb#);g^rW$e%clopoE^^(- zdAZ!*lxuW%5i_Fc%~%<4AIgliF7>DjpvStVcGrlG z*(b-4h#nnrXPhQj0Bhssd!&aY*6lAjF0sV{EZ5FDP@3v0S*lFgln=i%3@SZ@bMbns z(q~!S4i|`0(A5~Ciw;13*l`VfJO1ddguJH;EJjk>dC@atW8Aokppf)6u0S^A5|$u< zt?RX)?qFoLd43ueg5ELVb`R6vc8n+9{ho|TQY?L`n8I%3xi?Mu!`f-d=piL4;BRsauhlGQjU~vEY}N zg9xZBaPZWM2SZ)HS=Ik;JJ*u?NY#ZjKJq~jydWI8>cNda0$M5AqkYF~z4R_jxTczf zcf}+ctf)c@6JJffPF-H6rMQZ&!!m?rw$`A#Dr6L`(SMWfX}$-mOyid`{LYU*@Yt1T zvi(R{1r$1iguN}2q8*^9F3Tk)(Ix@b2cZT;-~z>l*UO91J~QVpMa)jbqPw)-mfA@p zK*~+_F;h!%Y!;MT|^2aoiWw_?Ml-k2Nx{ogJkzV8Uw}VBWJZW%`#9ZW{** ze@SA>z?H>R;Y%pX09y#!C%S=5J8!LW?f~RLOXJ=yU3ewhyn#yAzBiXUbMh-=;-JYy z_hNV4%D)GB((9YBj4DHMqBR@}q zPfz;5d>%z_#`gwFwkgpS_`&tQw3O~RzVTB|>xlyhgiw6uf9iaw3UI+!*Wq(hCA^6r%N{+LZAyD!!I>cwhGo>jQocL%?sz|@sPxayKxA>T zQGn38nc>49wPRl`+VI!(wmRAGK0n=()G=B3bWb5$&FtCXHoF3^naW^hh{ez!0>!8l zQ7TrHrBkgn*rFtNp@T18Daz#L`IV)=M$FG-rkkK>170VVAu{B@p>|VhIoiMeCGeVu zz37K-?uF3FPdC&nj@Km`J`5AHC68b+WIJuQMOlrJO%zEoP>hvrV9I~$ywAQpJyqlI z^UK9cYNsnd8ovI>tFm_6m_om+p1E6p#qa$!zM~%?@j03-GQB2jh)^ZAaor%5c`BJZt0IFwXsO9qTAogJvK` zXW0h(aqYh^THGDp&wb*$!(2v~q4#4iu{F^E16xjLyEO$zh|Ht)$?1rJdFEn>;v%zV zZ>d(bR?#mUK}{(7)>sUU#1T>gQKX-sV`4sEqbCV;@M%EhL)FREj$x5gfPyXxtpN^V z8>_HH&|4(Pn1A_e-w8fv<-bG#hZjKg-S&pB;4;LbQ<`nq77ToQHxSwX8qNcoxfbyF zW9e(TNpxH$pOEX;q32eSwqNaaC1P#j6~H%;;_r~Pzpy**j1ni|Wa|Iyk!CztwZ4t= zJn<0+P%mMHZbneQ?t-hxATo8P;loORhv%_8*JSc^6jZodTIijCVLO z0CN^)^#V(bp$MfS1z*y4yPePUUnpLP#qZpo{Pf{x&glb>uv^Grl;h-SL@`iIVcL$p z@n|?LM?Ro8XJ_X+qekNoHYRsrZsbeSN7PgqZu zc16yNLWF|v1q0B0Bs0TmTgQn05K8;+jEIMXDH#w@CGR&$ynOv`75VR;kv-QTq3SqCko35R-kDFYDL+Ri2YZf}c-p+fMyR zvvya~;?T3ylvj_BdW3%b%$6-*i_lA+yFzX!H$^SZzo!9=k2Ni)m7GhlnyNKee-2NN zy+}E3I~|bM*s_9I#`b@J4XIU-tKnyJ{JV z39}4w#rE6tDJRD({nxXVlbYV5*C%fGOHydP9)9cvB?j9Taxe4mBPFJN{b(19@2kcQ z>j`B_;;3s1n)cS~So5qOZ^)KdWp#~`^I1b}H&H%X4Y^0w^{l9RV|xQsY0yg=|{$2)qC37 z&XqR=9&_4EZ+l!!sqRvjx~HD0eRdjlyu%tpF~}0|&hV)HXTpy%x0(#4a_hraT1X4zW)-3Tu(vz$v3LZ%TEH+Ngo&A!xCOM5{-hC1E zt9opoJQ+6lVk1-ikWoWzMD8{*l_Q|7CQX;o`{xx8J&)4&Jl{x|uG^O<$Oh|oUPXy= zP`q;v@XY%BIEc3B66$)Pqv_H%c*K8QIsaZd7*uEshv>#m=f|Uhf(r;~(0%=PbZ{E@ zziD|u*A}d&|Neiv6@d6jY3=`gLMg@VEmr>XfYDu;3G;SK2T-IQ0QU;yJcB??0rFE? ztnEjQvyxX>27OposDZSi)J?J+WT-*I)ie>D%G+T3Wdk@k${dUr3hfIhW3`t9@^mtx z`G4I|TdyI+TIVs;$IiV5J(B5qVTl6X{52Ae+u&3Kb>*euJU!3@pxi=}$?snTJ;B?D z?&{%hUyxH5QY&i5(_o9gq-S_YNry&+RQJ_F7!bOIKzT#qy3+>)3P4{k&98ft-8RASb+8B*Yhc|`z!Y^ zAy_GuVDCq%quxsdPypiU_BVX{S6o&v5xVf`$|}mt2I$mdwXRj+t?_I|?I1m2LBI9% zQ!Iu@9qvf}(}toR!Ex~2nQi)HF}M%Tb7t42hXSs4?tTlrNzf~At)mv$IZcYi4E5v6-|8BSplv&WI}HI&H{+wSbPq|@!py$i61P+B4c#S%xm3z8)_me zB3_r#yA)PEgs)<8SdMJMMT@SX%uay^RuXegC=>&SFbaVNDQ%@r)W-Of&ZXd4lZ5Y0 z55oW?-A|;i`!oG+sGc@8wB~|&kt^`5ocXRr`bA#!7$HbkP4gdL0zRnG0VgeokgHcoIHYR#q)2ATFp)m))vM9*Pid=GRXnc-3rG!L(yv8eY z7#lh!t$+v2O}T+?nRVP>H#6ZKST6e5ujYAy4R1B_5<&PZz%h`S$yE<5kY`w zvq>SZXp|61UCOP_k8Afx;d4Y3h$SVD`4+Wrv0oav0mOk zpf%sJfcJqdbMnzrZqj4&1l#sIwGN6VxUCNm;N(zj1>tZH>c>V{<$}?nUUhW@(Xg(X zM&JytuUvm|67;Ja7L0#?u^!FFL>z7rX~rFd35Ls*L7hz+n1+es)&pW>3iu`6n70j0+MMW zW^IlaEpHdjcQt)Xr@{!(LSALtLfuioSumaKM7Q^ey_u4NDFW8L{5^{{)c5?Kg!MCW zB4y%%CqA7F?UHbCvn3bjX8$agHvVF`~`uxB>apE(;}~U7o{;L>^^8Xdm)YmHEIAM z6b+v@eY|d0AsXG|0WZoW;R4>*5O%^cKRVRk->;cd*Z&!gMD5Vf9|seZt^E&tm`GUs z%0rdc1fLFzSq|UQN|wT_f8#2m_#f9mPepw=>mDtgMV``^w_xZ>gt86Hcj;%CG2Qp! zn>;@qYQGW$$G-ilEYZTxE(e$fZ!j_i_T<>D`X0ZRxDEp3K(hx9|Fw!OC+O`D#9trs z1&`7(HZLa-t{;oJ!Pac8_>X=ZHApz?1&?XmNMMv&$bnQ7UgJ>^%eD4@BO>I-I?zaF3tV2YnkX-T z+d(yBN@xWMYtNc=)Gd?({hzQ!n357XZypQF=!3=L0R=Fk3p_vER5GCzpfbdNjTOZt z^}*89+HeD0rb!>W#FCT3@;qYGS#Z54c!SoWC+Oz&e~0OP#RE`;#=We_De&F{Kg$;Y zo$X`QN|qddXZ+8zyx?Jj+1hamSnU}5ylI|hK_XmP5;f3i(EYcj#V?`63aG~eHU~1( zU=%f4{vt`>7zBc)MwidO3m>r3W9S7E`akoXj4ZD1M9I8+tWmG$P|g~?*8v0~$BnlJ z*9lB3QJ%uM3Rj|5JYesmtN@WTMV7i)rHEKpTh!gB^RUZR%#tt*F?@rzVRiPWgs z@uaP@6QsIFD#3>gO*#SYU@_klSo%S)4Li{b6b^7qS9jrj3{n^frpBPFk6680?n6Ka z=G<@2PEX!{10KLA5cvrg@fyD*jlFYH&;N@};rk1N@K-km%lD<35;nI7Y@b`;srMMR zpjB{DpEpTx1*6m-?&Gm<7r%_DZYHuDo?pjXz~j&1?<&9G&Eb@-vvEEGr>xZdvmf+b zGG!H}DjZ5dh9AZ5iY6+3lu2#BDK5q)ZiMNDFXO6AsC=1D?6-Sze|pg3L%Wk7C*fy> zt9Bb}6J|f`_D*9XhD(OVEb?Y*HUwOUiV}92QVhcDKmd)JbRZ;9j|PBSK6Nt_7#9Fl zla+7!J`R&fBtu@sCwEM5_!E}E(_e`n5B(`+xgXq5jZ1^Xz@eA`p&|Hp+AsH`>$t!h z{(HWSfW~0pJ~ft9i6on{&-pLiF_WW(JrL*NfmJA5t1a@7B^`~xvcD`fD| zTIKE;s8JLh4;6(`zTUr-kz&F~F-mtNJ^{g`*4k9fcozk`>-^@7!H_aK9dyWLyZ z6ceS`iCbChikZyrr=~f*BtpyBvk`dS#Yv0+1+iTolTK-8*Ii}=9JNeKIT)|tUilb?|1Cb{(iQP* z1NX#Cv49@f1|eHw+$jJxmIE^9PxJ_$Qd+_nZCsCh0-HG%J1NPL7pA9F^mWP)9QL3Y zf}+(;VwXI8)Ch5<;p)LYGVokfB=t9@YWCg(m2RvUpBk4F0rprWacmo(Yr!}zMqLE; z@cL25$6c_mf{Ck#@RP|4wUwua!KLuZfqmQ_aqqba(C(g(!zupnCs1lVX?`d6Wxq6M zjwhz4-v!oC=lyjn69LGYcyi9#*rN|P#zg4EDEX0NfI1eNsj} zytV!6>-Z7fXw#Os|C!+cgYJ>b&mZ?3oVSh(er!zc2F%&VN!au5Zm4~cK+nz9EKh7O zBcHfYUa(CZ_WaHIUV8~+)q+f#oIW@nlp>yTSn^6?byvuJJNyZX#Y!*%H+WSGa*J3F zvwn~iJO-Gv^#y)mVAC4N;cvW>rZc0wZ#&-#{YK89#4!O!PQV+Bb4!rl#UZM#zfPqL zrtOccaOR2L4Vfk)5A)s3$)nXA$NWzWZ^4kx-TB66)J zYPYl^;_T-)gO(E%6SikUk4dM5Oq)LkFUYC{+t7Yl6o0V7nJatpSjVv|n!}>|kzM7J ze*1&j8Ly8w*!)&Z+L0q4QNmQ6pVhy+ipJd*B9erV(Q=L zklYZ;IA}GI^mj9R84*z#Df0cz%6g9cQK?|rZcWL?0oB}_KdUXxYb4{Tp;8`oAT@vp z+3>Dfwq^meYq_K5|3eni=wA>V6Q6;bwSk%otm|`*5+tuu@r6Gt#&W*^?FXz$2N2(Z zkMJYFFQJ$S^s2i$z=$6!At6G;!@P@DlYiw`$hG6@O+R8j8_UCA3ps{dVq^UMi}m3| z^t5LI#x<$C=@l<_oAU{Loln7-z0^L3FOL~ZbQWY-S*mH>Aley(T^tNzQ2v43M?d~% z^{rqu0NqUdc|*41gy>4-f*>C!`CHWt9-{i1- zXN|Kb4?l5Pi+tSTg8rQ+zy+cmx$u@sxHK5&2DPBH7|qAuIo#k|W1@o9iEd=jER{h2 zc-f=o5{d4Qx&hUxKd)R|N3uFTo!uN0c+}P%#~+a(-a+VBog6HM@a{W1*?3c04f+I5 z^7uxW3Lk>E*LES#HD+h|RSJ8Beg*gs-*QmqGkTZx zic3Fl+y(1#5>*yNoNTO%7vC;eqzorX;`CQvWUcaqzAX}beL^J8452fHMjeo}ygO|+ z?&Ki8=%!R0F!#ag7i8zN=HP|_eSyBIm-61%K5~ZC&KjH{TB$smrbwreEb5+?0FLf= zMPZ;{Ce*jOp?0tEf{>)VJo1^RJHO$x`G=-AiRCW*xT)Rv>LhZFMJL~KHs42WyvB7u z+o#C*4G*7V?S%b3**Jmi$Qon`!mVFQk-Z9P8iUzd?CIb#y#Tg&4X@r}3bOsWRzMSpH3-EmMhofQ+htBVujEAbm~=&Z1&vR5 zk#S9NgEc88)S7CX3%&*UgQ4toTFS-EIe)(H32wvIKrr*|1-cc%O58ytBCUk#^ze zTkRNV&S?4UAZOy9qFj{(OFdFlb*6xDtR|kjQ&T7r;;aN&v8o>MOEzAHk_RRqZ>eS@ zFSDkurDv11RbgWRRWRkz0gyDr1qPU&uu2rF&VYT9cuA74pLxr=HEosE-4ZM@hHzVB z&$ZY=udQ)byN9)NhwOHXa=O;wme8O#0rE;;@k0Q}KI{EXbYGYIa|(*3(A3t{H&PjK zA{v7&wcP_8*s@{)-=r6TN8g(HEnN>jCw<&NbDU^;TB0;+K@X(SwAyM;B@v{GG=Ri2Vw?F}?MM3w zIb1yl>JR#!a0|2F-kO(@$=wzvh``t&N#g7TP_?g{Os*i{w^WnHt>FVSBCTCxHAi!tV-{^Hnv%O7?U`r^&F)_ z)SP{RCQ@7UJ2)Umx}HU(Ux>DBG*Z6E_nX(`2=-0dfZ&oLR>>G<7tTcOWg0}3xciTL z)M?8EJ;>y-xx;0%)i#3LIw_X^x;*q>g(^-6)?QgWXME;*Yj-x?R{d-+Ld=OtFQ+=^ zvls_*v#Sniv6@jXI(^5ZLyUt9qg)|~TD)_0^ZGY|IGah&=%>SXBpmq-{dr#S*Y_Qj z`@R9I*vR57qn1dkSqy6^3D?B&8WNmsh}PG9w7-?$wDRuZ_5Eg!WY%AE#qW4qW-ck8 z!iq6YguYr;13JFZSQ&C-=<|`+U#k_Ouhu+1wT6w^ERt|aRngUKOrm$^37=+L_clFA zo7+nkN&Hl@DEyd^{&a-!=ZBmd5_uQo?pmt$T7SQ3_F5a%sE3TtyPA*tK|VXKUb+J^9Y@pC3Ke zwhpHvhi`7~Hmnc7Pbsi%rr7LhNASJFW%3TV7Msy48F^V z=}C!r@{xw`=`EDpvzSdsXp5$$S9V8QQL?;S^{wa?S(DaV{k%0=XA<%J)x?F7 zWp8JfttKMS`}$^6Ji4*-94DO%D~3)DbJ0d2|L42-_k$2tDA~4&FE2`Tj+8e}OL|yb zW1qPtyShU*Z)n^kl!9{L2Coz$amVLplG$mI?=X4jROzbM&Nn`F)tGb)*;mooD=_)UIR*)_<&rq%8 zAW^5~QzDiI(4E`ZJ32_Tunc+Up||3G&E=`JhtYA1`22{y;V>?@i4wy9DzO;zV_QV{5c-HmoWs^X!EcFw0rJeKWRzB)-P+di2q0W$atvMPtx&kbx!(NGcwKyp&ddmCtZOfc}mG{vM`0bm$o?} zbffH-1;!Z*wn-itV{cI*C{1jP)#kpLUiyKLcu2zhNwZ~~�|C`|uL}1K)e)VXG{c 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 Oezeu~DY Date: Fri, 23 Sep 2022 12:19:36 -0400 Subject: [PATCH 14/18] fix --- content/concepts/transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index 6d21f077..d2272ea5 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -160,7 +160,7 @@ more stable data transmission. The following diagram illustrates the OSI model for HTTP/2 and HTTP/3 [1]: -![HTTP/2 & HTTP/3 OSI model](transports/http3-osi.png) +![HTTP/2 & HTTP/3 OSI model](http3-osi.png) A web browser connection typically entails the following **(TCP+TLS+HTTP/2)**: From dae6a7338367159e63cb8d0c97a7fc40cab6baa3 Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Fri, 23 Sep 2022 13:07:06 -0400 Subject: [PATCH 15/18] direct ref to image src --- content/concepts/transport.md | 8 ++------ content/concepts/transports/http3-osi.png | Bin 46314 -> 0 bytes 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 content/concepts/transports/http3-osi.png diff --git a/content/concepts/transport.md b/content/concepts/transport.md index d2272ea5..e1f9b4b6 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -158,9 +158,9 @@ which turned into a proposed standard for HTTP/3 in of the existing transfer protocols HTTP/2 and HTTP over QUIC in one standard for faster and more stable data transmission. -The following diagram illustrates the OSI model for HTTP/2 and HTTP/3 [1]: +The following diagram illustrates the OSI model for HTTP/2 and HTTP/3: -![HTTP/2 & HTTP/3 OSI model](http3-osi.png) +![HTTP/2 & HTTP/3 OSI model](https://cloudspoint.xyz/wp-content/uploads/2022/03/http3.png) A web browser connection typically entails the following **(TCP+TLS+HTTP/2)**: @@ -214,7 +214,3 @@ two nodes using QUIC only takes a single RTT. Following the multiaddress format described earlier, a standard QUIC connection will look like: `/ip4/127.0.0.1/udp/65432/quic/`. - -### References - -[1] [Cloudspoint: What is HTTP/3?](https://cloudspoint.xyz/what-is-http3/) diff --git a/content/concepts/transports/http3-osi.png b/content/concepts/transports/http3-osi.png deleted file mode 100644 index addd2e38562929d5805ab33a9a3a35bfe1768501..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46314 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�|C`|uL}1K)e)VXG{c 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 Oezeu~DY Date: Thu, 29 Sep 2022 03:38:56 -0400 Subject: [PATCH 16/18] incorporate additional pr feedback + edits --- content/concepts/transport.md | 70 +++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index e1f9b4b6..ec4f00f5 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -119,14 +119,16 @@ and some places in the codebase still use the "swarm" terminology. ## QUIC QUIC is a new transport protocol that provides an always-encrypted, stream-multiplexed -connection built on top of UDP. It started as an experiment by Google on Google Chrome -in 2014, and was later standardized by the IETF in -[RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000). +connection built on top of UDP. It started as an experiment by Google between Google +services and Chrome in 2014, and was later standardized by the IETF in +[RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), +[RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), and +[RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002). ### Key challenges with TCP -1. Head-of-line blocking (HoL blocking): TCP is a single byte stream exposed by the kernel, - so streams layered on top of TCP experience head-of-line (HoL) blocking. +1. Head-of-line blocking (HoL blocking): TCP is a single byte stream exposed by the + kernel, so streams layered on top of TCP experience head-of-line (HoL) blocking. {{% notice "info" %}} In TCP, head-of-line blocking occurs when a single packet is lost, and packets delivered @@ -134,21 +136,23 @@ in 2014, and was later standardized by the IETF in is received. {{% /notice %}} -2. Ossification: Because the header of TCP packet is unencrypted, middleboxes can inspect and modify - TCP header fields and may break unexpectedly when they encounter anything they don’t understand. - This makes it practically impossible to deploy any changes to the TCP protocol that change the - wire format. +2. Ossification: Because the header of TCP packet is not encrypted, middleboxes can + inspect and modify TCP header fields and may break unexpectedly when they encounter + anything they don’t understand. This makes it practically impossible to deploy any + changes to the TCP protocol that change the wire format. -3. Handshake inefficiency: the 3-way handshake is inefficient, as it spends 1-RTT on verifying - the client’s address. +3. Handshake inefficiency: TCP spends one network round-trip (RTT) on verifying the + client's address. Only after this can TLS start the cryptographic handshake, consuming + another RTT. Setting up an encrypted connection therefore always takes 2-RTTs. QUIC was designed with the following goals in mind: -- Streams at the transport layer, thereby overcoming HoL blocking +- Making the transport layer aware of streams, so that packet loss doesn't cause HoL blocking + between streams. - Reducing the latency of connection establishment to a single RTT for new connections, and to - allow sending of 0-RTT application data for resumed connections + allow sending of 0-RTT application data for resumed connections. - Encrypting as much as possible. This eliminates the ossification risk, as middleboxes aren't - able to read any encrypted fields, and allows future evolution of the protocol + able to read any encrypted fields. This allows future evolution of the protocol. ### Comparing HTTP/2 and HTTP/3 @@ -158,7 +162,7 @@ which turned into a proposed standard for HTTP/3 in of the existing transfer protocols HTTP/2 and HTTP over QUIC in one standard for faster and more stable data transmission. -The following diagram illustrates the OSI model for HTTP/2 and HTTP/3: +The following diagram illustrates the OSI model for HTTP/2 and HTTP/3 [1]: ![HTTP/2 & HTTP/3 OSI model](https://cloudspoint.xyz/wp-content/uploads/2022/03/http3.png) @@ -180,29 +184,29 @@ found in TCP and use all the advantages of HTTP/2 and HTTP over QUIC. ### What is QUIC? -QUIC combines the functionality of these layers. It sends UDP packets and therefore -it is responsible for loss detection and repair itself. By using encryption, -QUIC avoids ossified middleboxes. The TLS 1.3 handshake is performed in the first flight, -removing the 1-RTT cost of verifying the client’s address. QUIC also exposes multiple -streams, so no stream multiplexer is needed at the application layer. Part of the application -layer is also built directly into QUIC; when you run HTTP on top of QUIC; only a small shim -layer exists that maps -[HTTP semantics](https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html) -onto QUIC streams. +QUIC combines the functionality of these layers. Instead of TCP, it builds on UDP. +When a UDP datagram is lost, it is not automatically retransmitted by the kernel. +QUIC therefore takes responsibility for loss detection and repair itself. By using +encryption, QUIC avoids ossified middleboxes. The TLS 1.3 handshake is performed in +the first flight, removing the cost of verifying the client’s address and saving an +RTT. QUIC also exposes multiple streams (and not just a single byte stream), so +no stream multiplexer is needed at the application layer. Part of the application +layer is also built directly into QUIC. -QUIC supports the resumption of connections (0-RTT connections), allowing a -client to send application data right away, even before the QUIC handshake has finished. - - +In addition, a client can make use of QUIC's 0-RTT feature for subsequent connections +when it has already communicated with a certain server. The client can then send +(encrypted) application data even before the QUIC handshake has finished. ### QUIC in libp2p libp2p only supports bidirectional streams and uses TLS 1.3 by default. +Since QUIC already provides an encrypted, stream-multiplexed connection, libp2p directly uses QUIC streams, without any additional framing. -To authenticate each others' peer IDs, peers encode their peer ID into a self-signed certificate, -which they sign using their host's private key. This is the same way peer IDs are authenticated in -the [libp2p TLS handshake](https://github.com/libp2p/specs/blob/master/tls/tls.md). +To authenticate each others' peer IDs, peers encode their peer ID into a self-signed +certificate, which they sign using their host's private key. This is the same way peer +IDs are authenticated in the +[libp2p TLS handshake](https://github.com/libp2p/specs/blob/master/tls/tls.md). {{% notice "note" %}} @@ -214,3 +218,7 @@ two nodes using QUIC only takes a single RTT. Following the multiaddress format described earlier, a standard QUIC connection will look like: `/ip4/127.0.0.1/udp/65432/quic/`. + +## References + +[1] [What is HTTP/3 by Cloudspoint](https://cloudspoint.xyz/what-is-http3/) From 16f13ede75da359e5d8903129230e26621ac7bbd Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Thu, 29 Sep 2022 03:41:15 -0400 Subject: [PATCH 17/18] edits --- content/concepts/transport.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index ec4f00f5..b9f97990 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -143,14 +143,14 @@ services and Chrome in 2014, and was later standardized by the IETF in 3. Handshake inefficiency: TCP spends one network round-trip (RTT) on verifying the client's address. Only after this can TLS start the cryptographic handshake, consuming - another RTT. Setting up an encrypted connection therefore always takes 2-RTTs. + another RTT. Setting up an encrypted connection therefore always takes 2 RTTs. QUIC was designed with the following goals in mind: - Making the transport layer aware of streams, so that packet loss doesn't cause HoL blocking between streams. - Reducing the latency of connection establishment to a single RTT for new connections, and to - allow sending of 0-RTT application data for resumed connections. + allow sending of 0 RTT application data for resumed connections. - Encrypting as much as possible. This eliminates the ossification risk, as middleboxes aren't able to read any encrypted fields. This allows future evolution of the protocol. @@ -173,7 +173,7 @@ A web browser connection typically entails the following **(TCP+TLS+HTTP/2)**: - TCP provides a reliable, bidirectional connection between two end systems. 2. Security layer: A TLS handshake runs on top of TCP to establish an encrypted and authenticated connection. - - Standard TLS over TCP requires 3-RTT. A typical TLS 1.3 handshake takes 1-RTT. + - Standard TLS over TCP requires 3 RTT. A typical TLS 1.3 handshake takes 1 RTT. 3. Application layer: HTTP runs on a secure transport connection to transfer information and applies a stream muxer to serve multiple requests. - Application data starts to flow. @@ -193,7 +193,7 @@ RTT. QUIC also exposes multiple streams (and not just a single byte stream), so no stream multiplexer is needed at the application layer. Part of the application layer is also built directly into QUIC. -In addition, a client can make use of QUIC's 0-RTT feature for subsequent connections +In addition, a client can make use of QUIC's 0 RTT feature for subsequent connections when it has already communicated with a certain server. The client can then send (encrypted) application data even before the QUIC handshake has finished. From 74d97ddd137c3d8dbe79c8f5de5db607d3726de6 Mon Sep 17 00:00:00 2001 From: Danny Salman Date: Fri, 30 Sep 2022 05:45:51 -0400 Subject: [PATCH 18/18] Apply suggestions from code review Co-authored-by: Marten Seemann --- content/concepts/transport.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/content/concepts/transport.md b/content/concepts/transport.md index b9f97990..76bb4114 100644 --- a/content/concepts/transport.md +++ b/content/concepts/transport.md @@ -156,9 +156,8 @@ QUIC was designed with the following goals in mind: ### Comparing HTTP/2 and HTTP/3 -The IETF introduced a new hypertext transfer protocol standard in late 2018, -which turned into a proposed standard for HTTP/3 in -[RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114). HTTP/3 combines the advantages +In addition to defining the QUIC transport, the IETF also standardized a new version of HTTP that runs on top of QUIC: HTTP/3 ( +[RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114)). HTTP/3 combines the advantages of the existing transfer protocols HTTP/2 and HTTP over QUIC in one standard for faster and more stable data transmission.