快速UDP网络连接

**QUIC**（讀作「quick」）是一個通用的傳輸層網路協定，最初由 Google 的 Jim Roskind 設計。該協定於 2012 年實現並部署，2013 年隨著實驗範圍的擴大而公開發布，並向 IETF 描述。雖然長期處於網際網路草案階段，但從 Chrome 瀏覽器至 Google 伺服器的連接中超過一半的連接都使用了 QUIC。Microsoft Edge、Firefox 都已支援此協定；Safari 實現了 QUIC，但預設情況下沒有啟用。QUIC 於 RFC9000 中被正式標準化。

雖然 QUIC 的名稱最初是「快速 UDP 網際網路連接」（Quick UDP Internet Connection）的首字母縮寫，但 IETF 指定的標準中 QUIC 並不是任何內容的縮寫。QUIC 提高了目前使用 TCP 的面向連接的網路應用的效能。它透過使用使用者資料報協定（UDP）在兩個端點之間建立若干個多路連接來實現這一目標，其目的是為了在網路層淘汰 TCP，以滿足許多應用的需求，因此該協定偶爾也會獲得 「TCP/2」的暱稱。

QUIC 與 HTTP/2 的多路復用連接協同工作，允許多個資料流獨立到達所有端點，因此不受涉及其他資料流的丟包影響。相反，HTTP/2 建立在傳輸控制協定（TCP）上，如果任何一個 TCP 封包延遲或遺失，所有多路資料流都會遭受隊頭阻塞延遲。

QUIC 的次要目標包括降低連接和傳輸時延，以及每個方向的頻寬估計以避免擁塞。它還將擁塞控制演算法移到了兩個端點的使用者空間，而不是核心空間，據稱這將使這些演算法得到更快的改進。此外，該協定還可以擴充正向錯誤校正（FEC），以進一步提高預期錯誤時的效能，這被視為協定演進的下一步。

2015 年 6 月，QUIC 規範的網際網路草案提交給 IETF 進行標準化。2016 年，成立了 QUIC 工作群組。2018 年 10 月，IETF 的 HTTP 工作群組和 QUIC 工作群組共同決定將 QUIC 上的 HTTP 對映稱為 "HTTP/3"，以提前使其成為全球標準。2021 年 5 月 IETF 公布 RFC9000，QUIC 規範推出了標準化版本。

## 背景

傳輸控制協定 (TCP) 旨在為兩個端點之間傳送資料流提供一個介面。資料交給 TCP 系統，TCP 系統確保資料以完全相同的形式傳到另一端，否則連接將提示存在錯誤。

為此，TCP 將資料分解成網路封包，並在每個封包中添加少量資料。這些附加資料包括一個序列號，用於檢測遺失或到達順序不正確的封包，以及一個校驗和，可以檢測封包資料內的錯誤。當其中任何一個問題發生時，TCP 使用自動重傳請求（ARQ）告訴傳送方重新傳送遺失或損壞的封包。

在大多數實現中，TCP 會將連接上的任何錯誤視為阻塞，停止進一步傳輸，直到錯誤得到解決或連接被視為失敗。如果使用單個連接來傳送多個資料流，就像在 HTTP/2 協定中那樣，所有這些資料流都會被阻止，儘管其中只有一個可能有問題。例如，如果在下載用於收藏夾圖示的 GIF 圖像時出現一個錯誤，頁面的其餘部分將等待問題得到解決。

由於 TCP 系統被設計成類似「資料管道」或流，TCP 刻意被設計成並不知曉其傳輸的資料之細節。如果對傳輸的資料存在額外需求，如需要使用 TLS 加密，那麼此類協定必須建立在 TCP 的上層。每種協定都需要自己的握手過程，結果會導致在建立連接前需要大量交換資料，加之長距離通信的原生延遲，從而給整個傳輸過程增加大量開銷。

## 介紹

QUIC 旨在提供幾乎等同於 TCP 連接的可靠性，但延遲大大減少。它主要透過兩個理解 HTTP 流量的行為來實現這一點。

第一個變化是在連接建立期間大大減少開銷。由於大多數 HTTP 連接都需要 TLS，因此 QUIC 使協商金鑰和支援的協定成為初始握手過程的一部分。
當客戶端打開連接時，伺服器回應的封包包括將來的封包加密所需的資料。這消除了 TCP 上的先連接並透過附加封包協商安全協定的需要。其他協定可以以相同的方式進行服務，並將多個步驟組合到一個請求中。
然後，這些資料既可用於初始設定中的後續請求，也可用於未來的請求。

QUIC 使用 UDP 協定作為其基礎，不包括遺失恢復。相反，每個 QUIC 流是單獨控制的，並且在 QUIC 級別而不是 UDP 級別重傳遺失的資料。這意味著如果在一個流中發生錯誤，協定棧仍然可以獨立地繼續為其他流提供服務。
這在提高易出錯鏈路的效能方面非常有用，因為在大多數情況下 TCP 協定通知封包遺失或損壞之前可能會收到大量的正常資料，但是在糾正錯誤之前其他的正常請求都會等待甚至重發。
QUIC 在修復單個流時可以自由處理其他資料，也就是說即使一個請求發生了錯誤也不會影響到其他的請求。

QUIC 包括許多其他更普通的更改，這些更改也可以最佳化整體延遲和吞吐量。例如，每個封包是單獨加密的，因此加密資料時不需要等待部分封包。
在 TCP 下通常不可能這樣做，其中加密記錄在位元組流中，並且協定棧不知道該流中的更高層邊界。這些可以由執行在更上層的協定進行協商，但 QUIC 旨在透過單個握手過程完成這些。

QUIC 的另一個目標是提高網路切換期間的效能，例如當行動裝置的使用者從 WiFi 熱點切換到行動網路時發生的情況。
當這發生在 TCP 上時，一個冗長的過程開始了：每個現有連接一個接一個地逾時，然後根據需要重新建立。期間存在較高延遲，因為新連接需要等待舊連接逾時後才會建立。
為解決此問題，QUIC 包含一個連接識別碼，該識別碼唯一地標識客戶端與伺服器之間的連接，而無論源 IP 位址是什麼。這樣只需傳送一個包含此 ID 的封包即可重新建立連接，因為即使使用者的 IP 位址發生變化，原始連接 ID 仍然有效。

QUIC 在應用程式空間中實現，而不是在作業系統核心中實現。當資料在應用程式之間移動時，這通常會由於上下文交換而呼叫額外的開銷。
但是在 QUIC 下協定棧旨在由單個應用程式使用，每個應用程式使用 QUIC 在 UDP 上代管自己的連接。最終差異可能非常小，因為整個 HTTP/2 堆疊的大部分已經存在於應用程式（或更常見的庫）中。
將剩餘部分放在這些庫中，基本上是糾錯，對 HTTP/2 堆疊的大小或整體複雜性幾乎沒有影響。

QUIC 允許更容易地進行未來更改，因為它不需要更改核心就可以進行更新。
QUIC 的長期目標之一是添加正向錯誤校正和改進的擁塞控制。

關於從 TCP 遷移到 UDP 的一個問題是 TCP 被廣泛採用，並且網際網路基礎設施中的許多中間裝置被調整為 UDP 速率限制甚至阻止 UDP。
Google 進行了一些探索性實驗來描述這一點，發現只有少數連接存在此問題。所以 Chromium 的網路堆疊同時打開 QUIC 和傳統 TCP 連接，並在 QUIC 連接失敗時以零延遲回退到 TCP 連接。

### gQUIC 與 iQUIC

由 Google 建立並以 QUIC 的名稱提交給 IETF 的協定與隨後在 IETF 中建立的 QUIC 完全不同（儘管名稱相同）。
最初的 Google QUIC（也稱為 gQUIC）嚴格來說是透過加密 UDP 傳送 HTTP/2 影格的協定，而 IETF 建立的 QUIC 是通用傳輸協定，也就是說 HTTP 以外的其他協定（如 SMTP、DNS、SSH、Telnet、NTP）也可以使用它。重要的是要注意並記住其差異。
自 2012 年以來，Google 在其服務及 Chrome 中使用的 QUIC 版本（直到 2019 年 2 月）為 Google QUIC。隨著時間的推移，它正在逐漸變得類似於 IETF QUIC（也稱為 iQUIC）。

## 流量控制

與大多數傳輸協定一樣，QUIC 具有流量控制以保護接收端免受緩衝區 overflow 的影響。QUIC 是基於 UDP 傳輸，而 UDP 沒有流量控制，因此 QUIC 實現了自己的流量控制機制。與 TCP 不同，QUIC 並非透過 ACK 回應目前接收到第幾筆資料，而是透過 control frame 實現類似於 HTTP/2 的基於信用的方案。

## 實現

### 客戶端

Google Chrome 於 2012 年開始開發 QUIC 協定並且於 Chromium 版本 29（2013 年 8 月 20 日釋出）發布。QUIC 協定在當前 Chrome 版本中被預設開啟，活躍的對談列表在 `_chrome://net-internals/#quic_` 中可見。

### 伺服器端

截至 2017 年，有三種活躍維護中的實現。Google 的伺服器及 Google 發布的原型伺服器 （頁面存檔備份，存於網際網路檔案館）使用 Go 語言編寫的 quic-go （頁面存檔備份，存於網際網路檔案館）及 Caddy 的試驗性 QUIC 支援。在 2017 年 7 月 11 日，LiteSpeed 科技正式在他們的負載均衡（WebADC （頁面存檔備份，存於網際網路檔案館））及 LiteSpeed 伺服器中支援 QUIC。截止 17 年 12 月， 97.5% 的使用 QUIC 協定的網站在 LiteSpeed 伺服器中執行。

另有幾種不再維護的社群產品，基於 Chromium 實現並且減少使用依賴的 libquic （頁面存檔備份，存於網際網路檔案館）、提供 libquic 的 Go 語言繫結的 goquic （頁面存檔備份，存於網際網路檔案館）、打包為 Docker 鏡像的用來轉換為普通 HTTP 請求的反向代理 quic-reverse-proxy （頁面存檔備份，存於網際網路檔案館）。

2020 年 12 月，支援 DNS-over-QUIC 協定的公共 DNS 解析器，由 AdGuard 首次公開推出服務。

## 參見

* HTTP/3
* HTTP/2
* SPDY
* 串流控制傳輸協定
* UDT
* TLS
* DTLS
* 三方交握

## 參考資料

## 外部連結

* Chromium: QUIC, a multiplexed stream transport over UDP （頁面存檔備份，存於網際網路檔案館）
* QUIC: Design Document and Specification Rationale（頁面存檔備份，存於網際網路檔案館）, Jim Roskind's original document (2012/2013)
* Daniel Stenberg: HTTP/3 explained （頁面存檔備份，存於網際網路檔案館）
* Linux Weekly News: Connecting on the QUIC （頁面存檔備份，存於網際網路檔案館） (2013)
* QUIC: （頁面存檔備份，存於網際網路檔案館）, IETF-88 TSV Area Presentation (2013-11-07)
* Chromium Blog: Experimenting with QUIC （頁面存檔備份，存於網際網路檔案館） (2013)
* QUIC: next generation multiplexed transport over UDP （頁面存檔備份，存於網際網路檔案館） (Google Developers, 2014)
* HTTP over UDP: an Experimental Investigation of QUIC（頁面存檔備份，存於網際網路檔案館）
* Multipath QUIC （頁面存檔備份，存於網際網路檔案館） (extension to QUIC)
* Innovating Transport with QUIC: Design Approaches and Research Challenges（頁面存檔備份，存於網際網路檔案館） (2017)