QUIC(Quick UDP Internet Connections,快速UDP互聯網連接)是Google提出的一種基於UDP改進的通信協議,其目的是降低網絡通信的延遲,提供更好的用戶互動體驗。
QUIC的主要特點包括:具有SPDY(SPDY是谷歌研制的提升HTTP速度的協議,是HTTP/2.0的基礎)所有的優點;0-RTT連接;減少丟包;前向糾錯,減少重傳時延;自適應擁塞控制, 減少重新連接;相當於TLS加密。
1.重傳與恢復
與TCP類似,QUIC每發送一個包后,都會等待回復一個確認包。當丟包率超過協議的糾錯門限時,會顯式或隱式地進行重傳
對於某些重要的數據包,如初始密鑰協商時的數據包,在建立連接時非常重要,如果這類包丟失會阻塞整體數據流。QUIC對於這一類數據包在確認發生丟失前就會嘗試重傳,通常是等待較短的時間(如20ms)沒收到確認后就馬上再次發送。這樣在網絡中會有若干個相同的包同時傳輸,只要有一個能成功抵達就完成了連接,這樣降低了丟包率。接收方對於關鍵數據包的多次發送和普通數據包的超時重傳,都采用相同的重復包處理機制
QUIC在擁塞避免算法的基礎上還加入了心跳包,用於減少丟包率
QUIC使用了FEC(前向糾錯碼)來恢復數據,FEC采用簡單異或的方式。每次發送一組數據,包括若干個數據包后,並對這些數據包依次作異或運算,最后的結果作為一個FEC包再發送出去。接收方收到一組數據后,根據數據包和FEC包即可以進行校驗和糾錯。
2.安全性
QUIC對每個散裝的UDP包都進行了加密和認證的保護,並且避免使用前向依賴的處理方法(如CBC模式),這樣每個UDP包可以獨立地根據IV進行加密或認證處理。
QUIC采用了兩級密鑰機制:初始密鑰和會話密鑰。初次連接時不加密,並協商初始密鑰。初始密鑰協商完畢后會馬上再協商會話密鑰,這樣可以保證密鑰的前向安全性,之后可以在通信的過程中就實現對密鑰的更新。接收方意識到有新的密鑰要更新時,會嘗試用新舊兩種密鑰對數據進行解密,直到成功才會正式更新密鑰,否則會一直保留舊密鑰有效。
3. 0-RTT握手過程
QUIC握手的過程是需要一次數據交互,0-RTT時延即可完成握手過程中的密鑰協商,比TLS相比效率提高了5倍,且具有更高的安全性。
QUIC在握手過程中使用Diffie-Hellman算法協商初始密鑰,初始密鑰依賴於服務器存儲的一組配置參數,該參數會周期性的更新。初始密鑰協商成功后,服務器會提供一個臨時隨機數,雙方根據這個數再生成會話密鑰。
具體握手過程如下:
(1) 客戶端判斷本地是否已有服務器的全部配置參數,如果有則直接跳轉到(5),否則繼續
(2) 客戶端向服務器發送inchoate client hello(CHLO)消息,請求服務器傳輸配置參數
(3) 服務器收到CHLO,回復rejection(REJ)消息,其中包含服務器的部分配置參數
(4) 客戶端收到REJ,提取並存儲服務器配置參數,跳回到(1)
(5) 客戶端向服務器發送full client hello消息,開始正式握手,消息中包括客戶端選擇的公開數。此時客戶端根據獲取的服務器配置參數和自己選擇的公開數,可以計算出初始密鑰。
(6) 服務器收到full client hello,如果不同意連接就回復REJ,同(3);如果同意連接,根據客戶端的公開數計算出初始密鑰,回復server hello(SHLO)消息,SHLO用初始密鑰加密,並且其中包含服務器選擇的一個臨時公開數。
(7) 客戶端收到服務器的回復,如果是REJ則情況同(4);如果是SHLO,則嘗試用初始密鑰解密,提取出臨時公開數
(8) 客戶端和服務器根據臨時公開數和初始密鑰,各自基於SHA-256算法推導出會話密鑰
(9) 雙方更換為使用會話密鑰通信,初始密鑰此時已無用,QUIC握手過程完畢。之后會話密鑰更新的流程與以上過程類似,只是數據包中的某些字段略有不同。
Quic協議原理
1,0RTT 建連
先聲明一點,如果一對使用QUIC進行加密通信的雙方此前從來沒有通信過,0RTT是不可能的。
所以第一次C和S建連還是會走正常的tls握手流程,但過了一會兒或者一段時間后,C又想和S通信,此時C已經有了剛剛和S協商出來的密鑰(可能是存在內存or外存)。C就會利用剛剛的密鑰K1來和S加密首次數據,在第二個RTT期間,S會和C協商出新的密鑰K2,作為接下來的通信密鑰。
2,沒有歧義的重傳
TCP 重傳的 包 的 sequence number 和原始的 包 的 Sequence Number 是保持不變的,也正是由於這個特性,引入了 Tcp 重傳的歧義問題。
超時事件 RTO 發生后,客戶端發起重傳,然后接收到了 Ack 數據。由於Sequence Number一樣,這個 Ack 到底是原始請求的響應還是重傳請求的響應呢?這就間接導致了RTT計算的歧義。
Quic 使用 Packet Number 代替了 TCP 的 sequence number,並且每個 Packet Number 都嚴格遞增,也就是說就算 Packet N 丟失了,重傳的 Packet N 的 Packet Number 已經不是 N,而是一個比 N 大的值,這就解決了RTT計算的歧義問題。
3,保證包的順序
QUIC 引入了一個叫 Stream Offset 的概念。
假設 Packet N 丟失了,發起重傳,重傳的 Packet Number 是 N+2,但是它的 Stream 的 Offset 依然是 x,這樣就算 Packet N + 2 是后到的,依然可以將 Stream x 和 Stream x+y 按照順序組織起來。
4,解決ack delay
TCP 的 RTT 計算:
Quic的RTT計算:
5,隊頭阻塞
拿http2舉例,
http2 在一個 TCP 連接上同時發送 4 個 請求。其中 請求1 已經正確到達,並被應用層讀取。但是 請求2 的第三個 tcp包丟失了,為了保證數據的順序,需要發送端重傳第 3 個包才能通知應用層讀取接下去的數據,雖然這個時候 請求3 和 請求4 的全部數據已經到達了接收端,但都被阻塞住了。
Quic基於UDP,各個請求之間相互獨立,比如 請求2 丟了一個 Pakcet,不會影響 請求3 和 請求4,不存在 TCP 隊頭阻塞。
四,Quic和http3
QUIC 協議最初是由Google發起的項目,后面慢慢成為了 HTTP/2-encrypted-over-UDP 協議。
當 IETF 開始進行協議標准化工作時,協議被分為兩層:傳輸部分和 HTTP 部分。這個想法的初衷是考慮到該傳輸協議也可用於傳輸其他數據,而不僅僅用於 HTTP 協議。
社區中大家使用 iQUIC 和 gQUIC 這樣的非正式名稱來引用這些不同版本的協議,以便將IETF 和 Google提出的QUIC 協議分開。
通過 iQUIC 發送 HTTP 請求的協議被稱為HTTP-over-QUIC,即HTTP3。
例子:
https://www.cnblogs.com/jb2011/p/8458549.html
參考資料
下一代通信協議:Quic
https://knownsec-fed.com/2018-01-19-xia-yi-dai-tong-xin-xie-yi-quic/
QUIC協議是如何做到0RTT加密傳輸的
https://blog.csdn.net/dog250/article/details/80935534
Web服務器快速啟用QUIC協議
https://my.oschina.net/u/347901/blog/1647385
QUIC協議原理分析
https://zhuanlan.zhihu.com/p/32553477
QUIC在騰訊的實踐及性能優化
https://zhuanlan.zhihu.com/p/32560981
七牛雲 QUIC 推流方案如何實現直播 0 卡頓
https://zhuanlan.zhihu.com/p/33698793
當我們在討論http隊頭阻塞時,我們在討論什么?
https://liudanking.com/arch/what-is-head-of-line-blocking-http2-quic/
QUIC官方文檔
https://www.chromium.org/quic
QUIC協議規范
https://www.wolfcstech.com/2017/01/13/QUIC%E5%8D%8F%E8%AE%AE%E8%A7%84%E8%8C%83/