QUIC(Quick UDP Internet Connections,快速UDP互聯網連接)是Google提出的一種基於UDP改進的通信協議,其目的是降低網絡通信的延遲,提供更好的用戶互動體驗。
QUIC的主要特點包括:具有SPDY(SPDY是谷歌研制的提升HTTP速度的協議,是HTTP/2.0的基礎)所有的優點;0-RTT連接;減少丟包;前向糾錯,減少重傳時延;自適應擁塞控制, 減少重新連接;相當於TLS加密。
有關QUIC的詳細資料可以參考http://www.chromium.org/quic里的相關文檔和代碼。
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握手過程完畢。之后會話密鑰更新的流程與以上過程類似,只是數據包中的某些字段略有不同。