官术网_书友最值得收藏!

1.4 QUIC的誕生

根據TCP、TLS和HTTP進化歷史的描述,我們可以看出每個層都在嘗試解決現實世界中遇到的問題。其中最想要的特性就是盡早發送數據,減少用戶感知到的延遲,如TCP Fast Open、TLS False Start等;另外,應用希望更快地發送和接收數據,這方面的改進如HTTP的多路復用,但可能遇到TCP的隊首阻塞導致的帶寬利用率不足的問題;在解決這些問題的過程中又遇到了協議僵化,無法將新特性廣泛應用。我們希望能有一個新的傳輸協議徹底解決這些問題,于是QUIC來了!

谷歌于2012年提出了QUIC,隨后開始在瀏覽器和服務中使用。QUIC最初的定義是Quick UDP Internet Connections,思想是基于UDP提供并發、安全的傳輸方式,同時改進了TCP中存在的一些其他問題,比如擁塞控制、協議僵化、啟動慢、重連慢、安全弱等見https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqsQx7rFV-ev2jRFUoVD34/edit#。。QUIC基本功能和位置如圖1-32所示。

圖1-32 QUIC基本功能和位置

QUIC主要從以下幾個方面改進了傳統的傳輸方式。

1)實現了沒有隊首阻塞的并發。HTTP2為了支持并發,增加了流和幀的概念,通過幀的封裝實現了流的并發,如圖1-33所示。但是HTTP2是基于TCP的,TCP并看不到流,而是將HTTP2的所有幀作為一個字節流傳輸,也就只能按照整個TCP連接按序交付,如果一塊數據丟失,其他數據即使收到了也不能交付,這就是TCP的隊首阻塞,這在一定程度上影響了HTTP2的并發。為了解決這個問題,QUIC借鑒了HTTP2中流的思想,將流的概念引入傳輸層,傳輸層通過幀的封裝識別了流;通過遞增的報文編號檢測丟包,與應用數據交付分離,從而實現了傳輸層的并發。如果QUIC丟了一個報文,僅僅影響對應流的交付,不會阻塞其他流。

圖1-33 連接、流和幀

2)盡可能地加密。QUIC與TLS 1.3緊密協作,完成了數據加密,提供了數據的安全性和保密性,實現了比TCP+TLS更好的安全,如圖1-34所示。此外還增加了QUIC報文的首部加密,除保證了報文安全性,提高了攻擊門檻,還避免了協議僵化。這是因為中間件看不到QUIC報文的報文編號等信息,無法做進一步處理,后續端點想要修改QUIC的行為就不需要考慮大部分中間件的兼容性了。QUIC是與TLS深度融合的,早在HTTP2標準討論的時候,就有提出過強制加密見https://http2.github.io/faq/#does-http2-require-encryption和https://lists.w3.org/Archives/Public/ietf-http-wg/2013JulSep/0909.html。,最終雖然沒有寫入標準,但是HTTP2的實現基本都是僅支持與加密共同使用(TCP+TLS),HTTP2的明文方式也被證明存在安全問題見https://bishopfox.com/blog/h2c-smuggling-request。,所以QUIC選擇了必須加密的傳輸協議。

圖1-34 加密部分對比

3)選擇UDP作為底層傳輸。QUIC底層傳輸基于UDP,從而提供避免隊首阻塞的條件,也兼容了主機和中間件。一方面,UDP只管將數據報(其中封裝了一個或多個QUIC報文)發出去,而不管報文之間的順序,所以UDP本身不會形成隊首阻塞,可以更好地實現并發。另外一方面,多年以來互聯網技術的發展使主機(包括電腦、手機、服務器、虛擬機等)和中間件(NAT、防火墻、負載均衡器等)幾乎成了TCP和UDP的天下,如果采用新的協議,主機和中間件都要升級,這在互聯網中不太現實,起碼中間件大部分都不受自己控制,無法進行升級。所以要使用新的協議,必須考慮當前的現實,UDP作為底層傳輸是現實的選擇。

4)用戶態實現。QUIC將功能放在了用戶態(而TCP位于內核態),如圖1-35所示,這樣可以更加靈活地修改、升級,防止了重演TCP在主機上的僵化問題。前文提到的很多問題,都可以通過改進TCP來解決,但都沒有大規模應用,這是由于TCP位于內核態,難以單獨升級,當然中間件的僵化也是原因之一,這應該也是QUIC對于僵化如此敏感的原因。

圖1-35 各功能在用戶態和內核態的分布

5)低延遲的連接建立。QUIC通過與TLS 1.3的緊密結合,實現了首次最低1-RTT發送應用數據;恢復連接時發送應用數據最低只需0-RTT。這樣在時延較大或者丟包率較高的弱網環境中可以提供更好的用戶體驗,與其他方案的對比如圖1-36和圖1-37所示。需要說明的是,TFO+TLS 1.3也能實現首次1-RTT和重連0-RTT的數據發送,但是除了在最早發送應用數據與QUIC相同之外沒有其他優勢,比如:避免隊首阻塞、更強的安全性、防止協議僵化等。

圖1-36 首次連接對比

圖1-37 恢復連接對比

6)無縫的連接遷移。QUIC的連接基于連接標識,改變IP或者UDP端口號并不影響連接的識別,因此可以實現無縫的連接遷移,具體過程見3.6節。但是這給負載均衡帶來了挑戰,具體見第6章。另外也增加了放大攻擊風險,具體考慮見3.6節。

7)改進的流量控制。QUIC的流量控制通過對偏移的限額實現,可以支持連接和流兩個級別。除此之外,還可以限制打開中流的個數。因為完成了報文編號和數據偏移的分離,可以支持亂序確認,這比TCP+HTTP2的流量控制更加靈活。

8)改進的擁塞控制。QUIC在擁塞控制方面做出了很多優化,包括不同加密級別互相獨立的報文編號空間、單向遞增的報文編號、更清晰的丟包周期、確認過的報文不允許反悔、支持更多的確認范圍、顯式修正延遲等。對于使用多個TCP連接實現并發的應用來說,更明顯的好處是可以協調所有數據間的網絡占用,而不會像多個TCP連接一樣競爭網絡資源。

9)協議行為作為負載。TCP將協議的行為都放在首部,如ACK、序號、選項等,由于TCP首部長度限制為40字節,表達力受到了很大限制,擴展也會比較困難,而且即使使用了TLS,協議行為還是都暴露了出來。QUIC則將協議的行為大部分都作為不同的幀放在負載中攜帶,可以方便地擴展。

谷歌最初使用的是gQUIC,跟IETF QUIC有些不同。直到2015年6月,谷歌將QUIC提交給IETF,才開始了QUIC的標準化之路。之后,IETF正式認定QUIC為一個名稱,而不再作為縮寫。QUIC的發展歷程如圖1-38所示。

圖1-38 QUIC的發展歷程

2021年5月,QUIC一系列核心草案獲得標準化,包括如下內容。

《RFC8999 QUIC的版本無關屬性》定義了QUIC所有版本通用的屬性。

《RFC9000 QUIC:基于UDP的多路和安全傳輸》定義了傳輸協議的核心內容。

《RFC9001使用TLS保護QUIC》描述了怎么使用TLS來保護QUIC。

《RFC9002 QUIC丟包檢測和擁塞控制》描述了QUIC的丟包檢測和擁塞控制機制。

此后,QUIC標準被不斷完善。2022年3月,QUIC的不可靠擴展實現了標準化——《RFC9221 QUIC不可靠數據報擴展》。2022年8月,《RFC9287使用QUIC位》也標準化了。

很多應用從2022年也開始了使用QUIC的標準化之路。2022年5月,DNS標準化了基于QUIC的傳輸方式,發布了《RFC9250基于專用QUIC連接的DNS》。

2022年6月基于QUIC的HTTP3也標準化了,包括兩個QUIC定制化的標準:

《RFC9114 HTTP3》描述了基于QUIC的HTTP語義映射,還確定了QUIC包含的HTTP2功能,并描述了如何將HTTP2擴展移植到HTTP3。

《RFC9204 QPACK:HTTP3的字段壓縮》基于QUIC改進了HPACK,以盡量避免隊首阻塞。

2022年9月,IETF標準化了用于指導中間件管理QUIC和應用使用QUIC的兩個標準,即《RFC9312 QUIC傳輸協議的可管理性》和《RFC9308 QUIC傳輸協議的適用性》。

QUIC和SCTP有很多相似之處,很多特性可以對比來看。我們可以看出,多宿主多流模式是傳輸協議的發展方向,安全也成為傳輸協議需要考慮的重要問題,總的來說傳輸層功能越來越多了。

SCTP和QUIC的不同出身也決定了他們的不同應用范圍。

SCTP來源于電話信號傳輸的需求,作為核心網傳輸層更在意可靠性、單個消息的低時延,甚至支持了應用可以定制的消息有效期,超出有效期則不再重傳,這對電話信號來說簡直太友好了!在核心網中,中間件都是運營商控制的,可以不太在意兼容性,這給了SCTP生存空間。

QUIC來源于谷歌,也就更在意終端用戶的感受,所以QUIC作為應用的傳輸層更在意首包低時延,可以更快地發送應用數據,讓用戶感受到更低的時延。QUIC也在意更弱網環境和移動設備,設計上對手機等要使用無線傳輸的設備來說比較友好;同時QUIC也考慮了中間件的支持,底層傳輸選用UDP,這在復雜網絡環境中能更好地傳輸,同樣也是對個人終端友好的表現。QUIC還支持了不可靠的數據報方式,對于終端上的直播和游戲類應用提供了更好的支持。

WebRTC(Web Real-Time Communications,網絡實時通訊)也支持了QUIC,因為QUIC比SCTP更適合終端傳輸,當然兩者都是谷歌推動標準化的,結合有一定的必然性。谷歌提出的新一代實時數據傳遞框架WebTransport直接采用了HTTP3,并使用QUIC提高傳輸效率。

主站蜘蛛池模板: 大丰市| 嘉定区| 阿克| 昌平区| 锡林浩特市| 宜阳县| 成都市| 博罗县| 中方县| 平舆县| 唐山市| 宜兰市| 山丹县| 京山县| 垦利县| 宽甸| 保亭| 通河县| 徐州市| 广东省| 黎川县| 久治县| 隆昌县| 哈密市| 湾仔区| 巴马| 泾阳县| 湖州市| 靖江市| 铁岭县| 安泽县| 天水市| 萍乡市| 闻喜县| 黔南| 盖州市| 吉木萨尔县| 白山市| 蓬溪县| 陕西省| 云梦县|